@@ -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 }
@@ -1287,8 +1293,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12871293 // At least one of the candidates has been split into subcandidates.
12881294 // We need to change the candidate list to include those.
12891295 let mut new_candidates = Vec :: new ( ) ;
1290-
1291- for candidate in candidates {
1296+ for candidate in candidates. iter_mut ( ) {
12921297 candidate. visit_leaves ( |leaf_candidate| new_candidates. push ( leaf_candidate) ) ;
12931298 }
12941299 self . match_simplified_candidates (
@@ -1298,6 +1303,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12981303 otherwise_block,
12991304 & mut * new_candidates,
13001305 ) ;
1306+
1307+ for candidate in candidates {
1308+ self . merge_trivial_subcandidates ( candidate) ;
1309+ }
13011310 } else {
13021311 self . match_simplified_candidates (
13031312 span,
@@ -1531,16 +1540,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15311540 & mut or_candidate_refs,
15321541 ) ;
15331542 candidate. subcandidates = or_candidates;
1534- self . merge_trivial_subcandidates ( candidate, self . source_info ( or_span) ) ;
1543+ candidate. or_span = Some ( or_span) ;
1544+ self . merge_trivial_subcandidates ( candidate) ;
15351545 }
15361546
15371547 /// Try to merge all of the subcandidates of the given candidate into one.
15381548 /// 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- ) {
1549+ fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
15441550 if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
15451551 // FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
15461552 return ;
@@ -1550,7 +1556,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15501556
15511557 // Not `Iterator::all` because we don't want to short-circuit.
15521558 for subcandidate in & mut candidate. subcandidates {
1553- self . merge_trivial_subcandidates ( subcandidate, source_info ) ;
1559+ self . merge_trivial_subcandidates ( subcandidate) ;
15541560
15551561 // FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
15561562 can_merge &=
@@ -1559,6 +1565,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15591565
15601566 if can_merge {
15611567 let any_matches = self . cfg . start_new_block ( ) ;
1568+ let or_span = candidate. or_span . take ( ) . unwrap ( ) ;
1569+ let source_info = self . source_info ( or_span) ;
15621570 for subcandidate in mem:: take ( & mut candidate. subcandidates ) {
15631571 let or_block = subcandidate. pre_binding_block . unwrap ( ) ;
15641572 self . cfg . goto ( or_block, source_info, any_matches) ;
0 commit comments