Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

match lowering: Use an iterator to find expand_until #127707

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1536,10 +1536,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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
Expand All @@ -1556,17 +1559,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.
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`.
Expand All @@ -1581,6 +1584,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
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);
}
}
Expand Down
Loading