From c6172f3f6d3fb0982ae17f48507608609d46d179 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 13 Dec 2020 22:13:16 +0100 Subject: Add LifetimeParam resolving to Semantics --- crates/hir_def/src/generics.rs | 49 ++++++++++++++++++++--------------- crates/hir_def/src/item_tree/lower.rs | 5 ++-- crates/hir_def/src/keys.rs | 5 ++-- 3 files changed, 33 insertions(+), 26 deletions(-) (limited to 'crates/hir_def') diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index 5189c7e9f..81912a454 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs @@ -19,10 +19,10 @@ use crate::{ db::DefDatabase, dyn_map::DynMap, keys, - src::HasChildSource, src::HasSource, type_ref::{LifetimeRef, TypeBound, TypeRef}, - AdtId, GenericDefId, LocalTypeParamId, Lookup, TypeParamId, + AdtId, GenericDefId, LifetimeParamId, LocalLifetimeParamId, LocalTypeParamId, Lookup, + TypeParamId, }; /// Data about a generic parameter (to a function, struct, impl, ...). @@ -72,7 +72,11 @@ pub enum WherePredicateTypeTarget { // FIXME: ForLifetime(Vec, TypeRef) } -type SourceMap = ArenaMap>; +#[derive(Default)] +pub struct SourceMaps { + pub type_params: ArenaMap>, + pub lifetime_params: ArenaMap, +} impl GenericParams { pub(crate) fn generic_params_query( @@ -129,9 +133,9 @@ impl GenericParams { Arc::new(generics) } - fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile) { + fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile) { let mut generics = GenericParams::default(); - let mut sm = ArenaMap::default(); + let mut sm = SourceMaps::default(); // FIXME: add `: Sized` bound for everything except for `Self` in traits let file_id = match def { @@ -174,7 +178,7 @@ impl GenericParams { default: None, provenance: TypeParamProvenance::TraitSelf, }); - sm.insert(self_param_id, Either::Left(src.value.clone())); + sm.type_params.insert(self_param_id, Either::Left(src.value.clone())); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar let self_param = TypeRef::Path(name![Self].into()); @@ -210,7 +214,7 @@ impl GenericParams { pub(crate) fn fill( &mut self, lower_ctx: &LowerCtx, - sm: &mut SourceMap, + sm: &mut SourceMaps, node: &dyn GenericParamsOwner, ) { if let Some(params) = node.generic_param_list() { @@ -237,7 +241,7 @@ impl GenericParams { fn fill_params( &mut self, lower_ctx: &LowerCtx, - sm: &mut SourceMap, + sm: &mut SourceMaps, params: ast::GenericParamList, ) { for type_param in params.type_params() { @@ -250,7 +254,7 @@ impl GenericParams { provenance: TypeParamProvenance::TypeParamList, }; let param_id = self.types.alloc(param); - sm.insert(param_id, Either::Right(type_param.clone())); + sm.type_params.insert(param_id, Either::Right(type_param.clone())); let type_ref = TypeRef::Path(name.into()); self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref)); @@ -260,7 +264,8 @@ impl GenericParams { .lifetime_token() .map_or_else(Name::missing, |tok| Name::new_lifetime(&tok)); let param = LifetimeParamData { name: name.clone() }; - let _param_id = self.lifetimes.alloc(param); + let param_id = self.lifetimes.alloc(param); + sm.lifetime_params.insert(param_id, lifetime_param.clone()); let lifetime_ref = LifetimeRef::new_name(name); self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref)); } @@ -340,27 +345,29 @@ impl GenericParams { }) } } - -impl HasChildSource for GenericDefId { - type ChildId = LocalTypeParamId; - type Value = Either; - fn child_source(&self, db: &dyn DefDatabase) -> InFile { - let (_, sm) = GenericParams::new(db, *self); - sm +impl GenericDefId { + // FIXME: Change HasChildSource's ChildId AssocItem to be a generic parameter instead + pub fn child_source(&self, db: &dyn DefDatabase) -> InFile { + GenericParams::new(db, *self).1 } } impl ChildBySource for GenericDefId { fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { let mut res = DynMap::default(); - let arena_map = self.child_source(db); - let arena_map = arena_map.as_ref(); - for (local_id, src) in arena_map.value.iter() { + let (_, sm) = GenericParams::new(db, *self); + + let sm = sm.as_ref(); + for (local_id, src) in sm.value.type_params.iter() { let id = TypeParamId { parent: *self, local_id }; if let Either::Right(type_param) = src { - res[keys::TYPE_PARAM].insert(arena_map.with_value(type_param.clone()), id) + res[keys::TYPE_PARAM].insert(sm.with_value(type_param.clone()), id) } } + for (local_id, src) in sm.value.lifetime_params.iter() { + let id = LifetimeParamId { parent: *self, local_id }; + res[keys::LIFETIME_PARAM].insert(sm.with_value(src.clone()), id); + } res } } diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index f7ce2e26d..2939c6b1e 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -2,7 +2,6 @@ use std::{collections::hash_map::Entry, mem, sync::Arc}; -use arena::map::ArenaMap; use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, name::known, HirFileId}; use smallvec::SmallVec; use syntax::{ @@ -607,7 +606,7 @@ impl Ctx { owner: GenericsOwner<'_>, node: &impl ast::GenericParamsOwner, ) -> GenericParamsId { - let mut sm = &mut ArenaMap::default(); + let mut sm = &mut Default::default(); let mut generics = GenericParams::default(); match owner { GenericsOwner::Function(func) => { @@ -630,7 +629,7 @@ impl Ctx { default: None, provenance: TypeParamProvenance::TraitSelf, }); - sm.insert(self_param_id, Either::Left(trait_def.clone())); + sm.type_params.insert(self_param_id, Either::Left(trait_def.clone())); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar let self_param = TypeRef::Path(name![Self].into()); diff --git a/crates/hir_def/src/keys.rs b/crates/hir_def/src/keys.rs index 40a5d92b5..9c585de2c 100644 --- a/crates/hir_def/src/keys.rs +++ b/crates/hir_def/src/keys.rs @@ -8,8 +8,8 @@ use syntax::{ast, AstNode, AstPtr}; use crate::{ dyn_map::{DynMap, Policy}, - ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, StaticId, StructId, TraitId, - TypeAliasId, TypeParamId, UnionId, + ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, StaticId, + StructId, TraitId, TypeAliasId, TypeParamId, UnionId, }; pub type Key = crate::dyn_map::Key, V, AstPtrPolicy>; @@ -28,6 +28,7 @@ pub const VARIANT: Key = Key::new(); pub const TUPLE_FIELD: Key = Key::new(); pub const RECORD_FIELD: Key = Key::new(); pub const TYPE_PARAM: Key = Key::new(); +pub const LIFETIME_PARAM: Key = Key::new(); pub const MACRO: Key = Key::new(); -- cgit v1.2.3