From 30fefcc08cc0c670ce541476491238d258ca55c1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 6 Dec 2019 17:35:05 +0100 Subject: Store GenericParams in arena --- crates/ra_hir_def/src/generics.rs | 25 +++++++++++++------------ crates/ra_hir_def/src/lib.rs | 10 ++++++++++ crates/ra_hir_def/src/resolver.rs | 2 +- crates/ra_hir_ty/src/infer/expr.rs | 2 +- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 5f648ffc3..abe749a40 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -5,18 +5,19 @@ use std::sync::Arc; use hir_expand::name::{self, AsName, Name}; +use ra_arena::Arena; use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; use crate::{ db::DefDatabase, src::HasSource, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, ContainerId, GenericDefId, Lookup, + AdtId, AstItemDef, ContainerId, GenericDefId, LocalGenericParamId, Lookup, }; /// Data about a generic parameter (to a function, struct, impl, ...). #[derive(Clone, PartialEq, Eq, Debug)] -pub struct GenericParam { +pub struct GenericParamData { // FIXME: give generic params proper IDs pub idx: u32, pub name: Name, @@ -27,7 +28,7 @@ pub struct GenericParam { #[derive(Clone, PartialEq, Eq, Debug)] pub struct GenericParams { pub parent_params: Option>, - pub params: Vec, + pub params: Arena, pub where_predicates: Vec, } @@ -56,7 +57,7 @@ impl GenericParams { parent_params: Option>, ) -> GenericParams { let mut generics = - GenericParams { params: Vec::new(), parent_params, where_predicates: Vec::new() }; + GenericParams { params: Arena::default(), parent_params, where_predicates: Vec::new() }; let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; // FIXME: add `: Sized` bound for everything except for `Self` in traits match def { @@ -66,7 +67,7 @@ impl GenericParams { GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), GenericDefId::TraitId(it) => { // traits get the Self type as an implicit first type parameter - generics.params.push(GenericParam { + generics.params.alloc(GenericParamData { idx: start, name: name::SELF_TYPE, default: None, @@ -110,8 +111,8 @@ impl GenericParams { let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); // FIXME: Use `Path::from_src` let default = type_param.default_type().map(TypeRef::from_ast); - let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; - self.params.push(param); + let param = GenericParamData { idx: idx as u32 + start, name: name.clone(), default }; + self.params.alloc(param); let type_ref = TypeRef::Path(name.into()); self.fill_bounds(&type_param, type_ref); @@ -140,8 +141,8 @@ impl GenericParams { self.where_predicates.push(WherePredicate { type_ref, bound }); } - pub fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { - self.params.iter().find(|p| &p.name == name) + pub fn find_by_name(&self, name: &Name) -> Option<&GenericParamData> { + self.params.iter().map(|(_id, data)| data).find(|p| &p.name == name) } pub fn count_parent_params(&self) -> usize { @@ -153,14 +154,14 @@ impl GenericParams { parent_count + self.params.len() } - fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) { + fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParamData)) { if let Some(parent) = &self.parent_params { parent.for_each_param(f); } - self.params.iter().for_each(f); + self.params.iter().map(|(_id, data)| data).for_each(f); } - pub fn params_including_parent(&self) -> Vec<&GenericParam> { + pub fn params_including_parent(&self) -> Vec<&GenericParamData> { let mut vec = Vec::with_capacity(self.count_params_including_parent()); self.for_each_param(&mut |p| vec.push(p)); vec diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 68e66d276..b8dfc0ab1 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -317,6 +317,16 @@ macro_rules! impl_froms { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct GenericParamId { + pub parent: GenericDefId, + pub local_id: LocalGenericParamId, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct LocalGenericParamId(RawId); +impl_arena_id!(LocalGenericParamId); + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ContainerId { ModuleId(ModuleId), diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 7d4df222e..ee19d79a7 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -426,7 +426,7 @@ impl Scope { } } Scope::GenericParams { params, .. } => { - for param in params.params.iter() { + for (_id, param) in params.params.iter() { f(param.name.clone(), ScopeDef::GenericParam(param.idx)) } } diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index b8df27706..0c3428999 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -662,7 +662,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let mut substs = Vec::with_capacity(parent_param_count + param_count); // Parent arguments are unknown, except for the receiver type if let Some(parent_generics) = def_generics.and_then(|p| p.parent_params.clone()) { - for param in &parent_generics.params { + for (_id, param) in parent_generics.params.iter() { if param.name == name::SELF_TYPE { substs.push(receiver_ty.clone()); } else { -- cgit v1.2.3