Skip to content

Commit e091c35

Browse files
committed
Improve merge_trivial_subcandidates
1 parent 3b7e4bc commit e091c35

File tree

1 file changed

+15
-5
lines changed
  • compiler/rustc_mir_build/src/build/matches

1 file changed

+15
-5
lines changed

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,8 +1744,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17441744
/// Try to merge all of the subcandidates of the given candidate into one. This avoids
17451745
/// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The candidate should have been
17461746
/// expanded with `create_or_subcandidates`.
1747+
///
1748+
/// Note that this takes place _after_ the subcandidates have participated
1749+
/// in match tree lowering.
17471750
fn merge_trivial_subcandidates(&mut self, candidate: &mut Candidate<'_, 'tcx>) {
1748-
if candidate.subcandidates.is_empty() || candidate.has_guard {
1751+
assert!(!candidate.subcandidates.is_empty());
1752+
if candidate.has_guard {
17491753
// FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
17501754
return;
17511755
}
@@ -1759,20 +1763,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17591763
}
17601764

17611765
let mut last_otherwise = None;
1762-
let any_matches = self.cfg.start_new_block();
1766+
let shared_pre_binding_block = self.cfg.start_new_block();
1767+
// This candidate is about to become a leaf, so unset `or_span`.
17631768
let or_span = candidate.or_span.take().unwrap();
17641769
let source_info = self.source_info(or_span);
17651770

17661771
if candidate.false_edge_start_block.is_none() {
17671772
candidate.false_edge_start_block = candidate.subcandidates[0].false_edge_start_block;
17681773
}
17691774

1775+
// Remove the (known-trivial) subcandidates from the candidate tree,
1776+
// so that they aren't visible after match tree lowering, and wire them
1777+
// all to join up at a single shared pre-binding block.
1778+
// (Note that the subcandidates have already had their part of the match
1779+
// tree lowered by this point, which is why we can add a goto to them.)
17701780
for subcandidate in mem::take(&mut candidate.subcandidates) {
1771-
let or_block = subcandidate.pre_binding_block.unwrap();
1772-
self.cfg.goto(or_block, source_info, any_matches);
1781+
let subcandidate_block = subcandidate.pre_binding_block.unwrap();
1782+
self.cfg.goto(subcandidate_block, source_info, shared_pre_binding_block);
17731783
last_otherwise = subcandidate.otherwise_block;
17741784
}
1775-
candidate.pre_binding_block = Some(any_matches);
1785+
candidate.pre_binding_block = Some(shared_pre_binding_block);
17761786
assert!(last_otherwise.is_some());
17771787
candidate.otherwise_block = last_otherwise;
17781788
}

0 commit comments

Comments
 (0)