Skip to content

Commit 2d1a7fb

Browse files
committed
Use create_or_subcandidates for all or-pattern expansions
1 parent f1614c5 commit 2d1a7fb

File tree

2 files changed

+31
-38
lines changed

2 files changed

+31
-38
lines changed

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

+30-26
Original file line numberDiff line numberDiff line change
@@ -1282,9 +1282,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12821282
) {
12831283
let mut split_or_candidate = false;
12841284
for candidate in &mut *candidates {
1285-
if let [MatchPair { test_case: TestCase::Or { pats, .. }, .. }] =
1286-
&*candidate.match_pairs
1287-
{
1285+
if let [MatchPair { test_case: TestCase::Or { .. }, .. }] = &*candidate.match_pairs {
12881286
// Split a candidate in which the only match-pair is an or-pattern into multiple
12891287
// candidates. This is so that
12901288
//
@@ -1294,9 +1292,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12941292
// }
12951293
//
12961294
// only generates a single switch.
1297-
candidate.subcandidates = self.create_or_subcandidates(pats, candidate.has_guard);
1298-
let first_match_pair = candidate.match_pairs.pop().unwrap();
1299-
candidate.or_span = Some(first_match_pair.pattern.span);
1295+
let match_pair = candidate.match_pairs.pop().unwrap();
1296+
self.create_or_subcandidates(candidate, &match_pair);
13001297
split_or_candidate = true;
13011298
}
13021299
}
@@ -1486,12 +1483,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14861483

14871484
let match_pairs = mem::take(&mut first_candidate.match_pairs);
14881485
let (first_match_pair, remaining_match_pairs) = match_pairs.split_first().unwrap();
1489-
let TestCase::Or { ref pats } = &first_match_pair.test_case else { unreachable!() };
14901486

14911487
let remainder_start = self.cfg.start_new_block();
1492-
let or_span = first_match_pair.pattern.span;
14931488
// Test the alternatives of this or-pattern.
1494-
self.test_or_pattern(first_candidate, start_block, remainder_start, pats, or_span);
1489+
self.test_or_pattern(first_candidate, start_block, remainder_start, first_match_pair);
14951490

14961491
if !remaining_match_pairs.is_empty() {
14971492
// If more match pairs remain, test them after each subcandidate.
@@ -1526,39 +1521,48 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15261521
);
15271522
}
15281523

1529-
#[instrument(
1530-
skip(self, start_block, otherwise_block, or_span, candidate, pats),
1531-
level = "debug"
1532-
)]
1524+
#[instrument(skip(self, start_block, otherwise_block, candidate, match_pair), level = "debug")]
15331525
fn test_or_pattern<'pat>(
15341526
&mut self,
15351527
candidate: &mut Candidate<'pat, 'tcx>,
15361528
start_block: BasicBlock,
15371529
otherwise_block: BasicBlock,
1538-
pats: &[FlatPat<'pat, 'tcx>],
1539-
or_span: Span,
1530+
match_pair: &MatchPair<'pat, 'tcx>,
15401531
) {
1541-
debug!("candidate={:#?}\npats={:#?}", candidate, pats);
1542-
let mut or_candidates: Vec<_> = pats
1543-
.iter()
1544-
.cloned()
1545-
.map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard))
1546-
.collect();
1547-
let mut or_candidate_refs: Vec<_> = or_candidates.iter_mut().collect();
1532+
self.create_or_subcandidates(candidate, match_pair);
1533+
let mut or_candidate_refs: Vec<_> = candidate.subcandidates.iter_mut().collect();
1534+
let or_span = match_pair.pattern.span;
15481535
self.match_candidates(
15491536
or_span,
15501537
or_span,
15511538
start_block,
15521539
otherwise_block,
15531540
&mut or_candidate_refs,
15541541
);
1555-
candidate.subcandidates = or_candidates;
1556-
candidate.or_span = Some(or_span);
15571542
self.merge_trivial_subcandidates(candidate);
15581543
}
15591544

1560-
/// Try to merge all of the subcandidates of the given candidate into one.
1561-
/// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`.
1545+
/// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
1546+
/// subcandidate. Any candidate that has been expanded that way should be passed to
1547+
/// `merge_trivial_subcandidates` after its subcandidates have been processed.
1548+
fn create_or_subcandidates<'pat>(
1549+
&mut self,
1550+
candidate: &mut Candidate<'pat, 'tcx>,
1551+
match_pair: &MatchPair<'pat, 'tcx>,
1552+
) {
1553+
let TestCase::Or { ref pats } = &match_pair.test_case else { bug!() };
1554+
debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats);
1555+
candidate.or_span = Some(match_pair.pattern.span);
1556+
candidate.subcandidates = pats
1557+
.iter()
1558+
.cloned()
1559+
.map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard))
1560+
.collect();
1561+
}
1562+
1563+
/// Try to merge all of the subcandidates of the given candidate into one. This avoids
1564+
/// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The or-pattern should have
1565+
/// been expanded with `create_or_subcandidates`.
15621566
fn merge_trivial_subcandidates(&mut self, candidate: &mut Candidate<'_, 'tcx>) {
15631567
if candidate.subcandidates.is_empty() || candidate.has_guard {
15641568
// FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.

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

+1-12
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
//! sort of test: for example, testing which variant an enum is, or
1313
//! testing a value against a constant.
1414
15-
use crate::build::matches::{
16-
Candidate, DerefTemporary, FlatPat, MatchPair, PatternExtraData, TestCase,
17-
};
15+
use crate::build::matches::{DerefTemporary, MatchPair, PatternExtraData, TestCase};
1816
use crate::build::Builder;
1917

2018
use std::mem;
@@ -79,13 +77,4 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
7977
match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. }));
8078
debug!(simplified = ?match_pairs, "simplify_match_pairs");
8179
}
82-
83-
/// Create a new candidate for each pattern in `pats`.
84-
pub(super) fn create_or_subcandidates<'pat>(
85-
&mut self,
86-
pats: &[FlatPat<'pat, 'tcx>],
87-
has_guard: bool,
88-
) -> Vec<Candidate<'pat, 'tcx>> {
89-
pats.iter().cloned().map(|flat_pat| Candidate::from_flat_pat(flat_pat, has_guard)).collect()
90-
}
9180
}

0 commit comments

Comments
 (0)