@@ -983,13 +983,13 @@ struct Matrix<'p, Cx: TypeCx> {
983
983
/// each column must have the same type. Each column corresponds to a place within the
984
984
/// scrutinee.
985
985
rows : Vec < MatrixRow < ' p , Cx > > ,
986
- /// Stores an extra fictitious row full of wildcards. Mostly used to keep track of the
987
- /// relevancy. This must obey the same invariants as the real rows.
988
- wildcard_row : PatStack < ' p , Cx > ,
989
986
/// Track the type of each column/place.
990
987
place_ty : SmallVec < [ Cx :: Ty ; 2 ] > ,
991
988
/// Track for each column/place whether it contains a known valid value.
992
989
place_validity : SmallVec < [ ValidityConstraint ; 2 ] > ,
990
+ /// Track whether the virtual wildcard row used to compute exhaustiveness is relevant. See top
991
+ /// of the file for details on relevancy.
992
+ wildcard_row_is_relevant : bool ,
993
993
}
994
994
995
995
impl < ' p , Cx : TypeCx > Matrix < ' p , Cx > {
@@ -1013,13 +1013,11 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
1013
1013
scrut_ty : Cx :: Ty ,
1014
1014
scrut_validity : ValidityConstraint ,
1015
1015
) -> Self {
1016
- let wild_pattern = wildcard_arena. alloc ( DeconstructedPat :: wildcard ( scrut_ty) ) ;
1017
- let wildcard_row = PatStack :: from_pattern ( wild_pattern) ;
1018
1016
let mut matrix = Matrix {
1019
1017
rows : Vec :: with_capacity ( arms. len ( ) ) ,
1020
- wildcard_row,
1021
1018
place_ty : smallvec ! [ scrut_ty] ,
1022
1019
place_validity : smallvec ! [ scrut_validity] ,
1020
+ wildcard_row_is_relevant : true ,
1023
1021
} ;
1024
1022
for ( row_id, arm) in arms. iter ( ) . enumerate ( ) {
1025
1023
let v = MatrixRow {
@@ -1067,17 +1065,16 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
1067
1065
) -> Matrix < ' p , Cx > {
1068
1066
let tys = pcx. ctor_sub_tys ( ctor) ;
1069
1067
let new_place_ty = tys. iter ( ) . chain ( self . place_ty [ 1 ..] . iter ( ) ) . copied ( ) . collect ( ) ;
1070
- let wildcard_row = self . wildcard_row . pop_head_constructor ( pcx, ctor, tys, ctor_is_relevant) ;
1071
1068
let new_validity = self . place_validity [ 0 ] . specialize ( ctor) ;
1072
1069
let new_place_validity = std:: iter:: repeat ( new_validity)
1073
1070
. take ( ctor. arity ( pcx) )
1074
1071
. chain ( self . place_validity [ 1 ..] . iter ( ) . copied ( ) )
1075
1072
. collect ( ) ;
1076
1073
let mut matrix = Matrix {
1077
1074
rows : Vec :: new ( ) ,
1078
- wildcard_row,
1079
1075
place_ty : new_place_ty,
1080
1076
place_validity : new_place_validity,
1077
+ wildcard_row_is_relevant : self . wildcard_row_is_relevant && ctor_is_relevant,
1081
1078
} ;
1082
1079
for ( i, row) in self . rows ( ) . enumerate ( ) {
1083
1080
if ctor. is_covered_by ( pcx, row. head ( ) . ctor ( ) ) {
@@ -1343,7 +1340,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
1343
1340
) -> WitnessMatrix < Cx > {
1344
1341
debug_assert ! ( matrix. rows( ) . all( |r| r. len( ) == matrix. column_count( ) ) ) ;
1345
1342
1346
- if !matrix. wildcard_row . relevant && matrix. rows ( ) . all ( |r| !r. pats . relevant ) {
1343
+ if !matrix. wildcard_row_is_relevant && matrix. rows ( ) . all ( |r| !r. pats . relevant ) {
1347
1344
// Here we know that nothing will contribute further to exhaustiveness or usefulness. This
1348
1345
// is purely an optimization: skipping this check doesn't affect correctness. See the top of
1349
1346
// the file for details.
@@ -1364,7 +1361,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
1364
1361
}
1365
1362
// No (unguarded) rows, so the match is not exhaustive. We return a new witness unless
1366
1363
// irrelevant.
1367
- return if matrix. wildcard_row . relevant {
1364
+ return if matrix. wildcard_row_is_relevant {
1368
1365
WitnessMatrix :: unit_witness ( )
1369
1366
} else {
1370
1367
// We choose to not report anything here; see at the top for details.
0 commit comments