From 64c21ed19594b323e72605ba8c5dd4c6eee433f6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 17:39:58 +0300 Subject: Switch type aliases to new sources --- crates/ra_hir/src/code_model.rs | 28 ++++---- crates/ra_hir/src/code_model/src.rs | 2 +- crates/ra_hir/src/from_source.rs | 112 ++++++++++++++++++----------- crates/ra_hir_def/src/db.rs | 6 +- crates/ra_hir_def/src/generics.rs | 2 +- crates/ra_hir_def/src/impls.rs | 13 ++-- crates/ra_hir_def/src/lib.rs | 48 +++++++++++-- crates/ra_hir_def/src/nameres/collector.rs | 14 ++-- crates/ra_hir_def/src/traits.rs | 10 ++- 9 files changed, 162 insertions(+), 73 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index c49190a0f..b8d48a500 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -13,7 +13,7 @@ use hir_def::{ traits::TraitData, type_ref::{Mutability, TypeRef}, AssocItemId, CrateModuleId, FunctionContainerId, HasModule, ImplId, LocalEnumVariantId, - LocalStructFieldId, Lookup, ModuleId, UnionId, + LocalStructFieldId, Lookup, ModuleId, TypeAliasContainerId, UnionId, }; use hir_expand::{ diagnostics::DiagnosticSink, @@ -954,30 +954,34 @@ pub struct TypeAlias { impl TypeAlias { pub fn module(self, db: &impl DefDatabase) -> Module { - Module { id: self.id.module(db) } + Module { id: self.id.lookup(db).module(db) } } pub fn krate(self, db: &impl DefDatabase) -> Option { Some(self.module(db).krate()) } - /// The containing impl block, if this is a method. + /// The containing impl block, if this is a type alias. pub fn impl_block(self, db: &impl DefDatabase) -> Option { - ImplBlock::containing(db, self.into()) + match self.container(db) { + Some(Container::ImplBlock(it)) => Some(it), + _ => None, + } } - /// The containing trait, if this is a trait method definition. + /// The containing trait, if this is a trait type alias definition. pub fn parent_trait(self, db: &impl DefDatabase) -> Option { - db.trait_items_index(self.module(db).id).get_parent_trait(self.id.into()).map(Trait::from) + match self.container(db) { + Some(Container::Trait(it)) => Some(it), + _ => None, + } } pub fn container(self, db: &impl DefDatabase) -> Option { - if let Some(impl_block) = self.impl_block(db) { - Some(impl_block.into()) - } else if let Some(trait_) = self.parent_trait(db) { - Some(trait_.into()) - } else { - None + match self.id.lookup(db).container { + TypeAliasContainerId::TraitId(it) => Some(Container::Trait(it.into())), + TypeAliasContainerId::ImplId(it) => Some(Container::ImplBlock(it.into())), + TypeAliasContainerId::ModuleId(_) => None, } } diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index 91cab7414..04675e08e 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs @@ -138,7 +138,7 @@ impl HasSource for Trait { impl HasSource for TypeAlias { type Ast = ast::TypeAliasDef; fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source { - self.id.source(db) + self.id.lookup(db).source(db) } } impl HasSource for MacroDef { diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 303d5f138..f5fdaafa3 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs @@ -4,7 +4,7 @@ use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId}; use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; use ra_syntax::{ ast::{self, AstNode, NameOwner}, - match_ast, AstPtr, + match_ast, AstPtr, SyntaxNode, }; use crate::{ @@ -52,48 +52,27 @@ impl FromSource for Trait { impl FromSource for Function { type Ast = ast::FnDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - // FIXME: this doesn't try to handle nested declarations - for container in src.value.syntax().ancestors() { - let res = match_ast! { - match container { - ast::TraitDef(it) => { - let c = Trait::from_source(db, src.with_value(it))?; - c.items(db) - .into_iter() - .filter_map(|it| match it { - AssocItem::Function(it) => Some(it), - _ => None - }) - .find(|it| same_source(&it.source(db), &src))? - }, - ast::ImplBlock(it) => { - let c = ImplBlock::from_source(db, src.with_value(it))?; - c.items(db) - .into_iter() - .filter_map(|it| match it { - AssocItem::Function(it) => Some(it), - _ => None - }) - .find(|it| same_source(&it.source(db), &src))? - - }, - _ => { continue }, - } - }; - return Some(res); - } - - let module_source = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); - let c = Module::from_definition(db, src.with_value(module_source))?; - let res = c - .declarations(db) + let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { + Container::Trait(it) => it.items(db), + Container::ImplBlock(it) => it.items(db), + Container::Module(m) => { + return m + .declarations(db) + .into_iter() + .filter_map(|it| match it { + ModuleDef::Function(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)) + } + }; + items .into_iter() .filter_map(|it| match it { - ModuleDef::Function(it) => Some(it), + AssocItem::Function(it) => Some(it), _ => None, }) - .find(|it| same_source(&it.source(db), &src)); - res + .find(|it| same_source(&it.source(db), &src)) } } @@ -114,8 +93,27 @@ impl FromSource for Static { impl FromSource for TypeAlias { type Ast = ast::TypeAliasDef; fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source) -> Option { - let id = from_source(db, src)?; - Some(TypeAlias { id }) + let items = match Container::find(db, src.as_ref().map(|it| it.syntax()))? { + Container::Trait(it) => it.items(db), + Container::ImplBlock(it) => it.items(db), + Container::Module(m) => { + return m + .declarations(db) + .into_iter() + .filter_map(|it| match it { + ModuleDef::TypeAlias(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)) + } + }; + items + .into_iter() + .filter_map(|it| match it { + AssocItem::TypeAlias(it) => Some(it), + _ => None, + }) + .find(|it| same_source(&it.source(db), &src)) } } @@ -258,6 +256,38 @@ where Some(DEF::from_ast(ctx, &src.value)) } +enum Container { + Trait(Trait), + ImplBlock(ImplBlock), + Module(Module), +} + +impl Container { + fn find(db: &impl DefDatabase, src: Source<&SyntaxNode>) -> Option { + // FIXME: this doesn't try to handle nested declarations + for container in src.value.ancestors() { + let res = match_ast! { + match container { + ast::TraitDef(it) => { + let c = Trait::from_source(db, src.with_value(it))?; + Container::Trait(c) + }, + ast::ImplBlock(it) => { + let c = ImplBlock::from_source(db, src.with_value(it))?; + Container::ImplBlock(c) + }, + _ => { continue }, + } + }; + return Some(res); + } + + let module_source = ModuleSource::from_child_node(db, src); + let c = Module::from_definition(db, src.with_value(module_source))?; + Some(Container::Module(c)) + } +} + /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are /// equal if they point to exactly the same object. /// diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index e4ffdebe9..d6d32fb8c 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -14,13 +14,13 @@ use crate::{ CrateDefMap, }, traits::{TraitData, TraitItemsIndex}, - DefWithBodyId, EnumId, FunctionLoc, ImplId, ItemLoc, ModuleId, StructOrUnionId, TraitId, + DefWithBodyId, EnumId, ImplId, ItemLoc, ModuleId, StructOrUnionId, TraitId, }; #[salsa::query_group(InternDatabaseStorage)] pub trait InternDatabase: SourceDatabase { #[salsa::interned] - fn intern_function(&self, loc: FunctionLoc) -> crate::FunctionId; + fn intern_function(&self, loc: crate::FunctionLoc) -> crate::FunctionId; #[salsa::interned] fn intern_struct_or_union(&self, loc: ItemLoc) -> crate::StructOrUnionId; #[salsa::interned] @@ -32,7 +32,7 @@ pub trait InternDatabase: SourceDatabase { #[salsa::interned] fn intern_trait(&self, loc: ItemLoc) -> crate::TraitId; #[salsa::interned] - fn intern_type_alias(&self, loc: ItemLoc) -> crate::TypeAliasId; + fn intern_type_alias(&self, loc: crate::TypeAliasLoc) -> crate::TypeAliasId; #[salsa::interned] fn intern_impl(&self, loc: ItemLoc) -> crate::ImplId; } diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 11dd2a948..17a5d5f43 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -72,7 +72,7 @@ impl GenericParams { let self_param = TypeRef::Path(name::SELF_TYPE.into()); generics.fill_bounds(&it.source(db).value, self_param); } - GenericDefId::TypeAliasId(it) => generics.fill(&it.source(db).value, start), + GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value, start), // Note that we don't add `Self` here: in `impl`s, `Self` is not a // type-parameter, but rather is a type-alias for impl's target // type, so this is handled by the resolver. diff --git a/crates/ra_hir_def/src/impls.rs b/crates/ra_hir_def/src/impls.rs index 9be38c5e1..703e4d503 100644 --- a/crates/ra_hir_def/src/impls.rs +++ b/crates/ra_hir_def/src/impls.rs @@ -10,7 +10,7 @@ use ra_syntax::ast; use crate::{ db::DefDatabase2, type_ref::TypeRef, AssocItemId, AstItemDef, ConstId, FunctionContainerId, - FunctionLoc, ImplId, Intern, LocationCtx, TypeAliasId, + FunctionLoc, ImplId, Intern, LocationCtx, TypeAliasContainerId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -36,18 +36,23 @@ impl ImplData { .impl_items() .map(|item_node| match item_node { ast::ImplItem::FnDef(it) => { - let func_id = FunctionLoc { + let def = FunctionLoc { container: FunctionContainerId::ImplId(id), ast_id: AstId::new(src.file_id, items.ast_id(&it)), } .intern(db); - func_id.into() + def.into() } ast::ImplItem::ConstDef(it) => { ConstId::from_ast_id(ctx, items.ast_id(&it)).into() } ast::ImplItem::TypeAliasDef(it) => { - TypeAliasId::from_ast_id(ctx, items.ast_id(&it)).into() + let def = TypeAliasLoc { + container: TypeAliasContainerId::ImplId(id), + ast_id: AstId::new(src.file_id, items.ast_id(&it)), + } + .intern(db); + def.into() } }) .collect() diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index b9a13776f..6052370b4 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -332,15 +332,34 @@ impl AstItemDef for TraitId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TypeAliasId(salsa::InternId); impl_intern_key!(TypeAliasId); -impl AstItemDef for TypeAliasId { - fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { - db.intern_type_alias(loc) + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct TypeAliasLoc { + pub container: TypeAliasContainerId, + pub ast_id: AstId, +} + +impl Intern for TypeAliasLoc { + type ID = TypeAliasId; + fn intern(self, db: &impl db::DefDatabase2) -> TypeAliasId { + db.intern_type_alias(self) } - fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { - db.lookup_intern_type_alias(self) +} + +impl Lookup for TypeAliasId { + type Data = TypeAliasLoc; + fn lookup(&self, db: &impl db::DefDatabase2) -> TypeAliasLoc { + db.lookup_intern_type_alias(*self) } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum TypeAliasContainerId { + ModuleId(ModuleId), + ImplId(ImplId), + TraitId(TraitId), +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ImplId(salsa::InternId); impl_intern_key!(ImplId); @@ -476,6 +495,16 @@ impl HasModule for FunctionLoc { } } +impl HasModule for TypeAliasLoc { + fn module(&self, db: &impl db::DefDatabase2) -> ModuleId { + match self.container { + TypeAliasContainerId::ModuleId(it) => it, + TypeAliasContainerId::ImplId(it) => it.module(db), + TypeAliasContainerId::TraitId(it) => it.module(db), + } + } +} + pub trait HasSource { type Value; fn source(&self, db: &impl db::DefDatabase2) -> Source; @@ -489,3 +518,12 @@ impl HasSource for FunctionLoc { Source::new(self.ast_id.file_id(), node) } } + +impl HasSource for TypeAliasLoc { + type Value = ast::TypeAliasDef; + + fn source(&self, db: &impl db::DefDatabase2) -> Source { + let node = self.ast_id.to_node(db); + Source::new(self.ast_id.file_id(), node) + } +} diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index d2ed94a87..060185b61 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -21,7 +21,7 @@ use crate::{ path::{Path, PathKind}, AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionContainerId, FunctionLoc, ImplId, Intern, LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, - StructOrUnionId, TraitId, TypeAliasId, UnionId, + StructOrUnionId, TraitId, TypeAliasContainerId, TypeAliasLoc, UnionId, }; pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap { @@ -673,13 +673,13 @@ where let name = def.name.clone(); let def: PerNs = match def.kind { raw::DefKind::Function(ast_id) => { - let f = FunctionLoc { + let def = FunctionLoc { container: FunctionContainerId::ModuleId(module), ast_id: AstId::new(self.file_id, ast_id), } .intern(self.def_collector.db); - PerNs::values(f.into()) + PerNs::values(def.into()) } raw::DefKind::Struct(ast_id) => { let id = StructOrUnionId::from_ast_id(ctx, ast_id).into(); @@ -698,7 +698,13 @@ where } raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()), raw::DefKind::TypeAlias(ast_id) => { - PerNs::types(TypeAliasId::from_ast_id(ctx, ast_id).into()) + let def = TypeAliasLoc { + container: TypeAliasContainerId::ModuleId(module), + ast_id: AstId::new(self.file_id, ast_id), + } + .intern(self.def_collector.db); + + PerNs::types(def.into()) } }; let resolution = Resolution { def, import: None }; diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs index 6e36bc0d0..228524a57 100644 --- a/crates/ra_hir_def/src/traits.rs +++ b/crates/ra_hir_def/src/traits.rs @@ -12,7 +12,7 @@ use rustc_hash::FxHashMap; use crate::{ db::DefDatabase2, AssocItemId, AstItemDef, ConstId, FunctionContainerId, FunctionLoc, Intern, - LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasId, + LocationCtx, ModuleDefId, ModuleId, TraitId, TypeAliasContainerId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -41,7 +41,12 @@ impl TraitData { .intern(db) .into(), ast::ImplItem::ConstDef(it) => ConstId::from_ast(ctx, &it).into(), - ast::ImplItem::TypeAliasDef(it) => TypeAliasId::from_ast(ctx, &it).into(), + ast::ImplItem::TypeAliasDef(it) => TypeAliasLoc { + container: TypeAliasContainerId::TraitId(tr), + ast_id: AstId::new(src.file_id, ast_id_map.ast_id(&it)), + } + .intern(db) + .into(), }) .collect() } else { @@ -65,6 +70,7 @@ impl TraitItemsIndex { for item in db.trait_data(tr).items.iter() { match item { AssocItemId::FunctionId(_) => (), + AssocItemId::TypeAliasId(_) => (), _ => { let prev = index.traits_by_def.insert(*item, tr); assert!(prev.is_none()); -- cgit v1.2.3