@@ -1003,6 +1003,10 @@ struct Candidate<'pat, 'tcx> {
10031003 /// ...and the guard must be evaluated; if it's `false` then branch to `otherwise_block`.
10041004 otherwise_block : Option < BasicBlock > ,
10051005
1006+ /// If we filled `self.subcandidate`, we store here the span or the or-pattern they came from.
1007+ // Invariant: it is `None` iff `subcandidates.is_empty()`.
1008+ or_span : Option < Span > ,
1009+
10061010 /// The block before the `bindings` have been established.
10071011 pre_binding_block : Option < BasicBlock > ,
10081012 /// The pre-binding block of the next candidate.
@@ -1027,6 +1031,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
10271031 ascriptions : flat_pat. ascriptions ,
10281032 has_guard,
10291033 subcandidates : Vec :: new ( ) ,
1034+ or_span : None ,
10301035 otherwise_block : None ,
10311036 pre_binding_block : None ,
10321037 next_candidate_pre_binding_block : None ,
@@ -1260,7 +1265,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12601265 //
12611266 // only generates a single switch.
12621267 candidate. subcandidates = self . create_or_subcandidates ( pats, candidate. has_guard ) ;
1263- candidate. match_pairs . pop ( ) ;
1268+ let first_match_pair = candidate. match_pairs . pop ( ) . unwrap ( ) ;
1269+ candidate. or_span = Some ( first_match_pair. pattern . span ) ;
12641270 split_or_candidate = true ;
12651271 }
12661272 }
@@ -1514,16 +1520,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15141520 & mut or_candidate_refs,
15151521 ) ;
15161522 candidate. subcandidates = or_candidates;
1517- self . merge_trivial_subcandidates ( candidate, self . source_info ( or_span) ) ;
1523+ candidate. or_span = Some ( or_span) ;
1524+ self . merge_trivial_subcandidates ( candidate) ;
15181525 }
15191526
15201527 /// Try to merge all of the subcandidates of the given candidate into one.
15211528 /// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`.
1522- fn merge_trivial_subcandidates (
1523- & mut self ,
1524- candidate : & mut Candidate < ' _ , ' tcx > ,
1525- source_info : SourceInfo ,
1526- ) {
1529+ fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
15271530 if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
15281531 // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
15291532 return ;
@@ -1533,7 +1536,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15331536
15341537 // Not `Iterator::all` because we don't want to short-circuit.
15351538 for subcandidate in & mut candidate. subcandidates {
1536- self . merge_trivial_subcandidates ( subcandidate, source_info ) ;
1539+ self . merge_trivial_subcandidates ( subcandidate) ;
15371540
15381541 // FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
15391542 can_merge &= subcandidate. subcandidates . is_empty ( )
@@ -1543,10 +1546,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15431546
15441547 if can_merge {
15451548 let any_matches = self . cfg . start_new_block ( ) ;
1549+ let source_info = self . source_info ( candidate. or_span . unwrap ( ) ) ;
15461550 for subcandidate in mem:: take ( & mut candidate. subcandidates ) {
15471551 let or_block = subcandidate. pre_binding_block . unwrap ( ) ;
15481552 self . cfg . goto ( or_block, source_info, any_matches) ;
15491553 }
1554+ candidate. or_span = None ;
15501555 candidate. pre_binding_block = Some ( any_matches) ;
15511556 }
15521557 }
0 commit comments