@@ -1575,21 +1575,52 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1575
1575
}
1576
1576
1577
1577
let first_match_pair = first_candidate. match_pairs . remove ( 0 ) ;
1578
- let remaining_match_pairs = mem:: take ( & mut first_candidate. match_pairs ) ;
1579
1578
let remainder_start = self . cfg . start_new_block ( ) ;
1580
1579
// Test the alternatives of this or-pattern.
1581
- self . test_or_pattern ( first_candidate, start_block, remainder_start, first_match_pair) ;
1580
+ self . test_or_pattern (
1581
+ span,
1582
+ scrutinee_span,
1583
+ first_candidate,
1584
+ start_block,
1585
+ remainder_start,
1586
+ first_match_pair,
1587
+ ) ;
1588
+
1589
+ // Test the remaining candidates.
1590
+ self . match_candidates (
1591
+ span,
1592
+ scrutinee_span,
1593
+ remainder_start,
1594
+ otherwise_block,
1595
+ remaining_candidates,
1596
+ ) ;
1597
+ }
1598
+
1599
+ /// Simplify subcandidates and process any leftover match pairs. The candidate should have been
1600
+ /// expanded with `create_or_subcandidates`.
1601
+ fn finalize_or_candidate (
1602
+ & mut self ,
1603
+ span : Span ,
1604
+ scrutinee_span : Span ,
1605
+ candidate : & mut Candidate < ' _ , ' tcx > ,
1606
+ ) {
1607
+ if candidate. subcandidates . is_empty ( ) {
1608
+ return ;
1609
+ }
1610
+
1611
+ self . merge_trivial_subcandidates ( candidate) ;
1582
1612
1583
- if !remaining_match_pairs . is_empty ( ) {
1613
+ if !candidate . match_pairs . is_empty ( ) {
1584
1614
// If more match pairs remain, test them after each subcandidate.
1585
1615
// We could add them to the or-candidates before the call to `test_or_pattern` but this
1586
1616
// would make it impossible to detect simplifiable or-patterns. That would guarantee
1587
1617
// exponentially large CFGs for cases like `(1 | 2, 3 | 4, ...)`.
1588
1618
let mut last_otherwise = None ;
1589
- first_candidate . visit_leaves ( |leaf_candidate| {
1619
+ candidate . visit_leaves ( |leaf_candidate| {
1590
1620
last_otherwise = leaf_candidate. otherwise_block ;
1591
1621
} ) ;
1592
- first_candidate. visit_leaves ( |leaf_candidate| {
1622
+ let remaining_match_pairs = mem:: take ( & mut candidate. match_pairs ) ;
1623
+ candidate. visit_leaves ( |leaf_candidate| {
1593
1624
assert ! ( leaf_candidate. match_pairs. is_empty( ) ) ;
1594
1625
leaf_candidate. match_pairs . extend ( remaining_match_pairs. iter ( ) . cloned ( ) ) ;
1595
1626
let or_start = leaf_candidate. pre_binding_block . unwrap ( ) ;
@@ -1612,20 +1643,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1612
1643
) ;
1613
1644
} ) ;
1614
1645
}
1615
-
1616
- // Test the remaining candidates.
1617
- self . match_candidates (
1618
- span,
1619
- scrutinee_span,
1620
- remainder_start,
1621
- otherwise_block,
1622
- remaining_candidates,
1623
- ) ;
1624
1646
}
1625
1647
1626
1648
#[ instrument( skip( self , start_block, otherwise_block, candidate, match_pair) , level = "debug" ) ]
1627
1649
fn test_or_pattern < ' pat > (
1628
1650
& mut self ,
1651
+ span : Span ,
1652
+ scrutinee_span : Span ,
1629
1653
candidate : & mut Candidate < ' pat , ' tcx > ,
1630
1654
start_block : BasicBlock ,
1631
1655
otherwise_block : BasicBlock ,
@@ -1641,12 +1665,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1641
1665
otherwise_block,
1642
1666
& mut or_candidate_refs,
1643
1667
) ;
1644
- self . merge_trivial_subcandidates ( candidate) ;
1668
+ self . finalize_or_candidate ( span , scrutinee_span , candidate) ;
1645
1669
}
1646
1670
1647
1671
/// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
1648
1672
/// subcandidate. Any candidate that has been expanded that way should be passed to
1649
- /// `merge_trivial_subcandidates ` after its subcandidates have been processed.
1673
+ /// `finalize_or_candidate ` after its subcandidates have been processed.
1650
1674
fn create_or_subcandidates < ' pat > (
1651
1675
& mut self ,
1652
1676
candidate : & mut Candidate < ' pat , ' tcx > ,
@@ -1664,8 +1688,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1664
1688
}
1665
1689
1666
1690
/// Try to merge all of the subcandidates of the given candidate into one. This avoids
1667
- /// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The or-pattern should have
1668
- /// been expanded with `create_or_subcandidates`.
1691
+ /// exponentially large CFGs in cases like `(1 | 2, 3 | 4, ...)`. The candidate should have been
1692
+ /// expanded with `create_or_subcandidates`.
1669
1693
fn merge_trivial_subcandidates ( & mut self , candidate : & mut Candidate < ' _ , ' tcx > ) {
1670
1694
if candidate. subcandidates . is_empty ( ) || candidate. has_guard {
1671
1695
// FIXME(or_patterns; matthewjasper) Don't give up if we have a guard.
0 commit comments