Skip to content

Commit 740b1b4

Browse files
committed
Make simplify_candidate more general
Because we will soon need to apply it to match pairs that aren't directly in a candidate.
1 parent 4d8ee0d commit 740b1b4

File tree

2 files changed

+56
-48
lines changed

2 files changed

+56
-48
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11701170
// be a switch or pattern comparison.
11711171
let mut split_or_candidate = false;
11721172
for candidate in &mut *candidates {
1173-
self.simplify_candidate(candidate);
1173+
self.simplify_match_pairs(
1174+
&mut candidate.match_pairs,
1175+
&mut candidate.bindings,
1176+
&mut candidate.ascriptions,
1177+
);
11741178
if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place, .. }] =
11751179
&*candidate.match_pairs
11761180
{
@@ -1183,7 +1187,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11831187
// }
11841188
//
11851189
// only generates a single switch.
1186-
candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats);
1190+
candidate.subcandidates =
1191+
self.create_or_subcandidates(place, pats, candidate.has_guard);
11871192
candidate.match_pairs.pop();
11881193
split_or_candidate = true;
11891194
}

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

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//! - `place @ (P1, P2)` can be simplified to `[place.0 @ P1, place.1 @ P2]`
77
//! - `place @ x` can be simplified to `[]` by binding `x` to `place`
88
//!
9-
//! The `simplify_candidate` routine just repeatedly applies these
9+
//! The `simplify_match_pairs` routine just repeatedly applies these
1010
//! sort of simplifications until there is nothing left to
1111
//! simplify. Match pairs cannot be simplified if they require some
1212
//! sort of test: for example, testing which variant an enum is, or
@@ -22,10 +22,15 @@ use rustc_middle::ty;
2222
use std::mem;
2323

2424
impl<'a, 'tcx> Builder<'a, 'tcx> {
25-
/// Simplify a candidate so that all match pairs require a test.
26-
#[instrument(skip(self, candidate), level = "debug")]
27-
pub(super) fn simplify_candidate<'pat>(&mut self, candidate: &mut Candidate<'pat, 'tcx>) {
28-
debug!("{candidate:#?}");
25+
/// Simplify a list of match pairs so they all require a test. Stores relevant bindings and
26+
/// ascriptions in the provided `Vec`s.
27+
#[instrument(skip(self), level = "debug")]
28+
pub(super) fn simplify_match_pairs<'pat>(
29+
&mut self,
30+
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
31+
candidate_bindings: &mut Vec<Binding<'tcx>>,
32+
candidate_ascriptions: &mut Vec<Ascription<'tcx>>,
33+
) {
2934
// In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
3035
// bindings in `pat` before `x`. E.g. (#69971):
3136
//
@@ -53,60 +58,70 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5358
// bindings in iter 2: [6, 7]
5459
//
5560
// final bindings: [6, 7, 4, 5, 1, 2, 3]
56-
let mut accumulated_bindings = mem::take(&mut candidate.bindings);
61+
let mut accumulated_bindings = mem::take(candidate_bindings);
5762
// Repeatedly simplify match pairs until fixed point is reached
5863
loop {
5964
let mut changed = false;
60-
for match_pair in mem::take(&mut candidate.match_pairs) {
61-
match self.simplify_match_pair(match_pair, candidate) {
65+
for match_pair in mem::take(match_pairs) {
66+
match self.simplify_match_pair(
67+
match_pair,
68+
candidate_bindings,
69+
candidate_ascriptions,
70+
match_pairs,
71+
) {
6272
Ok(()) => {
6373
changed = true;
6474
}
6575
Err(match_pair) => {
66-
candidate.match_pairs.push(match_pair);
76+
match_pairs.push(match_pair);
6777
}
6878
}
6979
}
7080

7181
// This does: accumulated_bindings = candidate.bindings.take() ++ accumulated_bindings
72-
candidate.bindings.extend_from_slice(&accumulated_bindings);
73-
mem::swap(&mut candidate.bindings, &mut accumulated_bindings);
74-
candidate.bindings.clear();
82+
candidate_bindings.extend_from_slice(&accumulated_bindings);
83+
mem::swap(candidate_bindings, &mut accumulated_bindings);
84+
candidate_bindings.clear();
7585

7686
if !changed {
7787
// If we were not able to simplify anymore, done.
7888
break;
7989
}
8090
}
8191

82-
// Store computed bindings back in `candidate`.
83-
mem::swap(&mut candidate.bindings, &mut accumulated_bindings);
92+
// Store computed bindings back in `candidate_bindings`.
93+
mem::swap(candidate_bindings, &mut accumulated_bindings);
8494

8595
// Move or-patterns to the end, because they can result in us
8696
// creating additional candidates, so we want to test them as
8797
// late as possible.
88-
candidate.match_pairs.sort_by_key(|pair| matches!(pair.pattern.kind, PatKind::Or { .. }));
89-
debug!(simplified = ?candidate, "simplify_candidate");
98+
match_pairs.sort_by_key(|pair| matches!(pair.pattern.kind, PatKind::Or { .. }));
99+
debug!(simplified = ?match_pairs, "simplify_match_pairs");
90100
}
91101

92102
/// Given `candidate` that has a single or-pattern for its match-pairs,
93103
/// creates a fresh candidate for each of its input subpatterns passed via
94104
/// `pats`.
95105
pub(super) fn create_or_subcandidates<'pat>(
96106
&mut self,
97-
candidate: &Candidate<'pat, 'tcx>,
98107
place: &PlaceBuilder<'tcx>,
99108
pats: &'pat [Box<Pat<'tcx>>],
109+
has_guard: bool,
100110
) -> Vec<Candidate<'pat, 'tcx>> {
101111
pats.iter()
102112
.map(|box pat| {
103-
let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard, self);
104-
self.simplify_candidate(&mut candidate);
113+
let mut candidate = Candidate::new(place.clone(), pat, has_guard, self);
114+
self.simplify_match_pairs(
115+
&mut candidate.match_pairs,
116+
&mut candidate.bindings,
117+
&mut candidate.ascriptions,
118+
);
105119

106120
if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place, .. }] =
107121
&*candidate.match_pairs
108122
{
109-
candidate.subcandidates = self.create_or_subcandidates(&candidate, place, pats);
123+
candidate.subcandidates =
124+
self.create_or_subcandidates(place, pats, candidate.has_guard);
110125
candidate.match_pairs.pop();
111126
}
112127
candidate
@@ -122,7 +137,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
122137
fn simplify_match_pair<'pat>(
123138
&mut self,
124139
match_pair: MatchPair<'pat, 'tcx>,
125-
candidate: &mut Candidate<'pat, 'tcx>,
140+
bindings: &mut Vec<Binding<'tcx>>,
141+
ascriptions: &mut Vec<Ascription<'tcx>>,
142+
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
126143
) -> Result<(), MatchPair<'pat, 'tcx>> {
127144
match match_pair.pattern.kind {
128145
PatKind::AscribeUserType {
@@ -131,14 +148,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
131148
} => {
132149
// Apply the type ascription to the value at `match_pair.place`
133150
if let Some(source) = match_pair.place.try_to_place(self) {
134-
candidate.ascriptions.push(Ascription {
151+
ascriptions.push(Ascription {
135152
annotation: annotation.clone(),
136153
source,
137154
variance,
138155
});
139156
}
140157

141-
candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern, self));
158+
match_pairs.push(MatchPair::new(match_pair.place, subpattern, self));
142159

143160
Ok(())
144161
}
@@ -158,7 +175,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
158175
is_primary: _,
159176
} => {
160177
if let Some(source) = match_pair.place.try_to_place(self) {
161-
candidate.bindings.push(Binding {
178+
bindings.push(Binding {
162179
span: match_pair.pattern.span,
163180
source,
164181
var_id: var,
@@ -168,7 +185,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
168185

169186
if let Some(subpattern) = subpattern.as_ref() {
170187
// this is the `x @ P` case; have to keep matching against `P` now
171-
candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern, self));
188+
match_pairs.push(MatchPair::new(match_pair.place, subpattern, self));
172189
}
173190

174191
Ok(())
@@ -211,13 +228,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
211228
span,
212229
user_ty: Box::new(user_ty),
213230
};
214-
candidate.ascriptions.push(Ascription {
231+
ascriptions.push(Ascription {
215232
annotation,
216233
source,
217234
variance: ty::Contravariant,
218235
});
219236
}
220-
candidate.match_pairs.push(MatchPair::new(match_pair.place, pattern, self));
237+
match_pairs.push(MatchPair::new(match_pair.place, pattern, self));
221238

222239
Ok(())
223240
}
@@ -233,13 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
233250
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
234251
if prefix.is_empty() && slice.is_some() && suffix.is_empty() {
235252
// irrefutable
236-
self.prefix_slice_suffix(
237-
&mut candidate.match_pairs,
238-
&match_pair.place,
239-
prefix,
240-
slice,
241-
suffix,
242-
);
253+
self.prefix_slice_suffix(match_pairs, &match_pair.place, prefix, slice, suffix);
243254
Ok(())
244255
} else {
245256
Err(match_pair)
@@ -260,35 +271,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
260271
|| !adt_def.is_variant_list_non_exhaustive());
261272
if irrefutable {
262273
let place_builder = match_pair.place.downcast(adt_def, variant_index);
263-
candidate
264-
.match_pairs
265-
.extend(self.field_match_pairs(place_builder, subpatterns));
274+
match_pairs.extend(self.field_match_pairs(place_builder, subpatterns));
266275
Ok(())
267276
} else {
268277
Err(match_pair)
269278
}
270279
}
271280

272281
PatKind::Array { ref prefix, ref slice, ref suffix } => {
273-
self.prefix_slice_suffix(
274-
&mut candidate.match_pairs,
275-
&match_pair.place,
276-
prefix,
277-
slice,
278-
suffix,
279-
);
282+
self.prefix_slice_suffix(match_pairs, &match_pair.place, prefix, slice, suffix);
280283
Ok(())
281284
}
282285

283286
PatKind::Leaf { ref subpatterns } => {
284287
// tuple struct, match subpats (if any)
285-
candidate.match_pairs.extend(self.field_match_pairs(match_pair.place, subpatterns));
288+
match_pairs.extend(self.field_match_pairs(match_pair.place, subpatterns));
286289
Ok(())
287290
}
288291

289292
PatKind::Deref { ref subpattern } => {
290293
let place_builder = match_pair.place.deref();
291-
candidate.match_pairs.push(MatchPair::new(place_builder, subpattern, self));
294+
match_pairs.push(MatchPair::new(place_builder, subpattern, self));
292295
Ok(())
293296
}
294297

0 commit comments

Comments
 (0)