Skip to content

Commit e9bffde

Browse files
committed
Pass Candidate exploded to simplify
1 parent d9d89fd commit e9bffde

File tree

2 files changed

+76
-49
lines changed

2 files changed

+76
-49
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11721172
// be a switch or pattern comparison.
11731173
let mut split_or_candidate = false;
11741174
for candidate in &mut *candidates {
1175-
split_or_candidate |= self.simplify_candidate(candidate);
1175+
split_or_candidate |= self.simplify_candidate(
1176+
&mut candidate.bindings,
1177+
&mut candidate.ascriptions,
1178+
&mut candidate.match_pairs,
1179+
&mut candidate.subcandidates,
1180+
candidate.has_guard,
1181+
);
11761182
}
11771183

11781184
ensure_sufficient_stack(|| {

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

Lines changed: 69 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::build::expr::as_place::PlaceBuilder;
1616
use crate::build::matches::{Ascription, Binding, Candidate, MatchPair};
1717
use crate::build::Builder;
1818
use rustc_middle::thir::{self, *};
19+
use smallvec::SmallVec;
1920

2021
use std::mem;
2122

@@ -33,13 +34,36 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
3334
///
3435
/// only generates a single switch. If this happens this method returns
3536
/// `true`.
36-
#[instrument(skip(self, candidate), level = "debug")]
37+
#[instrument(skip(self), level = "debug")]
3738
pub(super) fn simplify_candidate<'pat>(
3839
&mut self,
39-
candidate: &mut Candidate<'pat, 'tcx>,
40+
bindings: &mut Vec<Binding<'tcx>>,
41+
ascriptions: &mut Vec<Ascription<'tcx>>,
42+
match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>,
43+
subcandidates: &mut Vec<Candidate<'pat, 'tcx>>,
44+
has_guard: bool,
4045
) -> bool {
46+
self.simplify_candidate_inner(bindings, ascriptions, match_pairs);
47+
48+
if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place, .. }] =
49+
&**match_pairs
50+
{
51+
*subcandidates = self.create_or_subcandidates(place, pats, has_guard);
52+
match_pairs.pop();
53+
return true;
54+
}
55+
56+
false
57+
}
58+
59+
#[instrument(skip(self), level = "debug")]
60+
pub(super) fn simplify_candidate_inner<'pat>(
61+
&mut self,
62+
candidate_bindings: &mut Vec<Binding<'tcx>>,
63+
candidate_ascriptions: &mut Vec<Ascription<'tcx>>,
64+
candidate_match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>,
65+
) {
4166
// repeatedly simplify match pairs until fixed point is reached
42-
debug!("{candidate:#?}");
4367

4468
// existing_bindings and new_bindings exists to keep the semantics in order.
4569
// Reversing the binding order for bindings after `@` changes the binding order in places
@@ -59,28 +83,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5983
// binding in iter 2: [6, 7]
6084
//
6185
// final binding: [1, 2, 3, 6, 7, 4, 5]
62-
let mut existing_bindings = mem::take(&mut candidate.bindings);
86+
let mut existing_bindings = mem::take(candidate_bindings);
6387
let mut new_bindings = Vec::new();
6488
loop {
65-
let match_pairs = mem::take(&mut candidate.match_pairs);
89+
let mut match_pairs = mem::take(candidate_match_pairs);
6690

67-
if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place }] =
68-
&*match_pairs
91+
if let [MatchPair { pattern: Pat { kind: PatKind::Or { .. }, .. }, .. }] = &*match_pairs
6992
{
7093
existing_bindings.extend_from_slice(&new_bindings);
71-
mem::swap(&mut candidate.bindings, &mut existing_bindings);
72-
candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats);
73-
return true;
94+
mem::swap(candidate_bindings, &mut existing_bindings);
95+
mem::swap(candidate_match_pairs, &mut match_pairs);
96+
return;
7497
}
7598

7699
let mut changed = false;
77100
for match_pair in match_pairs {
78-
match self.simplify_match_pair(match_pair, candidate) {
101+
match self.simplify_match_pair(
102+
match_pair,
103+
candidate_bindings,
104+
candidate_ascriptions,
105+
candidate_match_pairs,
106+
) {
79107
Ok(()) => {
80108
changed = true;
81109
}
82110
Err(match_pair) => {
83-
candidate.match_pairs.push(match_pair);
111+
candidate_match_pairs.push(match_pair);
84112
}
85113
}
86114
}
@@ -97,21 +125,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
97125
// let z = x.copy_field;
98126
// let y = x;
99127
// }
100-
candidate.bindings.extend_from_slice(&new_bindings);
101-
mem::swap(&mut candidate.bindings, &mut new_bindings);
102-
candidate.bindings.clear();
128+
candidate_bindings.extend_from_slice(&new_bindings);
129+
mem::swap(candidate_bindings, &mut new_bindings);
130+
candidate_bindings.clear();
103131

104132
if !changed {
105133
existing_bindings.extend_from_slice(&new_bindings);
106-
mem::swap(&mut candidate.bindings, &mut existing_bindings);
134+
mem::swap(candidate_bindings, &mut existing_bindings);
107135
// Move or-patterns to the end, because they can result in us
108136
// creating additional candidates, so we want to test them as
109137
// late as possible.
110-
candidate
111-
.match_pairs
138+
candidate_match_pairs
112139
.sort_by_key(|pair| matches!(pair.pattern.kind, PatKind::Or { .. }));
113-
debug!(simplified = ?candidate, "simplify_candidate");
114-
return false; // if we were not able to simplify any, done.
140+
debug!(simplified = ?candidate_match_pairs, "simplify_candidate");
141+
return; // if we were not able to simplify any, done.
115142
}
116143
}
117144
}
@@ -121,14 +148,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
121148
/// `pats`.
122149
fn create_or_subcandidates<'pat>(
123150
&mut self,
124-
candidate: &Candidate<'pat, 'tcx>,
125151
place: &PlaceBuilder<'tcx>,
126152
pats: &'pat [Box<Pat<'tcx>>],
153+
has_guard: bool,
127154
) -> Vec<Candidate<'pat, 'tcx>> {
128155
pats.iter()
129156
.map(|box pat| {
130-
let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard, self);
131-
self.simplify_candidate(&mut candidate);
157+
let mut candidate = Candidate::new(place.clone(), pat, has_guard, self);
158+
self.simplify_candidate(
159+
&mut candidate.bindings,
160+
&mut candidate.ascriptions,
161+
&mut candidate.match_pairs,
162+
&mut candidate.subcandidates,
163+
candidate.has_guard,
164+
);
132165
candidate
133166
})
134167
.collect()
@@ -142,7 +175,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
142175
fn simplify_match_pair<'pat>(
143176
&mut self,
144177
match_pair: MatchPair<'pat, 'tcx>,
145-
candidate: &mut Candidate<'pat, 'tcx>,
178+
bindings: &mut Vec<Binding<'tcx>>,
179+
ascriptions: &mut Vec<Ascription<'tcx>>,
180+
match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>,
146181
) -> Result<(), MatchPair<'pat, 'tcx>> {
147182
match match_pair.pattern.kind {
148183
PatKind::AscribeUserType {
@@ -151,14 +186,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
151186
} => {
152187
// Apply the type ascription to the value at `match_pair.place`, which is the
153188
if let Some(source) = match_pair.place.try_to_place(self) {
154-
candidate.ascriptions.push(Ascription {
189+
ascriptions.push(Ascription {
155190
annotation: annotation.clone(),
156191
source,
157192
variance,
158193
});
159194
}
160195

161-
candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern, self));
196+
match_pairs.push(MatchPair::new(match_pair.place, subpattern, self));
162197

163198
Ok(())
164199
}
@@ -178,7 +213,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
178213
is_primary: _,
179214
} => {
180215
if let Some(source) = match_pair.place.try_to_place(self) {
181-
candidate.bindings.push(Binding {
216+
bindings.push(Binding {
182217
span: match_pair.pattern.span,
183218
source,
184219
var_id: var,
@@ -188,7 +223,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
188223

189224
if let Some(subpattern) = subpattern.as_ref() {
190225
// this is the `x @ P` case; have to keep matching against `P` now
191-
candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern, self));
226+
match_pairs.push(MatchPair::new(match_pair.place, subpattern, self));
192227
}
193228

194229
Ok(())
@@ -206,7 +241,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
206241
}
207242

208243
PatKind::InlineConstant { subpattern: ref pattern, def: _ } => {
209-
candidate.match_pairs.push(MatchPair::new(match_pair.place, pattern, self));
244+
match_pairs.push(MatchPair::new(match_pair.place, pattern, self));
210245

211246
Ok(())
212247
}
@@ -222,13 +257,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
222257
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
223258
if prefix.is_empty() && slice.is_some() && suffix.is_empty() {
224259
// irrefutable
225-
self.prefix_slice_suffix(
226-
&mut candidate.match_pairs,
227-
&match_pair.place,
228-
prefix,
229-
slice,
230-
suffix,
231-
);
260+
self.prefix_slice_suffix(match_pairs, &match_pair.place, prefix, slice, suffix);
232261
Ok(())
233262
} else {
234263
Err(match_pair)
@@ -248,35 +277,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
248277
|| !adt_def.is_variant_list_non_exhaustive());
249278
if irrefutable {
250279
let place_builder = match_pair.place.downcast(adt_def, variant_index);
251-
candidate
252-
.match_pairs
253-
.extend(self.field_match_pairs(place_builder, subpatterns));
280+
match_pairs.extend(self.field_match_pairs(place_builder, subpatterns));
254281
Ok(())
255282
} else {
256283
Err(match_pair)
257284
}
258285
}
259286

260287
PatKind::Array { ref prefix, ref slice, ref suffix } => {
261-
self.prefix_slice_suffix(
262-
&mut candidate.match_pairs,
263-
&match_pair.place,
264-
prefix,
265-
slice,
266-
suffix,
267-
);
288+
self.prefix_slice_suffix(match_pairs, &match_pair.place, prefix, slice, suffix);
268289
Ok(())
269290
}
270291

271292
PatKind::Leaf { ref subpatterns } => {
272293
// tuple struct, match subpats (if any)
273-
candidate.match_pairs.extend(self.field_match_pairs(match_pair.place, subpatterns));
294+
match_pairs.extend(self.field_match_pairs(match_pair.place, subpatterns));
274295
Ok(())
275296
}
276297

277298
PatKind::Deref { ref subpattern } => {
278299
let place_builder = match_pair.place.deref();
279-
candidate.match_pairs.push(MatchPair::new(place_builder, subpattern, self));
300+
match_pairs.push(MatchPair::new(place_builder, subpattern, self));
280301
Ok(())
281302
}
282303

0 commit comments

Comments
 (0)