@@ -642,15 +642,17 @@ impl<'tcx> Constructor<'tcx> {
642
642
}
643
643
}
644
644
645
+ /// This returns one wildcard pattern for each argument to this constructor.
645
646
fn wildcard_subpatterns < ' a > (
646
647
& self ,
647
648
cx : & MatchCheckCtxt < ' a , ' tcx > ,
648
649
ty : Ty < ' tcx > ,
649
- ) -> Vec < Pat < ' tcx > > {
650
- constructor_sub_pattern_tys ( cx, self , ty)
651
- . into_iter ( )
652
- . map ( |ty| Pat { ty, span : DUMMY_SP , kind : box PatKind :: Wild } )
653
- . collect ( )
650
+ ) -> impl Iterator < Item = Pat < ' tcx > > + DoubleEndedIterator {
651
+ constructor_sub_pattern_tys ( cx, self , ty) . into_iter ( ) . map ( |ty| Pat {
652
+ ty,
653
+ span : DUMMY_SP ,
654
+ kind : box PatKind :: Wild ,
655
+ } )
654
656
}
655
657
656
658
/// This computes the arity of a constructor. The arity of a constructor
@@ -735,6 +737,12 @@ impl<'tcx> Constructor<'tcx> {
735
737
736
738
Pat { ty, span : DUMMY_SP , kind : Box :: new ( pat) }
737
739
}
740
+
741
+ /// Like `apply`, but where all the subpatterns are wildcards `_`.
742
+ fn apply_wildcards < ' a > ( & self , cx : & MatchCheckCtxt < ' a , ' tcx > , ty : Ty < ' tcx > ) -> Pat < ' tcx > {
743
+ let pats = self . wildcard_subpatterns ( cx, ty) . rev ( ) ;
744
+ self . apply ( cx, ty, pats)
745
+ }
738
746
}
739
747
740
748
#[ derive( Clone , Debug ) ]
@@ -807,16 +815,6 @@ impl<'tcx> Witness<'tcx> {
807
815
self . 0 . into_iter ( ) . next ( ) . unwrap ( )
808
816
}
809
817
810
- fn push_wild_constructor < ' a > (
811
- mut self ,
812
- cx : & MatchCheckCtxt < ' a , ' tcx > ,
813
- ctor : & Constructor < ' tcx > ,
814
- ty : Ty < ' tcx > ,
815
- ) -> Self {
816
- self . 0 . extend ( ctor. wildcard_subpatterns ( cx, ty) ) ;
817
- self . apply_constructor ( cx, ctor, ty)
818
- }
819
-
820
818
/// Constructs a partial witness for a pattern given a list of
821
819
/// patterns expanded by the specialization step.
822
820
///
@@ -1530,33 +1528,28 @@ pub fn is_useful<'p, 'a, 'tcx>(
1530
1528
// `(<direction-1>, <direction-2>, true)` - we are
1531
1529
// satisfied with `(_, _, true)`. In this case,
1532
1530
// `used_ctors` is empty.
1533
- let new_witnesses = if is_non_exhaustive || used_ctors. is_empty ( ) {
1534
- // All constructors are unused. Add wild patterns
1531
+ let new_patterns = if is_non_exhaustive || used_ctors. is_empty ( ) {
1532
+ // All constructors are unused. Add a wild pattern
1535
1533
// rather than each individual constructor.
1536
- pats. into_iter ( )
1537
- . map ( |mut witness| {
1538
- witness. 0 . push ( Pat {
1539
- ty : pcx. ty ,
1540
- span : DUMMY_SP ,
1541
- kind : box PatKind :: Wild ,
1542
- } ) ;
1543
- witness
1544
- } )
1545
- . collect ( )
1534
+ vec ! [ Pat { ty: pcx. ty, span: DUMMY_SP , kind: box PatKind :: Wild } ]
1546
1535
} else {
1547
- let missing_ctors: Vec < _ > = missing_ctors. collect ( ) ;
1548
- pats. into_iter ( )
1549
- . flat_map ( |witness| {
1550
- missing_ctors. iter ( ) . map ( move |ctor| {
1551
- // Extends the witness with a "wild" version of this
1552
- // constructor, that matches everything that can be built with
1553
- // it. For example, if `ctor` is a `Constructor::Variant` for
1554
- // `Option::Some`, this pushes the witness for `Some(_)`.
1555
- witness. clone ( ) . push_wild_constructor ( cx, ctor, pcx. ty )
1556
- } )
1557
- } )
1558
- . collect ( )
1536
+ // Construct for each missing constructor a "wild" version of this
1537
+ // constructor, that matches everything that can be built with
1538
+ // it. For example, if `ctor` is a `Constructor::Variant` for
1539
+ // `Option::Some`, we get the pattern `Some(_)`.
1540
+ missing_ctors. map ( |ctor| ctor. apply_wildcards ( cx, pcx. ty ) ) . collect ( )
1559
1541
} ;
1542
+ // Add the new patterns to each witness
1543
+ let new_witnesses = pats
1544
+ . into_iter ( )
1545
+ . flat_map ( |witness| {
1546
+ new_patterns. iter ( ) . map ( move |pat| {
1547
+ let mut witness = witness. clone ( ) ;
1548
+ witness. 0 . push ( pat. clone ( ) ) ;
1549
+ witness
1550
+ } )
1551
+ } )
1552
+ . collect ( ) ;
1560
1553
UsefulWithWitness ( new_witnesses)
1561
1554
}
1562
1555
result => result,
@@ -1578,7 +1571,7 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
1578
1571
) -> Usefulness < ' tcx > {
1579
1572
debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, lty) ;
1580
1573
1581
- let wild_patterns_owned = ctor. wildcard_subpatterns ( cx, lty) ;
1574
+ let wild_patterns_owned: Vec < _ > = ctor. wildcard_subpatterns ( cx, lty) . collect ( ) ;
1582
1575
let wild_patterns: Vec < _ > = wild_patterns_owned. iter ( ) . collect ( ) ;
1583
1576
let matrix = matrix. specialize_constructor ( cx, & ctor, & wild_patterns) ;
1584
1577
match v. specialize_constructor ( cx, & ctor, & wild_patterns) {
0 commit comments