@@ -1706,6 +1706,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1706
1706
}
1707
1707
1708
1708
self . merge_trivial_subcandidates ( candidate) ;
1709
+ self . remove_never_subcandidates ( candidate) ;
1709
1710
1710
1711
if !candidate. match_pairs . is_empty ( ) {
1711
1712
let or_span = candidate. or_span . unwrap_or ( candidate. extra_data . span ) ;
@@ -1753,44 +1754,53 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1753
1754
let can_merge = candidate. subcandidates . iter ( ) . all ( |subcandidate| {
1754
1755
subcandidate. subcandidates . is_empty ( ) && subcandidate. extra_data . is_empty ( )
1755
1756
} ) ;
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
1793
1799
}
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 ( ) ) ;
1794
1804
}
1795
1805
}
1796
1806
0 commit comments