Factor out the "process remaining candidates" cases
This commit is contained in:
parent
8a222ffd6b
commit
fc40247c6b
@ -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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user