@@ -642,15 +642,17 @@ impl<'tcx> Constructor<'tcx> {
642642 }
643643 }
644644
645+ /// This returns one wildcard pattern for each argument to this constructor.
645646 fn wildcard_subpatterns < ' a > (
646647 & self ,
647648 cx : & MatchCheckCtxt < ' a , ' tcx > ,
648649 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+ } )
654656 }
655657
656658 /// This computes the arity of a constructor. The arity of a constructor
@@ -735,6 +737,12 @@ impl<'tcx> Constructor<'tcx> {
735737
736738 Pat { ty, span : DUMMY_SP , kind : Box :: new ( pat) }
737739 }
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+ }
738746}
739747
740748#[ derive( Clone , Debug ) ]
@@ -807,16 +815,6 @@ impl<'tcx> Witness<'tcx> {
807815 self . 0 . into_iter ( ) . next ( ) . unwrap ( )
808816 }
809817
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-
820818 /// Constructs a partial witness for a pattern given a list of
821819 /// patterns expanded by the specialization step.
822820 ///
@@ -1530,33 +1528,28 @@ pub fn is_useful<'p, 'a, 'tcx>(
15301528 // `(<direction-1>, <direction-2>, true)` - we are
15311529 // satisfied with `(_, _, true)`. In this case,
15321530 // `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
15351533 // 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 } ]
15461535 } 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 ( )
15591541 } ;
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 ( ) ;
15601553 UsefulWithWitness ( new_witnesses)
15611554 }
15621555 result => result,
@@ -1578,7 +1571,7 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
15781571) -> Usefulness < ' tcx > {
15791572 debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, lty) ;
15801573
1581- let wild_patterns_owned = ctor. wildcard_subpatterns ( cx, lty) ;
1574+ let wild_patterns_owned: Vec < _ > = ctor. wildcard_subpatterns ( cx, lty) . collect ( ) ;
15821575 let wild_patterns: Vec < _ > = wild_patterns_owned. iter ( ) . collect ( ) ;
15831576 let matrix = matrix. specialize_constructor ( cx, & ctor, & wild_patterns) ;
15841577 match v. specialize_constructor ( cx, & ctor, & wild_patterns) {
0 commit comments