@@ -1706,6 +1706,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17061706 }
17071707
17081708 self . merge_trivial_subcandidates ( candidate) ;
1709+ self . remove_never_subcandidates ( candidate) ;
17091710
17101711 if !candidate. match_pairs . is_empty ( ) {
17111712 let or_span = candidate. or_span . unwrap_or ( candidate. extra_data . span ) ;
@@ -1753,44 +1754,53 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17531754 let can_merge = candidate. subcandidates . iter ( ) . all ( |subcandidate| {
17541755 subcandidate. subcandidates . is_empty ( ) && subcandidate. extra_data . is_empty ( )
17551756 } ) ;
1756- if can_merge {
1757- let mut last_otherwise = None ;
1758- let any_matches = self . cfg . start_new_block ( ) ;
1759- let or_span = candidate. or_span . take ( ) . unwrap ( ) ;
1760- let source_info = self . source_info ( or_span) ;
1761- if candidate. false_edge_start_block . is_none ( ) {
1762- candidate. false_edge_start_block =
1763- candidate. subcandidates [ 0 ] . false_edge_start_block ;
1764- }
1765- for subcandidate in mem:: take ( & mut candidate. subcandidates ) {
1766- let or_block = subcandidate. pre_binding_block . unwrap ( ) ;
1767- self . cfg . goto ( or_block, source_info, any_matches) ;
1768- last_otherwise = subcandidate. otherwise_block ;
1769- }
1770- candidate. pre_binding_block = Some ( any_matches) ;
1771- assert ! ( last_otherwise. is_some( ) ) ;
1772- candidate. otherwise_block = last_otherwise;
1773- } else {
1774- // Never subcandidates may have a set of bindings inconsistent with their siblings,
1775- // which would break later code. So we filter them out. Note that we can't filter out
1776- // top-level candidates this way.
1777- candidate. subcandidates . retain_mut ( |candidate| {
1778- if candidate. extra_data . is_never {
1779- candidate. visit_leaves ( |subcandidate| {
1780- let block = subcandidate. pre_binding_block . unwrap ( ) ;
1781- // That block is already unreachable but needs a terminator to make the MIR well-formed.
1782- let source_info = self . source_info ( subcandidate. extra_data . span ) ;
1783- self . cfg . terminate ( block, source_info, TerminatorKind :: Unreachable ) ;
1784- } ) ;
1785- false
1786- } else {
1787- true
1788- }
1789- } ) ;
1790- if candidate. subcandidates . is_empty ( ) {
1791- // If `candidate` has become a leaf candidate, ensure it has a `pre_binding_block`.
1792- candidate. pre_binding_block = Some ( self . cfg . start_new_block ( ) ) ;
1757+ if !can_merge {
1758+ return ;
1759+ }
1760+
1761+ let mut last_otherwise = None ;
1762+ let any_matches = self . cfg . start_new_block ( ) ;
1763+ let or_span = candidate. or_span . take ( ) . unwrap ( ) ;
1764+ let source_info = self . source_info ( or_span) ;
1765+
1766+ if candidate. false_edge_start_block . is_none ( ) {
1767+ candidate. false_edge_start_block = candidate. subcandidates [ 0 ] . false_edge_start_block ;
1768+ }
1769+
1770+ 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) ;
1773+ last_otherwise = subcandidate. otherwise_block ;
1774+ }
1775+ candidate. pre_binding_block = Some ( any_matches) ;
1776+ assert ! ( last_otherwise. is_some( ) ) ;
1777+ candidate. otherwise_block = last_otherwise;
1778+ }
1779+
1780+ /// Never subcandidates may have a set of bindings inconsistent with their siblings,
1781+ /// which would break later code. So we filter them out. Note that we can't filter out
1782+ /// top-level candidates this way.
1783+ fn remove_never_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
1784+ if candidate. subcandidates . is_empty ( ) {
1785+ return ;
1786+ }
1787+
1788+ candidate. subcandidates . retain_mut ( |candidate| {
1789+ if candidate. extra_data . is_never {
1790+ candidate. visit_leaves ( |subcandidate| {
1791+ let block = subcandidate. pre_binding_block . unwrap ( ) ;
1792+ // That block is already unreachable but needs a terminator to make the MIR well-formed.
1793+ let source_info = self . source_info ( subcandidate. extra_data . span ) ;
1794+ self . cfg . terminate ( block, source_info, TerminatorKind :: Unreachable ) ;
1795+ } ) ;
1796+ false
1797+ } else {
1798+ true
17931799 }
1800+ } ) ;
1801+ if candidate. subcandidates . is_empty ( ) {
1802+ // If `candidate` has become a leaf candidate, ensure it has a `pre_binding_block`.
1803+ candidate. pre_binding_block = Some ( self . cfg . start_new_block ( ) ) ;
17941804 }
17951805 }
17961806
0 commit comments