@@ -1426,46 +1426,56 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1426
1426
fake_borrows : & mut Option < FxIndexSet < Place < ' tcx > > > ,
1427
1427
) {
1428
1428
let ( first_candidate, remaining_candidates) = candidates. split_first_mut ( ) . unwrap ( ) ;
1429
-
1430
- // All of the or-patterns have been sorted to the end, so if the first
1431
- // pattern is an or-pattern we only have or-patterns.
1432
- match first_candidate. match_pairs [ 0 ] . pattern . kind {
1433
- PatKind :: Or { .. } => ( ) ,
1434
- _ => {
1435
- self . test_candidates (
1436
- span,
1437
- scrutinee_span,
1438
- candidates,
1439
- block,
1440
- otherwise_block,
1441
- fake_borrows,
1442
- ) ;
1443
- return ;
1444
- }
1429
+ if !matches ! ( first_candidate. match_pairs[ 0 ] . pattern. kind, PatKind :: Or { .. } ) {
1430
+ self . test_candidates (
1431
+ span,
1432
+ scrutinee_span,
1433
+ candidates,
1434
+ block,
1435
+ otherwise_block,
1436
+ fake_borrows,
1437
+ ) ;
1438
+ return ;
1445
1439
}
1446
1440
1447
1441
let match_pairs = mem:: take ( & mut first_candidate. match_pairs ) ;
1448
- first_candidate. pre_binding_block = Some ( block) ;
1442
+ let ( first_match_pair, remaining_match_pairs) = match_pairs. split_first ( ) . unwrap ( ) ;
1443
+ let PatKind :: Or { ref pats } = & first_match_pair. pattern . kind else { unreachable ! ( ) } ;
1449
1444
1445
+ first_candidate. pre_binding_block = Some ( block) ;
1450
1446
let remainder_start = self . cfg . start_new_block ( ) ;
1451
- for match_pair in match_pairs {
1452
- let PatKind :: Or { ref pats } = & match_pair. pattern . kind else {
1453
- bug ! ( "Or-patterns should have been sorted to the end" ) ;
1454
- } ;
1455
- let or_span = match_pair. pattern . span ;
1447
+ let or_span = first_match_pair. pattern . span ;
1448
+ // Test the alternatives of this or-pattern.
1449
+ self . test_or_pattern (
1450
+ first_candidate,
1451
+ remainder_start,
1452
+ pats,
1453
+ or_span,
1454
+ & first_match_pair. place ,
1455
+ fake_borrows,
1456
+ ) ;
1456
1457
1458
+ if !remaining_match_pairs. is_empty ( ) {
1459
+ // If more match pairs remain, test them after each subcandidate.
1460
+ // We could add them to the or-candidates before the call to `test_or_pattern` but this
1461
+ // would make it impossible to detect simplifiable or-patterns. That would guarantee
1462
+ // exponentially large CFGs for cases like `(1 | 2, 3 | 4, ...)`.
1457
1463
first_candidate. visit_leaves ( |leaf_candidate| {
1458
- self . test_or_pattern (
1459
- leaf_candidate,
1464
+ assert ! ( leaf_candidate. match_pairs. is_empty( ) ) ;
1465
+ leaf_candidate. match_pairs . extend ( remaining_match_pairs. iter ( ) . cloned ( ) ) ;
1466
+ let block = leaf_candidate. pre_binding_block . unwrap ( ) ;
1467
+ self . test_candidates_with_or (
1468
+ span,
1469
+ scrutinee_span,
1470
+ & mut [ leaf_candidate] ,
1471
+ block,
1460
1472
remainder_start,
1461
- pats,
1462
- or_span,
1463
- & match_pair. place ,
1464
1473
fake_borrows,
1465
1474
) ;
1466
1475
} ) ;
1467
1476
}
1468
1477
1478
+ // Test the remaining candidates.
1469
1479
self . match_candidates (
1470
1480
span,
1471
1481
scrutinee_span,
0 commit comments