Skip to content

Commit 374b3d8

Browse files
committed
Test one or pattern at a time
1 parent a84bb95 commit 374b3d8

File tree

1 file changed

+37
-27
lines changed
  • compiler/rustc_mir_build/src/build/matches

1 file changed

+37
-27
lines changed

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

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,46 +1426,56 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14261426
fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>,
14271427
) {
14281428
let (first_candidate, remaining_candidates) = candidates.split_first_mut().unwrap();
1429-
1430-
// All of the or-patterns have been sorted to the end, so if the first
1431-
// pattern is an or-pattern we only have or-patterns.
1432-
match first_candidate.match_pairs[0].pattern.kind {
1433-
PatKind::Or { .. } => (),
1434-
_ => {
1435-
self.test_candidates(
1436-
span,
1437-
scrutinee_span,
1438-
candidates,
1439-
block,
1440-
otherwise_block,
1441-
fake_borrows,
1442-
);
1443-
return;
1444-
}
1429+
if !matches!(first_candidate.match_pairs[0].pattern.kind, PatKind::Or { .. }) {
1430+
self.test_candidates(
1431+
span,
1432+
scrutinee_span,
1433+
candidates,
1434+
block,
1435+
otherwise_block,
1436+
fake_borrows,
1437+
);
1438+
return;
14451439
}
14461440

14471441
let match_pairs = mem::take(&mut first_candidate.match_pairs);
1448-
first_candidate.pre_binding_block = Some(block);
1442+
let (first_match_pair, remaining_match_pairs) = match_pairs.split_first().unwrap();
1443+
let PatKind::Or { ref pats } = &first_match_pair.pattern.kind else { unreachable!() };
14491444

1445+
first_candidate.pre_binding_block = Some(block);
14501446
let remainder_start = self.cfg.start_new_block();
1451-
for match_pair in match_pairs {
1452-
let PatKind::Or { ref pats } = &match_pair.pattern.kind else {
1453-
bug!("Or-patterns should have been sorted to the end");
1454-
};
1455-
let or_span = match_pair.pattern.span;
1447+
let or_span = first_match_pair.pattern.span;
1448+
// Test the alternatives of this or-pattern.
1449+
self.test_or_pattern(
1450+
first_candidate,
1451+
remainder_start,
1452+
pats,
1453+
or_span,
1454+
&first_match_pair.place,
1455+
fake_borrows,
1456+
);
14561457

1458+
if !remaining_match_pairs.is_empty() {
1459+
// If more match pairs remain, test them after each subcandidate.
1460+
// We could add them to the or-candidates before the call to `test_or_pattern` but this
1461+
// would make it impossible to detect simplifiable or-patterns. That would guarantee
1462+
// exponentially large CFGs for cases like `(1 | 2, 3 | 4, ...)`.
14571463
first_candidate.visit_leaves(|leaf_candidate| {
1458-
self.test_or_pattern(
1459-
leaf_candidate,
1464+
assert!(leaf_candidate.match_pairs.is_empty());
1465+
leaf_candidate.match_pairs.extend(remaining_match_pairs.iter().cloned());
1466+
let block = leaf_candidate.pre_binding_block.unwrap();
1467+
self.test_candidates_with_or(
1468+
span,
1469+
scrutinee_span,
1470+
&mut [leaf_candidate],
1471+
block,
14601472
remainder_start,
1461-
pats,
1462-
or_span,
1463-
&match_pair.place,
14641473
fake_borrows,
14651474
);
14661475
});
14671476
}
14681477

1478+
// Test the remaining candidates.
14691479
self.match_candidates(
14701480
span,
14711481
scrutinee_span,

0 commit comments

Comments
 (0)