@@ -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 } ;
@@ -1398,14 +1400,27 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
1398
1400
1399
1401
// `compile_submatch` works one column of arm patterns a time and
1400
1402
// then peels that column off. So as we progress, it may become
1401
- // impossible to tell whether we have a genuine default arm, i.e.
1402
- // `_ => foo` or not. Sometimes it is important to know that in order
1403
- // to decide whether moving on to the next condition or falling back
1404
- // to the default arm.
1405
- let has_default = arms. last ( ) . map_or ( false , |arm| {
1406
- arm. pats . len ( ) == 1
1407
- && arm. pats . last ( ) . unwrap ( ) . node == ast:: PatWild ( ast:: PatWildSingle )
1408
- } ) ;
1403
+ // impossible to tell whether we have a genuine default arm or not.
1404
+ // Computing such property upfront, however, is straightforward -
1405
+ // if the last arm of the match expression shadows a `PatWildSingle`,
1406
+ // then it is a genuine default arm.
1407
+ //
1408
+ // Sometimes it is important to know that in order to decide whether
1409
+ // moving on to the next arm or falling back to the default one.
1410
+ let is_geniune_default = |& : pats: & Vec < P < ast:: Pat > > | {
1411
+ let mcx = check_match:: MatchCheckCtxt {
1412
+ tcx : tcx,
1413
+ param_env : ty:: empty_parameter_environment ( tcx) ,
1414
+ } ;
1415
+ let ps = pats. iter ( ) . map ( |p| & * * p) . collect ( ) ;
1416
+ let matrix = check_match:: Matrix ( vec ! [ ps] ) ;
1417
+ let candidate = [ check_match:: DUMMY_WILD_PAT ] ;
1418
+ match check_match:: is_useful ( & mcx, & matrix, & candidate, LeaveOutWitness ) {
1419
+ NotUseful => true ,
1420
+ _ => false
1421
+ }
1422
+ } ;
1423
+ let has_default = arm_pats. iter ( ) . last ( ) . map_or ( false , is_geniune_default) ;
1409
1424
1410
1425
compile_submatch ( bcx, & matches[ ] , & [ discr_datum. val ] , & chk, has_default) ;
1411
1426
0 commit comments