@@ -1457,7 +1457,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14571457 & mut self ,
14581458 span : Span ,
14591459 scrutinee_span : Span ,
1460- mut start_block : BasicBlock ,
1460+ start_block : BasicBlock ,
14611461 otherwise_block : BasicBlock ,
14621462 candidates : & mut [ & mut Candidate < ' _ , ' tcx > ] ,
14631463 ) {
@@ -1467,41 +1467,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14671467 }
14681468 }
14691469
1470- 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.
14741474 let source_info = self . source_info ( span) ;
14751475 self . 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 }
15061505
15071506 /// Link up matched candidates.
@@ -1547,16 +1546,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15471546 }
15481547
15491548 /// 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 ,
15541553 span : Span ,
15551554 scrutinee_span : Span ,
15561555 start_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 }
16271625
1628- // 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 }
16371628
16381629 /// 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 ,
20082001 span : Span ,
20092002 scrutinee_span : Span ,
20102003 candidates : & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] ,
20112004 start_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.
20152007 let ( match_place, test) = self . pick_test ( candidates) ;
20162008
@@ -2050,13 +2042,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20502042 target_blocks,
20512043 ) ;
20522044
2053- 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
0 commit comments