@@ -441,7 +441,7 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
441441 & self ,
442442 cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
443443 constructor : & Constructor < ' tcx > ,
444- ctor_wild_subpatterns : & ' p [ Pat < ' tcx > ] ,
444+ ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
445445 ) -> Option < PatStack < ' p , ' tcx > > {
446446 let new_heads = specialize_one_pattern ( cx, self . head ( ) , constructor, ctor_wild_subpatterns) ;
447447 new_heads. map ( |mut new_head| {
@@ -503,7 +503,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
503503 & self ,
504504 cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
505505 constructor : & Constructor < ' tcx > ,
506- ctor_wild_subpatterns : & ' p [ Pat < ' tcx > ] ,
506+ ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
507507 ) -> Matrix < ' p , ' tcx > {
508508 self . 0
509509 . iter ( )
@@ -722,10 +722,12 @@ impl Slice {
722722 }
723723}
724724
725+ /// A value can be decomposed into a constructor applied to some fields. This struct represents
726+ /// the constructor. See also `Fields`.
725727#[ derive( Clone , Debug , PartialEq ) ]
726728enum Constructor < ' tcx > {
727- /// The constructor of all patterns that don't vary by constructor,
728- /// e.g., struct patterns and fixed-length arrays.
729+ /// The constructor for patterns that have a single constructor, like tuples, struct patterns
730+ /// and fixed-length arrays.
729731 Single ,
730732 /// Enum variants.
731733 Variant ( DefId ) ,
@@ -1027,6 +1029,38 @@ impl<'tcx> Constructor<'tcx> {
10271029 }
10281030}
10291031
1032+ /// A value can be decomposed into a constructor applied to some fields. This struct represents
1033+ /// those fields, generalized to allow patterns in each field. See also `Constructor`.
1034+ #[ derive( Debug , Clone ) ]
1035+ enum Fields < ' p , ' tcx > {
1036+ Slice ( & ' p [ Pat < ' tcx > ] ) ,
1037+ }
1038+
1039+ impl < ' p , ' tcx > Fields < ' p , ' tcx > {
1040+ /// Creates a new list of wildcard fields for a given constructor.
1041+ fn wildcards (
1042+ cx : & MatchCheckCtxt < ' p , ' tcx > ,
1043+ constructor : & Constructor < ' tcx > ,
1044+ ty : Ty < ' tcx > ,
1045+ ) -> Self {
1046+ debug ! ( "Fields::wildcards({:#?}, {:?})" , constructor, ty) ;
1047+ let pats = cx. pattern_arena . alloc_from_iter ( constructor. wildcard_subpatterns ( cx, ty) ) ;
1048+ Fields :: Slice ( pats)
1049+ }
1050+
1051+ fn len ( & self ) -> usize {
1052+ match self {
1053+ Fields :: Slice ( pats) => pats. len ( ) ,
1054+ }
1055+ }
1056+
1057+ fn iter < ' a > ( & ' a self ) -> impl Iterator < Item = & ' p Pat < ' tcx > > + Captures < ' a > {
1058+ match self {
1059+ Fields :: Slice ( pats) => pats. iter ( ) ,
1060+ }
1061+ }
1062+ }
1063+
10301064#[ derive( Clone , Debug ) ]
10311065crate enum Usefulness < ' tcx , ' p > {
10321066 /// Carries a list of unreachable subpatterns. Used only in the presence of or-patterns.
@@ -1823,10 +1857,9 @@ fn is_useful_specialized<'p, 'tcx>(
18231857) -> Usefulness < ' tcx , ' p > {
18241858 debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, lty) ;
18251859
1826- let ctor_wild_subpatterns =
1827- cx. pattern_arena . alloc_from_iter ( ctor. wildcard_subpatterns ( cx, lty) ) ;
1828- let matrix = matrix. specialize_constructor ( cx, & ctor, ctor_wild_subpatterns) ;
1829- v. specialize_constructor ( cx, & ctor, ctor_wild_subpatterns)
1860+ let ctor_wild_subpatterns = Fields :: wildcards ( cx, & ctor, lty) ;
1861+ let matrix = matrix. specialize_constructor ( cx, & ctor, & ctor_wild_subpatterns) ;
1862+ v. specialize_constructor ( cx, & ctor, & ctor_wild_subpatterns)
18301863 . map ( |v| is_useful ( cx, & matrix, & v, witness_preference, hir_id, is_under_guard, false ) )
18311864 . map ( |u| u. apply_constructor ( cx, & ctor, lty) )
18321865 . unwrap_or ( NotUseful )
@@ -2295,7 +2328,7 @@ fn constructor_covered_by_range<'tcx>(
22952328fn patterns_for_variant < ' p , ' tcx > (
22962329 cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
22972330 subpatterns : & ' p [ FieldPat < ' tcx > ] ,
2298- ctor_wild_subpatterns : & ' p [ Pat < ' tcx > ] ,
2331+ ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
22992332 is_non_exhaustive : bool ,
23002333) -> PatStack < ' p , ' tcx > {
23012334 let mut result: SmallVec < _ > = ctor_wild_subpatterns. iter ( ) . collect ( ) ;
@@ -2326,7 +2359,7 @@ fn specialize_one_pattern<'p, 'tcx>(
23262359 cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
23272360 pat : & ' p Pat < ' tcx > ,
23282361 constructor : & Constructor < ' tcx > ,
2329- ctor_wild_subpatterns : & ' p [ Pat < ' tcx > ] ,
2362+ ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
23302363) -> Option < PatStack < ' p , ' tcx > > {
23312364 if let NonExhaustive = constructor {
23322365 // Only a wildcard pattern can match the special extra constructor
0 commit comments