Skip to content

Commit 5958489

Browse files
committed
Use create_or_subcandidates for all or-pattern expansions
1 parent 26ae53d commit 5958489

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
@@ -1252,9 +1252,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12521252
) {
12531253
let mut split_or_candidate = false;
12541254
for candidate in &mut *candidates {
1255-
if let [MatchPair { test_case: TestCase::Or { pats, .. }, .. }] =
1256-
&*candidate.match_pairs
1257-
{
1255+
if let [MatchPair { test_case: TestCase::Or { .. }, .. }] = &*candidate.match_pairs {
12581256
// Split a candidate in which the only match-pair is an or-pattern into multiple
12591257
// candidates. This is so that
12601258
//
@@ -1264,9 +1262,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12641262
// }
12651263
//
12661264
// only generates a single switch.
1267-
candidate.subcandidates = self.create_or_subcandidates(pats, candidate.has_guard);
1268-
let first_match_pair = candidate.match_pairs.pop().unwrap();
1269-
candidate.or_span = Some(first_match_pair.pattern.span);
1265+
let match_pair = candidate.match_pairs.pop().unwrap();
1266+
self.create_or_subcandidates(candidate, &match_pair);
12701267
split_or_candidate = true;
12711268
}
12721269
}
@@ -1456,12 +1453,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14561453

14571454
let match_pairs = mem::take(&mut first_candidate.match_pairs);
14581455
let (first_match_pair, remaining_match_pairs) = match_pairs.split_first().unwrap();
1459-
let TestCase::Or { ref pats } = &first_match_pair.test_case else { unreachable!() };
14601456

14611457
let remainder_start = self.cfg.start_new_block();
1462-
let or_span = first_match_pair.pattern.span;
14631458
// Test the alternatives of this or-pattern.
1464-
self.test_or_pattern(first_candidate, start_block, remainder_start, pats, or_span);
1459+
self.test_or_pattern(first_candidate, start_block, remainder_start, first_match_pair);
14651460

14661461
if !remaining_match_pairs.is_empty() {
14671462
// If more match pairs remain, test them after each subcandidate.
@@ -1496,39 +1491,48 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14961491
);
14971492
}
14981493

1499-
#[instrument(
1500-
skip(self, start_block, otherwise_block, or_span, candidate, pats),
1501-
level = "debug"
1502-
)]
1494+
#[instrument(skip(self, start_block, otherwise_block, candidate, match_pair), level = "debug")]
15031495
fn test_or_pattern<'pat>(
15041496
&mut self,
15051497
candidate: &mut Candidate<'pat, 'tcx>,
15061498
start_block: BasicBlock,
15071499
otherwise_block: BasicBlock,
1508-
pats: &[FlatPat<'pat, 'tcx>],
1509-
or_span: Span,
1500+
match_pair: &MatchPair<'pat, 'tcx>,
15101501
) {
1511-
debug!("candidate={:#?}\npats={:#?}", candidate, pats);
1512-
let mut or_candidates: Vec<_> = pats
1513-
.iter()
1514-
.cloned()
1515-
.map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard))
1516-
.collect();
1517-
let mut or_candidate_refs: Vec<_> = or_candidates.iter_mut().collect();
1502+
self.create_or_subcandidates(candidate, match_pair);
1503+
let mut or_candidate_refs: Vec<_> = candidate.subcandidates.iter_mut().collect();
1504+
let or_span = match_pair.pattern.span;
15181505
self.match_candidates(
15191506
or_span,
15201507
or_span,
15211508
start_block,
15221509
otherwise_block,
15231510
&mut or_candidate_refs,
15241511
);
1525-
candidate.subcandidates = or_candidates;
1526-
candidate.or_span = Some(or_span);
15271512
self.merge_trivial_subcandidates(candidate);
15281513
}
15291514

1530-
/// Try to merge all of the subcandidates of the given candidate into one.
1531-
/// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`.
1515+
/// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
1516+
/// subcandidate. Any candidate that has been expanded that way should be passed to
1517+
/// `merge_trivial_subcandidates` after its subcandidates have been processed.
1518+
fn create_or_subcandidates<'pat>(
1519+
&mut self,
1520+
candidate: &mut Candidate<'pat, 'tcx>,
1521+
match_pair: &MatchPair<'pat, 'tcx>,
1522+
) {
1523+
let TestCase::Or { ref pats } = &match_pair.test_case else { bug!() };
1524+
debug!("expanding or-pattern: candidate={:#?}\npats={:#?}", candidate, pats);
1525+
candidate.or_span = Some(match_pair.pattern.span);
1526+
candidate.subcandidates = pats
1527+
.iter()
1528+
.cloned()
1529+
.map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard))
1530+
.collect();
1531+
}
1532+
1533+
/// Try to merge all of the subcandidates of the given candidate into one. This avoids
1534+
/// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The or-pattern should have
1535+
/// been expanded with `create_or_subcandidates`.
15321536
fn merge_trivial_subcandidates(&mut self, candidate: &mut Candidate<'_, 'tcx>) {
15331537
if candidate.subcandidates.is_empty() || candidate.has_guard {
15341538
// 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::{Ascription, Binding, Candidate, FlatPat, MatchPair, TestCase};
15+
use crate::build::matches::{Ascription, Binding, MatchPair, TestCase};
1616
use crate::build::Builder;
1717

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

0 commit comments

Comments
 (0)