@@ -526,7 +526,7 @@ fn enter_default<'a, 'b>(
526526 // Collect all of the matches that can match against anything.
527527 let matches = enter_match ( bcx, dm, m, col, val, |p| {
528528 match p. node {
529- ast:: PatWild | ast:: PatWildMulti | ast :: PatTup ( _ ) => Some ( Vec :: new ( ) ) ,
529+ ast:: PatWild | ast:: PatWildMulti => Some ( Vec :: new ( ) ) ,
530530 ast:: PatIdent ( _, _, None ) if pat_is_binding ( dm, p) => Some ( Vec :: new ( ) ) ,
531531 _ => None
532532 }
@@ -712,18 +712,7 @@ fn enter_opt<'a, 'b>(
712712 }
713713 _ => {
714714 assert_is_binding_or_wild ( bcx, p) ;
715- // In most cases, a binding/wildcard match be
716- // considered to match against any Opt. However, when
717- // doing vector pattern matching, submatches are
718- // considered even if the eventual match might be from
719- // a different submatch. Thus, when a submatch fails
720- // when doing a vector match, we proceed to the next
721- // submatch. Thus, including a default match would
722- // cause the default match to fire spuriously.
723- match * opt {
724- vec_len( ..) => None ,
725- _ => Some ( Vec :: from_elem ( variant_size, dummy) )
726- }
715+ Some ( Vec :: from_elem ( variant_size, dummy) )
727716 }
728717 } ;
729718 i += 1 ;
@@ -1363,7 +1352,8 @@ fn compile_guard<'a, 'b>(
13631352 data : & ArmData ,
13641353 m : & ' a [ Match < ' a , ' b > ] ,
13651354 vals : & [ ValueRef ] ,
1366- chk : & FailureHandler )
1355+ chk : & FailureHandler ,
1356+ has_genuine_default : bool )
13671357 -> & ' b Block < ' b > {
13681358 debug ! ( "compile_guard(bcx={}, guard_expr={}, m={}, vals={})" ,
13691359 bcx. to_str( ) ,
@@ -1394,7 +1384,17 @@ fn compile_guard<'a, 'b>(
13941384 // Guard does not match: free the values we copied,
13951385 // and remove all bindings from the lllocals table
13961386 let bcx = drop_bindings ( bcx, data) ;
1397- compile_submatch ( bcx, m, vals, chk) ;
1387+ match chk {
1388+ // If the default arm is the only one left, move on to the next
1389+ // condition explicitly rather than (possibly) falling back to
1390+ // the default arm.
1391+ & JumpToBasicBlock ( _) if m. len ( ) == 1 && has_genuine_default => {
1392+ Br ( bcx, chk. handle_fail ( ) ) ;
1393+ }
1394+ _ => {
1395+ compile_submatch ( bcx, m, vals, chk, has_genuine_default) ;
1396+ }
1397+ } ;
13981398 bcx
13991399 } ) ;
14001400
@@ -1418,7 +1418,8 @@ fn compile_submatch<'a, 'b>(
14181418 bcx : & ' b Block < ' b > ,
14191419 m : & ' a [ Match < ' a , ' b > ] ,
14201420 vals : & [ ValueRef ] ,
1421- chk : & FailureHandler ) {
1421+ chk : & FailureHandler ,
1422+ has_genuine_default : bool ) {
14221423 debug ! ( "compile_submatch(bcx={}, m={}, vals={})" ,
14231424 bcx. to_str( ) ,
14241425 m. repr( bcx. tcx( ) ) ,
@@ -1448,7 +1449,8 @@ fn compile_submatch<'a, 'b>(
14481449 m[ 0 ] . data ,
14491450 m. slice ( 1 , m. len ( ) ) ,
14501451 vals,
1451- chk) ;
1452+ chk,
1453+ has_genuine_default) ;
14521454 }
14531455 _ => ( )
14541456 }
@@ -1466,9 +1468,10 @@ fn compile_submatch<'a, 'b>(
14661468 vals,
14671469 chk,
14681470 col,
1469- val)
1471+ val,
1472+ has_genuine_default)
14701473 } else {
1471- compile_submatch_continue ( bcx, m, vals, chk, col, val)
1474+ compile_submatch_continue ( bcx, m, vals, chk, col, val, has_genuine_default )
14721475 }
14731476}
14741477
@@ -1478,7 +1481,8 @@ fn compile_submatch_continue<'a, 'b>(
14781481 vals : & [ ValueRef ] ,
14791482 chk : & FailureHandler ,
14801483 col : uint ,
1481- val : ValueRef ) {
1484+ val : ValueRef ,
1485+ has_genuine_default : bool ) {
14821486 let fcx = bcx. fcx ;
14831487 let tcx = bcx. tcx ( ) ;
14841488 let dm = & tcx. def_map ;
@@ -1512,7 +1516,7 @@ fn compile_submatch_continue<'a, 'b>(
15121516 rec_fields. as_slice ( ) ,
15131517 val) . as_slice ( ) ,
15141518 rec_vals. append ( vals_left. as_slice ( ) ) . as_slice ( ) ,
1515- chk) ;
1519+ chk, has_genuine_default ) ;
15161520 } ) ;
15171521 return ;
15181522 }
@@ -1537,7 +1541,7 @@ fn compile_submatch_continue<'a, 'b>(
15371541 val,
15381542 n_tup_elts) . as_slice ( ) ,
15391543 tup_vals. append ( vals_left. as_slice ( ) ) . as_slice ( ) ,
1540- chk) ;
1544+ chk, has_genuine_default ) ;
15411545 return ;
15421546 }
15431547
@@ -1562,7 +1566,7 @@ fn compile_submatch_continue<'a, 'b>(
15621566 enter_tuple_struct ( bcx, dm, m, col, val,
15631567 struct_element_count) . as_slice ( ) ,
15641568 llstructvals. append ( vals_left. as_slice ( ) ) . as_slice ( ) ,
1565- chk) ;
1569+ chk, has_genuine_default ) ;
15661570 return ;
15671571 }
15681572
@@ -1571,7 +1575,7 @@ fn compile_submatch_continue<'a, 'b>(
15711575 compile_submatch ( bcx,
15721576 enter_uniq ( bcx, dm, m, col, val) . as_slice ( ) ,
15731577 ( vec ! ( llbox) ) . append ( vals_left. as_slice ( ) ) . as_slice ( ) ,
1574- chk) ;
1578+ chk, has_genuine_default ) ;
15751579 return ;
15761580 }
15771581
@@ -1580,7 +1584,7 @@ fn compile_submatch_continue<'a, 'b>(
15801584 compile_submatch ( bcx,
15811585 enter_region ( bcx, dm, m, col, val) . as_slice ( ) ,
15821586 ( vec ! ( loaded_val) ) . append ( vals_left. as_slice ( ) ) . as_slice ( ) ,
1583- chk) ;
1587+ chk, has_genuine_default ) ;
15841588 return ;
15851589 }
15861590
@@ -1637,9 +1641,9 @@ fn compile_submatch_continue<'a, 'b>(
16371641
16381642 // Compile subtrees for each option
16391643 for ( i, opt) in opts. iter ( ) . enumerate ( ) {
1640- // In some cases in vector pattern matching, we need to override
1641- // the failure case so that instead of failing, it proceeds to
1642- // try more matching. branch_chk, then, is the proper failure case
1644+ // In some cases of range and vector pattern matching, we need to
1645+ // override the failure case so that instead of failing, it proceeds
1646+ // to try more matching. branch_chk, then, is the proper failure case
16431647 // for the current conditional branch.
16441648 let mut branch_chk = None ;
16451649 let mut opt_cx = else_cx;
@@ -1689,6 +1693,16 @@ fn compile_submatch_continue<'a, 'b>(
16891693 }
16901694 } ;
16911695 bcx = fcx. new_temp_block ( "compare_next" ) ;
1696+
1697+ // If none of the sub-cases match, and the current condition
1698+ // is guarded or has multiple patterns, move on to the next
1699+ // condition, if there is any, rather than falling back to
1700+ // the default.
1701+ let guarded = m[ i] . data . arm . guard . is_some ( ) ;
1702+ let multi_pats = m[ i] . pats . len ( ) > 1 ;
1703+ if i+1 < len && ( guarded || multi_pats) {
1704+ branch_chk = Some ( JumpToBasicBlock ( bcx. llbb ) ) ;
1705+ }
16921706 CondBr ( after_cx, matches, opt_cx. llbb , bcx. llbb ) ;
16931707 }
16941708 compare_vec_len => {
@@ -1726,8 +1740,10 @@ fn compile_submatch_continue<'a, 'b>(
17261740 bcx = fcx. new_temp_block ( "compare_vec_len_next" ) ;
17271741
17281742 // If none of these subcases match, move on to the
1729- // next condition.
1730- branch_chk = Some ( JumpToBasicBlock ( bcx. llbb ) ) ;
1743+ // next condition if there is any.
1744+ if i+1 < len {
1745+ branch_chk = Some ( JumpToBasicBlock ( bcx. llbb ) ) ;
1746+ }
17311747 CondBr ( after_cx, matches, opt_cx. llbb , bcx. llbb ) ;
17321748 }
17331749 _ => ( )
@@ -1767,27 +1783,38 @@ fn compile_submatch_continue<'a, 'b>(
17671783 compile_submatch ( opt_cx,
17681784 opt_ms. as_slice ( ) ,
17691785 opt_vals. as_slice ( ) ,
1770- chk)
1786+ chk,
1787+ has_genuine_default)
17711788 }
17721789 Some ( branch_chk) => {
17731790 compile_submatch ( opt_cx,
17741791 opt_ms. as_slice ( ) ,
17751792 opt_vals. as_slice ( ) ,
1776- & branch_chk)
1793+ & branch_chk,
1794+ has_genuine_default)
17771795 }
17781796 }
17791797 }
17801798
17811799 // Compile the fall-through case, if any
1782- if !exhaustive {
1800+ if !exhaustive && kind != single {
17831801 if kind == compare || kind == compare_vec_len {
17841802 Br ( bcx, else_cx. llbb ) ;
17851803 }
1786- if kind != single {
1787- compile_submatch ( else_cx,
1788- defaults. as_slice ( ) ,
1789- vals_left. as_slice ( ) ,
1790- chk) ;
1804+ match chk {
1805+ // If there is only one default arm left, move on to the next
1806+ // condition explicitly rather than (eventually) falling back to
1807+ // the last default arm.
1808+ & JumpToBasicBlock ( _) if defaults. len ( ) == 1 && has_genuine_default => {
1809+ Br ( else_cx, chk. handle_fail ( ) ) ;
1810+ }
1811+ _ => {
1812+ compile_submatch ( else_cx,
1813+ defaults. as_slice ( ) ,
1814+ vals_left. as_slice ( ) ,
1815+ chk,
1816+ has_genuine_default) ;
1817+ }
17911818 }
17921819 }
17931820}
@@ -1892,7 +1919,22 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>,
18921919 } ) ) ;
18931920 }
18941921
1895- compile_submatch ( bcx, matches. as_slice ( ) , [ discr_datum. val ] , & chk) ;
1922+ // `compile_submatch` works one column of arm patterns a time and
1923+ // then peels that column off. So as we progress, it may become
1924+ // impossible to know whether we have a genuine default arm, i.e.
1925+ // `_ => foo` or not. Sometimes it is important to know that in order
1926+ // to decide whether moving on to the next condition or falling back
1927+ // to the default arm.
1928+ let has_default = arms. len ( ) > 0 && {
1929+ let ref pats = arms. last ( ) . unwrap ( ) . pats ;
1930+
1931+ pats. len ( ) == 1
1932+ && match pats. last ( ) . unwrap ( ) . node {
1933+ ast:: PatWild => true , _ => false
1934+ }
1935+ } ;
1936+
1937+ compile_submatch ( bcx, matches. as_slice ( ) , [ discr_datum. val ] , & chk, has_default) ;
18961938
18971939 let mut arm_cxs = Vec :: new ( ) ;
18981940 for arm_data in arm_datas. iter ( ) {
0 commit comments