@@ -1119,6 +1119,11 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
11191119 }
11201120 }
11211121
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+
11221127 /// Visit the leaf candidates (those with no subcandidates) contained in
11231128 /// this candidate.
11241129 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> {
14351440 otherwise_block : BasicBlock ,
14361441 candidates : & mut [ & mut Candidate < ' _ , ' tcx > ] ,
14371442 ) {
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- } ) ;
14461443 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+ )
14651451 } ) ;
14661452 }
14671453
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 (
14711457 & mut self ,
14721458 span : Span ,
14731459 scrutinee_span : Span ,
@@ -1492,12 +1478,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14921478 // The first candidate has satisfied all its match pairs; we link it up and continue
14931479 // with the remaining candidates.
14941480 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 (
14961487 span,
14971488 scrutinee_span,
14981489 start_block,
14991490 otherwise_block,
1500- remaining ,
1491+ candidates ,
15011492 )
15021493 }
15031494 candidates => {
@@ -1591,9 +1582,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15911582 let mut expand_until = 0 ;
15921583 for ( i, candidate) in candidates. iter ( ) . enumerate ( ) {
15931584 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 ( ) {
15971586 // The candidate has an or-pattern as well as more match pairs: we must
15981587 // split the candidates list here.
15991588 break ;
@@ -1604,8 +1593,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
16041593 // Expand one level of or-patterns for each candidate in `candidates_to_expand`.
16051594 let mut expanded_candidates = Vec :: new ( ) ;
16061595 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 ( ) {
16091597 let or_match_pair = candidate. match_pairs . remove ( 0 ) ;
16101598 // Expand the or-pattern into subcandidates.
16111599 self . create_or_subcandidates ( candidate, or_match_pair) ;
0 commit comments