Intern more TypeRefs in generics

Saves ~3 MB
This commit is contained in:
Jonas Schievink 2021-04-05 02:03:37 +02:00
parent 19e09a4a54
commit 24e876b52e
4 changed files with 15 additions and 14 deletions

View file

@ -18,6 +18,7 @@ use crate::{
child_by_source::ChildBySource, child_by_source::ChildBySource,
db::DefDatabase, db::DefDatabase,
dyn_map::DynMap, dyn_map::DynMap,
intern::Interned,
keys, keys,
src::{HasChildSource, HasSource}, src::{HasChildSource, HasSource},
type_ref::{LifetimeRef, TypeBound, TypeRef}, type_ref::{LifetimeRef, TypeBound, TypeRef},
@ -29,7 +30,7 @@ use crate::{
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
pub struct TypeParamData { pub struct TypeParamData {
pub name: Option<Name>, pub name: Option<Name>,
pub default: Option<TypeRef>, pub default: Option<Interned<TypeRef>>,
pub provenance: TypeParamProvenance, pub provenance: TypeParamProvenance,
} }
@ -43,7 +44,7 @@ pub struct LifetimeParamData {
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
pub struct ConstParamData { pub struct ConstParamData {
pub name: Name, pub name: Name,
pub ty: TypeRef, pub ty: Interned<TypeRef>,
} }
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
@ -75,7 +76,7 @@ pub enum WherePredicate {
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
pub enum WherePredicateTypeTarget { pub enum WherePredicateTypeTarget {
TypeRef(TypeRef), TypeRef(Interned<TypeRef>),
/// For desugared where predicates that can directly refer to a type param. /// For desugared where predicates that can directly refer to a type param.
TypeParam(LocalTypeParamId), TypeParam(LocalTypeParamId),
} }
@ -256,7 +257,8 @@ impl GenericParams {
for type_param in params.type_params() { for type_param in params.type_params() {
let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
// FIXME: Use `Path::from_src` // FIXME: Use `Path::from_src`
let default = type_param.default_type().map(|it| TypeRef::from_ast(lower_ctx, it)); let default =
type_param.default_type().map(|it| Interned::new(TypeRef::from_ast(lower_ctx, it)));
let param = TypeParamData { let param = TypeParamData {
name: Some(name.clone()), name: Some(name.clone()),
default, default,
@ -280,7 +282,7 @@ impl GenericParams {
for const_param in params.const_params() { for const_param in params.const_params() {
let name = const_param.name().map_or_else(Name::missing, |it| it.as_name()); let name = const_param.name().map_or_else(Name::missing, |it| it.as_name());
let ty = const_param.ty().map_or(TypeRef::Error, |it| TypeRef::from_ast(lower_ctx, it)); let ty = const_param.ty().map_or(TypeRef::Error, |it| TypeRef::from_ast(lower_ctx, it));
let param = ConstParamData { name, ty }; let param = ConstParamData { name, ty: Interned::new(ty) };
let param_id = self.consts.alloc(param); let param_id = self.consts.alloc(param);
sm.const_params.insert(param_id, const_param.clone()); sm.const_params.insert(param_id, const_param.clone());
} }
@ -334,11 +336,11 @@ impl GenericParams {
(Either::Left(type_ref), bound) => match hrtb_lifetimes { (Either::Left(type_ref), bound) => match hrtb_lifetimes {
Some(hrtb_lifetimes) => WherePredicate::ForLifetime { Some(hrtb_lifetimes) => WherePredicate::ForLifetime {
lifetimes: hrtb_lifetimes.clone(), lifetimes: hrtb_lifetimes.clone(),
target: WherePredicateTypeTarget::TypeRef(type_ref), target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)),
bound, bound,
}, },
None => WherePredicate::TypeBound { None => WherePredicate::TypeBound {
target: WherePredicateTypeTarget::TypeRef(type_ref), target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)),
bound, bound,
}, },
}, },

View file

@ -122,7 +122,7 @@ impl ModPath {
pub struct Path { pub struct Path {
/// Type based path like `<T>::foo`. /// Type based path like `<T>::foo`.
/// Note that paths like `<Type as Trait>::foo` are desugard to `Trait::<Self=Type>::foo`. /// Note that paths like `<Type as Trait>::foo` are desugard to `Trait::<Self=Type>::foo`.
type_anchor: Option<Box<TypeRef>>, type_anchor: Option<Interned<TypeRef>>,
mod_path: Interned<ModPath>, mod_path: Interned<ModPath>,
/// Invariant: the same len as `self.mod_path.segments` /// Invariant: the same len as `self.mod_path.segments`
generic_args: Vec<Option<Arc<GenericArgs>>>, generic_args: Vec<Option<Arc<GenericArgs>>>,

View file

@ -69,7 +69,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
match trait_ref { match trait_ref {
// <T>::foo // <T>::foo
None => { None => {
type_anchor = Some(Box::new(self_type)); type_anchor = Some(Interned::new(self_type));
kind = PathKind::Plain; kind = PathKind::Plain;
} }
// <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo

View file

@ -32,11 +32,10 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
.filter_map(|pred| match pred { .filter_map(|pred| match pred {
WherePredicate::ForLifetime { target, bound, .. } WherePredicate::ForLifetime { target, bound, .. }
| WherePredicate::TypeBound { target, bound } => match target { | WherePredicate::TypeBound { target, bound } => match target {
WherePredicateTypeTarget::TypeRef(TypeRef::Path(p)) WherePredicateTypeTarget::TypeRef(type_ref) => match &**type_ref {
if p == &Path::from(name![Self]) => TypeRef::Path(p) if p == &Path::from(name![Self]) => bound.as_path(),
{ _ => None,
bound.as_path() },
}
WherePredicateTypeTarget::TypeParam(local_id) if Some(*local_id) == trait_self => { WherePredicateTypeTarget::TypeParam(local_id) if Some(*local_id) == trait_self => {
bound.as_path() bound.as_path()
} }