Skip to content

Commit 95b968e

Browse files
committed
Move a bit of the logic to match_simplified_candidates
1 parent e712fb6 commit 95b968e

File tree

1 file changed

+42
-40
lines changed
  • compiler/rustc_mir_build/src/build/matches

1 file changed

+42
-40
lines changed

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

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,9 +1260,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12601260
fake_borrows,
12611261
)
12621262
}
1263+
[first, remaining @ ..]
1264+
if matches!(first.match_pairs[0].pattern.kind, PatKind::Or { .. }) =>
1265+
{
1266+
// The first candidate has an or-pattern.
1267+
let remainder_start = self.cfg.start_new_block();
1268+
// Test the or-pattern.
1269+
self.test_or_candidate(
1270+
span,
1271+
scrutinee_span,
1272+
first,
1273+
start_block,
1274+
remainder_start,
1275+
fake_borrows,
1276+
);
1277+
// Test the remaining candidates.
1278+
self.match_candidates(
1279+
span,
1280+
scrutinee_span,
1281+
remainder_start,
1282+
otherwise_block,
1283+
remaining,
1284+
fake_borrows,
1285+
);
1286+
}
12631287
candidates => {
1264-
// The first candidate has some unsatisfied match pairs; we proceed to do more tests.
1265-
self.test_candidates_with_or(
1288+
// The first candidate has some unsatisfied match pairs that aren't or-patterns; we
1289+
// proceed to do more tests.
1290+
self.test_candidates(
12661291
span,
12671292
scrutinee_span,
12681293
candidates,
@@ -1350,8 +1375,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
13501375
otherwise_block
13511376
}
13521377

1353-
/// Tests a candidate where there are only or-patterns left to test, or
1354-
/// forwards to [Builder::test_candidates].
1378+
/// Tests a candidate whose first match-pair is an or-pattern.
13551379
///
13561380
/// Given a pattern `(P | Q, R | S)` we (in principle) generate a CFG like
13571381
/// so:
@@ -1403,40 +1427,28 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14031427
/// |
14041428
/// ...
14051429
/// ```
1406-
fn test_candidates_with_or(
1430+
fn test_or_candidate(
14071431
&mut self,
14081432
span: Span,
14091433
scrutinee_span: Span,
1410-
candidates: &mut [&mut Candidate<'_, 'tcx>],
1434+
candidate: &mut Candidate<'_, 'tcx>,
14111435
start_block: BasicBlock,
14121436
otherwise_block: BasicBlock,
14131437
fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>,
14141438
) {
1415-
let (first_candidate, remaining_candidates) = candidates.split_first_mut().unwrap();
1416-
assert!(first_candidate.subcandidates.is_empty());
1417-
if !matches!(first_candidate.match_pairs[0].pattern.kind, PatKind::Or { .. }) {
1418-
self.test_candidates(
1419-
span,
1420-
scrutinee_span,
1421-
candidates,
1422-
start_block,
1423-
otherwise_block,
1424-
fake_borrows,
1425-
);
1426-
return;
1427-
}
1428-
1429-
let match_pairs = mem::take(&mut first_candidate.match_pairs);
1439+
assert!(candidate.subcandidates.is_empty());
1440+
let match_pairs = mem::take(&mut candidate.match_pairs);
14301441
let (first_match_pair, remaining_match_pairs) = match_pairs.split_first().unwrap();
1431-
let PatKind::Or { ref pats } = &first_match_pair.pattern.kind else { unreachable!() };
1442+
let PatKind::Or { ref pats } = &first_match_pair.pattern.kind else {
1443+
bug!("Only call `test_or_candidate` if the first match pair is an or-pattern")
1444+
};
14321445

1433-
let remainder_start = self.cfg.start_new_block();
14341446
let or_span = first_match_pair.pattern.span;
14351447
// Test the alternatives of this or-pattern.
14361448
self.test_or_pattern(
1437-
first_candidate,
1449+
candidate,
14381450
start_block,
1439-
remainder_start,
1451+
otherwise_block,
14401452
pats,
14411453
or_span,
14421454
&first_match_pair.place,
@@ -1448,34 +1460,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14481460
// We could add them to the or-candidates before the call to `test_or_pattern` but this
14491461
// would make it impossible to detect simplifiable or-patterns. That would guarantee
14501462
// exponentially large CFGs for cases like `(1 | 2, 3 | 4, ...)`.
1451-
first_candidate.visit_leaves(|leaf_candidate| {
1463+
candidate.visit_leaves(|leaf_candidate| {
14521464
assert!(leaf_candidate.match_pairs.is_empty());
14531465
leaf_candidate.match_pairs.extend(remaining_match_pairs.iter().cloned());
14541466
let or_start = leaf_candidate.pre_binding_block.unwrap();
14551467
// In a case like `(a | b, c | d)`, if `a` succeeds and `c | d` fails, we know `(b,
14561468
// c | d)` will fail too. If there is no guard, we skip testing of `b` by branching
1457-
// directly to `remainder_start`. If there is a guard, we have to try `(b, c | d)`.
1458-
let or_otherwise = leaf_candidate.otherwise_block.unwrap_or(remainder_start);
1459-
self.test_candidates_with_or(
1469+
// directly to `otherwise_block`. If there is a guard, we have to try `(b, c | d)`.
1470+
let or_otherwise = leaf_candidate.otherwise_block.unwrap_or(otherwise_block);
1471+
self.match_simplified_candidates(
14601472
span,
14611473
scrutinee_span,
1462-
&mut [leaf_candidate],
14631474
or_start,
14641475
or_otherwise,
1476+
&mut [leaf_candidate],
14651477
fake_borrows,
14661478
);
14671479
});
14681480
}
1469-
1470-
// Test the remaining candidates.
1471-
self.match_candidates(
1472-
span,
1473-
scrutinee_span,
1474-
remainder_start,
1475-
otherwise_block,
1476-
remaining_candidates,
1477-
fake_borrows,
1478-
);
14791481
}
14801482

14811483
#[instrument(

0 commit comments

Comments
 (0)