@@ -1575,21 +1575,52 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15751575 }
15761576
15771577 let first_match_pair = first_candidate. match_pairs . remove ( 0 ) ;
1578- let remaining_match_pairs = mem:: take ( & mut first_candidate. match_pairs ) ;
15791578 let remainder_start = self . cfg . start_new_block ( ) ;
15801579 // Test the alternatives of this or-pattern.
1581- self . test_or_pattern ( first_candidate, start_block, remainder_start, first_match_pair) ;
1580+ self . test_or_pattern (
1581+ span,
1582+ scrutinee_span,
1583+ first_candidate,
1584+ start_block,
1585+ remainder_start,
1586+ first_match_pair,
1587+ ) ;
1588+
1589+ // Test the remaining candidates.
1590+ self . match_candidates (
1591+ span,
1592+ scrutinee_span,
1593+ remainder_start,
1594+ otherwise_block,
1595+ remaining_candidates,
1596+ ) ;
1597+ }
1598+
1599+ /// Simplify subcandidates and process any leftover match pairs. The candidate should have been
1600+ /// expanded with `create_or_subcandidates`.
1601+ fn finalize_or_candidate (
1602+ & mut self ,
1603+ span : Span ,
1604+ scrutinee_span : Span ,
1605+ candidate : & mut Candidate < ' _ , ' tcx > ,
1606+ ) {
1607+ if candidate. subcandidates . is_empty ( ) {
1608+ return ;
1609+ }
1610+
1611+ self . merge_trivial_subcandidates ( candidate) ;
15821612
1583- if !remaining_match_pairs . is_empty ( ) {
1613+ if !candidate . match_pairs . is_empty ( ) {
15841614 // If more match pairs remain, test them after each subcandidate.
15851615 // We could add them to the or-candidates before the call to `test_or_pattern` but this
15861616 // would make it impossible to detect simplifiable or-patterns. That would guarantee
15871617 // exponentially large CFGs for cases like `(1 | 2, 3 | 4, ...)`.
15881618 let mut last_otherwise = None ;
1589- first_candidate . visit_leaves ( |leaf_candidate| {
1619+ candidate . visit_leaves ( |leaf_candidate| {
15901620 last_otherwise = leaf_candidate. otherwise_block ;
15911621 } ) ;
1592- first_candidate. visit_leaves ( |leaf_candidate| {
1622+ let remaining_match_pairs = mem:: take ( & mut candidate. match_pairs ) ;
1623+ candidate. visit_leaves ( |leaf_candidate| {
15931624 assert ! ( leaf_candidate. match_pairs. is_empty( ) ) ;
15941625 leaf_candidate. match_pairs . extend ( remaining_match_pairs. iter ( ) . cloned ( ) ) ;
15951626 let or_start = leaf_candidate. pre_binding_block . unwrap ( ) ;
@@ -1612,20 +1643,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
16121643 ) ;
16131644 } ) ;
16141645 }
1615-
1616- // Test the remaining candidates.
1617- self . match_candidates (
1618- span,
1619- scrutinee_span,
1620- remainder_start,
1621- otherwise_block,
1622- remaining_candidates,
1623- ) ;
16241646 }
16251647
16261648 #[ instrument( skip( self , start_block, otherwise_block, candidate, match_pair) , level = "debug" ) ]
16271649 fn test_or_pattern < ' pat > (
16281650 & mut self ,
1651+ span : Span ,
1652+ scrutinee_span : Span ,
16291653 candidate : & mut Candidate < ' pat , ' tcx > ,
16301654 start_block : BasicBlock ,
16311655 otherwise_block : BasicBlock ,
@@ -1641,12 +1665,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
16411665 otherwise_block,
16421666 & mut or_candidate_refs,
16431667 ) ;
1644- self . merge_trivial_subcandidates ( candidate) ;
1668+ self . finalize_or_candidate ( span , scrutinee_span , candidate) ;
16451669 }
16461670
16471671 /// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
16481672 /// subcandidate. Any candidate that has been expanded that way should be passed to
1649- /// `merge_trivial_subcandidates ` after its subcandidates have been processed.
1673+ /// `finalize_or_candidate ` after its subcandidates have been processed.
16501674 fn create_or_subcandidates < ' pat > (
16511675 & mut self ,
16521676 candidate : & mut Candidate < ' pat , ' tcx > ,
@@ -1664,8 +1688,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
16641688 }
16651689
16661690 /// Try to merge all of the subcandidates of the given candidate into one. This avoids
1667- /// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The or-pattern should have
1668- /// been expanded with `create_or_subcandidates`.
1691+ /// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The candidate should have been
1692+ /// expanded with `create_or_subcandidates`.
16691693 fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
16701694 if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
16711695 // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
0 commit comments