@@ -521,10 +521,11 @@ fn enter_match<'r>(bcx: @mut Block,
521
521
}
522
522
523
523
fn enter_default < ' r > ( bcx : @mut Block ,
524
- dm : DefMap ,
525
- m : & [ Match < ' r > ] ,
526
- col : uint ,
527
- val : ValueRef )
524
+ dm : DefMap ,
525
+ m : & [ Match < ' r > ] ,
526
+ col : uint ,
527
+ val : ValueRef ,
528
+ chk : Option < mk_fail > )
528
529
-> ~[ Match < ' r > ] {
529
530
debug ! ( "enter_default(bcx=%s, m=%s, col=%u, val=%s)" ,
530
531
bcx. to_str( ) ,
@@ -533,13 +534,36 @@ fn enter_default<'r>(bcx: @mut Block,
533
534
bcx. val_to_str( val) ) ;
534
535
let _indenter = indenter ( ) ;
535
536
536
- do enter_match ( bcx, dm, m, col, val) |p| {
537
+ // Collect all of the matches that can match against anything.
538
+ let matches = do enter_match ( bcx, dm, m, col, val) |p| {
537
539
match p. node {
538
540
ast:: pat_wild | ast:: pat_tup( _) => Some ( ~[ ] ) ,
539
541
ast:: pat_ident( _, _, None ) if pat_is_binding ( dm, p) => Some ( ~[ ] ) ,
540
542
_ => None
541
543
}
542
- }
544
+ } ;
545
+
546
+ // Ok, now, this is pretty subtle. A "default" match is a match
547
+ // that needs to be considered if none of the actual checks on the
548
+ // value being considered succeed. The subtlety lies in that sometimes
549
+ // identifier/wildcard matches are *not* default matches. Consider:
550
+ // "match x { _ if something => foo, true => bar, false => baz }".
551
+ // There is a wildcard match, but it is *not* a default case. The boolean
552
+ // case on the value being considered is exhaustive. If the case is
553
+ // exhaustive, then there are no defaults.
554
+ //
555
+ // We detect whether the case is exhaustive in the following
556
+ // somewhat kludgy way: if the last wildcard/binding match has a
557
+ // guard, then by non-redundancy, we know that there aren't any
558
+ // non guarded matches, and thus by exhaustiveness, we know that
559
+ // we don't need any default cases. If the check *isn't* nonexhaustive
560
+ // (because chk is Some), then we need the defaults anyways.
561
+ let is_exhaustive = match matches. last_opt ( ) {
562
+ Some ( m) if m. data . arm . guard . is_some ( ) && chk. is_none ( ) => true ,
563
+ _ => false
564
+ } ;
565
+
566
+ if is_exhaustive { ~[ ] } else { matches }
543
567
}
544
568
545
569
// <pcwalton> nmatsakis: what does enter_opt do?
@@ -1575,7 +1599,7 @@ fn compile_submatch_continue(mut bcx: @mut Block,
1575
1599
C_int ( ccx, 0 ) // Placeholder for when not using a switch
1576
1600
} ;
1577
1601
1578
- let defaults = enter_default ( else_cx, dm, m, col, val) ;
1602
+ let defaults = enter_default ( else_cx, dm, m, col, val, chk ) ;
1579
1603
let exhaustive = chk. is_none ( ) && defaults. len ( ) == 0 u;
1580
1604
let len = opts. len ( ) ;
1581
1605
0 commit comments