@@ -1006,6 +1006,10 @@ struct Candidate<'pat, 'tcx> {
10061006 /// If the candidate matches, bindings and ascriptions must be established.
10071007 extra_data : PatternExtraData < ' tcx > ,
10081008
1009+ /// If we filled `self.subcandidate`, we store here the span of the or-pattern they came from.
1010+ // Invariant: it is `None` iff `subcandidates.is_empty()`.
1011+ or_span : Option < Span > ,
1012+
10091013 /// The block before the `bindings` have been established.
10101014 pre_binding_block : Option < BasicBlock > ,
10111015 /// The pre-binding block of the next candidate.
@@ -1028,6 +1032,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
10281032 extra_data : flat_pat. extra_data ,
10291033 has_guard,
10301034 subcandidates : Vec :: new ( ) ,
1035+ or_span : None ,
10311036 otherwise_block : None ,
10321037 pre_binding_block : None ,
10331038 next_candidate_pre_binding_block : None ,
@@ -1277,7 +1282,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12771282 //
12781283 // only generates a single switch.
12791284 candidate. subcandidates = self . create_or_subcandidates ( pats, candidate. has_guard ) ;
1280- candidate. match_pairs . pop ( ) ;
1285+ let first_match_pair = candidate. match_pairs . pop ( ) . unwrap ( ) ;
1286+ candidate. or_span = Some ( first_match_pair. pattern . span ) ;
12811287 split_or_candidate = true ;
12821288 }
12831289 }
@@ -1531,16 +1537,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15311537 & mut or_candidate_refs,
15321538 ) ;
15331539 candidate. subcandidates = or_candidates;
1534- self . merge_trivial_subcandidates ( candidate, self . source_info ( or_span) ) ;
1540+ candidate. or_span = Some ( or_span) ;
1541+ self . merge_trivial_subcandidates ( candidate) ;
15351542 }
15361543
15371544 /// Try to merge all of the subcandidates of the given candidate into one.
15381545 /// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`.
1539- fn merge_trivial_subcandidates (
1540- & mut self ,
1541- candidate : & mut Candidate < ' _ , ' tcx > ,
1542- source_info : SourceInfo ,
1543- ) {
1546+ fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
15441547 if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
15451548 // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
15461549 return ;
@@ -1550,7 +1553,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15501553
15511554 // Not `Iterator::all` because we don't want to short-circuit.
15521555 for subcandidate in & mut candidate. subcandidates {
1553- self . merge_trivial_subcandidates ( subcandidate, source_info ) ;
1556+ self . merge_trivial_subcandidates ( subcandidate) ;
15541557
15551558 // FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
15561559 can_merge &=
@@ -1559,6 +1562,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15591562
15601563 if can_merge {
15611564 let any_matches = self . cfg . start_new_block ( ) ;
1565+ let or_span = candidate. or_span . take ( ) . unwrap ( ) ;
1566+ let source_info = self . source_info ( or_span) ;
15621567 for subcandidate in mem:: take ( & mut candidate. subcandidates ) {
15631568 let or_block = subcandidate. pre_binding_block . unwrap ( ) ;
15641569 self . cfg . goto ( or_block, source_info, any_matches) ;
0 commit comments