Skip to content

Commit 7d27cad

Browse files
committed
Use a Vec instead of a slice in DeconstructedPat
1 parent acd463f commit 7d27cad

File tree

5 files changed

+52
-55
lines changed

5 files changed

+52
-55
lines changed

compiler/rustc_pattern_analysis/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub trait TypeCx: Sized + fmt::Debug {
111111
fn ctors_for_ty(&self, ty: &Self::Ty) -> Result<ConstructorSet<Self>, Self::Error>;
112112

113113
/// Best-effort `Debug` implementation.
114-
fn debug_pat(f: &mut fmt::Formatter<'_>, pat: &DeconstructedPat<'_, Self>) -> fmt::Result;
114+
fn debug_pat(f: &mut fmt::Formatter<'_>, pat: &DeconstructedPat<Self>) -> fmt::Result;
115115

116116
/// Raise a bug.
117117
fn bug(&self, fmt: fmt::Arguments<'_>) -> !;
@@ -121,9 +121,9 @@ pub trait TypeCx: Sized + fmt::Debug {
121121
/// The default implementation does nothing.
122122
fn lint_overlapping_range_endpoints(
123123
&self,
124-
_pat: &DeconstructedPat<'_, Self>,
124+
_pat: &DeconstructedPat<Self>,
125125
_overlaps_on: IntRange,
126-
_overlaps_with: &[&DeconstructedPat<'_, Self>],
126+
_overlaps_with: &[&DeconstructedPat<Self>],
127127
) {
128128
}
129129
}
@@ -133,7 +133,7 @@ pub trait TypeCx: Sized + fmt::Debug {
133133
#[derive(derivative::Derivative)]
134134
#[derivative(Clone(bound = ""), Copy(bound = ""))]
135135
pub struct MatchArm<'p, Cx: TypeCx> {
136-
pub pat: &'p DeconstructedPat<'p, Cx>,
136+
pub pat: &'p DeconstructedPat<Cx>,
137137
pub has_guard: bool,
138138
pub arm_data: Cx::ArmData,
139139
}

compiler/rustc_pattern_analysis/src/pat.rs

+19-13
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::fmt;
66
use smallvec::{smallvec, SmallVec};
77

88
use crate::constructor::{Constructor, Slice, SliceKind};
9-
use crate::{Captures, TypeCx};
9+
use crate::TypeCx;
1010

1111
use self::Constructor::*;
1212

@@ -21,9 +21,9 @@ use self::Constructor::*;
2121
/// This happens if a private or `non_exhaustive` field is uninhabited, because the code mustn't
2222
/// observe that it is uninhabited. In that case that field is not included in `fields`. Care must
2323
/// be taken when converting to/from `thir::Pat`.
24-
pub struct DeconstructedPat<'p, Cx: TypeCx> {
24+
pub struct DeconstructedPat<Cx: TypeCx> {
2525
ctor: Constructor<Cx>,
26-
fields: &'p [DeconstructedPat<'p, Cx>],
26+
fields: Vec<DeconstructedPat<Cx>>,
2727
ty: Cx::Ty,
2828
/// Extra data to store in a pattern. `None` if the pattern is a wildcard that does not
2929
/// correspond to a user-supplied pattern.
@@ -32,14 +32,20 @@ pub struct DeconstructedPat<'p, Cx: TypeCx> {
3232
useful: Cell<bool>,
3333
}
3434

35-
impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
35+
impl<Cx: TypeCx> DeconstructedPat<Cx> {
3636
pub fn wildcard(ty: Cx::Ty) -> Self {
37-
DeconstructedPat { ctor: Wildcard, fields: &[], ty, data: None, useful: Cell::new(false) }
37+
DeconstructedPat {
38+
ctor: Wildcard,
39+
fields: Vec::new(),
40+
ty,
41+
data: None,
42+
useful: Cell::new(false),
43+
}
3844
}
3945

4046
pub fn new(
4147
ctor: Constructor<Cx>,
42-
fields: &'p [DeconstructedPat<'p, Cx>],
48+
fields: Vec<DeconstructedPat<Cx>>,
4349
ty: Cx::Ty,
4450
data: Cx::PatData,
4551
) -> Self {
@@ -62,17 +68,17 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
6268
self.data.as_ref()
6369
}
6470

65-
pub fn iter_fields(&self) -> impl Iterator<Item = &'p DeconstructedPat<'p, Cx>> + Captures<'_> {
71+
pub fn iter_fields<'a>(&'a self) -> impl Iterator<Item = &'a DeconstructedPat<Cx>> {
6672
self.fields.iter()
6773
}
6874

6975
/// Specialize this pattern with a constructor.
7076
/// `other_ctor` can be different from `self.ctor`, but must be covered by it.
71-
pub(crate) fn specialize(
72-
&self,
77+
pub(crate) fn specialize<'a>(
78+
&'a self,
7379
other_ctor: &Constructor<Cx>,
7480
ctor_arity: usize,
75-
) -> SmallVec<[PatOrWild<'p, Cx>; 2]> {
81+
) -> SmallVec<[PatOrWild<'a, Cx>; 2]> {
7682
let wildcard_sub_tys = || (0..ctor_arity).map(|_| PatOrWild::Wild).collect();
7783
match (&self.ctor, other_ctor) {
7884
// Return a wildcard for each field of `other_ctor`.
@@ -139,7 +145,7 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
139145
}
140146

141147
/// This is best effort and not good enough for a `Display` impl.
142-
impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> {
148+
impl<Cx: TypeCx> fmt::Debug for DeconstructedPat<Cx> {
143149
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144150
Cx::debug_pat(f, self)
145151
}
@@ -155,11 +161,11 @@ pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
155161
/// A non-user-provided wildcard, created during specialization.
156162
Wild,
157163
/// A user-provided pattern.
158-
Pat(&'p DeconstructedPat<'p, Cx>),
164+
Pat(&'p DeconstructedPat<Cx>),
159165
}
160166

161167
impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> {
162-
pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<'p, Cx>> {
168+
pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<Cx>> {
163169
match self {
164170
PatOrWild::Wild => None,
165171
PatOrWild::Pat(pat) => Some(pat),

compiler/rustc_pattern_analysis/src/pat_column.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{Captures, MatchArm, TypeCx};
1313
#[derive(Debug)]
1414
pub struct PatternColumn<'p, Cx: TypeCx> {
1515
/// This must not contain an or-pattern. `expand_and_push` takes care to expand them.
16-
patterns: Vec<&'p DeconstructedPat<'p, Cx>>,
16+
patterns: Vec<&'p DeconstructedPat<Cx>>,
1717
}
1818

1919
impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
@@ -41,7 +41,7 @@ impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
4141
pub fn head_ty(&self) -> Option<&Cx::Ty> {
4242
self.patterns.first().map(|pat| pat.ty())
4343
}
44-
pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'p DeconstructedPat<'p, Cx>> + Captures<'a> {
44+
pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'p DeconstructedPat<Cx>> + Captures<'a> {
4545
self.patterns.iter().copied()
4646
}
4747

compiler/rustc_pattern_analysis/src/rustc.rs

+25-34
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use smallvec::SmallVec;
21
use std::fmt;
32
use std::iter::once;
43

@@ -28,8 +27,7 @@ use crate::constructor::Constructor::*;
2827
pub type Constructor<'p, 'tcx> = crate::constructor::Constructor<RustcMatchCheckCtxt<'p, 'tcx>>;
2928
pub type ConstructorSet<'p, 'tcx> =
3029
crate::constructor::ConstructorSet<RustcMatchCheckCtxt<'p, 'tcx>>;
31-
pub type DeconstructedPat<'p, 'tcx> =
32-
crate::pat::DeconstructedPat<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
30+
pub type DeconstructedPat<'p, 'tcx> = crate::pat::DeconstructedPat<RustcMatchCheckCtxt<'p, 'tcx>>;
3331
pub type MatchArm<'p, 'tcx> = crate::MatchArm<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
3432
pub type Usefulness<'p, 'tcx> = crate::usefulness::Usefulness<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
3533
pub type UsefulnessReport<'p, 'tcx> =
@@ -452,21 +450,20 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
452450
/// Note: the input patterns must have been lowered through
453451
/// `rustc_mir_build::thir::pattern::check_match::MatchVisitor::lower_pattern`.
454452
pub fn lower_pat(&self, pat: &'p Pat<'tcx>) -> DeconstructedPat<'p, 'tcx> {
455-
let singleton = |pat| std::slice::from_ref(self.pattern_arena.alloc(pat));
456453
let cx = self;
457454
let ty = cx.reveal_opaque_ty(pat.ty);
458455
let ctor;
459-
let fields: &[_];
456+
let mut fields: Vec<_>;
460457
match &pat.kind {
461458
PatKind::AscribeUserType { subpattern, .. }
462459
| PatKind::InlineConstant { subpattern, .. } => return self.lower_pat(subpattern),
463460
PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
464461
PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
465462
ctor = Wildcard;
466-
fields = &[];
463+
fields = vec![];
467464
}
468465
PatKind::Deref { subpattern } => {
469-
fields = singleton(self.lower_pat(subpattern));
466+
fields = vec![self.lower_pat(subpattern)];
470467
ctor = match ty.kind() {
471468
// This is a box pattern.
472469
ty::Adt(adt, ..) if adt.is_box() => Struct,
@@ -478,15 +475,14 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
478475
match ty.kind() {
479476
ty::Tuple(fs) => {
480477
ctor = Struct;
481-
let mut wilds: SmallVec<[_; 2]> = fs
478+
fields = fs
482479
.iter()
483480
.map(|ty| cx.reveal_opaque_ty(ty))
484481
.map(|ty| DeconstructedPat::wildcard(ty))
485482
.collect();
486483
for pat in subpatterns {
487-
wilds[pat.field.index()] = self.lower_pat(&pat.pattern);
484+
fields[pat.field.index()] = self.lower_pat(&pat.pattern);
488485
}
489-
fields = cx.pattern_arena.alloc_from_iter(wilds);
490486
}
491487
ty::Adt(adt, args) if adt.is_box() => {
492488
// The only legal patterns of type `Box` (outside `std`) are `_` and box
@@ -508,7 +504,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
508504
DeconstructedPat::wildcard(self.reveal_opaque_ty(args.type_at(0)))
509505
};
510506
ctor = Struct;
511-
fields = singleton(pat);
507+
fields = vec![pat];
512508
}
513509
ty::Adt(adt, _) => {
514510
ctor = match pat.kind {
@@ -528,14 +524,12 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
528524
ty
529525
},
530526
);
531-
let mut wilds: SmallVec<[_; 2]> =
532-
tys.map(|ty| DeconstructedPat::wildcard(ty)).collect();
527+
fields = tys.map(|ty| DeconstructedPat::wildcard(ty)).collect();
533528
for pat in subpatterns {
534529
if let Some(i) = field_id_to_id[pat.field.index()] {
535-
wilds[i] = self.lower_pat(&pat.pattern);
530+
fields[i] = self.lower_pat(&pat.pattern);
536531
}
537532
}
538-
fields = cx.pattern_arena.alloc_from_iter(wilds);
539533
}
540534
_ => bug!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, ty),
541535
}
@@ -547,7 +541,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
547541
Some(b) => Bool(b),
548542
None => Opaque(OpaqueId::new()),
549543
};
550-
fields = &[];
544+
fields = vec![];
551545
}
552546
ty::Char | ty::Int(_) | ty::Uint(_) => {
553547
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
@@ -563,7 +557,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
563557
}
564558
None => Opaque(OpaqueId::new()),
565559
};
566-
fields = &[];
560+
fields = vec![];
567561
}
568562
ty::Float(ty::FloatTy::F32) => {
569563
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
@@ -574,7 +568,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
574568
}
575569
None => Opaque(OpaqueId::new()),
576570
};
577-
fields = &[];
571+
fields = vec![];
578572
}
579573
ty::Float(ty::FloatTy::F64) => {
580574
ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
@@ -585,7 +579,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
585579
}
586580
None => Opaque(OpaqueId::new()),
587581
};
588-
fields = &[];
582+
fields = vec![];
589583
}
590584
ty::Ref(_, t, _) if t.is_str() => {
591585
// We want a `&str` constant to behave like a `Deref` pattern, to be compatible
@@ -596,16 +590,16 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
596590
// subfields.
597591
// Note: `t` is `str`, not `&str`.
598592
let ty = self.reveal_opaque_ty(*t);
599-
let subpattern = DeconstructedPat::new(Str(*value), &[], ty, pat);
593+
let subpattern = DeconstructedPat::new(Str(*value), Vec::new(), ty, pat);
600594
ctor = Ref;
601-
fields = singleton(subpattern)
595+
fields = vec![subpattern]
602596
}
603597
// All constants that can be structurally matched have already been expanded
604598
// into the corresponding `Pat`s by `const_to_pat`. Constants that remain are
605599
// opaque.
606600
_ => {
607601
ctor = Opaque(OpaqueId::new());
608-
fields = &[];
602+
fields = vec![];
609603
}
610604
}
611605
}
@@ -642,7 +636,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
642636
}
643637
_ => bug!("invalid type for range pattern: {}", ty.inner()),
644638
};
645-
fields = &[];
639+
fields = vec![];
646640
}
647641
PatKind::Array { prefix, slice, suffix } | PatKind::Slice { prefix, slice, suffix } => {
648642
let array_len = match ty.kind() {
@@ -658,25 +652,22 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
658652
SliceKind::FixedLen(prefix.len() + suffix.len())
659653
};
660654
ctor = Slice(Slice::new(array_len, kind));
661-
fields = cx.pattern_arena.alloc_from_iter(
662-
prefix.iter().chain(suffix.iter()).map(|p| self.lower_pat(&*p)),
663-
)
655+
fields = prefix.iter().chain(suffix.iter()).map(|p| self.lower_pat(&*p)).collect();
664656
}
665657
PatKind::Or { .. } => {
666658
ctor = Or;
667659
let pats = expand_or_pat(pat);
668-
fields =
669-
cx.pattern_arena.alloc_from_iter(pats.into_iter().map(|p| self.lower_pat(p)))
660+
fields = pats.into_iter().map(|p| self.lower_pat(p)).collect();
670661
}
671662
PatKind::Never => {
672663
// FIXME(never_patterns): handle `!` in exhaustiveness. This is a sane default
673664
// in the meantime.
674665
ctor = Wildcard;
675-
fields = &[];
666+
fields = vec![];
676667
}
677668
PatKind::Error(_) => {
678669
ctor = Opaque(OpaqueId::new());
679-
fields = &[];
670+
fields = vec![];
680671
}
681672
}
682673
DeconstructedPat::new(ctor, fields, ty, pat)
@@ -849,7 +840,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
849840
/// Best-effort `Debug` implementation.
850841
pub(crate) fn debug_pat(
851842
f: &mut fmt::Formatter<'_>,
852-
pat: &crate::pat::DeconstructedPat<'_, Self>,
843+
pat: &crate::pat::DeconstructedPat<Self>,
853844
) -> fmt::Result {
854845
let mut first = true;
855846
let mut start_or_continue = |s| {
@@ -975,7 +966,7 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
975966

976967
fn debug_pat(
977968
f: &mut fmt::Formatter<'_>,
978-
pat: &crate::pat::DeconstructedPat<'_, Self>,
969+
pat: &crate::pat::DeconstructedPat<Self>,
979970
) -> fmt::Result {
980971
Self::debug_pat(f, pat)
981972
}
@@ -985,9 +976,9 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
985976

986977
fn lint_overlapping_range_endpoints(
987978
&self,
988-
pat: &crate::pat::DeconstructedPat<'_, Self>,
979+
pat: &crate::pat::DeconstructedPat<Self>,
989980
overlaps_on: IntRange,
990-
overlaps_with: &[&crate::pat::DeconstructedPat<'_, Self>],
981+
overlaps_with: &[&crate::pat::DeconstructedPat<Self>],
991982
) {
992983
let overlap_as_pat = self.hoist_pat_range(&overlaps_on, *pat.ty());
993984
let overlaps: Vec<_> = overlaps_with

compiler/rustc_pattern_analysis/src/usefulness.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,7 @@ struct PatStack<'p, Cx: TypeCx> {
826826
}
827827

828828
impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
829-
fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self {
829+
fn from_pattern(pat: &'p DeconstructedPat<Cx>) -> Self {
830830
PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true }
831831
}
832832

@@ -1537,7 +1537,7 @@ pub enum Usefulness<'p, Cx: TypeCx> {
15371537
/// The arm is useful. This additionally carries a set of or-pattern branches that have been
15381538
/// found to be redundant despite the overall arm being useful. Used only in the presence of
15391539
/// or-patterns, otherwise it stays empty.
1540-
Useful(Vec<&'p DeconstructedPat<'p, Cx>>),
1540+
Useful(Vec<&'p DeconstructedPat<Cx>>),
15411541
/// The arm is redundant and can be removed without changing the behavior of the match
15421542
/// expression.
15431543
Redundant,

0 commit comments

Comments
 (0)