Skip to content

Commit 7843e46

Browse files
committed
Factor out non-branch-related pattern data
1 parent 4282576 commit 7843e46

File tree

3 files changed

+61
-71
lines changed

3 files changed

+61
-71
lines changed

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

+53-58
Original file line numberDiff line numberDiff line change
@@ -506,13 +506,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
506506
traverse_candidate(
507507
candidate,
508508
&mut Vec::new(),
509-
&mut |leaf_candidate, parent_bindings| {
509+
&mut |leaf_candidate, parent_data| {
510510
if let Some(arm) = arm {
511511
self.clear_top_scope(arm.scope);
512512
}
513513
let binding_end = self.bind_and_guard_matched_candidate(
514514
leaf_candidate,
515-
parent_bindings,
515+
parent_data,
516516
fake_borrow_temps,
517517
scrutinee_span,
518518
arm_match_scope,
@@ -524,12 +524,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
524524
}
525525
self.cfg.goto(binding_end, outer_source_info, target_block);
526526
},
527-
|inner_candidate, parent_bindings| {
528-
parent_bindings.push((inner_candidate.bindings, inner_candidate.ascriptions));
527+
|inner_candidate, parent_data| {
528+
parent_data.push(inner_candidate.extra_data);
529529
inner_candidate.subcandidates.into_iter()
530530
},
531-
|parent_bindings| {
532-
parent_bindings.pop();
531+
|parent_data| {
532+
parent_data.pop();
533533
},
534534
);
535535

@@ -651,7 +651,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
651651
if set_match_place {
652652
let mut next = Some(&candidate);
653653
while let Some(candidate_ref) = next.take() {
654-
for binding in &candidate_ref.bindings {
654+
for binding in &candidate_ref.extra_data.bindings {
655655
let local = self.var_local_id(binding.var_id, OutsideGuard);
656656
// `try_to_place` may fail if it is unable to resolve the given
657657
// `PlaceBuilder` inside a closure. In this case, we don't want to include
@@ -924,22 +924,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
924924
}
925925
}
926926

927-
/// A pattern in a form suitable for generating code.
927+
/// Data extracted from a pattern that doesn't affect which branch is taken. Collected during
928+
/// pattern simplification and not mutated later.
928929
#[derive(Debug, Clone)]
929-
struct FlatPat<'pat, 'tcx> {
930+
struct PatternExtraData<'tcx> {
930931
/// [`Span`] of the original pattern.
931932
span: Span,
932933

934+
/// Bindings that must be established.
935+
bindings: Vec<Binding<'tcx>>,
936+
937+
/// Types that must be asserted.
938+
ascriptions: Vec<Ascription<'tcx>>,
939+
}
940+
941+
/// A pattern in a form suitable for generating code.
942+
#[derive(Debug, Clone)]
943+
struct FlatPat<'pat, 'tcx> {
933944
/// To match the pattern, all of these must be satisfied...
934945
// Invariant: all the `MatchPair`s are recursively simplified.
935946
// Invariant: or-patterns must be sorted to the end.
936947
match_pairs: Vec<MatchPair<'pat, 'tcx>>,
937948

938-
/// ...these bindings established...
939-
bindings: Vec<Binding<'tcx>>,
940-
941-
/// ...and these types asserted.
942-
ascriptions: Vec<Ascription<'tcx>>,
949+
extra_data: PatternExtraData<'tcx>,
943950
}
944951

945952
impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
@@ -948,43 +955,38 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
948955
pattern: &'pat Pat<'tcx>,
949956
cx: &mut Builder<'_, 'tcx>,
950957
) -> Self {
951-
let mut match_pairs = vec![MatchPair::new(place, pattern, cx)];
952-
let mut bindings = Vec::new();
953-
let mut ascriptions = Vec::new();
954-
955-
cx.simplify_match_pairs(&mut match_pairs, &mut bindings, &mut ascriptions);
956-
957-
FlatPat { span: pattern.span, match_pairs, bindings, ascriptions }
958+
let mut flat_pat = FlatPat {
959+
match_pairs: vec![MatchPair::new(place, pattern, cx)],
960+
extra_data: PatternExtraData {
961+
span: pattern.span,
962+
bindings: Vec::new(),
963+
ascriptions: Vec::new(),
964+
},
965+
};
966+
cx.simplify_match_pairs(&mut flat_pat.match_pairs, &mut flat_pat.extra_data);
967+
flat_pat
958968
}
959969
}
960970

961971
#[derive(Debug)]
962972
struct Candidate<'pat, 'tcx> {
963-
/// [`Span`] of the original pattern that gave rise to this candidate.
964-
span: Span,
965-
966-
/// Whether this `Candidate` has a guard.
967-
has_guard: bool,
968-
969-
/// All of these must be satisfied...
973+
/// For the candidate to match, &ll of these must be satisfied...
970974
// Invariant: all the `MatchPair`s are recursively simplified.
971975
// Invariant: or-patterns must be sorted at the end.
972976
match_pairs: Vec<MatchPair<'pat, 'tcx>>,
973977

974-
/// ...these bindings established...
975-
// Invariant: not mutated after candidate creation.
976-
bindings: Vec<Binding<'tcx>>,
977-
978-
/// ...and these types asserted...
979-
// Invariant: not mutated after candidate creation.
980-
ascriptions: Vec<Ascription<'tcx>>,
981-
982978
/// ...and if this is non-empty, one of these subcandidates also has to match...
983979
subcandidates: Vec<Candidate<'pat, 'tcx>>,
984980

985-
/// ...and the guard must be evaluated; if it's `false` then branch to `otherwise_block`.
981+
/// ...and the guard must be evaluated if there is one.
982+
has_guard: bool,
983+
984+
/// If the guard is `false` then branch to `otherwise_block`.
986985
otherwise_block: Option<BasicBlock>,
987986

987+
/// If the candidate matches, bindings and ascriptions must be established.
988+
extra_data: PatternExtraData<'tcx>,
989+
988990
/// The block before the `bindings` have been established.
989991
pre_binding_block: Option<BasicBlock>,
990992
/// The pre-binding block of the next candidate.
@@ -1003,10 +1005,8 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
10031005

10041006
fn from_flat_pat(flat_pat: FlatPat<'pat, 'tcx>, has_guard: bool) -> Self {
10051007
Candidate {
1006-
span: flat_pat.span,
10071008
match_pairs: flat_pat.match_pairs,
1008-
bindings: flat_pat.bindings,
1009-
ascriptions: flat_pat.ascriptions,
1009+
extra_data: flat_pat.extra_data,
10101010
has_guard,
10111011
subcandidates: Vec::new(),
10121012
otherwise_block: None,
@@ -1519,8 +1519,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15191519

15201520
// FIXME(or_patterns; matthewjasper) Try to be more aggressive here.
15211521
can_merge &= subcandidate.subcandidates.is_empty()
1522-
&& subcandidate.bindings.is_empty()
1523-
&& subcandidate.ascriptions.is_empty();
1522+
&& subcandidate.extra_data.bindings.is_empty()
1523+
&& subcandidate.extra_data.ascriptions.is_empty();
15241524
}
15251525

15261526
if can_merge {
@@ -1943,7 +1943,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19431943
fn bind_and_guard_matched_candidate<'pat>(
19441944
&mut self,
19451945
candidate: Candidate<'pat, 'tcx>,
1946-
parent_bindings: &[(Vec<Binding<'tcx>>, Vec<Ascription<'tcx>>)],
1946+
parent_data: &[PatternExtraData<'tcx>],
19471947
fake_borrows: &[(Place<'tcx>, Local)],
19481948
scrutinee_span: Span,
19491949
arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>,
@@ -1954,7 +1954,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19541954

19551955
debug_assert!(candidate.match_pairs.is_empty());
19561956

1957-
let candidate_source_info = self.source_info(candidate.span);
1957+
let candidate_source_info = self.source_info(candidate.extra_data.span);
19581958

19591959
let mut block = candidate.pre_binding_block.unwrap();
19601960

@@ -1971,11 +1971,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19711971

19721972
self.ascribe_types(
19731973
block,
1974-
parent_bindings
1974+
parent_data
19751975
.iter()
1976-
.flat_map(|(_, ascriptions)| ascriptions)
1976+
.flat_map(|d| &d.ascriptions)
19771977
.cloned()
1978-
.chain(candidate.ascriptions),
1978+
.chain(candidate.extra_data.ascriptions),
19791979
);
19801980

19811981
// rust-lang/rust#27282: The `autoref` business deserves some
@@ -2063,10 +2063,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20632063
&& let Some(guard) = arm.guard
20642064
{
20652065
let tcx = self.tcx;
2066-
let bindings = parent_bindings
2067-
.iter()
2068-
.flat_map(|(bindings, _)| bindings)
2069-
.chain(&candidate.bindings);
2066+
let bindings =
2067+
parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings);
20702068

20712069
self.bind_matched_candidate_for_guard(block, schedule_drops, bindings.clone());
20722070
let guard_frame = GuardFrame {
@@ -2144,10 +2142,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21442142
// ```
21452143
//
21462144
// and that is clearly not correct.
2147-
let by_value_bindings = parent_bindings
2145+
let by_value_bindings = parent_data
21482146
.iter()
2149-
.flat_map(|(bindings, _)| bindings)
2150-
.chain(&candidate.bindings)
2147+
.flat_map(|d| &d.bindings)
2148+
.chain(&candidate.extra_data.bindings)
21512149
.filter(|binding| matches!(binding.binding_mode, BindingMode::ByValue));
21522150
// Read all of the by reference bindings to ensure that the
21532151
// place they refer to can't be modified by the guard.
@@ -2172,10 +2170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21722170
self.bind_matched_candidate_for_arm_body(
21732171
block,
21742172
schedule_drops,
2175-
parent_bindings
2176-
.iter()
2177-
.flat_map(|(bindings, _)| bindings)
2178-
.chain(&candidate.bindings),
2173+
parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings),
21792174
storages_alive,
21802175
);
21812176
block

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

+6-11
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,19 @@
1212
//! sort of test: for example, testing which variant an enum is, or
1313
//! testing a value against a constant.
1414
15-
use crate::build::matches::{Ascription, Binding, Candidate, FlatPat, MatchPair, TestCase};
15+
use crate::build::matches::{Candidate, FlatPat, MatchPair, PatternExtraData, TestCase};
1616
use crate::build::Builder;
1717

1818
use std::mem;
1919

2020
impl<'a, 'tcx> Builder<'a, 'tcx> {
2121
/// Simplify a list of match pairs so they all require a test. Stores relevant bindings and
22-
/// ascriptions in the provided `Vec`s.
22+
/// ascriptions in `extra_data`.
2323
#[instrument(skip(self), level = "debug")]
2424
pub(super) fn simplify_match_pairs<'pat>(
2525
&mut self,
2626
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
27-
candidate_bindings: &mut Vec<Binding<'tcx>>,
28-
candidate_ascriptions: &mut Vec<Ascription<'tcx>>,
27+
extra_data: &mut PatternExtraData<'tcx>,
2928
) {
3029
// In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
3130
// bindings in `pat` before `x`. E.g. (#69971):
@@ -45,17 +44,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4544
// after any bindings in `pat`. This doesn't work for or-patterns: the current structure of
4645
// match lowering forces us to lower bindings inside or-patterns last.
4746
for mut match_pair in mem::take(match_pairs) {
48-
self.simplify_match_pairs(
49-
&mut match_pair.subpairs,
50-
candidate_bindings,
51-
candidate_ascriptions,
52-
);
47+
self.simplify_match_pairs(&mut match_pair.subpairs, extra_data);
5348
if let TestCase::Irrefutable { binding, ascription } = match_pair.test_case {
5449
if let Some(binding) = binding {
55-
candidate_bindings.push(binding);
50+
extra_data.bindings.push(binding);
5651
}
5752
if let Some(ascription) = ascription {
58-
candidate_ascriptions.push(ascription);
53+
extra_data.ascriptions.push(ascription);
5954
}
6055
// Simplifiable pattern; we replace it with its already simplified subpairs.
6156
match_pairs.append(&mut match_pair.subpairs);

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
280280
}
281281

282282
fn visit_candidate(&mut self, candidate: &Candidate<'_, 'tcx>) {
283-
for binding in &candidate.bindings {
283+
for binding in &candidate.extra_data.bindings {
284284
self.visit_binding(binding);
285285
}
286286
for match_pair in &candidate.match_pairs {
@@ -289,7 +289,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
289289
}
290290

291291
fn visit_flat_pat(&mut self, flat_pat: &FlatPat<'_, 'tcx>) {
292-
for binding in &flat_pat.bindings {
292+
for binding in &flat_pat.extra_data.bindings {
293293
self.visit_binding(binding);
294294
}
295295
for match_pair in &flat_pat.match_pairs {

0 commit comments

Comments
 (0)