@@ -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