@@ -1119,6 +1119,11 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
1119
1119
}
1120
1120
}
1121
1121
1122
+ /// Returns whether the first match pair of this candidate is an or-pattern.
1123
+ fn starts_with_or_pattern ( & self ) -> bool {
1124
+ matches ! ( & * self . match_pairs, [ MatchPair { test_case: TestCase :: Or { .. } , .. } , ..] )
1125
+ }
1126
+
1122
1127
/// Visit the leaf candidates (those with no subcandidates) contained in
1123
1128
/// this candidate.
1124
1129
fn visit_leaves < ' a > ( & ' a mut self , mut visit_leaf : impl FnMut ( & ' a mut Self ) ) {
@@ -1435,39 +1440,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1435
1440
otherwise_block : BasicBlock ,
1436
1441
candidates : & mut [ & mut Candidate < ' _ , ' tcx > ] ,
1437
1442
) {
1438
- // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
1439
- // can proceed further.
1440
- let expand_ors = candidates. iter ( ) . any ( |candidate| {
1441
- matches ! (
1442
- & * candidate. match_pairs,
1443
- [ MatchPair { test_case: TestCase :: Or { .. } , .. } , ..]
1444
- )
1445
- } ) ;
1446
1443
ensure_sufficient_stack ( || {
1447
- if !expand_ors {
1448
- // No candidates start with an or-pattern, we can continue.
1449
- self . match_expanded_candidates (
1450
- span,
1451
- scrutinee_span,
1452
- start_block,
1453
- otherwise_block,
1454
- candidates,
1455
- ) ;
1456
- } else {
1457
- self . expand_and_match_or_candidates (
1458
- span,
1459
- scrutinee_span,
1460
- start_block,
1461
- otherwise_block,
1462
- candidates,
1463
- ) ;
1464
- }
1444
+ self . match_candidates_with_enough_stack (
1445
+ span,
1446
+ scrutinee_span,
1447
+ start_block,
1448
+ otherwise_block,
1449
+ candidates,
1450
+ )
1465
1451
} ) ;
1466
1452
}
1467
1453
1468
- /// Construct the decision tree for `candidates`. Caller must ensure that no candidate in
1469
- /// `candidates` starts with an or-pattern .
1470
- fn match_expanded_candidates (
1454
+ /// Construct the decision tree for `candidates`. Don't call this, call `match_candidates`
1455
+ /// instead to reserve sufficient stack space .
1456
+ fn match_candidates_with_enough_stack (
1471
1457
& mut self ,
1472
1458
span : Span ,
1473
1459
scrutinee_span : Span ,
@@ -1492,12 +1478,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1492
1478
// The first candidate has satisfied all its match pairs; we link it up and continue
1493
1479
// with the remaining candidates.
1494
1480
start_block = self . select_matched_candidate ( first, start_block) ;
1495
- self . match_expanded_candidates (
1481
+ self . match_candidates ( span, scrutinee_span, start_block, otherwise_block, remaining)
1482
+ }
1483
+ candidates if candidates. iter ( ) . any ( |candidate| candidate. starts_with_or_pattern ( ) ) => {
1484
+ // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
1485
+ // can proceed further.
1486
+ self . expand_and_match_or_candidates (
1496
1487
span,
1497
1488
scrutinee_span,
1498
1489
start_block,
1499
1490
otherwise_block,
1500
- remaining ,
1491
+ candidates ,
1501
1492
)
1502
1493
}
1503
1494
candidates => {
@@ -1591,9 +1582,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1591
1582
let mut expand_until = 0 ;
1592
1583
for ( i, candidate) in candidates. iter ( ) . enumerate ( ) {
1593
1584
expand_until = i + 1 ;
1594
- if candidate. match_pairs . len ( ) > 1
1595
- && matches ! ( & candidate. match_pairs[ 0 ] . test_case, TestCase :: Or { .. } )
1596
- {
1585
+ if candidate. match_pairs . len ( ) > 1 && candidate. starts_with_or_pattern ( ) {
1597
1586
// The candidate has an or-pattern as well as more match pairs: we must
1598
1587
// split the candidates list here.
1599
1588
break ;
@@ -1604,8 +1593,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1604
1593
// Expand one level of or-patterns for each candidate in `candidates_to_expand`.
1605
1594
let mut expanded_candidates = Vec :: new ( ) ;
1606
1595
for candidate in candidates_to_expand. iter_mut ( ) {
1607
- if let [ MatchPair { test_case : TestCase :: Or { .. } , .. } , ..] = & * candidate. match_pairs
1608
- {
1596
+ if candidate. starts_with_or_pattern ( ) {
1609
1597
let or_match_pair = candidate. match_pairs . remove ( 0 ) ;
1610
1598
// Expand the or-pattern into subcandidates.
1611
1599
self . create_or_subcandidates ( candidate, or_match_pair) ;
0 commit comments