@@ -1536,10 +1536,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15361536 start_block : BasicBlock ,
15371537 candidates : & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] ,
15381538 ) -> BlockAnd < & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] > {
1539- // We can't expand or-patterns freely. The rule is: if the candidate has an
1540- // or-pattern as its only remaining match pair, we can expand it freely. If it has
1541- // other match pairs, we can expand it but we can't process more candidates after
1542- // it.
1539+ // We can't expand or-patterns freely. The rule is:
1540+ // - If a candidate doesn't start with an or-pattern, we include it in
1541+ // the expansion list as-is (i.e. it "expands" to itself).
1542+ // - If a candidate has an or-pattern as its only remaining match pair,
1543+ // we can expand it.
1544+ // - If it starts with an or-pattern but also has other match pairs,
1545+ // we can expand it, but we can't process more candidates after it.
15431546 //
15441547 // If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the
15451548 // following, or-pattern simplification (in `merge_trivial_subcandidates`) makes it
@@ -1556,17 +1559,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15561559 // }
15571560 // ```
15581561 //
1559- // We therefore split the `candidates` slice in two, expand or-patterns in the first half ,
1562+ // We therefore split the `candidates` slice in two, expand or-patterns in the first part ,
15601563 // and process the rest separately.
1561- let mut expand_until = 0 ;
1562- for ( i , candidate ) in candidates . iter ( ) . enumerate ( ) {
1563- expand_until = i + 1 ;
1564- if candidate . match_pairs . len ( ) > 1 && candidate. starts_with_or_pattern ( ) {
1565- // The candidate has an or-pattern as well as more match pairs: we must
1566- // split the candidates list here.
1567- break ;
1568- }
1569- }
1564+ let expand_until = candidates
1565+ . iter ( )
1566+ . position ( |candidate| {
1567+ // If a candidate starts with an or-pattern and has more match pairs,
1568+ // we can expand it, but we must stop expanding _after_ it.
1569+ candidate . match_pairs . len ( ) > 1 && candidate . starts_with_or_pattern ( )
1570+ } )
1571+ . map ( |pos| pos + 1 ) // Stop _after_ the found candidate
1572+ . unwrap_or ( candidates . len ( ) ) ; // Otherwise, include all candidates
15701573 let ( candidates_to_expand, remaining_candidates) = candidates. split_at_mut ( expand_until) ;
15711574
15721575 // Expand one level of or-patterns for each candidate in `candidates_to_expand`.
@@ -1581,6 +1584,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15811584 expanded_candidates. push ( subcandidate) ;
15821585 }
15831586 } else {
1587+ // A candidate that doesn't start with an or-pattern has nothing to
1588+ // expand, so it is included in the post-expansion list as-is.
15841589 expanded_candidates. push ( candidate) ;
15851590 }
15861591 }
0 commit comments