@@ -946,7 +946,7 @@ struct FlatPat<'pat, 'tcx> {
946
946
/// To match the pattern, all of these must be satisfied...
947
947
// Invariant: all the `MatchPair`s are recursively simplified.
948
948
// Invariant: or-patterns must be sorted to the end.
949
- match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
949
+ match_pairs : FxIndexMap < Place < ' tcx > , MatchPair < ' pat , ' tcx > > ,
950
950
951
951
/// ...these bindings established...
952
952
bindings : Vec < Binding < ' tcx > > ,
@@ -974,6 +974,8 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
974
974
&& ascriptions. is_empty ( )
975
975
&& match_pairs. iter ( ) . all ( |mp| mp. is_simple ( ) ) ;
976
976
977
+ let match_pairs = match_pairs. into_iter ( ) . map ( |mp| ( mp. place . unwrap ( ) , mp) ) . collect ( ) ;
978
+
977
979
FlatPat { span : pattern. span , match_pairs, bindings, ascriptions, simple }
978
980
}
979
981
}
@@ -989,7 +991,7 @@ struct Candidate<'pat, 'tcx> {
989
991
/// All of these must be satisfied...
990
992
// Invariant: all the `MatchPair`s are recursively simplified.
991
993
// Invariant: or-patterns must be sorted at the end.
992
- match_pairs : Vec < MatchPair < ' pat , ' tcx > > ,
994
+ match_pairs : FxIndexMap < Place < ' tcx > , MatchPair < ' pat , ' tcx > > ,
993
995
994
996
/// ...these bindings established...
995
997
// Invariant: not mutated after candidate creation.
@@ -1283,8 +1285,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1283
1285
) {
1284
1286
let mut split_or_candidate = false ;
1285
1287
for candidate in & mut * candidates {
1286
- if let [ MatchPair { test_case : TestCase :: Or { pats , .. } , .. } ] =
1287
- & * candidate. match_pairs
1288
+ if candidate . match_pairs . len ( ) == 1
1289
+ && let TestCase :: Or { pats , .. } = & candidate. match_pairs [ 0 ] . test_case
1288
1290
{
1289
1291
// Split a candidate in which the only match-pair is an or-pattern into multiple
1290
1292
// candidates. This is so that
@@ -1512,7 +1514,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1512
1514
return ;
1513
1515
}
1514
1516
1515
- let first_match_pair = first_candidate. match_pairs . remove ( 0 ) ;
1517
+ let first_match_pair = first_candidate. match_pairs . shift_remove_index ( 0 ) . unwrap ( ) . 1 ;
1516
1518
let or_span = first_match_pair. pattern . span ;
1517
1519
let TestCase :: Or { pats, simple } = first_match_pair. test_case else { unreachable ! ( ) } ;
1518
1520
debug ! ( "candidate={:#?}\n pats={:#?}" , first_candidate, pats) ;
@@ -1545,7 +1547,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1545
1547
let remaining_match_pairs = mem:: take ( & mut first_candidate. match_pairs ) ;
1546
1548
first_candidate. visit_leaves ( |leaf_candidate| {
1547
1549
assert ! ( leaf_candidate. match_pairs. is_empty( ) ) ;
1548
- leaf_candidate. match_pairs . extend ( remaining_match_pairs. iter ( ) . cloned ( ) ) ;
1550
+ leaf_candidate. match_pairs . clone_from ( & remaining_match_pairs) ;
1549
1551
let or_start = leaf_candidate. pre_binding_block . unwrap ( ) ;
1550
1552
// In a case like `(P | Q, R | S)`, if `P` succeeds and `R | S` fails, we know `(Q,
1551
1553
// R | S)` will fail too. If there is no guard, we skip testing of `Q` by branching
0 commit comments