@@ -1394,7 +1394,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
13941394 & mut self ,
13951395 span : Span ,
13961396 scrutinee_span : Span ,
1397- mut start_block : BasicBlock ,
1397+ start_block : BasicBlock ,
13981398 otherwise_block : BasicBlock ,
13991399 candidates : & mut [ & mut Candidate < ' _ , ' tcx > ] ,
14001400 ) {
@@ -1404,41 +1404,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14041404 }
14051405 }
14061406
1407- match candidates {
1407+ // Process a prefix of the candidates.
1408+ let rest = match candidates {
14081409 [ ] => {
1409- // If there are no candidates that still need testing, we're done. Since all matches are
1410- // exhaustive, execution should never reach this point.
1410+ // If there are no candidates that still need testing, we're done.
14111411 let source_info = self . source_info ( span) ;
14121412 self . cfg . goto ( start_block, source_info, otherwise_block) ;
1413+ return ;
14131414 }
14141415 [ first, remaining @ ..] if first. match_pairs . is_empty ( ) => {
14151416 // The first candidate has satisfied all its match pairs; we link it up and continue
14161417 // with the remaining candidates.
1417- start_block = self . select_matched_candidate ( first, start_block) ;
1418- self . match_candidates ( span , scrutinee_span , start_block , otherwise_block , remaining)
1418+ let remainder_start = self . select_matched_candidate ( first, start_block) ;
1419+ remainder_start . and ( remaining)
14191420 }
14201421 candidates if candidates. iter ( ) . any ( |candidate| candidate. starts_with_or_pattern ( ) ) => {
14211422 // If any candidate starts with an or-pattern, we have to expand the or-pattern before we
14221423 // can proceed further.
1423- self . expand_and_match_or_candidates (
1424- span,
1425- scrutinee_span,
1426- start_block,
1427- otherwise_block,
1428- candidates,
1429- )
1424+ self . expand_and_match_or_candidates ( span, scrutinee_span, start_block, candidates)
14301425 }
14311426 candidates => {
14321427 // The first candidate has some unsatisfied match pairs; we proceed to do more tests.
1433- self . test_candidates (
1434- span,
1435- scrutinee_span,
1436- candidates,
1437- start_block,
1438- otherwise_block,
1439- ) ;
1428+ self . test_candidates ( span, scrutinee_span, candidates, start_block)
14401429 }
1441- }
1430+ } ;
1431+
1432+ // Process any candidates that remain.
1433+ let BlockAnd ( start_block, remaining_candidates) = rest;
1434+ self . match_candidates (
1435+ span,
1436+ scrutinee_span,
1437+ start_block,
1438+ otherwise_block,
1439+ remaining_candidates,
1440+ ) ;
14421441 }
14431442
14441443 /// Link up matched candidates.
@@ -1484,16 +1483,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14841483 }
14851484
14861485 /// Takes a list of candidates such that some of the candidates' first match pairs are
1487- /// or-patterns, expands as many or-patterns as possible, and processes the resulting
1488- /// candidates.
1489- fn expand_and_match_or_candidates (
1486+ /// or-patterns. This expands as many or-patterns as possible and processes the resulting
1487+ /// candidates. Returns the unprocessed candidates if any.
1488+ fn expand_and_match_or_candidates < ' pat , ' b , ' c > (
14901489 & mut self ,
14911490 span : Span ,
14921491 scrutinee_span : Span ,
14931492 start_block : BasicBlock ,
1494- otherwise_block : BasicBlock ,
1495- candidates : & mut [ & mut Candidate < ' _ , ' tcx > ] ,
1496- ) {
1493+ candidates : & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] ,
1494+ ) -> BlockAnd < & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] > {
14971495 // We can't expand or-patterns freely. The rule is: if the candidate has an
14981496 // or-pattern as its only remaining match pair, we can expand it freely. If it has
14991497 // other match pairs, we can expand it but we can't process more candidates after
@@ -1562,14 +1560,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15621560 }
15631561 }
15641562
1565- // Process the remaining candidates.
1566- self . match_candidates (
1567- span,
1568- scrutinee_span,
1569- remainder_start,
1570- otherwise_block,
1571- remaining_candidates,
1572- ) ;
1563+ remainder_start. and ( remaining_candidates)
15731564 }
15741565
15751566 /// Given a match-pair that corresponds to an or-pattern, expand each subpattern into a new
@@ -1940,14 +1931,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19401931 /// }
19411932 /// # }
19421933 /// ```
1934+ ///
1935+ /// We return the unprocessed candidates.
19431936 fn test_candidates < ' pat , ' b , ' c > (
19441937 & mut self ,
19451938 span : Span ,
19461939 scrutinee_span : Span ,
19471940 candidates : & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] ,
19481941 start_block : BasicBlock ,
1949- otherwise_block : BasicBlock ,
1950- ) {
1942+ ) -> BlockAnd < & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] > {
19511943 // Extract the match-pair from the highest priority candidate and build a test from it.
19521944 let ( match_place, test) = self . pick_test ( candidates) ;
19531945
@@ -1987,13 +1979,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19871979 target_blocks,
19881980 ) ;
19891981
1990- self . match_candidates (
1991- span,
1992- scrutinee_span,
1993- remainder_start,
1994- otherwise_block,
1995- remaining_candidates,
1996- ) ;
1982+ remainder_start. and ( remaining_candidates)
19971983 }
19981984}
19991985
0 commit comments