@@ -946,7 +946,7 @@ struct FlatPat<'pat, 'tcx> {
946946 /// To match the pattern, all of these must be satisfied...
947947 // Invariant: all the `MatchPair`s are recursively simplified.
948948 // 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 > > ,
950950
951951 /// ...these bindings established...
952952 bindings : Vec < Binding < ' tcx > > ,
@@ -974,6 +974,8 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
974974 && ascriptions. is_empty ( )
975975 && match_pairs. iter ( ) . all ( |mp| mp. is_simple ( ) ) ;
976976
977+ let match_pairs = match_pairs. into_iter ( ) . map ( |mp| ( mp. place . unwrap ( ) , mp) ) . collect ( ) ;
978+
977979 FlatPat { span : pattern. span , match_pairs, bindings, ascriptions, simple }
978980 }
979981}
@@ -989,7 +991,7 @@ struct Candidate<'pat, 'tcx> {
989991 /// All of these must be satisfied...
990992 // Invariant: all the `MatchPair`s are recursively simplified.
991993 // 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 > > ,
993995
994996 /// ...these bindings established...
995997 // Invariant: not mutated after candidate creation.
@@ -1283,8 +1285,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
12831285 ) {
12841286 let mut split_or_candidate = false ;
12851287 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
12881290 {
12891291 // Split a candidate in which the only match-pair is an or-pattern into multiple
12901292 // candidates. This is so that
@@ -1512,7 +1514,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15121514 return ;
15131515 }
15141516
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 ;
15161518 let or_span = first_match_pair. pattern . span ;
15171519 let TestCase :: Or { pats, simple } = first_match_pair. test_case else { unreachable ! ( ) } ;
15181520 debug ! ( "candidate={:#?}\n pats={:#?}" , first_candidate, pats) ;
@@ -1545,7 +1547,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15451547 let remaining_match_pairs = mem:: take ( & mut first_candidate. match_pairs ) ;
15461548 first_candidate. visit_leaves ( |leaf_candidate| {
15471549 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) ;
15491551 let or_start = leaf_candidate. pre_binding_block . unwrap ( ) ;
15501552 // In a case like `(P | Q, R | S)`, if `P` succeeds and `R | S` fails, we know `(Q,
15511553 // R | S)` will fail too. If there is no guard, we skip testing of `Q` by branching
0 commit comments