Skip to content

Commit c5062f7

Browse files
committed
Move or-pattern expansion inside the main part of the algorithm
1 parent bff4d21 commit c5062f7

File tree

1 file changed

+24
-36
lines changed
  • compiler/rustc_mir_build/src/build/matches

1 file changed

+24
-36
lines changed

compiler/rustc_mir_build/src/build/matches/mod.rs

+24-36
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)