@@ -1012,6 +1012,10 @@ struct Candidate<'pat, 'tcx> {
10121012 /// If the candidate matches, bindings and ascriptions must be established.
10131013 extra_data : PatternExtraData < ' tcx > ,
10141014
1015+ /// If we filled `self.subcandidate`, we store here the span of the or-pattern they came from.
1016+ // Invariant: it is `None` iff `subcandidates.is_empty()`.
1017+ or_span : Option < Span > ,
1018+
10151019 /// The block before the `bindings` have been established.
10161020 pre_binding_block : Option < BasicBlock > ,
10171021 /// The pre-binding block of the next candidate.
@@ -1034,6 +1038,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
10341038 extra_data : flat_pat. extra_data ,
10351039 has_guard,
10361040 subcandidates : Vec :: new ( ) ,
1041+ or_span : None ,
10371042 otherwise_block : None ,
10381043 pre_binding_block : None ,
10391044 next_candidate_pre_binding_block : None ,
@@ -1290,7 +1295,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12901295 //
12911296 // only generates a single switch.
12921297 candidate. subcandidates = self . create_or_subcandidates ( pats, candidate. has_guard ) ;
1293- candidate. match_pairs . pop ( ) ;
1298+ let first_match_pair = candidate. match_pairs . pop ( ) . unwrap ( ) ;
1299+ candidate. or_span = Some ( first_match_pair. pattern . span ) ;
12941300 split_or_candidate = true ;
12951301 }
12961302 }
@@ -1544,16 +1550,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15441550 & mut or_candidate_refs,
15451551 ) ;
15461552 candidate. subcandidates = or_candidates;
1547- self . merge_trivial_subcandidates ( candidate, self . source_info ( or_span) ) ;
1553+ candidate. or_span = Some ( or_span) ;
1554+ self . merge_trivial_subcandidates ( candidate) ;
15481555 }
15491556
15501557 /// Try to merge all of the subcandidates of the given candidate into one.
15511558 /// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`.
1552- fn merge_trivial_subcandidates (
1553- & mut self ,
1554- candidate : & mut Candidate < ' _ , ' tcx > ,
1555- source_info : SourceInfo ,
1556- ) {
1559+ fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
15571560 if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
15581561 // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
15591562 return ;
@@ -1563,7 +1566,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15631566
15641567 // Not `Iterator::all` because we don't want to short-circuit.
15651568 for subcandidate in & mut candidate. subcandidates {
1566- self . merge_trivial_subcandidates ( subcandidate, source_info ) ;
1569+ self . merge_trivial_subcandidates ( subcandidate) ;
15671570
15681571 // FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
15691572 can_merge &=
@@ -1572,10 +1575,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15721575
15731576 if can_merge {
15741577 let any_matches = self . cfg . start_new_block ( ) ;
1578+ let source_info = self . source_info ( candidate. or_span . unwrap ( ) ) ;
15751579 for subcandidate in mem:: take ( & mut candidate. subcandidates ) {
15761580 let or_block = subcandidate. pre_binding_block . unwrap ( ) ;
15771581 self . cfg . goto ( or_block, source_info, any_matches) ;
15781582 }
1583+ candidate. or_span = None ;
15791584 candidate. pre_binding_block = Some ( any_matches) ;
15801585 }
15811586 }
0 commit comments