@@ -1394,7 +1394,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1394
1394
& mut self ,
1395
1395
span : Span ,
1396
1396
scrutinee_span : Span ,
1397
- mut start_block : BasicBlock ,
1397
+ start_block : BasicBlock ,
1398
1398
otherwise_block : BasicBlock ,
1399
1399
candidates : & mut [ & mut Candidate < ' _ , ' tcx > ] ,
1400
1400
) {
@@ -1404,41 +1404,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1404
1404
}
1405
1405
}
1406
1406
1407
- match candidates {
1407
+ // Process a prefix of the candidates.
1408
+ let rest = match candidates {
1408
1409
[ ] => {
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.
1411
1411
let source_info = self . source_info ( span) ;
1412
1412
self . cfg . goto ( start_block, source_info, otherwise_block) ;
1413
+ return ;
1413
1414
}
1414
1415
[ first, remaining @ ..] if first. match_pairs . is_empty ( ) => {
1415
1416
// The first candidate has satisfied all its match pairs; we link it up and continue
1416
1417
// 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)
1419
1420
}
1420
1421
candidates if candidates. iter ( ) . any ( |candidate| candidate. starts_with_or_pattern ( ) ) => {
1421
1422
// If any candidate starts with an or-pattern, we have to expand the or-pattern before we
1422
1423
// 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)
1430
1425
}
1431
1426
candidates => {
1432
1427
// 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)
1440
1429
}
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
+ ) ;
1442
1441
}
1443
1442
1444
1443
/// Link up matched candidates.
@@ -1484,16 +1483,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1484
1483
}
1485
1484
1486
1485
/// 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 > (
1490
1489
& mut self ,
1491
1490
span : Span ,
1492
1491
scrutinee_span : Span ,
1493
1492
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 > ] > {
1497
1495
// We can't expand or-patterns freely. The rule is: if the candidate has an
1498
1496
// or-pattern as its only remaining match pair, we can expand it freely. If it has
1499
1497
// 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> {
1562
1560
}
1563
1561
}
1564
1562
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)
1573
1564
}
1574
1565
1575
1566
/// 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> {
1940
1931
/// }
1941
1932
/// # }
1942
1933
/// ```
1934
+ ///
1935
+ /// We return the unprocessed candidates.
1943
1936
fn test_candidates < ' pat , ' b , ' c > (
1944
1937
& mut self ,
1945
1938
span : Span ,
1946
1939
scrutinee_span : Span ,
1947
1940
candidates : & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] ,
1948
1941
start_block : BasicBlock ,
1949
- otherwise_block : BasicBlock ,
1950
- ) {
1942
+ ) -> BlockAnd < & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] > {
1951
1943
// Extract the match-pair from the highest priority candidate and build a test from it.
1952
1944
let ( match_place, test) = self . pick_test ( candidates) ;
1953
1945
@@ -1987,13 +1979,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1987
1979
target_blocks,
1988
1980
) ;
1989
1981
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)
1997
1983
}
1998
1984
}
1999
1985
0 commit comments