Skip to content

Commit 6267474

Browse files
committed
Store match pairs indexed by their place
1 parent 8243436 commit 6267474

File tree

4 files changed

+22
-20
lines changed

4 files changed

+22
-20
lines changed

compiler/rustc_mir_build/src/build/matches/mod.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -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={:#?}\npats={:#?}", 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

compiler/rustc_mir_build/src/build/matches/simplify.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
113113
.cloned()
114114
.map(|flat_pat| {
115115
let mut candidate = Candidate::from_flat_pat(flat_pat, has_guard);
116-
if let [MatchPair { test_case: TestCase::Or { pats, .. }, .. }] =
117-
&*candidate.match_pairs
116+
if candidate.match_pairs.len() == 1
117+
&& let TestCase::Or { pats, .. } = &candidate.match_pairs[0].test_case
118118
{
119119
candidate.subcandidates = self.create_or_subcandidates(pats, has_guard);
120120
candidate.match_pairs.pop();

compiler/rustc_mir_build/src/build/matches/test.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -484,11 +484,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
484484
// than one, but it'd be very unusual to have two sides that
485485
// both require tests; you'd expect one side to be simplified
486486
// away.)
487-
let (match_pair_index, match_pair) = candidate
488-
.match_pairs
489-
.iter()
490-
.enumerate()
491-
.find(|&(_, mp)| mp.place == Some(test_place))?;
487+
let match_pair = candidate.match_pairs.get(&test_place)?;
492488

493489
let fully_matched;
494490
let ret = match (&test.kind, &match_pair.test_case) {
@@ -521,8 +517,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
521517
let is_conflicting_candidate = |candidate: &&mut Candidate<'_, 'tcx>| {
522518
candidate
523519
.match_pairs
524-
.iter()
525-
.any(|mp| mp.place == Some(test_place) && is_covering_range(&mp.test_case))
520+
.get(&test_place)
521+
.is_some_and(|mp| is_covering_range(&mp.test_case))
526522
};
527523
if sorted_candidates
528524
.get(&TestBranch::Failure)
@@ -674,10 +670,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
674670

675671
if fully_matched {
676672
// Replace the match pair by its sub-pairs.
677-
let match_pair = candidate.match_pairs.remove(match_pair_index);
678-
candidate.match_pairs.extend(match_pair.subpairs);
673+
let match_pair = candidate.match_pairs.shift_remove(&test_place).unwrap();
674+
candidate
675+
.match_pairs
676+
.extend(match_pair.subpairs.into_iter().map(|mp| (mp.place.unwrap(), mp)));
679677
// Move or-patterns to the end.
680-
candidate.match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. }));
678+
candidate
679+
.match_pairs
680+
.sort_by_cached_key(|_, pair| matches!(pair.test_case, TestCase::Or { .. }));
681681
}
682682

683683
ret

compiler/rustc_mir_build/src/build/matches/util.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
293293
for binding in &candidate.bindings {
294294
self.visit_binding(binding);
295295
}
296-
for match_pair in &candidate.match_pairs {
296+
for match_pair in candidate.match_pairs.values() {
297297
self.visit_match_pair(match_pair);
298298
}
299299
}
@@ -302,7 +302,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
302302
for binding in &flat_pat.bindings {
303303
self.visit_binding(binding);
304304
}
305-
for match_pair in &flat_pat.match_pairs {
305+
for match_pair in flat_pat.match_pairs.values() {
306306
self.visit_match_pair(match_pair);
307307
}
308308
}

0 commit comments

Comments
 (0)