Don't need an arena for types anymore

This commit is contained in:
Nadrieril 2024-02-06 05:06:53 +01:00
parent ba7b12e062
commit d2d4119d24
2 changed files with 15 additions and 36 deletions

View file

@ -153,14 +153,7 @@ impl ExprValidator {
} }
let pattern_arena = Arena::new(); let pattern_arena = Arena::new();
let ty_arena = Arena::new(); let cx = MatchCheckCtx::new(self.owner.module(db.upcast()), self.owner, db, &pattern_arena);
let cx = MatchCheckCtx::new(
self.owner.module(db.upcast()),
self.owner,
db,
&pattern_arena,
&ty_arena,
);
let mut m_arms = Vec::with_capacity(arms.len()); let mut m_arms = Vec::with_capacity(arms.len());
let mut has_lowering_errors = false; let mut has_lowering_errors = false;

View file

@ -9,7 +9,7 @@ use rustc_pattern_analysis::{
index::IdxContainer, index::IdxContainer,
Captures, TypeCx, Captures, TypeCx,
}; };
use smallvec::SmallVec; use smallvec::{smallvec, SmallVec};
use stdx::never; use stdx::never;
use typed_arena::Arena; use typed_arena::Arena;
@ -41,7 +41,6 @@ pub(crate) struct MatchCheckCtx<'p> {
body: DefWithBodyId, body: DefWithBodyId,
pub(crate) db: &'p dyn HirDatabase, pub(crate) db: &'p dyn HirDatabase,
pub(crate) pattern_arena: &'p Arena<DeconstructedPat<'p>>, pub(crate) pattern_arena: &'p Arena<DeconstructedPat<'p>>,
ty_arena: &'p Arena<Ty>,
exhaustive_patterns: bool, exhaustive_patterns: bool,
min_exhaustive_patterns: bool, min_exhaustive_patterns: bool,
} }
@ -58,21 +57,12 @@ impl<'p> MatchCheckCtx<'p> {
body: DefWithBodyId, body: DefWithBodyId,
db: &'p dyn HirDatabase, db: &'p dyn HirDatabase,
pattern_arena: &'p Arena<DeconstructedPat<'p>>, pattern_arena: &'p Arena<DeconstructedPat<'p>>,
ty_arena: &'p Arena<Ty>,
) -> Self { ) -> Self {
let def_map = db.crate_def_map(module.krate()); let def_map = db.crate_def_map(module.krate());
let exhaustive_patterns = def_map.is_unstable_feature_enabled("exhaustive_patterns"); let exhaustive_patterns = def_map.is_unstable_feature_enabled("exhaustive_patterns");
let min_exhaustive_patterns = let min_exhaustive_patterns =
def_map.is_unstable_feature_enabled("min_exhaustive_patterns"); def_map.is_unstable_feature_enabled("min_exhaustive_patterns");
Self { Self { module, body, db, pattern_arena, exhaustive_patterns, min_exhaustive_patterns }
module,
body,
db,
pattern_arena,
exhaustive_patterns,
min_exhaustive_patterns,
ty_arena,
}
} }
fn is_uninhabited(&self, ty: &Ty) -> bool { fn is_uninhabited(&self, ty: &Ty) -> bool {
@ -370,50 +360,46 @@ impl<'p> TypeCx for MatchCheckCtx<'p> {
ctor: &'a rustc_pattern_analysis::constructor::Constructor<Self>, ctor: &'a rustc_pattern_analysis::constructor::Constructor<Self>,
ty: &'a Self::Ty, ty: &'a Self::Ty,
) -> impl Iterator<Item = Self::Ty> + ExactSizeIterator + Captures<'a> { ) -> impl Iterator<Item = Self::Ty> + ExactSizeIterator + Captures<'a> {
use std::iter::once; let single = |ty| smallvec![ty];
fn alloc<'a>(cx: &'a MatchCheckCtx<'_>, iter: impl Iterator<Item = Ty>) -> &'a [Ty] { let tys: SmallVec<[_; 2]> = match ctor {
cx.ty_arena.alloc_extend(iter)
}
let slice = match ctor {
Struct | Variant(_) | UnionField => match ty.kind(Interner) { Struct | Variant(_) | UnionField => match ty.kind(Interner) {
TyKind::Tuple(_, substs) => { TyKind::Tuple(_, substs) => {
let tys = substs.iter(Interner).map(|ty| ty.assert_ty_ref(Interner)); let tys = substs.iter(Interner).map(|ty| ty.assert_ty_ref(Interner));
alloc(self, tys.cloned()) tys.cloned().collect()
} }
TyKind::Ref(.., rty) => alloc(self, once(rty.clone())), TyKind::Ref(.., rty) => single(rty.clone()),
&TyKind::Adt(AdtId(adt), ref substs) => { &TyKind::Adt(AdtId(adt), ref substs) => {
if is_box(self.db, adt) { if is_box(self.db, adt) {
// The only legal patterns of type `Box` (outside `std`) are `_` and box // The only legal patterns of type `Box` (outside `std`) are `_` and box
// patterns. If we're here we can assume this is a box pattern. // patterns. If we're here we can assume this is a box pattern.
let subst_ty = substs.at(Interner, 0).assert_ty_ref(Interner).clone(); let subst_ty = substs.at(Interner, 0).assert_ty_ref(Interner).clone();
alloc(self, once(subst_ty)) single(subst_ty)
} else { } else {
let variant = Self::variant_id_for_adt(ctor, adt).unwrap(); let variant = Self::variant_id_for_adt(ctor, adt).unwrap();
let tys = self.list_variant_nonhidden_fields(ty, variant).map(|(_, ty)| ty); self.list_variant_nonhidden_fields(ty, variant).map(|(_, ty)| ty).collect()
alloc(self, tys)
} }
} }
ty_kind => { ty_kind => {
never!("Unexpected type for `{:?}` constructor: {:?}", ctor, ty_kind); never!("Unexpected type for `{:?}` constructor: {:?}", ctor, ty_kind);
alloc(self, once(ty.clone())) single(ty.clone())
} }
}, },
Ref => match ty.kind(Interner) { Ref => match ty.kind(Interner) {
TyKind::Ref(.., rty) => alloc(self, once(rty.clone())), TyKind::Ref(.., rty) => single(rty.clone()),
ty_kind => { ty_kind => {
never!("Unexpected type for `{:?}` constructor: {:?}", ctor, ty_kind); never!("Unexpected type for `{:?}` constructor: {:?}", ctor, ty_kind);
alloc(self, once(ty.clone())) single(ty.clone())
} }
}, },
Slice(_) => unreachable!("Found a `Slice` constructor in match checking"), Slice(_) => unreachable!("Found a `Slice` constructor in match checking"),
Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..) Bool(..) | IntRange(..) | F32Range(..) | F64Range(..) | Str(..) | Opaque(..)
| NonExhaustive | Hidden | Missing | Wildcard => &[], | NonExhaustive | Hidden | Missing | Wildcard => smallvec![],
Or => { Or => {
never!("called `Fields::wildcards` on an `Or` ctor"); never!("called `Fields::wildcards` on an `Or` ctor");
&[] smallvec![]
} }
}; };
slice.into_iter().cloned() tys.into_iter()
} }
fn ctors_for_ty( fn ctors_for_ty(