@@ -1056,6 +1056,11 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
1056
1056
}
1057
1057
}
1058
1058
1059
+ /// Returns whether the first match pair of this candidate is an or-pattern.
1060
+ fn starts_with_or_pattern ( & self ) -> bool {
1061
+ matches ! ( & * self . match_pairs, [ MatchPair { test_case: TestCase :: Or { .. } , .. } , ..] )
1062
+ }
1063
+
1059
1064
/// Visit the leaf candidates (those with no subcandidates) contained in
1060
1065
/// this candidate.
1061
1066
fn visit_leaves < ' a > ( & ' a mut self , mut visit_leaf : impl FnMut ( & ' a mut Self ) ) {
@@ -1372,39 +1377,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1372
1377
otherwise_block : BasicBlock ,
1373
1378
candidates : & mut [ & mut Candidate < ' _ , ' tcx > ] ,
1374
1379
) {
1375
- // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
1376
- // can proceed further.
1377
- let expand_ors = candidates. iter ( ) . any ( |candidate| {
1378
- matches ! (
1379
- & * candidate. match_pairs,
1380
- [ MatchPair { test_case: TestCase :: Or { .. } , .. } , ..]
1381
- )
1382
- } ) ;
1383
1380
ensure_sufficient_stack ( || {
1384
- if !expand_ors {
1385
- // No candidates start with an or-pattern, we can continue.
1386
- self . match_expanded_candidates (
1387
- span,
1388
- scrutinee_span,
1389
- start_block,
1390
- otherwise_block,
1391
- candidates,
1392
- ) ;
1393
- } else {
1394
- self . expand_and_match_or_candidates (
1395
- span,
1396
- scrutinee_span,
1397
- start_block,
1398
- otherwise_block,
1399
- candidates,
1400
- ) ;
1401
- }
1381
+ self . match_candidates_with_enough_stack (
1382
+ span,
1383
+ scrutinee_span,
1384
+ start_block,
1385
+ otherwise_block,
1386
+ candidates,
1387
+ )
1402
1388
} ) ;
1403
1389
}
1404
1390
1405
- /// Construct the decision tree for `candidates`. Caller must ensure that no candidate in
1406
- /// `candidates` starts with an or-pattern .
1407
- fn match_expanded_candidates (
1391
+ /// Construct the decision tree for `candidates`. Don't call this, call `match_candidates`
1392
+ /// instead to reserve sufficient stack space .
1393
+ fn match_candidates_with_enough_stack (
1408
1394
& mut self ,
1409
1395
span : Span ,
1410
1396
scrutinee_span : Span ,
@@ -1429,12 +1415,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1429
1415
// The first candidate has satisfied all its match pairs; we link it up and continue
1430
1416
// with the remaining candidates.
1431
1417
start_block = self . select_matched_candidate ( first, start_block) ;
1432
- self . match_expanded_candidates (
1418
+ self . match_candidates ( span, scrutinee_span, start_block, otherwise_block, remaining)
1419
+ }
1420
+ candidates if candidates. iter ( ) . any ( |candidate| candidate. starts_with_or_pattern ( ) ) => {
1421
+ // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
1422
+ // can proceed further.
1423
+ self . expand_and_match_or_candidates (
1433
1424
span,
1434
1425
scrutinee_span,
1435
1426
start_block,
1436
1427
otherwise_block,
1437
- remaining ,
1428
+ candidates ,
1438
1429
)
1439
1430
}
1440
1431
candidates => {
@@ -1528,9 +1519,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1528
1519
let mut expand_until = 0 ;
1529
1520
for ( i, candidate) in candidates. iter ( ) . enumerate ( ) {
1530
1521
expand_until = i + 1 ;
1531
- if candidate. match_pairs . len ( ) > 1
1532
- && matches ! ( & candidate. match_pairs[ 0 ] . test_case, TestCase :: Or { .. } )
1533
- {
1522
+ if candidate. match_pairs . len ( ) > 1 && candidate. starts_with_or_pattern ( ) {
1534
1523
// The candidate has an or-pattern as well as more match pairs: we must
1535
1524
// split the candidates list here.
1536
1525
break ;
@@ -1541,8 +1530,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1541
1530
// Expand one level of or-patterns for each candidate in `candidates_to_expand`.
1542
1531
let mut expanded_candidates = Vec :: new ( ) ;
1543
1532
for candidate in candidates_to_expand. iter_mut ( ) {
1544
- if let [ MatchPair { test_case : TestCase :: Or { .. } , .. } , ..] = & * candidate. match_pairs
1545
- {
1533
+ if candidate. starts_with_or_pattern ( ) {
1546
1534
let or_match_pair = candidate. match_pairs . remove ( 0 ) ;
1547
1535
// Expand the or-pattern into subcandidates.
1548
1536
self . create_or_subcandidates ( candidate, or_match_pair) ;
0 commit comments