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);

`