Skip to content

Commit 3551f1a

Browse files
committed
Use Fields as output to specialize_one_pattern
1 parent 76dea86 commit 3551f1a

File tree

1 file changed

+51
-23
lines changed

1 file changed

+51
-23
lines changed

src/librustc_mir_build/hair/pattern/_match.rs

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -443,11 +443,9 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
443443
constructor: &Constructor<'tcx>,
444444
ctor_wild_subpatterns: &Fields<'p, 'tcx>,
445445
) -> Option<PatStack<'p, 'tcx>> {
446-
let new_heads = specialize_one_pattern(cx, self.head(), constructor, ctor_wild_subpatterns);
447-
new_heads.map(|mut new_head| {
448-
new_head.0.extend_from_slice(&self.0[1..]);
449-
new_head
450-
})
446+
let new_fields =
447+
specialize_one_pattern(cx, self.head(), constructor, ctor_wild_subpatterns)?;
448+
Some(new_fields.push_on_patstack(&self.0[1..]))
451449
}
452450
}
453451

@@ -1034,9 +1032,24 @@ impl<'tcx> Constructor<'tcx> {
10341032
#[derive(Debug, Clone)]
10351033
enum Fields<'p, 'tcx> {
10361034
Slice(&'p [Pat<'tcx>]),
1035+
Vec(SmallVec<[&'p Pat<'tcx>; 2]>),
10371036
}
10381037

10391038
impl<'p, 'tcx> Fields<'p, 'tcx> {
1039+
fn empty() -> Self {
1040+
Fields::Slice(&[])
1041+
}
1042+
1043+
/// Construct a new `Fields` from the given pattern. Must not be used if the pattern is a field
1044+
/// of a struct/tuple/variant.
1045+
fn from_single_pattern(pat: &'p Pat<'tcx>) -> Self {
1046+
Fields::Slice(std::slice::from_ref(pat))
1047+
}
1048+
1049+
fn from_vec(pats: SmallVec<[&'p Pat<'tcx>; 2]>) -> Self {
1050+
Fields::Vec(pats)
1051+
}
1052+
10401053
/// Creates a new list of wildcard fields for a given constructor.
10411054
fn wildcards(
10421055
cx: &MatchCheckCtxt<'p, 'tcx>,
@@ -1051,13 +1064,27 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
10511064
fn len(&self) -> usize {
10521065
match self {
10531066
Fields::Slice(pats) => pats.len(),
1067+
Fields::Vec(pats) => pats.len(),
10541068
}
10551069
}
10561070

1057-
fn iter<'a>(&'a self) -> impl Iterator<Item = &'p Pat<'tcx>> + Captures<'a> {
1058-
match self {
1059-
Fields::Slice(pats) => pats.iter(),
1060-
}
1071+
fn iter(&self) -> impl Iterator<Item = &'p Pat<'tcx>> {
1072+
let pats: SmallVec<_> = match self {
1073+
Fields::Slice(pats) => pats.iter().collect(),
1074+
Fields::Vec(pats) => pats.clone(),
1075+
};
1076+
pats.into_iter()
1077+
}
1078+
1079+
fn push_on_patstack(self, stack: &[&'p Pat<'tcx>]) -> PatStack<'p, 'tcx> {
1080+
let pats: SmallVec<_> = match self {
1081+
Fields::Slice(pats) => pats.iter().chain(stack.iter().copied()).collect(),
1082+
Fields::Vec(mut pats) => {
1083+
pats.extend_from_slice(stack);
1084+
pats
1085+
}
1086+
};
1087+
PatStack::from_vec(pats)
10611088
}
10621089
}
10631090

@@ -2330,7 +2357,7 @@ fn patterns_for_variant<'p, 'tcx>(
23302357
subpatterns: &'p [FieldPat<'tcx>],
23312358
ctor_wild_subpatterns: &Fields<'p, 'tcx>,
23322359
is_non_exhaustive: bool,
2333-
) -> PatStack<'p, 'tcx> {
2360+
) -> Fields<'p, 'tcx> {
23342361
let mut result: SmallVec<_> = ctor_wild_subpatterns.iter().collect();
23352362

23362363
for subpat in subpatterns {
@@ -2343,7 +2370,7 @@ fn patterns_for_variant<'p, 'tcx>(
23432370
"patterns_for_variant({:#?}, {:#?}) = {:#?}",
23442371
subpatterns, ctor_wild_subpatterns, result
23452372
);
2346-
PatStack::from_vec(result)
2373+
Fields::from_vec(result)
23472374
}
23482375

23492376
/// This is the main specialization step. It expands the pattern
@@ -2360,16 +2387,16 @@ fn specialize_one_pattern<'p, 'tcx>(
23602387
pat: &'p Pat<'tcx>,
23612388
constructor: &Constructor<'tcx>,
23622389
ctor_wild_subpatterns: &Fields<'p, 'tcx>,
2363-
) -> Option<PatStack<'p, 'tcx>> {
2390+
) -> Option<Fields<'p, 'tcx>> {
23642391
if let NonExhaustive = constructor {
23652392
// Only a wildcard pattern can match the special extra constructor
2366-
return if pat.is_wildcard() { Some(PatStack::default()) } else { None };
2393+
return if pat.is_wildcard() { Some(Fields::empty()) } else { None };
23672394
}
23682395

23692396
let result = match *pat.kind {
23702397
PatKind::AscribeUserType { .. } => bug!(), // Handled by `expand_pattern`
23712398

2372-
PatKind::Binding { .. } | PatKind::Wild => Some(ctor_wild_subpatterns.iter().collect()),
2399+
PatKind::Binding { .. } | PatKind::Wild => Some(ctor_wild_subpatterns.clone()),
23732400

23742401
PatKind::Variant { adt_def, variant_index, ref subpatterns, .. } => {
23752402
let variant = &adt_def.variants[variant_index];
@@ -2385,7 +2412,7 @@ fn specialize_one_pattern<'p, 'tcx>(
23852412
Some(patterns_for_variant(cx, subpatterns, ctor_wild_subpatterns, false))
23862413
}
23872414

2388-
PatKind::Deref { ref subpattern } => Some(PatStack::from_pattern(subpattern)),
2415+
PatKind::Deref { ref subpattern } => Some(Fields::from_single_pattern(subpattern)),
23892416

23902417
PatKind::Constant { value } if constructor.is_slice() => {
23912418
// We extract an `Option` for the pointer because slices of zero
@@ -2399,7 +2426,7 @@ fn specialize_one_pattern<'p, 'tcx>(
23992426
// the result would be exactly what we early return here.
24002427
if n == 0 {
24012428
if ctor_wild_subpatterns.len() as u64 == 0 {
2402-
return Some(PatStack::from_slice(&[]));
2429+
return Some(Fields::empty());
24032430
} else {
24042431
return None;
24052432
}
@@ -2440,7 +2467,7 @@ fn specialize_one_pattern<'p, 'tcx>(
24402467
// convert a constant slice/array pattern to a list of patterns.
24412468
let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
24422469
let ptr = Pointer::new(AllocId(0), offset);
2443-
(0..n)
2470+
let pats = (0..n)
24442471
.map(|i| {
24452472
let ptr = ptr.offset(layout.size * i, &cx.tcx).ok()?;
24462473
let scalar = alloc.read_scalar(&cx.tcx, ptr, layout.size).ok()?;
@@ -2450,7 +2477,8 @@ fn specialize_one_pattern<'p, 'tcx>(
24502477
Pat { ty, span: pat.span, kind: box PatKind::Constant { value } };
24512478
Some(&*cx.pattern_arena.alloc(pattern))
24522479
})
2453-
.collect()
2480+
.collect::<Option<_>>()?;
2481+
Some(Fields::from_vec(pats))
24542482
} else {
24552483
None
24562484
}
@@ -2466,7 +2494,7 @@ fn specialize_one_pattern<'p, 'tcx>(
24662494
// Constructor splitting should ensure that all intersections we encounter
24672495
// are actually inclusions.
24682496
assert!(ctor.is_subrange(&pat));
2469-
PatStack::default()
2497+
Fields::empty()
24702498
}),
24712499
_ => None,
24722500
}
@@ -2477,7 +2505,7 @@ fn specialize_one_pattern<'p, 'tcx>(
24772505
// range so intersection actually devolves into being covered
24782506
// by the pattern.
24792507
constructor_covered_by_range(cx.tcx, cx.param_env, constructor, pat)
2480-
.map(|()| PatStack::default())
2508+
.map(|()| Fields::empty())
24812509
}
24822510
}
24832511

@@ -2487,7 +2515,7 @@ fn specialize_one_pattern<'p, 'tcx>(
24872515
let pat_len = prefix.len() + suffix.len();
24882516
if let Some(slice_count) = ctor_wild_subpatterns.len().checked_sub(pat_len) {
24892517
if slice_count == 0 || slice.is_some() {
2490-
Some(
2518+
Some(Fields::from_vec(
24912519
prefix
24922520
.iter()
24932521
.chain(
@@ -2498,7 +2526,7 @@ fn specialize_one_pattern<'p, 'tcx>(
24982526
.chain(suffix.iter()),
24992527
)
25002528
.collect(),
2501-
)
2529+
))
25022530
} else {
25032531
None
25042532
}
@@ -2516,7 +2544,7 @@ fn specialize_one_pattern<'p, 'tcx>(
25162544
suffix,
25172545
cx.param_env,
25182546
) {
2519-
Ok(true) => Some(PatStack::default()),
2547+
Ok(true) => Some(Fields::empty()),
25202548
Ok(false) => None,
25212549
Err(ErrorReported) => None,
25222550
}

0 commit comments

Comments
 (0)