@@ -191,6 +191,8 @@ use self::FailureHandler::*;
191
191
use back:: abi;
192
192
use llvm:: { ValueRef , BasicBlockRef } ;
193
193
use middle:: check_match:: StaticInliner ;
194
+ use middle:: check_match:: Usefulness :: NotUseful ;
195
+ use middle:: check_match:: WitnessPreference :: LeaveOutWitness ;
194
196
use middle:: check_match;
195
197
use middle:: const_eval;
196
198
use middle:: def:: { self , DefMap } ;
@@ -1417,22 +1419,27 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
1417
1419
1418
1420
// `compile_submatch` works one column of arm patterns a time and
1419
1421
// then peels that column off. So as we progress, it may become
1420
- // impossible to tell whether we have a genuine default arm, i.e.
1421
- // _ => foo
1422
- // (_, _) => foo
1423
- // or not. Sometimes it is important to know that in order to decide
1424
- // whether moving on to the next arm or falling back to the default
1425
- // one.
1426
- fn all_wild_pat ( pat : & ast:: Pat ) -> bool {
1427
- match pat. node {
1428
- ast:: PatWild ( ast:: PatWildSingle ) => true ,
1429
- ast:: PatTup ( ref pats) => pats. iter ( ) . all ( |p| all_wild_pat ( & * * p) ) ,
1430
- _ => false ,
1422
+ // impossible to tell whether we have a genuine default arm or not.
1423
+ // Computing such property upfront, however, is straightforward -
1424
+ // if the last arm of the match expression shadows a `PatWildSingle`,
1425
+ // then it is a genuine default arm.
1426
+ //
1427
+ // Sometimes it is important to know that in order to decide whether
1428
+ // moving on to the next arm or falling back to the default one.
1429
+ let is_geniune_default = |& : pats: & Vec < P < ast:: Pat > > | {
1430
+ let mcx = check_match:: MatchCheckCtxt {
1431
+ tcx : tcx,
1432
+ param_env : ty:: empty_parameter_environment ( tcx) ,
1433
+ } ;
1434
+ let ps = pats. iter ( ) . map ( |p| & * * p) . collect ( ) ;
1435
+ let matrix = check_match:: Matrix ( vec ! [ ps] ) ;
1436
+ let candidate = [ check_match:: DUMMY_WILD_PAT ] ;
1437
+ match check_match:: is_useful ( & mcx, & matrix, & candidate, LeaveOutWitness ) {
1438
+ NotUseful => true ,
1439
+ _ => false
1431
1440
}
1432
- }
1433
- let has_default = arms. last ( ) . map_or ( false , |arm| {
1434
- arm. pats . len ( ) == 1 && all_wild_pat ( & * * arm. pats . last ( ) . unwrap ( ) )
1435
- } ) ;
1441
+ } ;
1442
+ let has_default = arm_pats. iter ( ) . last ( ) . map_or ( false , is_geniune_default) ;
1436
1443
1437
1444
compile_submatch ( bcx, & matches[ ] , & [ discr_datum. val ] , & chk, has_default) ;
1438
1445
0 commit comments