@@ -847,11 +847,8 @@ impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
847847 self . pats . len ( )
848848 }
849849
850- fn head_opt ( & self ) -> Option < & ' p DeconstructedPat < ' p , Cx > > {
851- self . pats . first ( ) . copied ( )
852- }
853850 fn head ( & self ) -> & ' p DeconstructedPat < ' p , Cx > {
854- self . head_opt ( ) . unwrap ( )
851+ self . pats [ 0 ]
855852 }
856853
857854 fn iter ( & self ) -> impl Iterator < Item = & ' p DeconstructedPat < ' p , Cx > > + Captures < ' _ > {
@@ -874,11 +871,12 @@ impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
874871 & self ,
875872 pcx : & PlaceCtxt < ' _ , ' p , Cx > ,
876873 ctor : & Constructor < Cx > ,
874+ ctor_sub_tys : & [ Cx :: Ty ] ,
877875 ctor_is_relevant : bool ,
878876 ) -> PatStack < ' p , Cx > {
879877 // We pop the head pattern and push the new fields extracted from the arguments of
880878 // `self.head()`.
881- let mut new_pats = self . head ( ) . specialize ( pcx, ctor) ;
879+ let mut new_pats = self . head ( ) . specialize ( pcx, ctor, ctor_sub_tys ) ;
882880 new_pats. extend_from_slice ( & self . pats [ 1 ..] ) ;
883881 // `ctor` is relevant for this row if it is the actual constructor of this row, or if the
884882 // row has a wildcard and `ctor` is relevant for wildcards.
@@ -950,11 +948,12 @@ impl<'p, Cx: TypeCx> MatrixRow<'p, Cx> {
950948 & self ,
951949 pcx : & PlaceCtxt < ' _ , ' p , Cx > ,
952950 ctor : & Constructor < Cx > ,
951+ ctor_sub_tys : & [ Cx :: Ty ] ,
953952 ctor_is_relevant : bool ,
954953 parent_row : usize ,
955954 ) -> MatrixRow < ' p , Cx > {
956955 MatrixRow {
957- pats : self . pats . pop_head_constructor ( pcx, ctor, ctor_is_relevant) ,
956+ pats : self . pats . pop_head_constructor ( pcx, ctor, ctor_sub_tys , ctor_is_relevant) ,
958957 parent_row,
959958 is_under_guard : self . is_under_guard ,
960959 useful : false ,
@@ -984,9 +983,11 @@ struct Matrix<'p, Cx: TypeCx> {
984983 /// each column must have the same type. Each column corresponds to a place within the
985984 /// scrutinee.
986985 rows : Vec < MatrixRow < ' p , Cx > > ,
987- /// Stores an extra fictitious row full of wildcards. Mostly used to keep track of the type of
988- /// each column . This must obey the same invariants as the real rows.
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.
989988 wildcard_row : PatStack < ' p , Cx > ,
989+ /// Track the type of each column/place.
990+ place_ty : SmallVec < [ Cx :: Ty ; 2 ] > ,
990991 /// Track for each column/place whether it contains a known valid value.
991992 place_validity : SmallVec < [ ValidityConstraint ; 2 ] > ,
992993}
@@ -1017,6 +1018,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
10171018 let mut matrix = Matrix {
10181019 rows : Vec :: with_capacity ( arms. len ( ) ) ,
10191020 wildcard_row,
1021+ place_ty : smallvec ! [ scrut_ty] ,
10201022 place_validity : smallvec ! [ scrut_validity] ,
10211023 } ;
10221024 for ( row_id, arm) in arms. iter ( ) . enumerate ( ) {
@@ -1032,10 +1034,10 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
10321034 }
10331035
10341036 fn head_ty ( & self ) -> Option < Cx :: Ty > {
1035- self . wildcard_row . head_opt ( ) . map ( |pat| pat . ty ( ) )
1037+ self . place_ty . first ( ) . copied ( )
10361038 }
10371039 fn column_count ( & self ) -> usize {
1038- self . wildcard_row . len ( )
1040+ self . place_ty . len ( )
10391041 }
10401042
10411043 fn rows (
@@ -1063,17 +1065,23 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
10631065 ctor : & Constructor < Cx > ,
10641066 ctor_is_relevant : bool ,
10651067 ) -> Matrix < ' p , Cx > {
1066- let wildcard_row = self . wildcard_row . pop_head_constructor ( pcx, ctor, ctor_is_relevant) ;
1068+ let tys = pcx. ctor_sub_tys ( ctor) ;
1069+ 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) ;
10671071 let new_validity = self . place_validity [ 0 ] . specialize ( ctor) ;
10681072 let new_place_validity = std:: iter:: repeat ( new_validity)
10691073 . take ( ctor. arity ( pcx) )
10701074 . chain ( self . place_validity [ 1 ..] . iter ( ) . copied ( ) )
10711075 . collect ( ) ;
1072- let mut matrix =
1073- Matrix { rows : Vec :: new ( ) , wildcard_row, place_validity : new_place_validity } ;
1076+ let mut matrix = Matrix {
1077+ rows : Vec :: new ( ) ,
1078+ wildcard_row,
1079+ place_ty : new_place_ty,
1080+ place_validity : new_place_validity,
1081+ } ;
10741082 for ( i, row) in self . rows ( ) . enumerate ( ) {
10751083 if ctor. is_covered_by ( pcx, row. head ( ) . ctor ( ) ) {
1076- let new_row = row. pop_head_constructor ( pcx, ctor, ctor_is_relevant, i) ;
1084+ let new_row = row. pop_head_constructor ( pcx, ctor, tys , ctor_is_relevant, i) ;
10771085 matrix. expand_and_push ( new_row) ;
10781086 }
10791087 }
0 commit comments