@@ -1285,7 +1285,9 @@ impl<'tcx> Constructor<'tcx> {
1285
1285
IntRange ( range) => return range. to_pat ( pcx. cx . tcx ) ,
1286
1286
NonExhaustive => PatKind :: Wild ,
1287
1287
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
+ ) ,
1289
1291
} ;
1290
1292
1291
1293
Pat { ty : pcx. ty , span : DUMMY_SP , kind : Box :: new ( pat) }
@@ -1610,27 +1612,13 @@ impl<'tcx> Usefulness<'tcx> {
1610
1612
pcx : PatCtxt < ' _ , ' p , ' tcx > ,
1611
1613
ctor : & Constructor < ' tcx > ,
1612
1614
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 ,
1629
1616
) -> Self {
1630
1617
match self {
1631
1618
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) ;
1634
1622
witnesses
1635
1623
. into_iter ( )
1636
1624
. flat_map ( |witness| {
@@ -1640,8 +1628,14 @@ impl<'tcx> Usefulness<'tcx> {
1640
1628
witness
1641
1629
} )
1642
1630
} )
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)
1645
1639
}
1646
1640
x => x,
1647
1641
}
@@ -2419,7 +2413,17 @@ crate fn is_useful<'p, 'tcx>(
2419
2413
constructor
2420
2414
. split ( pcx, Some ( hir_id) )
2421
2415
. 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
+ } )
2423
2427
. find ( |result| result. is_useful ( ) )
2424
2428
. unwrap_or ( NotUseful )
2425
2429
} else {
@@ -2446,20 +2450,31 @@ crate fn is_useful<'p, 'tcx>(
2446
2450
. into_iter ( )
2447
2451
. flat_map ( |ctor| ctor. split ( pcx, None ) )
2448
2452
. 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
+ )
2450
2462
} )
2451
2463
. find ( |result| result. is_useful ( ) )
2452
2464
. unwrap_or ( NotUseful )
2453
2465
} 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
+ )
2463
2478
}
2464
2479
} ;
2465
2480
debug ! ( "is_useful::returns({:#?}, {:#?}) = {:?}" , matrix, v, ret) ;
@@ -2471,20 +2486,22 @@ crate fn is_useful<'p, 'tcx>(
2471
2486
fn is_useful_specialized < ' p , ' tcx > (
2472
2487
pcx : PatCtxt < ' _ , ' p , ' tcx > ,
2473
2488
v : & PatStack < ' p , ' tcx > ,
2474
- ctor : Constructor < ' tcx > ,
2489
+ ctor : & Constructor < ' tcx > ,
2475
2490
witness_preference : WitnessPreference ,
2476
2491
hir_id : HirId ,
2477
2492
is_under_guard : bool ,
2493
+ is_top_level : bool ,
2478
2494
) -> Usefulness < ' tcx > {
2479
2495
debug ! ( "is_useful_specialized({:#?}, {:#?}, {:?})" , v, ctor, pcx. ty) ;
2480
2496
2481
2497
// 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)
2488
2505
}
2489
2506
2490
2507
/// Determines the constructor that the given pattern can be specialized to.
0 commit comments