@@ -1003,6 +1003,10 @@ struct Candidate<'pat, 'tcx> {
1003
1003
/// ...and the guard must be evaluated; if it's `false` then branch to `otherwise_block`.
1004
1004
otherwise_block : Option < BasicBlock > ,
1005
1005
1006
+ /// If we filled `self.subcandidate`, we store here the span or the or-pattern they came from.
1007
+ // Invariant: it is `None` iff `subcandidates.is_empty()`.
1008
+ or_span : Option < Span > ,
1009
+
1006
1010
/// The block before the `bindings` have been established.
1007
1011
pre_binding_block : Option < BasicBlock > ,
1008
1012
/// The pre-binding block of the next candidate.
@@ -1027,6 +1031,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
1027
1031
ascriptions : flat_pat. ascriptions ,
1028
1032
has_guard,
1029
1033
subcandidates : Vec :: new ( ) ,
1034
+ or_span : None ,
1030
1035
otherwise_block : None ,
1031
1036
pre_binding_block : None ,
1032
1037
next_candidate_pre_binding_block : None ,
@@ -1260,7 +1265,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1260
1265
//
1261
1266
// only generates a single switch.
1262
1267
candidate. subcandidates = self . create_or_subcandidates ( pats, candidate. has_guard ) ;
1263
- candidate. match_pairs . pop ( ) ;
1268
+ let first_match_pair = candidate. match_pairs . pop ( ) . unwrap ( ) ;
1269
+ candidate. or_span = Some ( first_match_pair. pattern . span ) ;
1264
1270
split_or_candidate = true ;
1265
1271
}
1266
1272
}
@@ -1514,16 +1520,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1514
1520
& mut or_candidate_refs,
1515
1521
) ;
1516
1522
candidate. subcandidates = or_candidates;
1517
- self . merge_trivial_subcandidates ( candidate, self . source_info ( or_span) ) ;
1523
+ candidate. or_span = Some ( or_span) ;
1524
+ self . merge_trivial_subcandidates ( candidate) ;
1518
1525
}
1519
1526
1520
1527
/// Try to merge all of the subcandidates of the given candidate into one.
1521
1528
/// This avoids exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`.
1522
- fn merge_trivial_subcandidates (
1523
- & mut self ,
1524
- candidate : & mut Candidate < ' _ , ' tcx > ,
1525
- source_info : SourceInfo ,
1526
- ) {
1529
+ fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
1527
1530
if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
1528
1531
// FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
1529
1532
return ;
@@ -1533,7 +1536,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1533
1536
1534
1537
// Not `Iterator::all` because we don't want to short-circuit.
1535
1538
for subcandidate in & mut candidate. subcandidates {
1536
- self . merge_trivial_subcandidates ( subcandidate, source_info ) ;
1539
+ self . merge_trivial_subcandidates ( subcandidate) ;
1537
1540
1538
1541
// FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
1539
1542
can_merge &= subcandidate. subcandidates . is_empty ( )
@@ -1543,10 +1546,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1543
1546
1544
1547
if can_merge {
1545
1548
let any_matches = self . cfg . start_new_block ( ) ;
1549
+ let source_info = self . source_info ( candidate. or_span . unwrap ( ) ) ;
1546
1550
for subcandidate in mem:: take ( & mut candidate. subcandidates ) {
1547
1551
let or_block = subcandidate. pre_binding_block . unwrap ( ) ;
1548
1552
self . cfg . goto ( or_block, source_info, any_matches) ;
1549
1553
}
1554
+ candidate. or_span = None ;
1550
1555
candidate. pre_binding_block = Some ( any_matches) ;
1551
1556
}
1552
1557
}
0 commit comments