From 00303c3b679613ff0a0741ea6d2bdaa5e3ff9924 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 10 Feb 2024 11:37:59 +0100 Subject: [PATCH] Abstract over ItemTreeLoc --- crates/hir-def/src/attr.rs | 52 +++++--------- crates/hir-def/src/child_by_source.rs | 56 +++++---------- crates/hir-def/src/generics.rs | 6 +- crates/hir-def/src/item_tree.rs | 47 ++++++------- crates/hir-def/src/item_tree/lower.rs | 4 +- crates/hir-def/src/lib.rs | 93 ++++++++++++++++++------- crates/hir-def/src/nameres/collector.rs | 4 +- crates/hir-def/src/src.rs | 90 ++++-------------------- crates/hir-ty/src/display.rs | 9 ++- crates/hir-ty/src/lower.rs | 9 ++- crates/hir/src/lib.rs | 19 +++-- 11 files changed, 160 insertions(+), 229 deletions(-) diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs index 2b352e2455..85c0542ad3 100644 --- a/crates/hir-def/src/attr.rs +++ b/crates/hir-def/src/attr.rs @@ -24,12 +24,11 @@ use triomphe::Arc; use crate::{ db::DefDatabase, - item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeModItemNode}, + item_tree::{AttrOwner, Fields, ItemTreeNode}, lang_item::LangItem, nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource}, - AdtId, AssocItemLoc, AttrDefId, GenericParamId, ItemLoc, LocalFieldId, Lookup, MacroId, - VariantId, + AdtId, AttrDefId, GenericParamId, ItemTreeLoc, LocalFieldId, Lookup, MacroId, VariantId, }; /// Desugared attributes of an item post `cfg_attr` expansion. @@ -356,11 +355,7 @@ impl AttrsWithOwner { AttrDefId::FieldId(it) => { return db.fields_attrs(it.parent)[it.local_id].clone(); } - AttrDefId::EnumVariantId(it) => { - let id = it.lookup(db).id; - let tree = id.item_tree(db); - tree.raw_attrs(id.value.into()).clone() - } + AttrDefId::EnumVariantId(it) => attrs_from_item_tree_loc(db, it), AttrDefId::AdtId(it) => match it { AdtId::StructId(it) => attrs_from_item_tree_loc(db, it), AdtId::EnumId(it) => attrs_from_item_tree_loc(db, it), @@ -369,15 +364,15 @@ impl AttrsWithOwner { AttrDefId::TraitId(it) => attrs_from_item_tree_loc(db, it), AttrDefId::TraitAliasId(it) => attrs_from_item_tree_loc(db, it), AttrDefId::MacroId(it) => match it { - MacroId::Macro2Id(it) => attrs_from_item_tree(db, it.lookup(db).id), - MacroId::MacroRulesId(it) => attrs_from_item_tree(db, it.lookup(db).id), - MacroId::ProcMacroId(it) => attrs_from_item_tree(db, it.lookup(db).id), + MacroId::Macro2Id(it) => attrs_from_item_tree_loc(db, it), + MacroId::MacroRulesId(it) => attrs_from_item_tree_loc(db, it), + MacroId::ProcMacroId(it) => attrs_from_item_tree_loc(db, it), }, AttrDefId::ImplId(it) => attrs_from_item_tree_loc(db, it), - AttrDefId::ConstId(it) => attrs_from_item_tree_assoc(db, it), - AttrDefId::StaticId(it) => attrs_from_item_tree_assoc(db, it), - AttrDefId::FunctionId(it) => attrs_from_item_tree_assoc(db, it), - AttrDefId::TypeAliasId(it) => attrs_from_item_tree_assoc(db, it), + AttrDefId::ConstId(it) => attrs_from_item_tree_loc(db, it), + AttrDefId::StaticId(it) => attrs_from_item_tree_loc(db, it), + AttrDefId::FunctionId(it) => attrs_from_item_tree_loc(db, it), + AttrDefId::TypeAliasId(it) => attrs_from_item_tree_loc(db, it), AttrDefId::GenericParamId(it) => match it { GenericParamId::ConstParamId(it) => { let src = it.parent().child_source(db); @@ -602,29 +597,14 @@ fn any_has_attrs<'db>( id.lookup(db).source(db).map(ast::AnyHasAttrs::new) } -fn attrs_from_item_tree( - db: &dyn DefDatabase, - id: ItemTreeId, +fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>( + db: &(dyn DefDatabase + 'db), + lookup: impl Lookup = dyn DefDatabase + 'db, Data = impl ItemTreeLoc>, ) -> RawAttrs { + let id = lookup.lookup(db).item_tree_id(); let tree = id.item_tree(db); - let mod_item = N::id_to_mod_item(id.value); - tree.raw_attrs(mod_item.into()).clone() -} - -fn attrs_from_item_tree_loc<'db, N: ItemTreeModItemNode>( - db: &(dyn DefDatabase + 'db), - lookup: impl Lookup = dyn DefDatabase + 'db, Data = ItemLoc>, -) -> RawAttrs { - let id = lookup.lookup(db).id; - attrs_from_item_tree(db, id) -} - -fn attrs_from_item_tree_assoc<'db, N: ItemTreeModItemNode>( - db: &(dyn DefDatabase + 'db), - lookup: impl Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc>, -) -> RawAttrs { - let id = lookup.lookup(db).id; - attrs_from_item_tree(db, id) + let attr_owner = N::attr_owner(id.value); + tree.raw_attrs(attr_owner).clone() } pub(crate) fn fields_attrs_source_map( diff --git a/crates/hir-def/src/child_by_source.rs b/crates/hir-def/src/child_by_source.rs index e44f7c1b56..5efa3e8d9e 100644 --- a/crates/hir-def/src/child_by_source.rs +++ b/crates/hir-def/src/child_by_source.rs @@ -14,11 +14,11 @@ use crate::{ DynMap, }, item_scope::ItemScope, - item_tree::ItemTreeModItemNode, + item_tree::ItemTreeNode, nameres::DefMap, src::{HasChildSource, HasSource}, - AdtId, AssocItemId, AssocItemLoc, DefWithBodyId, EnumId, FieldId, ImplId, ItemLoc, Lookup, - MacroId, ModuleDefId, ModuleId, TraitId, VariantId, + AdtId, AssocItemId, DefWithBodyId, EnumId, FieldId, ImplId, ItemTreeLoc, Lookup, MacroId, + ModuleDefId, ModuleId, TraitId, VariantId, }; pub trait ChildBySource { @@ -61,13 +61,9 @@ impl ChildBySource for ImplId { fn add_assoc_item(db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId, item: AssocItemId) { match item { - AssocItemId::FunctionId(func) => { - insert_assoc_item_loc(db, res, file_id, func, keys::FUNCTION) - } - AssocItemId::ConstId(konst) => insert_assoc_item_loc(db, res, file_id, konst, keys::CONST), - AssocItemId::TypeAliasId(ty) => { - insert_assoc_item_loc(db, res, file_id, ty, keys::TYPE_ALIAS) - } + AssocItemId::FunctionId(func) => insert_item_loc(db, res, file_id, func, keys::FUNCTION), + AssocItemId::ConstId(konst) => insert_item_loc(db, res, file_id, konst, keys::CONST), + AssocItemId::TypeAliasId(ty) => insert_item_loc(db, res, file_id, ty, keys::TYPE_ALIAS), } } @@ -87,7 +83,7 @@ impl ChildBySource for ItemScope { .for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::EXTERN_CRATE)); self.use_decls().for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::USE)); self.unnamed_consts(db) - .for_each(|konst| insert_assoc_item_loc(db, res, file_id, konst, keys::CONST)); + .for_each(|konst| insert_item_loc(db, res, file_id, konst, keys::CONST)); self.attr_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each( |(ast_id, call_id)| { res[keys::ATTR_MACRO_CALL].insert(ast_id.to_node(db.upcast()), call_id); @@ -132,17 +128,13 @@ impl ChildBySource for ItemScope { } match item { ModuleDefId::FunctionId(id) => { - insert_assoc_item_loc(db, map, file_id, id, keys::FUNCTION) - } - ModuleDefId::ConstId(id) => { - insert_assoc_item_loc(db, map, file_id, id, keys::CONST) + insert_item_loc(db, map, file_id, id, keys::FUNCTION) } + ModuleDefId::ConstId(id) => insert_item_loc(db, map, file_id, id, keys::CONST), ModuleDefId::TypeAliasId(id) => { - insert_assoc_item_loc(db, map, file_id, id, keys::TYPE_ALIAS) - } - ModuleDefId::StaticId(id) => { - insert_assoc_item_loc(db, map, file_id, id, keys::STATIC) + insert_item_loc(db, map, file_id, id, keys::TYPE_ALIAS) } + ModuleDefId::StaticId(id) => insert_item_loc(db, map, file_id, id, keys::STATIC), ModuleDefId::TraitId(id) => insert_item_loc(db, map, file_id, id, keys::TRAIT), ModuleDefId::TraitAliasId(id) => { insert_item_loc(db, map, file_id, id, keys::TRAIT_ALIAS) @@ -215,36 +207,20 @@ impl ChildBySource for DefWithBodyId { } } -fn insert_item_loc( +fn insert_item_loc( db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId, id: ID, key: Key, ) where - ID: for<'db> Lookup = dyn DefDatabase + 'db, Data = ItemLoc> + 'static, - N: ItemTreeModItemNode, + ID: for<'db> Lookup = dyn DefDatabase + 'db, Data = Data> + 'static, + Data: ItemTreeLoc, + N: ItemTreeNode, N::Source: 'static, { let loc = id.lookup(db); - if loc.id.file_id() == file_id { - res[key].insert(loc.source(db).value, id) - } -} - -fn insert_assoc_item_loc( - db: &dyn DefDatabase, - res: &mut DynMap, - file_id: HirFileId, - id: ID, - key: Key, -) where - ID: for<'db> Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc> + 'static, - N: ItemTreeModItemNode, - N::Source: 'static, -{ - let loc = id.lookup(db); - if loc.id.file_id() == file_id { + if loc.item_tree_id().file_id() == file_id { res[key].insert(loc.source(db).value, id) } } diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs index d11c397091..0edd5e6168 100644 --- a/crates/hir-def/src/generics.rs +++ b/crates/hir-def/src/generics.rs @@ -21,13 +21,13 @@ use crate::{ db::DefDatabase, dyn_map::{keys, DynMap}, expander::Expander, - item_tree::{ItemTree, ItemTreeModItemNode}, + item_tree::ItemTree, lower::LowerCtx, nameres::{DefMap, MacroSubNs}, src::{HasChildSource, HasSource}, type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef}, - AdtId, AssocItemLoc, ConstParamId, GenericDefId, HasModule, ItemLoc, LifetimeParamId, - LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId, + AdtId, ConstParamId, GenericDefId, HasModule, LifetimeParamId, LocalLifetimeParamId, + LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId, }; /// Data about a generic type parameter (to a function, struct, impl, ...). diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 27c5f14b7d..96b606ec1d 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -337,20 +337,15 @@ from_attrs!( LifetimeParamData(Idx), ); -/// Trait implemented by all item nodes in the item tree. -pub trait ItemTreeModItemNode: Clone { - type Source: AstIdNode + Into; +/// Trait implemented by all nodes in the item tree. +pub trait ItemTreeNode: Clone { + type Source: AstIdNode; fn ast_id(&self) -> FileAstId; /// Looks up an instance of `Self` in an item tree. fn lookup(tree: &ItemTree, index: Idx) -> &Self; - - /// Downcasts a `ModItem` to a `FileItemTreeId` specific to this type. - fn id_from_mod_item(mod_item: ModItem) -> Option>; - - /// Upcasts a `FileItemTreeId` to a generic `ModItem`. - fn id_to_mod_item(id: FileItemTreeId) -> ModItem; + fn attr_owner(id: FileItemTreeId) -> AttrOwner; } pub struct FileItemTreeId(Idx); @@ -495,7 +490,7 @@ macro_rules! mod_items { )+ $( - impl ItemTreeModItemNode for $typ { + impl ItemTreeNode for $typ { type Source = $ast; fn ast_id(&self) -> FileAstId { @@ -506,15 +501,8 @@ macro_rules! mod_items { &tree.data().$fld[index] } - fn id_from_mod_item(mod_item: ModItem) -> Option> { - match mod_item { - ModItem::$typ(id) => Some(id), - _ => None, - } - } - - fn id_to_mod_item(id: FileItemTreeId) -> ModItem { - ModItem::$typ(id) + fn attr_owner(id: FileItemTreeId) -> AttrOwner { + AttrOwner::ModItem(ModItem::$typ(id)) } } @@ -578,17 +566,26 @@ impl Index for ItemTree { } } -impl Index> for ItemTree { +impl Index> for ItemTree { type Output = N; fn index(&self, id: FileItemTreeId) -> &N { N::lookup(self, id.index()) } } -impl Index> for ItemTree { - type Output = Variant; - fn index(&self, id: FileItemTreeId) -> &Variant { - &self[id.index()] +impl ItemTreeNode for Variant { + type Source = ast::Variant; + + fn ast_id(&self) -> FileAstId { + self.ast_id + } + + fn lookup(tree: &ItemTree, index: Idx) -> &Self { + &tree.data().variants[index] + } + + fn attr_owner(id: FileItemTreeId) -> AttrOwner { + AttrOwner::Variant(id) } } @@ -1027,7 +1024,7 @@ impl AssocItem { } } -#[derive(Debug, Eq, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Variant { pub name: Name, pub fields: Fields, diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index b500f56b6c..1cc8158909 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -13,7 +13,7 @@ use crate::{ use super::*; -fn id(index: Idx) -> FileItemTreeId { +fn id(index: Idx) -> FileItemTreeId { FileItemTreeId(index) } @@ -267,7 +267,7 @@ impl<'a> Ctx<'a> { if let Some(data) = self.lower_variant(&variant) { let idx = self.data().variants.alloc(data); self.add_attrs( - FileItemTreeId(idx).into(), + id(idx).into(), RawAttrs::new(self.db.upcast(), &variant, self.span_map()), ); } diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 16e2f0532e..df1f61ae5f 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -98,8 +98,8 @@ use crate::{ data::adt::VariantData, db::DefDatabase, item_tree::{ - Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeModItemNode, Macro2, - MacroRules, Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant, + Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, Macro2, MacroRules, + Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant, }, }; @@ -212,28 +212,28 @@ impl ModuleId { pub type LocalModuleId = Idx; #[derive(Debug)] -pub struct ItemLoc { +pub struct ItemLoc { pub container: ModuleId, pub id: ItemTreeId, } -impl Clone for ItemLoc { +impl Clone for ItemLoc { fn clone(&self) -> Self { *self } } -impl Copy for ItemLoc {} +impl Copy for ItemLoc {} -impl PartialEq for ItemLoc { +impl PartialEq for ItemLoc { fn eq(&self, other: &Self) -> bool { self.container == other.container && self.id == other.id } } -impl Eq for ItemLoc {} +impl Eq for ItemLoc {} -impl Hash for ItemLoc { +impl Hash for ItemLoc { fn hash(&self, state: &mut H) { self.container.hash(state); self.id.hash(state); @@ -241,34 +241,41 @@ impl Hash for ItemLoc { } #[derive(Debug)] -pub struct AssocItemLoc { +pub struct AssocItemLoc { pub container: ItemContainerId, pub id: ItemTreeId, } -impl Clone for AssocItemLoc { +impl Clone for AssocItemLoc { fn clone(&self) -> Self { *self } } -impl Copy for AssocItemLoc {} +impl Copy for AssocItemLoc {} -impl PartialEq for AssocItemLoc { +impl PartialEq for AssocItemLoc { fn eq(&self, other: &Self) -> bool { self.container == other.container && self.id == other.id } } -impl Eq for AssocItemLoc {} +impl Eq for AssocItemLoc {} -impl Hash for AssocItemLoc { +impl Hash for AssocItemLoc { fn hash(&self, state: &mut H) { self.container.hash(state); self.id.hash(state); } } +pub trait ItemTreeLoc { + type Container; + type Id; + fn item_tree_id(&self) -> ItemTreeId; + fn container(&self) -> Self::Container; +} + macro_rules! impl_intern { ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => { impl_intern_key!($id); @@ -276,25 +283,44 @@ macro_rules! impl_intern { }; } +macro_rules! impl_loc { + ($loc:ident, $id:ident: $id_ty:ident, $container:ident: $container_type:ident) => { + impl ItemTreeLoc for $loc { + type Container = $container_type; + type Id = $id_ty; + fn item_tree_id(&self) -> ItemTreeId { + self.$id + } + fn container(&self) -> Self::Container { + self.$container + } + } + }; +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct FunctionId(salsa::InternId); type FunctionLoc = AssocItemLoc; impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); +impl_loc!(FunctionLoc, id: Function, container: ItemContainerId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct StructId(salsa::InternId); type StructLoc = ItemLoc; impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); +impl_loc!(StructLoc, id: Struct, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct UnionId(salsa::InternId); pub type UnionLoc = ItemLoc; impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); +impl_loc!(UnionLoc, id: Union, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct EnumId(salsa::InternId); pub type EnumLoc = ItemLoc; impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); +impl_loc!(EnumLoc, id: Enum, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct EnumVariantId(salsa::InternId); @@ -306,6 +332,7 @@ pub struct EnumVariantLoc { pub index: u32, } impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant); +impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct FieldId { @@ -328,46 +355,55 @@ pub struct TupleFieldId { pub struct ConstId(salsa::InternId); type ConstLoc = AssocItemLoc; impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); +impl_loc!(ConstLoc, id: Const, container: ItemContainerId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StaticId(salsa::InternId); pub type StaticLoc = AssocItemLoc; impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); +impl_loc!(StaticLoc, id: Static, container: ItemContainerId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TraitId(salsa::InternId); pub type TraitLoc = ItemLoc; impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait); +impl_loc!(TraitLoc, id: Trait, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TraitAliasId(salsa::InternId); pub type TraitAliasLoc = ItemLoc; impl_intern!(TraitAliasId, TraitAliasLoc, intern_trait_alias, lookup_intern_trait_alias); +impl_loc!(TraitAliasLoc, id: TraitAlias, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TypeAliasId(salsa::InternId); type TypeAliasLoc = AssocItemLoc; impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias); +impl_loc!(TypeAliasLoc, id: TypeAlias, container: ItemContainerId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct ImplId(salsa::InternId); type ImplLoc = ItemLoc; impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); +impl_loc!(ImplLoc, id: Impl, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct UseId(salsa::InternId); type UseLoc = ItemLoc; impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use); +impl_loc!(UseLoc, id: Use, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct ExternCrateId(salsa::InternId); type ExternCrateLoc = ItemLoc; impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate); +impl_loc!(ExternCrateLoc, id: ExternCrate, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct ExternBlockId(salsa::InternId); type ExternBlockLoc = ItemLoc; impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block); +impl_loc!(ExternBlockLoc, id: ExternBlock, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum MacroExpander { @@ -389,6 +425,7 @@ pub struct Macro2Loc { pub edition: Edition, } impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2); +impl_loc!(Macro2Loc, id: Macro2, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct MacroRulesId(salsa::InternId); @@ -401,6 +438,7 @@ pub struct MacroRulesLoc { pub edition: Edition, } impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules); +impl_loc!(MacroRulesLoc, id: MacroRules, container: ModuleId); bitflags::bitflags! { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -421,6 +459,7 @@ pub struct ProcMacroLoc { pub edition: Edition, } impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro); +impl_loc!(ProcMacroLoc, id: Function, container: CrateRootModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct BlockId(salsa::InternId); @@ -996,16 +1035,23 @@ pub trait HasModule { } } -impl HasModule for AssocItemLoc { - #[inline] - fn module(&self, db: &dyn DefDatabase) -> ModuleId { - self.container.module(db) - } -} +// In theory this impl should work out for us, but rustc thinks it collides with all the other +// manual impls that do not have a ModuleId container... +// impl HasModule for ItemId +// where +// N: ItemTreeNode, +// ItemId: for<'db> Lookup = dyn DefDatabase + 'db, Data = Data> + Copy, +// Data: ItemTreeLoc, +// { +// #[inline] +// fn module(&self, db: &dyn DefDatabase) -> ModuleId { +// self.lookup(db).container() +// } +// } impl HasModule for ItemId where - N: ItemTreeModItemNode, + N: ItemTreeNode, ItemId: for<'db> Lookup = dyn DefDatabase + 'db, Data = ItemLoc> + Copy, { #[inline] @@ -1031,10 +1077,7 @@ where #[inline] fn module_for_assoc_item_loc<'db>( db: &(dyn 'db + DefDatabase), - id: impl Lookup< - Database<'db> = dyn DefDatabase + 'db, - Data = AssocItemLoc, - >, + id: impl Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc>, ) -> ModuleId { id.lookup(db).container.module(db) } diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 49d59cf9ad..21cc28f1b3 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -33,8 +33,8 @@ use crate::{ db::DefDatabase, item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports}, item_tree::{ - self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, - ItemTreeModItemNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, + self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode, + Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, }, macro_call_as_call_id, macro_call_as_call_id_with_eager, nameres::{ diff --git a/crates/hir-def/src/src.rs b/crates/hir-def/src/src.rs index 9bd8c8d221..d820456b92 100644 --- a/crates/hir-def/src/src.rs +++ b/crates/hir-def/src/src.rs @@ -4,91 +4,29 @@ use hir_expand::InFile; use la_arena::ArenaMap; use syntax::ast; -use crate::{ - db::DefDatabase, item_tree::ItemTreeModItemNode, AssocItemLoc, EnumVariantLoc, ItemLoc, Lookup, - Macro2Loc, MacroRulesLoc, ProcMacroLoc, UseId, -}; +use crate::{db::DefDatabase, item_tree::ItemTreeNode, ItemTreeLoc, Lookup, UseId}; pub trait HasSource { type Value; fn source(&self, db: &dyn DefDatabase) -> InFile; } -impl HasSource for AssocItemLoc { - type Value = N::Source; - - fn source(&self, db: &dyn DefDatabase) -> InFile { - let tree = self.id.item_tree(db); - let ast_id_map = db.ast_id_map(self.id.file_id()); - let root = db.parse_or_expand(self.id.file_id()); - let node = &tree[self.id.value]; - - InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root)) - } -} - -impl HasSource for ItemLoc { - type Value = N::Source; - - fn source(&self, db: &dyn DefDatabase) -> InFile { - let tree = self.id.item_tree(db); - let ast_id_map = db.ast_id_map(self.id.file_id()); - let root = db.parse_or_expand(self.id.file_id()); - let node = &tree[self.id.value]; - - InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root)) - } -} - -impl HasSource for EnumVariantLoc { - type Value = ast::Variant; - - fn source(&self, db: &dyn DefDatabase) -> InFile { - let tree = self.id.item_tree(db); - let ast_id_map = db.ast_id_map(self.id.file_id()); - let root = db.parse_or_expand(self.id.file_id()); - let node = &tree[self.id.value]; - - InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id).to_node(&root)) - } -} - -impl HasSource for Macro2Loc { - type Value = ast::MacroDef; +impl HasSource for T +where + T: ItemTreeLoc, + T::Id: ItemTreeNode, +{ + type Value = ::Source; fn source(&self, db: &dyn DefDatabase) -> InFile { - let tree = self.id.item_tree(db); - let ast_id_map = db.ast_id_map(self.id.file_id()); - let root = db.parse_or_expand(self.id.file_id()); - let node = &tree[self.id.value]; + let id = self.item_tree_id(); + let file_id = id.file_id(); + let tree = id.item_tree(db); + let ast_id_map = db.ast_id_map(file_id); + let root = db.parse_or_expand(file_id); + let node = &tree[id.value]; - InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root)) - } -} - -impl HasSource for MacroRulesLoc { - type Value = ast::MacroRules; - - fn source(&self, db: &dyn DefDatabase) -> InFile { - let tree = self.id.item_tree(db); - let ast_id_map = db.ast_id_map(self.id.file_id()); - let root = db.parse_or_expand(self.id.file_id()); - let node = &tree[self.id.value]; - - InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root)) - } -} - -impl HasSource for ProcMacroLoc { - type Value = ast::Fn; - - fn source(&self, db: &dyn DefDatabase) -> InFile { - let tree = self.id.item_tree(db); - let ast_id_map = db.ast_id_map(self.id.file_id()); - let root = db.parse_or_expand(self.id.file_id()); - let node = &tree[self.id.value]; - - InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root)) + InFile::new(file_id, ast_id_map.get(node.ast_id()).to_node(&root)) } } diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 2327c8df1b..a57149ea60 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -814,9 +814,8 @@ impl HirDisplay for Ty { // Don't count Sized but count when it absent // (i.e. when explicit ?Sized bound is set). - let default_sized = SizedByDefault::Sized { - anchor: func.lookup(db.upcast()).module(db.upcast()).krate(), - }; + let default_sized = + SizedByDefault::Sized { anchor: func.krate(db.upcast()) }; let sized_bounds = bounds .skip_binders() .iter() @@ -1025,7 +1024,7 @@ impl HirDisplay for Ty { let data = (*datas).as_ref().map(|rpit| rpit.impl_traits[idx].bounds.clone()); let bounds = data.substitute(Interner, ¶meters); - let krate = func.lookup(db.upcast()).module(db.upcast()).krate(); + let krate = func.krate(db.upcast()); write_bounds_like_dyn_trait_with_prefix( f, "impl", @@ -1191,7 +1190,7 @@ impl HirDisplay for Ty { let data = (*datas).as_ref().map(|rpit| rpit.impl_traits[idx].bounds.clone()); let bounds = data.substitute(Interner, &opaque_ty.substitution); - let krate = func.lookup(db.upcast()).module(db.upcast()).krate(); + let krate = func.krate(db.upcast()); write_bounds_like_dyn_trait_with_prefix( f, "impl", diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 386a03d93f..142b954639 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -1225,7 +1225,7 @@ impl<'a> TyLoweringContext<'a> { .collect(); if !ctx.unsized_types.borrow().contains(&self_ty) { - let krate = func.lookup(ctx.db.upcast()).module(ctx.db.upcast()).krate(); + let krate = func.krate(ctx.db.upcast()); let sized_trait = ctx .db .lang_item(krate, LangItem::Sized) @@ -1824,11 +1824,10 @@ impl CallableDefId { pub fn krate(self, db: &dyn HirDatabase) -> CrateId { let db = db.upcast(); match self { - CallableDefId::FunctionId(f) => f.lookup(db).module(db), - CallableDefId::StructId(s) => s.lookup(db).container, - CallableDefId::EnumVariantId(e) => e.module(db), + CallableDefId::FunctionId(f) => f.krate(db), + CallableDefId::StructId(s) => s.krate(db), + CallableDefId::EnumVariantId(e) => e.krate(db), } - .krate() } } diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index aa1fb51fdd..1591bbc6bf 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -44,7 +44,7 @@ use hir_def::{ data::adt::VariantData, generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance}, hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat}, - item_tree::ItemTreeModItemNode, + item_tree::ItemTreeNode, lang_item::LangItemTarget, layout::{self, ReprOptions, TargetDataLayout}, nameres::{self, diagnostics::DefDiagnostic}, @@ -1768,7 +1768,7 @@ pub struct Function { impl Function { pub fn module(self, db: &dyn HirDatabase) -> Module { - self.id.lookup(db.upcast()).module(db.upcast()).into() + self.id.module(db.upcast()).into() } pub fn name(self, db: &dyn HirDatabase) -> Name { @@ -1909,8 +1909,7 @@ impl Function { { return None; } - let loc = self.id.lookup(db.upcast()); - let def_map = db.crate_def_map(HasModule::krate(&loc, db.upcast())); + let def_map = db.crate_def_map(HasModule::krate(&self.id, db.upcast())); def_map.fn_as_proc_macro(self.id).map(|id| Macro { id: id.into() }) } @@ -2119,7 +2118,7 @@ pub struct Const { impl Const { pub fn module(self, db: &dyn HirDatabase) -> Module { - Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } + Module { id: self.id.module(db.upcast()) } } pub fn name(self, db: &dyn HirDatabase) -> Option { @@ -2174,7 +2173,7 @@ pub struct Static { impl Static { pub fn module(self, db: &dyn HirDatabase) -> Module { - Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } + Module { id: self.id.module(db.upcast()) } } pub fn name(self, db: &dyn HirDatabase) -> Name { @@ -2293,7 +2292,7 @@ impl TypeAlias { } pub fn module(self, db: &dyn HirDatabase) -> Module { - Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } + Module { id: self.id.module(db.upcast()) } } pub fn type_ref(self, db: &dyn HirDatabase) -> Option { @@ -2566,15 +2565,15 @@ impl AsAssocItem for DefWithBody { } } -fn as_assoc_item<'db, ID, DEF, AST>( +fn as_assoc_item<'db, ID, DEF, LOC>( db: &(dyn HirDatabase + 'db), ctor: impl FnOnce(DEF) -> AssocItem, id: ID, ) -> Option where - ID: Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc>, + ID: Lookup = dyn DefDatabase + 'db, Data = AssocItemLoc>, DEF: From, - AST: ItemTreeModItemNode, + LOC: ItemTreeNode, { match id.lookup(db.upcast()).container { ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))),