@@ -1006,6 +1006,10 @@ struct Candidate<'pat, 'tcx> {
1006
1006
/// If the candidate matches, bindings and ascriptions must be established.
1007
1007
extra_data : PatternExtraData < ' tcx > ,
1008
1008
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
+
1009
1013
/// The block before the `bindings` have been established.
1010
1014
pre_binding_block : Option < BasicBlock > ,
1011
1015
/// The pre-binding block of the next candidate.
@@ -1028,6 +1032,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
1028
1032
extra_data : flat_pat. extra_data ,
1029
1033
has_guard,
1030
1034
subcandidates : Vec :: new ( ) ,
1035
+ or_span : None ,
1031
1036
otherwise_block : None ,
1032
1037
pre_binding_block : None ,
1033
1038
next_candidate_pre_binding_block : None ,
@@ -1277,7 +1282,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1277
1282
//
1278
1283
// only generates a single switch.
1279
1284
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 ) ;
1281
1287
split_or_candidate = true ;
1282
1288
}
1283
1289
}
@@ -1531,16 +1537,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1531
1537
& mut or_candidate_refs,
1532
1538
) ;
1533
1539
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) ;
1535
1542
}
1536
1543
1537
1544
/// Try to merge all of the subcandidates of the given candidate into one.
1538
1545
/// 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 > ) {
1544
1547
if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
1545
1548
// FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
1546
1549
return ;
@@ -1550,7 +1553,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1550
1553
1551
1554
// Not `Iterator::all` because we don't want to short-circuit.
1552
1555
for subcandidate in & mut candidate. subcandidates {
1553
- self . merge_trivial_subcandidates ( subcandidate, source_info ) ;
1556
+ self . merge_trivial_subcandidates ( subcandidate) ;
1554
1557
1555
1558
// FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
1556
1559
can_merge &=
@@ -1559,6 +1562,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1559
1562
1560
1563
if can_merge {
1561
1564
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) ;
1562
1567
for subcandidate in mem:: take ( & mut candidate. subcandidates ) {
1563
1568
let or_block = subcandidate. pre_binding_block . unwrap ( ) ;
1564
1569
self . cfg . goto ( or_block, source_info, any_matches) ;
0 commit comments