@@ -441,7 +441,7 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
441
441
& self ,
442
442
cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
443
443
constructor : & Constructor < ' tcx > ,
444
- ctor_wild_subpatterns : & ' p [ Pat < ' tcx > ] ,
444
+ ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
445
445
) -> Option < PatStack < ' p , ' tcx > > {
446
446
let new_heads = specialize_one_pattern ( cx, self . head ( ) , constructor, ctor_wild_subpatterns) ;
447
447
new_heads. map ( |mut new_head| {
@@ -503,7 +503,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
503
503
& self ,
504
504
cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
505
505
constructor : & Constructor < ' tcx > ,
506
- ctor_wild_subpatterns : & ' p [ Pat < ' tcx > ] ,
506
+ ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
507
507
) -> Matrix < ' p , ' tcx > {
508
508
self . 0
509
509
. iter ( )
@@ -722,10 +722,12 @@ impl Slice {
722
722
}
723
723
}
724
724
725
+ /// A value can be decomposed into a constructor applied to some fields. This struct represents
726
+ /// the constructor. See also `Fields`.
725
727
#[ derive( Clone , Debug , PartialEq ) ]
726
728
enum 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.
729
731
Single ,
730
732
/// Enum variants.
731
733
Variant ( DefId ) ,
@@ -1027,6 +1029,38 @@ impl<'tcx> Constructor<'tcx> {
1027
1029
}
1028
1030
}
1029
1031
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
+
1030
1064
#[ derive( Clone , Debug ) ]
1031
1065
crate enum Usefulness < ' tcx , ' p > {
1032
1066
/// Carries a list of unreachable subpatterns. Used only in the presence of or-patterns.
@@ -1823,10 +1857,9 @@ fn is_useful_specialized<'p, 'tcx>(
1823
1857
) -> Usefulness < ' tcx , ' p > {
1824
1858
debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, lty) ;
1825
1859
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)
1830
1863
. map ( |v| is_useful ( cx, & matrix, & v, witness_preference, hir_id, is_under_guard, false ) )
1831
1864
. map ( |u| u. apply_constructor ( cx, & ctor, lty) )
1832
1865
. unwrap_or ( NotUseful )
@@ -2295,7 +2328,7 @@ fn constructor_covered_by_range<'tcx>(
2295
2328
fn patterns_for_variant < ' p , ' tcx > (
2296
2329
cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
2297
2330
subpatterns : & ' p [ FieldPat < ' tcx > ] ,
2298
- ctor_wild_subpatterns : & ' p [ Pat < ' tcx > ] ,
2331
+ ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
2299
2332
is_non_exhaustive : bool ,
2300
2333
) -> PatStack < ' p , ' tcx > {
2301
2334
let mut result: SmallVec < _ > = ctor_wild_subpatterns. iter ( ) . collect ( ) ;
@@ -2326,7 +2359,7 @@ fn specialize_one_pattern<'p, 'tcx>(
2326
2359
cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
2327
2360
pat : & ' p Pat < ' tcx > ,
2328
2361
constructor : & Constructor < ' tcx > ,
2329
- ctor_wild_subpatterns : & ' p [ Pat < ' tcx > ] ,
2362
+ ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
2330
2363
) -> Option < PatStack < ' p , ' tcx > > {
2331
2364
if let NonExhaustive = constructor {
2332
2365
// Only a wildcard pattern can match the special extra constructor
0 commit comments