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,
candidates: &'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
// or-pattern as its only remaining match pair, we can expand it freely. If it has
// other match pairs, we can expand it but we can't process more candidates after
// it.
// We can't expand or-patterns freely. The rule is:
// - If a candidate doesn't start with an or-pattern, we include it in
// the expansion list as-is (i.e. it "expands" to itself).
// - 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
// 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.
let mut expand_until = 0;
for (i, candidate) in candidates.iter().enumerate() {
expand_until = i + 1;
if candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern() {
// The candidate has an or-pattern as well as more match pairs: we must
// split the candidates list here.
break;
}
}
let expand_until = candidates
.iter()
.position(|candidate| {
// If a candidate starts with an or-pattern and has more match pairs,
// we can expand it, but we must stop expanding _after_ it.
candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern()
})
.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);
// 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);
}
} 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);
}
}