@@ -1285,7 +1285,9 @@ impl<'tcx> Constructor<'tcx> {
12851285 IntRange ( range) => return range. to_pat ( pcx. cx . tcx ) ,
12861286 NonExhaustive => PatKind :: Wild ,
12871287 Opaque => bug ! ( "we should not try to apply an opaque constructor" ) ,
1288- Wildcard => bug ! ( "we should not try to apply a wildcard constructor" ) ,
1288+ Wildcard => bug ! (
1289+ "trying to apply a wildcard constructor; this should have been done in `apply_constructors`"
1290+ ) ,
12891291 } ;
12901292
12911293 Pat { ty : pcx. ty , span : DUMMY_SP , kind : Box :: new ( pat) }
@@ -1610,27 +1612,13 @@ impl<'tcx> Usefulness<'tcx> {
16101612 pcx : PatCtxt < ' _ , ' p , ' tcx > ,
16111613 ctor : & Constructor < ' tcx > ,
16121614 ctor_wild_subpatterns : & Fields < ' p , ' tcx > ,
1613- ) -> Self {
1614- match self {
1615- UsefulWithWitness ( witnesses) => UsefulWithWitness (
1616- witnesses
1617- . into_iter ( )
1618- . map ( |witness| witness. apply_constructor ( pcx, & ctor, ctor_wild_subpatterns) )
1619- . collect ( ) ,
1620- ) ,
1621- x => x,
1622- }
1623- }
1624-
1625- fn apply_wildcard < ' p > (
1626- self ,
1627- pcx : PatCtxt < ' _ , ' p , ' tcx > ,
1628- missing_ctors : MissingConstructors < ' tcx > ,
1615+ is_top_level : bool ,
16291616 ) -> Self {
16301617 match self {
16311618 UsefulWithWitness ( witnesses) => {
1632- let new_patterns = missing_ctors. report_patterns ( pcx) ;
1633- UsefulWithWitness (
1619+ let new_witnesses = if ctor. is_wildcard ( ) {
1620+ let missing_ctors = MissingConstructors :: new ( pcx, is_top_level) ;
1621+ let new_patterns = missing_ctors. report_patterns ( pcx) ;
16341622 witnesses
16351623 . into_iter ( )
16361624 . flat_map ( |witness| {
@@ -1640,8 +1628,14 @@ impl<'tcx> Usefulness<'tcx> {
16401628 witness
16411629 } )
16421630 } )
1643- . collect ( ) ,
1644- )
1631+ . collect ( )
1632+ } else {
1633+ witnesses
1634+ . into_iter ( )
1635+ . map ( |witness| witness. apply_constructor ( pcx, & ctor, ctor_wild_subpatterns) )
1636+ . collect ( )
1637+ } ;
1638+ UsefulWithWitness ( new_witnesses)
16451639 }
16461640 x => x,
16471641 }
@@ -2419,7 +2413,17 @@ crate fn is_useful<'p, 'tcx>(
24192413 constructor
24202414 . split ( pcx, Some ( hir_id) )
24212415 . into_iter ( )
2422- . map ( |c| is_useful_specialized ( pcx, v, c, witness_preference, hir_id, is_under_guard) )
2416+ . map ( |c| {
2417+ is_useful_specialized (
2418+ pcx,
2419+ v,
2420+ & c,
2421+ witness_preference,
2422+ hir_id,
2423+ is_under_guard,
2424+ is_top_level,
2425+ )
2426+ } )
24232427 . find ( |result| result. is_useful ( ) )
24242428 . unwrap_or ( NotUseful )
24252429 } else {
@@ -2446,20 +2450,31 @@ crate fn is_useful<'p, 'tcx>(
24462450 . into_iter ( )
24472451 . flat_map ( |ctor| ctor. split ( pcx, None ) )
24482452 . map ( |c| {
2449- is_useful_specialized ( pcx, v, c, witness_preference, hir_id, is_under_guard)
2453+ is_useful_specialized (
2454+ pcx,
2455+ v,
2456+ & c,
2457+ witness_preference,
2458+ hir_id,
2459+ is_under_guard,
2460+ is_top_level,
2461+ )
24502462 } )
24512463 . find ( |result| result. is_useful ( ) )
24522464 . unwrap_or ( NotUseful )
24532465 } else {
2454- let ctor_wild_subpatterns = Fields :: empty ( ) ;
2455- let matrix = matrix. specialize_constructor ( pcx, & constructor, & ctor_wild_subpatterns) ;
2456- // Unwrap is ok: v can always be specialized with its own constructor.
2457- let v =
2458- v. specialize_constructor ( pcx, & constructor, & ctor_wild_subpatterns, true ) . unwrap ( ) ;
2459- let usefulness =
2460- is_useful ( cx, & matrix, & v, witness_preference, hir_id, is_under_guard, false ) ;
2461-
2462- usefulness. apply_wildcard ( pcx, missing_ctors)
2466+ // Some constructors are missing, thus we can specialize with the wildcard constructor,
2467+ // which will stand for those constructors that are missing, and behaves like any of
2468+ // them.
2469+ is_useful_specialized (
2470+ pcx,
2471+ v,
2472+ constructor,
2473+ witness_preference,
2474+ hir_id,
2475+ is_under_guard,
2476+ is_top_level,
2477+ )
24632478 }
24642479 } ;
24652480 debug ! ( "is_useful::returns({:#?}, {:#?}) = {:?}" , matrix, v, ret) ;
@@ -2471,20 +2486,22 @@ crate fn is_useful<'p, 'tcx>(
24712486fn is_useful_specialized < ' p , ' tcx > (
24722487 pcx : PatCtxt < ' _ , ' p , ' tcx > ,
24732488 v : & PatStack < ' p , ' tcx > ,
2474- ctor : Constructor < ' tcx > ,
2489+ ctor : & Constructor < ' tcx > ,
24752490 witness_preference : WitnessPreference ,
24762491 hir_id : HirId ,
24772492 is_under_guard : bool ,
2493+ is_top_level : bool ,
24782494) -> Usefulness < ' tcx > {
24792495 debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, pcx. ty) ;
24802496
24812497 // We cache the result of `Fields::wildcards` because it is used a lot.
2482- let ctor_wild_subpatterns = Fields :: wildcards ( pcx, & ctor) ;
2483- let matrix = pcx. matrix . specialize_constructor ( pcx, & ctor, & ctor_wild_subpatterns) ;
2484- v. specialize_constructor ( pcx, & ctor, & ctor_wild_subpatterns, true )
2485- . map ( |v| is_useful ( pcx. cx , & matrix, & v, witness_preference, hir_id, is_under_guard, false ) )
2486- . map ( |u| u. apply_constructor ( pcx, & ctor, & ctor_wild_subpatterns) )
2487- . unwrap_or ( NotUseful )
2498+ let ctor_wild_subpatterns = Fields :: wildcards ( pcx, ctor) ;
2499+ let matrix = pcx. matrix . specialize_constructor ( pcx, ctor, & ctor_wild_subpatterns) ;
2500+ // Unwrap is ok: v can always be specialized with its own constructor.
2501+ let v = v. specialize_constructor ( pcx, ctor, & ctor_wild_subpatterns, true ) . unwrap ( ) ;
2502+ let usefulness =
2503+ is_useful ( pcx. cx , & matrix, & v, witness_preference, hir_id, is_under_guard, false ) ;
2504+ usefulness. apply_constructor ( pcx, ctor, & ctor_wild_subpatterns, is_top_level)
24882505}
24892506
24902507/// Determines the constructor that the given pattern can be specialized to.
0 commit comments