@@ -1547,10 +1547,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1547
1547
start_block : BasicBlock ,
1548
1548
candidates : & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] ,
1549
1549
) -> BlockAnd < & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] > {
1550
- // We can't expand or-patterns freely. The rule is: if the candidate has an
1551
- // or-pattern as its only remaining match pair, we can expand it freely. If it has
1552
- // other match pairs, we can expand it but we can't process more candidates after
1553
- // it.
1550
+ // We can't expand or-patterns freely. The rule is:
1551
+ // - If a candidate doesn't start with an or-pattern, we include it in
1552
+ // the expansion list as-is (i.e. it "expands" to itself).
1553
+ // - If a candidate has an or-pattern as its only remaining match pair,
1554
+ // we can expand it.
1555
+ // - If it starts with an or-pattern but also has other match pairs,
1556
+ // we can expand it, but we can't process more candidates after it.
1554
1557
//
1555
1558
// If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the
1556
1559
// following, or-pattern simplification (in `merge_trivial_subcandidates`) makes it
@@ -1567,17 +1570,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1567
1570
// }
1568
1571
// ```
1569
1572
//
1570
- // We therefore split the `candidates` slice in two, expand or-patterns in the first half ,
1573
+ // We therefore split the `candidates` slice in two, expand or-patterns in the first part ,
1571
1574
// and process the rest separately.
1572
- let mut expand_until = 0 ;
1573
- for ( i , candidate ) in candidates . iter ( ) . enumerate ( ) {
1574
- expand_until = i + 1 ;
1575
- if candidate . match_pairs . len ( ) > 1 && candidate. starts_with_or_pattern ( ) {
1576
- // The candidate has an or-pattern as well as more match pairs: we must
1577
- // split the candidates list here.
1578
- break ;
1579
- }
1580
- }
1575
+ let expand_until = candidates
1576
+ . iter ( )
1577
+ . position ( |candidate| {
1578
+ // If a candidate starts with an or-pattern and has more match pairs,
1579
+ // we can expand it, but we must stop expanding _after_ it.
1580
+ candidate . match_pairs . len ( ) > 1 && candidate . starts_with_or_pattern ( )
1581
+ } )
1582
+ . map ( |pos| pos + 1 ) // Stop _after_ the found candidate
1583
+ . unwrap_or ( candidates . len ( ) ) ; // Otherwise, include all candidates
1581
1584
let ( candidates_to_expand, remaining_candidates) = candidates. split_at_mut ( expand_until) ;
1582
1585
1583
1586
// Expand one level of or-patterns for each candidate in `candidates_to_expand`.
@@ -1592,6 +1595,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1592
1595
expanded_candidates. push ( subcandidate) ;
1593
1596
}
1594
1597
} else {
1598
+ // A candidate that doesn't start with an or-pattern has nothing to
1599
+ // expand, so it is included in the post-expansion list as-is.
1595
1600
expanded_candidates. push ( candidate) ;
1596
1601
}
1597
1602
}
0 commit comments