Factor out the "process remaining candidates" cases · rust-lang/rust@fc40247
@@ -1457,7 +1457,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14571457&mut self,
14581458span: Span,
14591459scrutinee_span: Span,
1460-mut start_block: BasicBlock,
1460+start_block: BasicBlock,
14611461otherwise_block: BasicBlock,
14621462candidates: &mut [&mut Candidate<'_, 'tcx>],
14631463) {
@@ -1467,41 +1467,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14671467}
14681468}
146914691470-match candidates {
1470+// Process a prefix of the candidates.
1471+let rest = match candidates {
14711472[] => {
1472-// If there are no candidates that still need testing, we're done. Since all matches are
1473-// exhaustive, execution should never reach this point.
1473+// If there are no candidates that still need testing, we're done.
14741474let source_info = self.source_info(span);
14751475self.cfg.goto(start_block, source_info, otherwise_block);
1476+return;
14761477}
14771478[first, remaining @ ..] if first.match_pairs.is_empty() => {
14781479// The first candidate has satisfied all its match pairs; we link it up and continue
14791480// with the remaining candidates.
1480-start_block = self.select_matched_candidate(first, start_block);
1481-self.match_candidates(span, scrutinee_span, start_block, otherwise_block, remaining)
1481+let remainder_start = self.select_matched_candidate(first, start_block);
1482+remainder_start.and(remaining)
14821483}
14831484 candidates if candidates.iter().any(|candidate| candidate.starts_with_or_pattern()) => {
14841485// If any candidate starts with an or-pattern, we have to expand the or-pattern before we
14851486// can proceed further.
1486-self.expand_and_match_or_candidates(
1487- span,
1488- scrutinee_span,
1489- start_block,
1490- otherwise_block,
1491- candidates,
1492-)
1487+self.expand_and_match_or_candidates(span, scrutinee_span, start_block, candidates)
14931488}
14941489 candidates => {
14951490// The first candidate has some unsatisfied match pairs; we proceed to do more tests.
1496-self.test_candidates(
1497- span,
1498- scrutinee_span,
1499- candidates,
1500- start_block,
1501- otherwise_block,
1502-);
1491+self.test_candidates(span, scrutinee_span, candidates, start_block)
15031492}
1504-}
1493+};
1494+1495+// Process any candidates that remain.
1496+let BlockAnd(start_block, remaining_candidates) = rest;
1497+self.match_candidates(
1498+ span,
1499+ scrutinee_span,
1500+ start_block,
1501+ otherwise_block,
1502+ remaining_candidates,
1503+);
15051504}
1506150515071506/// Link up matched candidates.
@@ -1547,16 +1546,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15471546}
1548154715491548/// Takes a list of candidates such that some of the candidates' first match pairs are
1550- /// or-patterns, expands as many or-patterns as possible, and processes the resulting
1551- /// candidates.
1552- fn expand_and_match_or_candidates(
1549+ /// or-patterns. This expands as many or-patterns as possible and processes the resulting
1550+ /// candidates. Returns the unprocessed candidates if any.
1551+ fn expand_and_match_or_candidates<'pat, 'b, 'c>(
15531552&mut self,
15541553span: Span,
15551554scrutinee_span: Span,
15561555start_block: BasicBlock,
1557-otherwise_block: BasicBlock,
1558-candidates: &mut [&mut Candidate<'_, 'tcx>],
1559-) {
1556+candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
1557+) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> {
15601558// We can't expand or-patterns freely. The rule is: if the candidate has an
15611559// or-pattern as its only remaining match pair, we can expand it freely. If it has
15621560// other match pairs, we can expand it but we can't process more candidates after
@@ -1625,14 +1623,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
16251623}
16261624}
162716251628-// Process the remaining candidates.
1629-self.match_candidates(
1630- span,
1631- scrutinee_span,
1632- remainder_start,
1633- otherwise_block,
1634- remaining_candidates,
1635-);
1626+ remainder_start.and(remaining_candidates)
16361627}
1637162816381629/// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
@@ -2003,14 +1994,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20031994 /// }
20041995 /// # }
20051996 /// ```
1997+ ///
1998+ /// We return the unprocessed candidates.
20061999 fn test_candidates<'pat, 'b, 'c>(
20072000&mut self,
20082001span: Span,
20092002scrutinee_span: Span,
20102003candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
20112004start_block: BasicBlock,
2012-otherwise_block: BasicBlock,
2013-) {
2005+) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> {
20142006// Extract the match-pair from the highest priority candidate and build a test from it.
20152007let (match_place, test) = self.pick_test(candidates);
20162008@@ -2050,13 +2042,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20502042 target_blocks,
20512043);
205220442053-self.match_candidates(
2054- span,
2055- scrutinee_span,
2056- remainder_start,
2057- otherwise_block,
2058- remaining_candidates,
2059-);
2045+ remainder_start.and(remaining_candidates)
20602046}
20612047}
20622048