Skip to content

Commit 7d71ea9

Browse files
committed
Move or-pattern expansion inside the main part of the algorithm
1 parent 1e01a25 commit 7d71ea9

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
@@ -1056,6 +1056,11 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
10561056
}
10571057
}
10581058

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+
10591064
/// Visit the leaf candidates (those with no subcandidates) contained in
10601065
/// this candidate.
10611066
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> {
13721377
otherwise_block: BasicBlock,
13731378
candidates: &mut [&mut Candidate<'_, 'tcx>],
13741379
) {
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-
});
13831380
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+
)
14021388
});
14031389
}
14041390

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(
14081394
&mut self,
14091395
span: Span,
14101396
scrutinee_span: Span,
@@ -1429,12 +1415,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14291415
// The first candidate has satisfied all its match pairs; we link it up and continue
14301416
// with the remaining candidates.
14311417
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(
14331424
span,
14341425
scrutinee_span,
14351426
start_block,
14361427
otherwise_block,
1437-
remaining,
1428+
candidates,
14381429
)
14391430
}
14401431
candidates => {
@@ -1528,9 +1519,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15281519
let mut expand_until = 0;
15291520
for (i, candidate) in candidates.iter().enumerate() {
15301521
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() {
15341523
// The candidate has an or-pattern as well as more match pairs: we must
15351524
// split the candidates list here.
15361525
break;
@@ -1541,8 +1530,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15411530
// Expand one level of or-patterns for each candidate in `candidates_to_expand`.
15421531
let mut expanded_candidates = Vec::new();
15431532
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() {
15461534
let or_match_pair = candidate.match_pairs.remove(0);
15471535
// Expand the or-pattern into subcandidates.
15481536
self.create_or_subcandidates(candidate, or_match_pair);

0 commit comments

Comments
 (0)