Move or-pattern expansion inside the main part of the algorithm · rust-lang/rust@c5062f7 (original) (raw)
`@@ -1119,6 +1119,11 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
`
1119
1119
`}
`
1120
1120
`}
`
1121
1121
``
``
1122
`+
/// Returns whether the first match pair of this candidate is an or-pattern.
`
``
1123
`+
fn starts_with_or_pattern(&self) -> bool {
`
``
1124
`+
matches!(&*self.match_pairs, [MatchPair { test_case: TestCase::Or { .. }, .. }, ..])
`
``
1125
`+
}
`
``
1126
+
1122
1127
`/// Visit the leaf candidates (those with no subcandidates) contained in
`
1123
1128
`/// this candidate.
`
1124
1129
`fn visit_leaves<'a>(&'a mut self, mut visit_leaf: impl FnMut(&'a mut Self)) {
`
`@@ -1435,39 +1440,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
`
1435
1440
`otherwise_block: BasicBlock,
`
1436
1441
`candidates: &mut [&mut Candidate<'_, 'tcx>],
`
1437
1442
`) {
`
1438
``
`-
// If any candidate starts with an or-pattern, we have to expand the or-pattern before we
`
1439
``
`-
// can proceed further.
`
1440
``
`-
let expand_ors = candidates.iter().any(|candidate| {
`
1441
``
`-
matches!(
`
1442
``
`-
&*candidate.match_pairs,
`
1443
``
`-
[MatchPair { test_case: TestCase::Or { .. }, .. }, ..]
`
1444
``
`-
)
`
1445
``
`-
});
`
1446
1443
`ensure_sufficient_stack(|| {
`
1447
``
`-
if !expand_ors {
`
1448
``
`-
// No candidates start with an or-pattern, we can continue.
`
1449
``
`-
self.match_expanded_candidates(
`
1450
``
`-
span,
`
1451
``
`-
scrutinee_span,
`
1452
``
`-
start_block,
`
1453
``
`-
otherwise_block,
`
1454
``
`-
candidates,
`
1455
``
`-
);
`
1456
``
`-
} else {
`
1457
``
`-
self.expand_and_match_or_candidates(
`
1458
``
`-
span,
`
1459
``
`-
scrutinee_span,
`
1460
``
`-
start_block,
`
1461
``
`-
otherwise_block,
`
1462
``
`-
candidates,
`
1463
``
`-
);
`
1464
``
`-
}
`
``
1444
`+
self.match_candidates_with_enough_stack(
`
``
1445
`+
span,
`
``
1446
`+
scrutinee_span,
`
``
1447
`+
start_block,
`
``
1448
`+
otherwise_block,
`
``
1449
`+
candidates,
`
``
1450
`+
)
`
1465
1451
`});
`
1466
1452
`}
`
1467
1453
``
1468
``
`` -
/// Construct the decision tree for candidates. Caller must ensure that no candidate in
``
1469
``
`` -
/// candidates starts with an or-pattern.
``
1470
``
`-
fn match_expanded_candidates(
`
``
1454
`` +
/// Construct the decision tree for candidates. Don't call this, call match_candidates
``
``
1455
`+
/// instead to reserve sufficient stack space.
`
``
1456
`+
fn match_candidates_with_enough_stack(
`
1471
1457
`&mut self,
`
1472
1458
`span: Span,
`
1473
1459
`scrutinee_span: Span,
`
`@@ -1492,12 +1478,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
`
1492
1478
`// The first candidate has satisfied all its match pairs; we link it up and continue
`
1493
1479
`// with the remaining candidates.
`
1494
1480
` start_block = self.select_matched_candidate(first, start_block);
`
1495
``
`-
self.match_expanded_candidates(
`
``
1481
`+
self.match_candidates(span, scrutinee_span, start_block, otherwise_block, remaining)
`
``
1482
`+
}
`
``
1483
`+
candidates if candidates.iter().any(|candidate| candidate.starts_with_or_pattern()) => {
`
``
1484
`+
// If any candidate starts with an or-pattern, we have to expand the or-pattern before we
`
``
1485
`+
// can proceed further.
`
``
1486
`+
self.expand_and_match_or_candidates(
`
1496
1487
` span,
`
1497
1488
` scrutinee_span,
`
1498
1489
` start_block,
`
1499
1490
` otherwise_block,
`
1500
``
`-
remaining,
`
``
1491
`+
candidates,
`
1501
1492
`)
`
1502
1493
`}
`
1503
1494
` candidates => {
`
`@@ -1591,9 +1582,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
`
1591
1582
`let mut expand_until = 0;
`
1592
1583
`for (i, candidate) in candidates.iter().enumerate() {
`
1593
1584
` expand_until = i + 1;
`
1594
``
`-
if candidate.match_pairs.len() > 1
`
1595
``
`-
&& matches!(&candidate.match_pairs[0].test_case, TestCase::Or { .. })
`
1596
``
`-
{
`
``
1585
`+
if candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern() {
`
1597
1586
`// The candidate has an or-pattern as well as more match pairs: we must
`
1598
1587
`// split the candidates list here.
`
1599
1588
`break;
`
`@@ -1604,8 +1593,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
`
1604
1593
`` // Expand one level of or-patterns for each candidate in candidates_to_expand.
``
1605
1594
`let mut expanded_candidates = Vec::new();
`
1606
1595
`for candidate in candidates_to_expand.iter_mut() {
`
1607
``
`-
if let [MatchPair { test_case: TestCase::Or { .. }, .. }, ..] = &*candidate.match_pairs
`
1608
``
`-
{
`
``
1596
`+
if candidate.starts_with_or_pattern() {
`
1609
1597
`let or_match_pair = candidate.match_pairs.remove(0);
`
1610
1598
`// Expand the or-pattern into subcandidates.
`
1611
1599
`self.create_or_subcandidates(candidate, or_match_pair);
`