@@ -993,6 +993,10 @@ struct Candidate<'pat, 'tcx> {
993993 /// If the candidate matches, bindings and ascriptions must be established.
994994 extra_data : PatternExtraData < ' tcx > ,
995995
996+ /// If we filled `self.subcandidate`, we store here the span of the or-pattern they came from.
997+ // Invariant: it is `None` iff `subcandidates.is_empty()`.
998+ or_span : Option < Span > ,
999+
9961000 /// The block before the `bindings` have been established.
9971001 pre_binding_block : Option < BasicBlock > ,
9981002 /// The pre-binding block of the next candidate.
@@ -1015,6 +1019,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
10151019 extra_data : flat_pat. extra_data ,
10161020 has_guard,
10171021 subcandidates : Vec :: new ( ) ,
1022+ or_span : None ,
10181023 otherwise_block : None ,
10191024 pre_binding_block : None ,
10201025 next_candidate_pre_binding_block : None ,
@@ -1248,7 +1253,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12481253 //
12491254 // only generates a single switch.
12501255 candidate. subcandidates = self . create_or_subcandidates ( pats, candidate. has_guard ) ;
1251- candidate. match_pairs . pop ( ) ;
1256+ let first_match_pair = candidate. match_pairs . pop ( ) . unwrap ( ) ;
1257+ candidate. or_span = Some ( first_match_pair. pattern . span ) ;
12521258 split_or_candidate = true ;
12531259 }
12541260 }
@@ -1502,16 +1508,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15021508 & mut or_candidate_refs,
15031509 ) ;
15041510 candidate. subcandidates = or_candidates;
1505- self . merge_trivial_subcandidates ( candidate, self . source_info ( or_span) ) ;
1511+ candidate. or_span = Some ( or_span) ;
1512+ self . merge_trivial_subcandidates ( candidate) ;
15061513 }
15071514
15081515 /// Try to merge all of the subcandidates of the given candidate into one.
15091516 /// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`.
1510- fn merge_trivial_subcandidates (
1511- & mut self ,
1512- candidate : & mut Candidate < ' _ , ' tcx > ,
1513- source_info : SourceInfo ,
1514- ) {
1517+ fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
15151518 if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
15161519 // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
15171520 return ;
@@ -1521,7 +1524,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15211524
15221525 // Not `Iterator::all` because we don't want to short-circuit.
15231526 for subcandidate in & mut candidate. subcandidates {
1524- self . merge_trivial_subcandidates ( subcandidate, source_info ) ;
1527+ self . merge_trivial_subcandidates ( subcandidate) ;
15251528
15261529 // FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
15271530 can_merge &=
@@ -1530,10 +1533,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15301533
15311534 if can_merge {
15321535 let any_matches = self . cfg . start_new_block ( ) ;
1536+ let source_info = self . source_info ( candidate. or_span . unwrap ( ) ) ;
15331537 for subcandidate in mem:: take ( & mut candidate. subcandidates ) {
15341538 let or_block = subcandidate. pre_binding_block . unwrap ( ) ;
15351539 self . cfg . goto ( or_block, source_info, any_matches) ;
15361540 }
1541+ candidate. or_span = None ;
15371542 candidate. pre_binding_block = Some ( any_matches) ;
15381543 }
15391544 }
0 commit comments