@@ -983,13 +983,13 @@ struct Matrix<'p, Cx: TypeCx> {
983983 /// each column must have the same type. Each column corresponds to a place within the
984984 /// scrutinee.
985985 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 > ,
989986 /// Track the type of each column/place.
990987 place_ty : SmallVec < [ Cx :: Ty ; 2 ] > ,
991988 /// Track for each column/place whether it contains a known valid value.
992989 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 ,
993993}
994994
995995impl < ' p , Cx : TypeCx > Matrix < ' p , Cx > {
@@ -1013,13 +1013,11 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
10131013 scrut_ty : Cx :: Ty ,
10141014 scrut_validity : ValidityConstraint ,
10151015 ) -> Self {
1016- let wild_pattern = wildcard_arena. alloc ( DeconstructedPat :: wildcard ( scrut_ty) ) ;
1017- let wildcard_row = PatStack :: from_pattern ( wild_pattern) ;
10181016 let mut matrix = Matrix {
10191017 rows : Vec :: with_capacity ( arms. len ( ) ) ,
1020- wildcard_row,
10211018 place_ty : smallvec ! [ scrut_ty] ,
10221019 place_validity : smallvec ! [ scrut_validity] ,
1020+ wildcard_row_is_relevant : true ,
10231021 } ;
10241022 for ( row_id, arm) in arms. iter ( ) . enumerate ( ) {
10251023 let v = MatrixRow {
@@ -1067,17 +1065,16 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
10671065 ) -> Matrix < ' p , Cx > {
10681066 let tys = pcx. ctor_sub_tys ( ctor) ;
10691067 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) ;
10711068 let new_validity = self . place_validity [ 0 ] . specialize ( ctor) ;
10721069 let new_place_validity = std:: iter:: repeat ( new_validity)
10731070 . take ( ctor. arity ( pcx) )
10741071 . chain ( self . place_validity [ 1 ..] . iter ( ) . copied ( ) )
10751072 . collect ( ) ;
10761073 let mut matrix = Matrix {
10771074 rows : Vec :: new ( ) ,
1078- wildcard_row,
10791075 place_ty : new_place_ty,
10801076 place_validity : new_place_validity,
1077+ wildcard_row_is_relevant : self . wildcard_row_is_relevant && ctor_is_relevant,
10811078 } ;
10821079 for ( i, row) in self . rows ( ) . enumerate ( ) {
10831080 if ctor. is_covered_by ( pcx, row. head ( ) . ctor ( ) ) {
@@ -1343,7 +1340,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
13431340) -> WitnessMatrix < Cx > {
13441341 debug_assert ! ( matrix. rows( ) . all( |r| r. len( ) == matrix. column_count( ) ) ) ;
13451342
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 ) {
13471344 // Here we know that nothing will contribute further to exhaustiveness or usefulness. This
13481345 // is purely an optimization: skipping this check doesn't affect correctness. See the top of
13491346 // the file for details.
@@ -1364,7 +1361,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
13641361 }
13651362 // No (unguarded) rows, so the match is not exhaustive. We return a new witness unless
13661363 // irrelevant.
1367- return if matrix. wildcard_row . relevant {
1364+ return if matrix. wildcard_row_is_relevant {
13681365 WitnessMatrix :: unit_witness ( )
13691366 } else {
13701367 // We choose to not report anything here; see at the top for details.
0 commit comments