@@ -1282,9 +1282,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12821282 ) {
12831283 let mut split_or_candidate = false ;
12841284 for candidate in & mut * candidates {
1285- if let [ MatchPair { test_case : TestCase :: Or { pats, .. } , .. } ] =
1286- & * candidate. match_pairs
1287- {
1285+ if let [ MatchPair { test_case : TestCase :: Or { .. } , .. } ] = & * candidate. match_pairs {
12881286 // Split a candidate in which the only match-pair is an or-pattern into multiple
12891287 // candidates. This is so that
12901288 //
@@ -1294,9 +1292,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12941292 // }
12951293 //
12961294 // only generates a single switch.
1297- candidate. subcandidates = self . create_or_subcandidates ( pats, candidate. has_guard ) ;
1298- let first_match_pair = candidate. match_pairs . pop ( ) . unwrap ( ) ;
1299- candidate. or_span = Some ( first_match_pair. pattern . span ) ;
1295+ let match_pair = candidate. match_pairs . pop ( ) . unwrap ( ) ;
1296+ self . create_or_subcandidates ( candidate, & match_pair) ;
13001297 split_or_candidate = true ;
13011298 }
13021299 }
@@ -1486,12 +1483,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14861483
14871484 let match_pairs = mem:: take ( & mut first_candidate. match_pairs ) ;
14881485 let ( first_match_pair, remaining_match_pairs) = match_pairs. split_first ( ) . unwrap ( ) ;
1489- let TestCase :: Or { ref pats } = & first_match_pair. test_case else { unreachable ! ( ) } ;
14901486
14911487 let remainder_start = self . cfg . start_new_block ( ) ;
1492- let or_span = first_match_pair. pattern . span ;
14931488 // Test the alternatives of this or-pattern.
1494- self . test_or_pattern ( first_candidate, start_block, remainder_start, pats , or_span ) ;
1489+ self . test_or_pattern ( first_candidate, start_block, remainder_start, first_match_pair ) ;
14951490
14961491 if !remaining_match_pairs. is_empty ( ) {
14971492 // If more match pairs remain, test them after each subcandidate.
@@ -1526,39 +1521,48 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15261521 ) ;
15271522 }
15281523
1529- #[ instrument(
1530- skip( self , start_block, otherwise_block, or_span, candidate, pats) ,
1531- level = "debug"
1532- ) ]
1524+ #[ instrument( skip( self , start_block, otherwise_block, candidate, match_pair) , level = "debug" ) ]
15331525 fn test_or_pattern < ' pat > (
15341526 & mut self ,
15351527 candidate : & mut Candidate < ' pat , ' tcx > ,
15361528 start_block : BasicBlock ,
15371529 otherwise_block : BasicBlock ,
1538- pats : & [ FlatPat < ' pat , ' tcx > ] ,
1539- or_span : Span ,
1530+ match_pair : & MatchPair < ' pat , ' tcx > ,
15401531 ) {
1541- debug ! ( "candidate={:#?}\n pats={:#?}" , candidate, pats) ;
1542- let mut or_candidates: Vec < _ > = pats
1543- . iter ( )
1544- . cloned ( )
1545- . map ( |flat_pat| Candidate :: from_flat_pat ( flat_pat, candidate. has_guard ) )
1546- . collect ( ) ;
1547- let mut or_candidate_refs: Vec < _ > = or_candidates. iter_mut ( ) . collect ( ) ;
1532+ self . create_or_subcandidates ( candidate, match_pair) ;
1533+ let mut or_candidate_refs: Vec < _ > = candidate. subcandidates . iter_mut ( ) . collect ( ) ;
1534+ let or_span = match_pair. pattern . span ;
15481535 self . match_candidates (
15491536 or_span,
15501537 or_span,
15511538 start_block,
15521539 otherwise_block,
15531540 & mut or_candidate_refs,
15541541 ) ;
1555- candidate. subcandidates = or_candidates;
1556- candidate. or_span = Some ( or_span) ;
15571542 self . merge_trivial_subcandidates ( candidate) ;
15581543 }
15591544
1560- /// Try to merge all of the subcandidates of the given candidate into one.
1561- /// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`.
1545+ /// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
1546+ /// subcandidate. Any candidate that has been expanded that way should be passed to
1547+ /// `merge_trivial_subcandidates` after its subcandidates have been processed.
1548+ fn create_or_subcandidates < ' pat > (
1549+ & mut self ,
1550+ candidate : & mut Candidate < ' pat , ' tcx > ,
1551+ match_pair : & MatchPair < ' pat , ' tcx > ,
1552+ ) {
1553+ let TestCase :: Or { ref pats } = & match_pair. test_case else { bug ! ( ) } ;
1554+ debug ! ( "expanding or-pattern: candidate={:#?}\n pats={:#?}" , candidate, pats) ;
1555+ candidate. or_span = Some ( match_pair. pattern . span ) ;
1556+ candidate. subcandidates = pats
1557+ . iter ( )
1558+ . cloned ( )
1559+ . map ( |flat_pat| Candidate :: from_flat_pat ( flat_pat, candidate. has_guard ) )
1560+ . collect ( ) ;
1561+ }
1562+
1563+ /// Try to merge all of the subcandidates of the given candidate into one. This avoids
1564+ /// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The or-pattern should have
1565+ /// been expanded with `create_or_subcandidates`.
15621566 fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
15631567 if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
15641568 // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
0 commit comments