Use an iterator to find expand_until

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.
This commit is contained in:
Zalathar 2024-07-07 23:29:18 +10:00
parent 00167abb41
commit e37b92ffd8

View File

@ -1536,10 +1536,13 @@ fn expand_and_match_or_candidates<'pat, 'b, 'c>(
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
@ -1556,17 +1559,17 @@ fn expand_and_match_or_candidates<'pat, 'b, 'c>(
// } // }
// ``` // ```
// //
// 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`.
@ -1581,6 +1584,8 @@ fn expand_and_match_or_candidates<'pat, 'b, 'c>(
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);
} }
} }