Rollup merge of #127707 - Zalathar:expand-until, r=Nadrieril

match lowering: Use an iterator to find `expand_until`

A small cleanup that I noticed while looking at #127164.

This makes it easier to see that the split point is always the index after the found item, or the whole list if no stopping point was found.

r? `@Nadrieril`
This commit is contained in:
Matthias Krüger 2024-07-16 18:09:09 +02:00 committed by GitHub
commit 7409a5281d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1547,10 +1547,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
start_block: BasicBlock, start_block: BasicBlock,
candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>], candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> { ) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> {
// We can't expand or-patterns freely. The rule is: if the candidate has an // We can't expand or-patterns freely. The rule is:
// or-pattern as its only remaining match pair, we can expand it freely. If it has // - If a candidate doesn't start with an or-pattern, we include it in
// other match pairs, we can expand it but we can't process more candidates after // the expansion list as-is (i.e. it "expands" to itself).
// it. // - If a candidate has an or-pattern as its only remaining match pair,
// we can expand it.
// - If it starts with an or-pattern but also has other match pairs,
// we can expand it, but we can't process more candidates after it.
// //
// If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the // If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the
// following, or-pattern simplification (in `merge_trivial_subcandidates`) makes it // following, or-pattern simplification (in `merge_trivial_subcandidates`) makes it
@ -1567,17 +1570,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// } // }
// ``` // ```
// //
// We therefore split the `candidates` slice in two, expand or-patterns in the first half, // We therefore split the `candidates` slice in two, expand or-patterns in the first part,
// and process the rest separately. // and process the rest separately.
let mut expand_until = 0; let expand_until = candidates
for (i, candidate) in candidates.iter().enumerate() { .iter()
expand_until = i + 1; .position(|candidate| {
if candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern() { // If a candidate starts with an or-pattern and has more match pairs,
// The candidate has an or-pattern as well as more match pairs: we must // we can expand it, but we must stop expanding _after_ it.
// split the candidates list here. candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern()
break; })
} .map(|pos| pos + 1) // Stop _after_ the found candidate
} .unwrap_or(candidates.len()); // Otherwise, include all candidates
let (candidates_to_expand, remaining_candidates) = candidates.split_at_mut(expand_until); let (candidates_to_expand, remaining_candidates) = candidates.split_at_mut(expand_until);
// Expand one level of or-patterns for each candidate in `candidates_to_expand`. // Expand one level of or-patterns for each candidate in `candidates_to_expand`.
@ -1592,6 +1595,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
expanded_candidates.push(subcandidate); expanded_candidates.push(subcandidate);
} }
} else { } else {
// A candidate that doesn't start with an or-pattern has nothing to
// expand, so it is included in the post-expansion list as-is.
expanded_candidates.push(candidate); expanded_candidates.push(candidate);
} }
} }