@@ -1457,7 +1457,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1457
1457
& mut self ,
1458
1458
span : Span ,
1459
1459
scrutinee_span : Span ,
1460
- mut start_block : BasicBlock ,
1460
+ start_block : BasicBlock ,
1461
1461
otherwise_block : BasicBlock ,
1462
1462
candidates : & mut [ & mut Candidate < ' _ , ' tcx > ] ,
1463
1463
) {
@@ -1467,41 +1467,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1467
1467
}
1468
1468
}
1469
1469
1470
- match candidates {
1470
+ // Process a prefix of the candidates.
1471
+ let rest = match candidates {
1471
1472
[ ] => {
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.
1474
1474
let source_info = self . source_info ( span) ;
1475
1475
self . cfg . goto ( start_block, source_info, otherwise_block) ;
1476
+ return ;
1476
1477
}
1477
1478
[ first, remaining @ ..] if first. match_pairs . is_empty ( ) => {
1478
1479
// The first candidate has satisfied all its match pairs; we link it up and continue
1479
1480
// 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)
1482
1483
}
1483
1484
candidates if candidates. iter ( ) . any ( |candidate| candidate. starts_with_or_pattern ( ) ) => {
1484
1485
// If any candidate starts with an or-pattern, we have to expand the or-pattern before we
1485
1486
// 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)
1493
1488
}
1494
1489
candidates => {
1495
1490
// 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)
1503
1492
}
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
+ ) ;
1505
1504
}
1506
1505
1507
1506
/// Link up matched candidates.
@@ -1547,16 +1546,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1547
1546
}
1548
1547
1549
1548
/// 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 > (
1553
1552
& mut self ,
1554
1553
span : Span ,
1555
1554
scrutinee_span : Span ,
1556
1555
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 > ] > {
1560
1558
// We can't expand or-patterns freely. The rule is: if the candidate has an
1561
1559
// or-pattern as its only remaining match pair, we can expand it freely. If it has
1562
1560
// 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> {
1625
1623
}
1626
1624
}
1627
1625
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)
1636
1627
}
1637
1628
1638
1629
/// 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> {
2003
1994
/// }
2004
1995
/// # }
2005
1996
/// ```
1997
+ ///
1998
+ /// We return the unprocessed candidates.
2006
1999
fn test_candidates < ' pat , ' b , ' c > (
2007
2000
& mut self ,
2008
2001
span : Span ,
2009
2002
scrutinee_span : Span ,
2010
2003
candidates : & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] ,
2011
2004
start_block : BasicBlock ,
2012
- otherwise_block : BasicBlock ,
2013
- ) {
2005
+ ) -> BlockAnd < & ' b mut [ & ' c mut Candidate < ' pat , ' tcx > ] > {
2014
2006
// Extract the match-pair from the highest priority candidate and build a test from it.
2015
2007
let ( match_place, test) = self . pick_test ( candidates) ;
2016
2008
@@ -2050,13 +2042,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2050
2042
target_blocks,
2051
2043
) ;
2052
2044
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)
2060
2046
}
2061
2047
}
2062
2048
0 commit comments