@@ -938,6 +938,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
938
938
}
939
939
}
940
940
941
+ /// A pattern in a form suitable for generating code.
942
+ #[ derive( Debug , Clone ) ]
943
+ struct FlatPat < ' pat , ' tcx > {
944
+ /// [`Span`] of the original pattern.
945
+ span : Span ,
946
+
947
+ /// To match the pattern, all of these must be satisfied...
948
+ // Invariant: all the `MatchPair`s are recursively simplified.
949
+ // Invariant: or-patterns must be sorted to the end.
950
+ match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
951
+
952
+ /// ...these bindings established...
953
+ bindings : Vec < Binding < ' tcx > > ,
954
+
955
+ /// ...and these types asserted.
956
+ ascriptions : Vec < Ascription < ' tcx > > ,
957
+ }
958
+
959
+ impl < ' tcx , ' pat > FlatPat < ' pat , ' tcx > {
960
+ fn new (
961
+ place : PlaceBuilder < ' tcx > ,
962
+ pattern : & ' pat Pat < ' tcx > ,
963
+ cx : & mut Builder < ' _ , ' tcx > ,
964
+ ) -> Self {
965
+ let mut match_pairs = vec ! [ MatchPair :: new( place, pattern, cx) ] ;
966
+ let mut bindings = Vec :: new ( ) ;
967
+ let mut ascriptions = Vec :: new ( ) ;
968
+
969
+ cx. simplify_match_pairs ( & mut match_pairs, & mut bindings, & mut ascriptions) ;
970
+
971
+ FlatPat { span : pattern. span , match_pairs, bindings, ascriptions }
972
+ }
973
+ }
974
+
941
975
#[ derive( Debug ) ]
942
976
struct Candidate < ' pat , ' tcx > {
943
977
/// [`Span`] of the original pattern that gave rise to this candidate.
@@ -952,11 +986,11 @@ struct Candidate<'pat, 'tcx> {
952
986
match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
953
987
954
988
/// ...these bindings established...
955
- // Invariant: not mutated outside `Candidate::new()` .
989
+ // Invariant: not mutated after candidate creation .
956
990
bindings : Vec < Binding < ' tcx > > ,
957
991
958
992
/// ...and these types asserted...
959
- // Invariant: not mutated outside `Candidate::new()` .
993
+ // Invariant: not mutated after candidate creation .
960
994
ascriptions : Vec < Ascription < ' tcx > > ,
961
995
962
996
/// ...and if this is non-empty, one of these subcandidates also has to match...
@@ -978,25 +1012,21 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
978
1012
has_guard : bool ,
979
1013
cx : & mut Builder < ' _ , ' tcx > ,
980
1014
) -> Self {
981
- let mut candidate = Candidate {
982
- span : pattern. span ,
1015
+ Self :: from_flat_pat ( FlatPat :: new ( place, pattern, cx) , has_guard)
1016
+ }
1017
+
1018
+ fn from_flat_pat ( flat_pat : FlatPat < ' pat , ' tcx > , has_guard : bool ) -> Self {
1019
+ Candidate {
1020
+ span : flat_pat. span ,
1021
+ match_pairs : flat_pat. match_pairs ,
1022
+ bindings : flat_pat. bindings ,
1023
+ ascriptions : flat_pat. ascriptions ,
983
1024
has_guard,
984
- match_pairs : vec ! [ MatchPair :: new( place, pattern, cx) ] ,
985
- bindings : Vec :: new ( ) ,
986
- ascriptions : Vec :: new ( ) ,
987
1025
subcandidates : Vec :: new ( ) ,
988
1026
otherwise_block : None ,
989
1027
pre_binding_block : None ,
990
1028
next_candidate_pre_binding_block : None ,
991
- } ;
992
-
993
- cx. simplify_match_pairs (
994
- & mut candidate. match_pairs ,
995
- & mut candidate. bindings ,
996
- & mut candidate. ascriptions ,
997
- ) ;
998
-
999
- candidate
1029
+ }
1000
1030
}
1001
1031
1002
1032
/// Visit the leaf candidates (those with no subcandidates) contained in
@@ -1059,7 +1089,7 @@ enum TestCase<'pat, 'tcx> {
1059
1089
Constant { value : mir:: Const < ' tcx > } ,
1060
1090
Range ( & ' pat PatRange < ' tcx > ) ,
1061
1091
Slice { len : usize , variable_length : bool } ,
1062
- Or ,
1092
+ Or { pats : Box < [ FlatPat < ' pat , ' tcx > ] > } ,
1063
1093
}
1064
1094
1065
1095
#[ derive( Debug , Clone ) ]
@@ -1217,7 +1247,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1217
1247
) {
1218
1248
let mut split_or_candidate = false ;
1219
1249
for candidate in & mut * candidates {
1220
- if let [ MatchPair { pattern : Pat { kind : PatKind :: Or { pats } , .. } , place , .. } ] =
1250
+ if let [ MatchPair { test_case : TestCase :: Or { pats, .. } , .. } ] =
1221
1251
& * candidate. match_pairs
1222
1252
{
1223
1253
// Split a candidate in which the only match-pair is an or-pattern into multiple
@@ -1229,8 +1259,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1229
1259
// }
1230
1260
//
1231
1261
// only generates a single switch.
1232
- candidate. subcandidates =
1233
- self . create_or_subcandidates ( place, pats, candidate. has_guard ) ;
1262
+ candidate. subcandidates = self . create_or_subcandidates ( pats, candidate. has_guard ) ;
1234
1263
candidate. match_pairs . pop ( ) ;
1235
1264
split_or_candidate = true ;
1236
1265
}
@@ -1449,7 +1478,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1449
1478
) {
1450
1479
let ( first_candidate, remaining_candidates) = candidates. split_first_mut ( ) . unwrap ( ) ;
1451
1480
assert ! ( first_candidate. subcandidates. is_empty( ) ) ;
1452
- if !matches ! ( first_candidate. match_pairs[ 0 ] . pattern . kind , PatKind :: Or { .. } ) {
1481
+ if !matches ! ( first_candidate. match_pairs[ 0 ] . test_case , TestCase :: Or { .. } ) {
1453
1482
self . test_candidates (
1454
1483
span,
1455
1484
scrutinee_span,
@@ -1463,7 +1492,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1463
1492
1464
1493
let match_pairs = mem:: take ( & mut first_candidate. match_pairs ) ;
1465
1494
let ( first_match_pair, remaining_match_pairs) = match_pairs. split_first ( ) . unwrap ( ) ;
1466
- let PatKind :: Or { ref pats } = & first_match_pair. pattern . kind else { unreachable ! ( ) } ;
1495
+ let TestCase :: Or { ref pats } = & first_match_pair. test_case else { unreachable ! ( ) } ;
1467
1496
1468
1497
let remainder_start = self . cfg . start_new_block ( ) ;
1469
1498
let or_span = first_match_pair. pattern . span ;
@@ -1474,7 +1503,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1474
1503
remainder_start,
1475
1504
pats,
1476
1505
or_span,
1477
- & first_match_pair. place ,
1478
1506
fake_borrows,
1479
1507
) ;
1480
1508
@@ -1514,23 +1542,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1514
1542
}
1515
1543
1516
1544
#[ instrument(
1517
- skip( self , start_block, otherwise_block, or_span, place , fake_borrows, candidate, pats) ,
1545
+ skip( self , start_block, otherwise_block, or_span, fake_borrows, candidate, pats) ,
1518
1546
level = "debug"
1519
1547
) ]
1520
1548
fn test_or_pattern < ' pat > (
1521
1549
& mut self ,
1522
1550
candidate : & mut Candidate < ' pat , ' tcx > ,
1523
1551
start_block : BasicBlock ,
1524
1552
otherwise_block : BasicBlock ,
1525
- pats : & ' pat [ Box < Pat < ' tcx > > ] ,
1553
+ pats : & [ FlatPat < ' pat , ' tcx > ] ,
1526
1554
or_span : Span ,
1527
- place : & PlaceBuilder < ' tcx > ,
1528
1555
fake_borrows : & mut Option < FxIndexSet < Place < ' tcx > > > ,
1529
1556
) {
1530
1557
debug ! ( "candidate={:#?}\n pats={:#?}" , candidate, pats) ;
1531
1558
let mut or_candidates: Vec < _ > = pats
1532
1559
. iter ( )
1533
- . map ( |pat| Candidate :: new ( place. clone ( ) , pat, candidate. has_guard , self ) )
1560
+ . cloned ( )
1561
+ . map ( |flat_pat| Candidate :: from_flat_pat ( flat_pat, candidate. has_guard ) )
1534
1562
. collect ( ) ;
1535
1563
let mut or_candidate_refs: Vec < _ > = or_candidates. iter_mut ( ) . collect ( ) ;
1536
1564
self . match_candidates (
0 commit comments