Factor out the "process remaining candidates" cases

This commit is contained in:
Nadrieril 2024-06-30 12:56:13 +02:00
parent 8a222ffd6b
commit fc40247c6b

View File

@ -1457,7 +1457,7 @@ fn match_candidates_with_enough_stack(
&mut self, &mut self,
span: Span, span: Span,
scrutinee_span: Span, scrutinee_span: Span,
mut start_block: BasicBlock, start_block: BasicBlock,
otherwise_block: BasicBlock, otherwise_block: BasicBlock,
candidates: &mut [&mut Candidate<'_, 'tcx>], candidates: &mut [&mut Candidate<'_, 'tcx>],
) { ) {
@ -1467,42 +1467,41 @@ fn match_candidates_with_enough_stack(
} }
} }
match candidates { // Process a prefix of the candidates.
let rest = match candidates {
[] => { [] => {
// If there are no candidates that still need testing, we're done. Since all matches are // If there are no candidates that still need testing, we're done.
// exhaustive, execution should never reach this point.
let source_info = self.source_info(span); let source_info = self.source_info(span);
self.cfg.goto(start_block, source_info, otherwise_block); self.cfg.goto(start_block, source_info, otherwise_block);
return;
} }
[first, remaining @ ..] if first.match_pairs.is_empty() => { [first, remaining @ ..] if first.match_pairs.is_empty() => {
// The first candidate has satisfied all its match pairs; we link it up and continue // The first candidate has satisfied all its match pairs; we link it up and continue
// with the remaining candidates. // with the remaining candidates.
start_block = self.select_matched_candidate(first, start_block); let remainder_start = self.select_matched_candidate(first, start_block);
self.match_candidates(span, scrutinee_span, start_block, otherwise_block, remaining) remainder_start.and(remaining)
} }
candidates if candidates.iter().any(|candidate| candidate.starts_with_or_pattern()) => { candidates if candidates.iter().any(|candidate| candidate.starts_with_or_pattern()) => {
// If any candidate starts with an or-pattern, we have to expand the or-pattern before we // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
// can proceed further. // can proceed further.
self.expand_and_match_or_candidates( self.expand_and_match_or_candidates(span, scrutinee_span, start_block, candidates)
span,
scrutinee_span,
start_block,
otherwise_block,
candidates,
)
} }
candidates => { candidates => {
// The first candidate has some unsatisfied match pairs; we proceed to do more tests. // The first candidate has some unsatisfied match pairs; we proceed to do more tests.
self.test_candidates( self.test_candidates(span, scrutinee_span, candidates, start_block)
}
};
// Process any candidates that remain.
let BlockAnd(start_block, remaining_candidates) = rest;
self.match_candidates(
span, span,
scrutinee_span, scrutinee_span,
candidates,
start_block, start_block,
otherwise_block, otherwise_block,
remaining_candidates,
); );
} }
}
}
/// Link up matched candidates. /// Link up matched candidates.
/// ///
@ -1547,16 +1546,15 @@ fn select_matched_candidate(
} }
/// Takes a list of candidates such that some of the candidates' first match pairs are /// Takes a list of candidates such that some of the candidates' first match pairs are
/// or-patterns, expands as many or-patterns as possible, and processes the resulting /// or-patterns. This expands as many or-patterns as possible and processes the resulting
/// candidates. /// candidates. Returns the unprocessed candidates if any.
fn expand_and_match_or_candidates( fn expand_and_match_or_candidates<'pat, 'b, 'c>(
&mut self, &mut self,
span: Span, span: Span,
scrutinee_span: Span, scrutinee_span: Span,
start_block: BasicBlock, start_block: BasicBlock,
otherwise_block: BasicBlock, candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
candidates: &mut [&mut Candidate<'_, '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: if the candidate has an
// or-pattern as its only remaining match pair, we can expand it freely. If it has // 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 // other match pairs, we can expand it but we can't process more candidates after
@ -1625,14 +1623,7 @@ fn expand_and_match_or_candidates(
} }
} }
// Process the remaining candidates. remainder_start.and(remaining_candidates)
self.match_candidates(
span,
scrutinee_span,
remainder_start,
otherwise_block,
remaining_candidates,
);
} }
/// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new /// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
@ -2003,14 +1994,15 @@ fn sort_candidates<'b, 'c, 'pat>(
/// } /// }
/// # } /// # }
/// ``` /// ```
///
/// We return the unprocessed candidates.
fn test_candidates<'pat, 'b, 'c>( fn test_candidates<'pat, 'b, 'c>(
&mut self, &mut self,
span: Span, span: Span,
scrutinee_span: Span, scrutinee_span: Span,
candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>], candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
start_block: BasicBlock, start_block: BasicBlock,
otherwise_block: BasicBlock, ) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> {
) {
// Extract the match-pair from the highest priority candidate and build a test from it. // Extract the match-pair from the highest priority candidate and build a test from it.
let (match_place, test) = self.pick_test(candidates); let (match_place, test) = self.pick_test(candidates);
@ -2050,13 +2042,7 @@ fn test_candidates<'pat, 'b, 'c>(
target_blocks, target_blocks,
); );
self.match_candidates( remainder_start.and(remaining_candidates)
span,
scrutinee_span,
remainder_start,
otherwise_block,
remaining_candidates,
);
} }
} }