Skip to content

Commit 79be3a9

Browse files
committed
Use create_or_subcandidates for all or-pattern expansions
1 parent 6b42dff commit 79be3a9

File tree

2 files changed

+31
-36
lines changed

2 files changed

+31
-36
lines changed

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

+30-26
Original file line numberDiff line numberDiff line change
@@ -1240,9 +1240,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12401240
) {
12411241
let mut split_or_candidate = false;
12421242
for candidate in &mut *candidates {
1243-
if let [MatchPair { test_case: TestCase::Or { pats, .. }, .. }] =
1244-
&*candidate.match_pairs
1245-
{
1243+
if let [MatchPair { test_case: TestCase::Or { .. }, .. }] = &*candidate.match_pairs {
12461244
// Split a candidate in which the only match-pair is an or-pattern into multiple
12471245
// candidates. This is so that
12481246
//
@@ -1252,9 +1250,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12521250
// }
12531251
//
12541252
// only generates a single switch.
1255-
candidate.subcandidates = self.create_or_subcandidates(pats, candidate.has_guard);
1256-
let first_match_pair = candidate.match_pairs.pop().unwrap();
1257-
candidate.or_span = Some(first_match_pair.pattern.span);
1253+
let match_pair = candidate.match_pairs.pop().unwrap();
1254+
self.create_or_subcandidates(candidate, &match_pair);
12581255
split_or_candidate = true;
12591256
}
12601257
}
@@ -1444,12 +1441,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14441441

14451442
let match_pairs = mem::take(&mut first_candidate.match_pairs);
14461443
let (first_match_pair, remaining_match_pairs) = match_pairs.split_first().unwrap();
1447-
let TestCase::Or { ref pats } = &first_match_pair.test_case else { unreachable!() };
14481444

14491445
let remainder_start = self.cfg.start_new_block();
1450-
let or_span = first_match_pair.pattern.span;
14511446
// Test the alternatives of this or-pattern.
1452-
self.test_or_pattern(first_candidate, start_block, remainder_start, pats, or_span);
1447+
self.test_or_pattern(first_candidate, start_block, remainder_start, first_match_pair);
14531448

14541449
if !remaining_match_pairs.is_empty() {
14551450
// If more match pairs remain, test them after each subcandidate.
@@ -1484,39 +1479,48 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14841479
);
14851480
}
14861481

1487-
#[instrument(
1488-
skip(self, start_block, otherwise_block, or_span, candidate, pats),
1489-
level = "debug"
1490-
)]
1482+
#[instrument(skip(self, start_block, otherwise_block, candidate, match_pair), level = "debug")]
14911483
fn test_or_pattern<'pat>(
14921484
&mut self,
14931485
candidate: &mut Candidate<'pat, 'tcx>,
14941486
start_block: BasicBlock,
14951487
otherwise_block: BasicBlock,
1496-
pats: &[FlatPat<'pat, 'tcx>],
1497-
or_span: Span,
1488+
match_pair: &MatchPair<'pat, 'tcx>,
14981489
) {
1499-
debug!("candidate={:#?}\npats={:#?}", candidate, pats);
1500-
let mut or_candidates: Vec<_> = pats
1501-
.iter()
1502-
.cloned()
1503-
.map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard))
1504-
.collect();
1505-
let mut or_candidate_refs: Vec<_> = or_candidates.iter_mut().collect();
1490+
self.create_or_subcandidates(candidate, match_pair);
1491+
let mut or_candidate_refs: Vec<_> = candidate.subcandidates.iter_mut().collect();
1492+
let or_span = match_pair.pattern.span;
15061493
self.match_candidates(
15071494
or_span,
15081495
or_span,
15091496
start_block,
15101497
otherwise_block,
15111498
&mut or_candidate_refs,
15121499
);
1513-
candidate.subcandidates = or_candidates;
1514-
candidate.or_span = Some(or_span);
15151500
self.merge_trivial_subcandidates(candidate);
15161501
}
15171502

1518-
/// Try to merge all of the subcandidates of the given candidate into one.
1519-
/// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`.
1503+
/// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
1504+
/// subcandidate. Any candidate that has been expanded that way should be passed to
1505+
/// `merge_trivial_subcandidates` after its subcandidates have been processed.
1506+
fn create_or_subcandidates<'pat>(
1507+
&mut self,
1508+
candidate: &mut Candidate<'pat, 'tcx>,
1509+
match_pair: &MatchPair<'pat, 'tcx>,
1510+
) {
1511+
let TestCase::Or { ref pats } = &match_pair.test_case else { bug!() };
1512+
debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats);
1513+
candidate.or_span = Some(match_pair.pattern.span);
1514+
candidate.subcandidates = pats
1515+
.iter()
1516+
.cloned()
1517+
.map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard))
1518+
.collect();
1519+
}
1520+
1521+
/// Try to merge all of the subcandidates of the given candidate into one. This avoids
1522+
/// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The or-pattern should have
1523+
/// been expanded with `create_or_subcandidates`.
15201524
fn merge_trivial_subcandidates(&mut self, candidate: &mut Candidate<'_, 'tcx>) {
15211525
if candidate.subcandidates.is_empty() || candidate.has_guard {
15221526
// FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.

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

+1-10
Original file line numberDiff line numberDiff line change
@@ -12,7 +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::{Candidate, FlatPat, MatchPair, PatternExtraData, TestCase};
15+
use crate::build::matches::{MatchPair, PatternExtraData, TestCase};
1616
use crate::build::Builder;
1717

1818
use std::mem;
@@ -66,13 +66,4 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
6666
match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. }));
6767
debug!(simplified = ?match_pairs, "simplify_match_pairs");
6868
}
69-
70-
/// Create a new candidate for each pattern in `pats`.
71-
pub(super) fn create_or_subcandidates<'pat>(
72-
&mut self,
73-
pats: &[FlatPat<'pat, 'tcx>],
74-
has_guard: bool,
75-
) -> Vec<Candidate<'pat, 'tcx>> {
76-
pats.iter().cloned().map(|flat_pat| Candidate::from_flat_pat(flat_pat, has_guard)).collect()
77-
}
7869
}

0 commit comments

Comments
 (0)