Skip to content

Commit e91e82a

Browse files
authored
Unrolled build for #154943
Rollup merge of #154943 - Zalathar:for-each-subpat, r=Nadrieril Move recursion out of `MatchPairTree::for_pattern` helpers The helper functions now just iterate over the relevant subpatterns, while leaving recursion up to the main function. This avoids passing parameters that were only used for recursive plumbing, and consolidates all recursive calls into `for_pattern` itself, which should make it easier to experiment with changes to the recursive structure. There should be no change to compiler behaviour.
2 parents 2f201bc + 4a5c24f commit e91e82a

1 file changed

Lines changed: 65 additions & 86 deletions

File tree

compiler/rustc_mir_build/src/builder/matches/match_pair.rs

Lines changed: 65 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -12,77 +12,58 @@ use crate::builder::matches::{
1212
FlatPat, MatchPairTree, PatConstKind, PatternExtraData, SliceLenOp, TestableCase,
1313
};
1414

15-
impl<'a, 'tcx> Builder<'a, 'tcx> {
16-
/// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in
17-
/// `subpatterns`, representing the fields of a [`PatKind::Variant`] or
18-
/// [`PatKind::Leaf`].
19-
///
20-
/// Used internally by [`MatchPairTree::for_pattern`].
21-
fn field_match_pairs(
22-
&mut self,
23-
match_pairs: &mut Vec<MatchPairTree<'tcx>>,
24-
extra_data: &mut PatternExtraData<'tcx>,
25-
place: PlaceBuilder<'tcx>,
26-
subpatterns: &[FieldPat<'tcx>],
27-
) {
28-
for fieldpat in subpatterns {
29-
let place = place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty));
30-
MatchPairTree::for_pattern(place, &fieldpat.pattern, self, match_pairs, extra_data);
31-
}
15+
/// For an array or slice pattern's subpatterns (prefix/slice/suffix), returns a list
16+
/// of those subpatterns, each paired with a suitably-projected [`PlaceBuilder`].
17+
fn prefix_slice_suffix<'a, 'tcx>(
18+
place: &PlaceBuilder<'tcx>,
19+
array_len: Option<u64>, // Some for array patterns; None for slice patterns
20+
prefix: &'a [Pat<'tcx>],
21+
opt_slice: &'a Option<Box<Pat<'tcx>>>,
22+
suffix: &'a [Pat<'tcx>],
23+
) -> Vec<(PlaceBuilder<'tcx>, &'a Pat<'tcx>)> {
24+
let prefix_len = u64::try_from(prefix.len()).unwrap();
25+
let suffix_len = u64::try_from(suffix.len()).unwrap();
26+
27+
let mut output_pairs =
28+
Vec::with_capacity(prefix.len() + usize::from(opt_slice.is_some()) + suffix.len());
29+
30+
// For slice patterns with a `..` followed by 0 or more suffix subpatterns,
31+
// the actual slice index of those subpatterns isn't statically known, so
32+
// we have to index them relative to the end of the slice.
33+
//
34+
// For array patterns, all subpatterns are indexed relative to the start.
35+
let (min_length, is_array) = match array_len {
36+
Some(len) => (len, true),
37+
None => (prefix_len + suffix_len, false),
38+
};
39+
40+
for (offset, prefix_subpat) in (0u64..).zip(prefix) {
41+
let elem = ProjectionElem::ConstantIndex { offset, min_length, from_end: false };
42+
let subplace = place.clone_project(elem);
43+
output_pairs.push((subplace, prefix_subpat));
3244
}
3345

34-
/// Builds [`MatchPairTree`] subtrees for the prefix/middle/suffix parts of an
35-
/// array pattern or slice pattern, and adds those trees to `match_pairs`.
36-
///
37-
/// Used internally by [`MatchPairTree::for_pattern`].
38-
fn prefix_slice_suffix(
39-
&mut self,
40-
match_pairs: &mut Vec<MatchPairTree<'tcx>>,
41-
extra_data: &mut PatternExtraData<'tcx>,
42-
place: &PlaceBuilder<'tcx>,
43-
array_len: Option<u64>,
44-
prefix: &[Pat<'tcx>],
45-
opt_slice: &Option<Box<Pat<'tcx>>>,
46-
suffix: &[Pat<'tcx>],
47-
) {
48-
let prefix_len = u64::try_from(prefix.len()).unwrap();
49-
let suffix_len = u64::try_from(suffix.len()).unwrap();
50-
51-
// For slice patterns with a `..` followed by 0 or more suffix subpatterns,
52-
// the actual slice index of those subpatterns isn't statically known, so
53-
// we have to index them relative to the end of the slice.
54-
//
55-
// For array patterns, all subpatterns are indexed relative to the start.
56-
let (min_length, is_array) = match array_len {
57-
Some(len) => (len, true),
58-
None => (prefix_len + suffix_len, false),
46+
if let Some(slice_subpat) = opt_slice {
47+
let elem = PlaceElem::Subslice {
48+
from: prefix_len,
49+
to: if is_array { min_length - suffix_len } else { suffix_len },
50+
from_end: !is_array,
5951
};
52+
let subplace = place.clone_project(elem);
53+
output_pairs.push((subplace, slice_subpat));
54+
}
6055

61-
for (offset, subpattern) in (0u64..).zip(prefix) {
62-
let elem = ProjectionElem::ConstantIndex { offset, min_length, from_end: false };
63-
let place = place.clone_project(elem);
64-
MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data)
65-
}
66-
67-
if let Some(subslice_pat) = opt_slice {
68-
let subslice = place.clone_project(PlaceElem::Subslice {
69-
from: prefix_len,
70-
to: if is_array { min_length - suffix_len } else { suffix_len },
71-
from_end: !is_array,
72-
});
73-
MatchPairTree::for_pattern(subslice, subslice_pat, self, match_pairs, extra_data);
74-
}
75-
76-
for (end_offset, subpattern) in (1u64..).zip(suffix.iter().rev()) {
77-
let elem = ProjectionElem::ConstantIndex {
78-
offset: if is_array { min_length - end_offset } else { end_offset },
79-
min_length,
80-
from_end: !is_array,
81-
};
82-
let place = place.clone_project(elem);
83-
MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data)
84-
}
56+
for (offset_from_end, suffix_subpat) in (1u64..).zip(suffix.iter().rev()) {
57+
let elem = ProjectionElem::ConstantIndex {
58+
offset: if is_array { min_length - offset_from_end } else { offset_from_end },
59+
min_length,
60+
from_end: !is_array,
61+
};
62+
let subplace = place.clone_project(elem);
63+
output_pairs.push((subplace, suffix_subpat));
8564
}
65+
66+
output_pairs
8667
}
8768

8869
impl<'tcx> MatchPairTree<'tcx> {
@@ -239,15 +220,11 @@ impl<'tcx> MatchPairTree<'tcx> {
239220
_ => None,
240221
};
241222
if let Some(array_len) = array_len {
242-
cx.prefix_slice_suffix(
243-
&mut subpairs,
244-
extra_data,
245-
&place_builder,
246-
Some(array_len),
247-
prefix,
248-
slice,
249-
suffix,
250-
);
223+
for (subplace, subpat) in
224+
prefix_slice_suffix(&place_builder, Some(array_len), prefix, slice, suffix)
225+
{
226+
MatchPairTree::for_pattern(subplace, subpat, cx, &mut subpairs, extra_data);
227+
}
251228
} else {
252229
// If the array length couldn't be determined, ignore the
253230
// subpatterns and delayed-assert that compilation will fail.
@@ -263,15 +240,11 @@ impl<'tcx> MatchPairTree<'tcx> {
263240
None
264241
}
265242
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
266-
cx.prefix_slice_suffix(
267-
&mut subpairs,
268-
extra_data,
269-
&place_builder,
270-
None,
271-
prefix,
272-
slice,
273-
suffix,
274-
);
243+
for (subplace, subpat) in
244+
prefix_slice_suffix(&place_builder, None, prefix, slice, suffix)
245+
{
246+
MatchPairTree::for_pattern(subplace, subpat, cx, &mut subpairs, extra_data);
247+
}
275248

276249
if prefix.is_empty() && slice.is_some() && suffix.is_empty() {
277250
// This pattern is shaped like `[..]`. It can match a slice
@@ -294,7 +267,10 @@ impl<'tcx> MatchPairTree<'tcx> {
294267

295268
PatKind::Variant { adt_def, variant_index, args: _, ref subpatterns } => {
296269
let downcast_place = place_builder.downcast(adt_def, variant_index); // `(x as Variant)`
297-
cx.field_match_pairs(&mut subpairs, extra_data, downcast_place, subpatterns);
270+
for &FieldPat { field, pattern: ref subpat } in subpatterns {
271+
let subplace = downcast_place.clone_project(PlaceElem::Field(field, subpat.ty));
272+
MatchPairTree::for_pattern(subplace, subpat, cx, &mut subpairs, extra_data);
273+
}
298274

299275
// We treat non-exhaustive enums the same independent of the crate they are
300276
// defined in, to avoid differences in the operational semantics between crates.
@@ -308,7 +284,10 @@ impl<'tcx> MatchPairTree<'tcx> {
308284
}
309285

310286
PatKind::Leaf { ref subpatterns } => {
311-
cx.field_match_pairs(&mut subpairs, extra_data, place_builder, subpatterns);
287+
for &FieldPat { field, pattern: ref subpat } in subpatterns {
288+
let subplace = place_builder.clone_project(PlaceElem::Field(field, subpat.ty));
289+
MatchPairTree::for_pattern(subplace, subpat, cx, &mut subpairs, extra_data);
290+
}
312291
None
313292
}
314293

0 commit comments

Comments
 (0)