Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir-def/src/attr.rs | 3 | ||||
| -rw-r--r-- | crates/hir-def/src/generics.rs | 37 | ||||
| -rw-r--r-- | crates/hir-def/src/item_tree.rs | 29 | ||||
| -rw-r--r-- | crates/hir-def/src/lib.rs | 370 |
4 files changed, 228 insertions, 211 deletions
diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs index 85c0542ad3..c91a549726 100644 --- a/crates/hir-def/src/attr.rs +++ b/crates/hir-def/src/attr.rs @@ -28,7 +28,8 @@ use crate::{ lang_item::LangItem, nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource}, - AdtId, AttrDefId, GenericParamId, ItemTreeLoc, LocalFieldId, Lookup, MacroId, VariantId, + AdtId, AttrDefId, GenericParamId, HasModule, ItemTreeLoc, LocalFieldId, Lookup, MacroId, + VariantId, }; /// Desugared attributes of an item post `cfg_attr` expansion. diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs index a4115d818c..1d2c7c3a55 100644 --- a/crates/hir-def/src/generics.rs +++ b/crates/hir-def/src/generics.rs @@ -18,11 +18,11 @@ use triomphe::Arc; use crate::{ db::DefDatabase, expander::Expander, - item_tree::ItemTree, + item_tree::{GenericsItemTreeNode, ItemTree}, lower::LowerCtx, nameres::{DefMap, MacroSubNs}, type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef}, - AdtId, ConstParamId, GenericDefId, HasModule, LocalTypeOrConstParamId, Lookup, + AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId, }; @@ -414,13 +414,18 @@ impl GenericParams { }) } }; - macro_rules! id_to_generics { - ($id:ident) => {{ - let id = $id.lookup(db).id; - let tree = id.item_tree(db); - let item = &tree[id.value]; - enabled_params(&item.generic_params, &tree) - }}; + fn id_to_generics<Id: GenericsItemTreeNode>( + db: &dyn DefDatabase, + id: impl for<'db> Lookup< + Database<'db> = dyn DefDatabase + 'db, + Data = impl ItemTreeLoc<Id = Id>, + >, + enabled_params: impl Fn(&Interned<GenericParams>, &ItemTree) -> Interned<GenericParams>, + ) -> Interned<GenericParams> { + let id = id.lookup(db).item_tree_id(); + let tree = id.item_tree(db); + let item = &tree[id.value]; + enabled_params(item.generic_params(), &tree) } match def { @@ -453,13 +458,13 @@ impl GenericParams { Interned::new(generic_params.finish()) } } - GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics!(id), - GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics!(id), - GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics!(id), - GenericDefId::TraitId(id) => id_to_generics!(id), - GenericDefId::TraitAliasId(id) => id_to_generics!(id), - GenericDefId::TypeAliasId(id) => id_to_generics!(id), - GenericDefId::ImplId(id) => id_to_generics!(id), + GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics(db, id, enabled_params), + GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics(db, id, enabled_params), + GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics(db, id, enabled_params), + GenericDefId::TraitId(id) => id_to_generics(db, id, enabled_params), + GenericDefId::TraitAliasId(id) => id_to_generics(db, id, enabled_params), + GenericDefId::TypeAliasId(id) => id_to_generics(db, id, enabled_params), + GenericDefId::ImplId(id) => id_to_generics(db, id, enabled_params), GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => { Interned::new(GenericParams { type_or_consts: Default::default(), diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 96b606ec1d..be16a5e31a 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -347,6 +347,9 @@ pub trait ItemTreeNode: Clone { fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self; fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner; } +pub trait GenericsItemTreeNode: ItemTreeNode { + fn generic_params(&self) -> &Interned<GenericParams>; +} pub struct FileItemTreeId<N>(Idx<N>); @@ -473,7 +476,7 @@ impl<N> Hash for ItemTreeId<N> { } macro_rules! mod_items { - ( $( $typ:ident in $fld:ident -> $ast:ty ),+ $(,)? ) => { + ( $( $typ:ident $(<$generic_params:ident>)? in $fld:ident -> $ast:ty ),+ $(,)? ) => { #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum ModItem { $( @@ -513,6 +516,14 @@ macro_rules! mod_items { &self.data().$fld[index] } } + + $( + impl GenericsItemTreeNode for $typ { + fn generic_params(&self) -> &Interned<GenericParams> { + &self.$generic_params + } + } + )? )+ }; } @@ -521,16 +532,16 @@ mod_items! { Use in uses -> ast::Use, ExternCrate in extern_crates -> ast::ExternCrate, ExternBlock in extern_blocks -> ast::ExternBlock, - Function in functions -> ast::Fn, - Struct in structs -> ast::Struct, - Union in unions -> ast::Union, - Enum in enums -> ast::Enum, + Function<explicit_generic_params> in functions -> ast::Fn, + Struct<generic_params> in structs -> ast::Struct, + Union<generic_params> in unions -> ast::Union, + Enum<generic_params> in enums -> ast::Enum, Const in consts -> ast::Const, Static in statics -> ast::Static, - Trait in traits -> ast::Trait, - TraitAlias in trait_aliases -> ast::TraitAlias, - Impl in impls -> ast::Impl, - TypeAlias in type_aliases -> ast::TypeAlias, + Trait<generic_params> in traits -> ast::Trait, + TraitAlias<generic_params> in trait_aliases -> ast::TraitAlias, + Impl<generic_params> in impls -> ast::Impl, + TypeAlias<generic_params> in type_aliases -> ast::TypeAlias, Mod in mods -> ast::Module, MacroCall in macro_calls -> ast::MacroCall, MacroRules in macro_rules -> ast::MacroRules, diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index c3564ca480..589e57cb6b 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -103,114 +103,6 @@ use crate::{ }, }; -/// A `ModuleId` that is always a crate's root module. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct CrateRootModuleId { - krate: CrateId, -} - -impl CrateRootModuleId { - pub fn def_map(&self, db: &dyn DefDatabase) -> Arc<DefMap> { - db.crate_def_map(self.krate) - } - - pub fn krate(self) -> CrateId { - self.krate - } -} - -impl PartialEq<ModuleId> for CrateRootModuleId { - fn eq(&self, other: &ModuleId) -> bool { - other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate - } -} -impl PartialEq<CrateRootModuleId> for ModuleId { - fn eq(&self, other: &CrateRootModuleId) -> bool { - other == self - } -} - -impl From<CrateRootModuleId> for ModuleId { - fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self { - ModuleId { krate, block: None, local_id: DefMap::ROOT } - } -} - -impl From<CrateRootModuleId> for ModuleDefId { - fn from(value: CrateRootModuleId) -> Self { - ModuleDefId::ModuleId(value.into()) - } -} - -impl From<CrateId> for CrateRootModuleId { - fn from(krate: CrateId) -> Self { - CrateRootModuleId { krate } - } -} - -impl TryFrom<ModuleId> for CrateRootModuleId { - type Error = (); - - fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result<Self, Self::Error> { - if block.is_none() && local_id == DefMap::ROOT { - Ok(CrateRootModuleId { krate }) - } else { - Err(()) - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct ModuleId { - krate: CrateId, - /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the - /// `BlockId` of that block expression. If `None`, this module is part of the crate-level - /// `DefMap` of `krate`. - block: Option<BlockId>, - /// The module's ID in its originating `DefMap`. - pub local_id: LocalModuleId, -} - -impl ModuleId { - pub fn def_map(self, db: &dyn DefDatabase) -> Arc<DefMap> { - match self.block { - Some(block) => db.block_def_map(block), - None => db.crate_def_map(self.krate), - } - } - - pub fn krate(self) -> CrateId { - self.krate - } - - pub fn name(self, db: &dyn DefDatabase) -> Option<Name> { - let def_map = self.def_map(db); - let parent = def_map[self.local_id].parent?; - def_map[parent].children.iter().find_map(|(name, module_id)| { - if *module_id == self.local_id { - Some(name.clone()) - } else { - None - } - }) - } - - pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> { - self.def_map(db).containing_module(self.local_id) - } - - pub fn containing_block(self) -> Option<BlockId> { - self.block - } - - pub fn is_block_module(self) -> bool { - self.block.is_some() && self.local_id == DefMap::ROOT - } -} - -/// An ID of a module, **local** to a `DefMap`. -pub type LocalModuleId = Idx<nameres::ModuleData>; - #[derive(Debug)] pub struct ItemLoc<N: ItemTreeNode> { pub container: ModuleId, @@ -323,35 +215,6 @@ 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); - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct EnumVariantLoc { - pub id: ItemTreeId<Variant>, - pub parent: EnumId, - 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 { - pub parent: VariantId, - pub local_id: LocalFieldId, -} - -pub type LocalFieldId = Idx<data::adt::FieldData>; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TupleId(pub u32); - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TupleFieldId { - pub tuple: TupleId, - pub index: u32, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ConstId(salsa::InternId); type ConstLoc = AssocItemLoc<Const>; impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); @@ -406,13 +269,16 @@ impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_e impl_loc!(ExternBlockLoc, id: ExternBlock, container: ModuleId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum MacroExpander { - Declarative, - BuiltIn(BuiltinFnLikeExpander), - BuiltInAttr(BuiltinAttrExpander), - BuiltInDerive(BuiltinDeriveExpander), - BuiltInEager(EagerExpander), +pub struct EnumVariantId(salsa::InternId); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct EnumVariantLoc { + pub id: ItemTreeId<Variant>, + pub parent: EnumId, + 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, Ord, PartialOrd)] pub struct Macro2Id(salsa::InternId); @@ -448,6 +314,14 @@ bitflags::bitflags! { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum MacroExpander { + Declarative, + BuiltIn(BuiltinFnLikeExpander), + BuiltInAttr(BuiltinAttrExpander), + BuiltInDerive(BuiltinDeriveExpander), + BuiltInEager(EagerExpander), +} #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct ProcMacroId(salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -471,6 +345,146 @@ pub struct BlockLoc { } impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block); +/// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and +/// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent. +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +pub struct ConstBlockId(salsa::InternId); +impl_intern!(ConstBlockId, ConstBlockLoc, intern_anonymous_const, lookup_intern_anonymous_const); + +#[derive(Debug, Hash, PartialEq, Eq, Clone)] +pub struct ConstBlockLoc { + /// The parent of the anonymous const block. + pub parent: DefWithBodyId, + /// The root expression of this const block in the parent body. + pub root: hir::ExprId, +} + +/// A `ModuleId` that is always a crate's root module. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct CrateRootModuleId { + krate: CrateId, +} + +impl CrateRootModuleId { + pub fn def_map(&self, db: &dyn DefDatabase) -> Arc<DefMap> { + db.crate_def_map(self.krate) + } + + pub fn krate(self) -> CrateId { + self.krate + } +} + +impl PartialEq<ModuleId> for CrateRootModuleId { + fn eq(&self, other: &ModuleId) -> bool { + other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate + } +} + +impl From<CrateId> for CrateRootModuleId { + fn from(krate: CrateId) -> Self { + CrateRootModuleId { krate } + } +} + +impl TryFrom<ModuleId> for CrateRootModuleId { + type Error = (); + + fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result<Self, Self::Error> { + if block.is_none() && local_id == DefMap::ROOT { + Ok(CrateRootModuleId { krate }) + } else { + Err(()) + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct ModuleId { + krate: CrateId, + /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the + /// `BlockId` of that block expression. If `None`, this module is part of the crate-level + /// `DefMap` of `krate`. + block: Option<BlockId>, + /// The module's ID in its originating `DefMap`. + pub local_id: LocalModuleId, +} + +impl ModuleId { + pub fn def_map(self, db: &dyn DefDatabase) -> Arc<DefMap> { + match self.block { + Some(block) => db.block_def_map(block), + None => db.crate_def_map(self.krate), + } + } + + pub fn krate(self) -> CrateId { + self.krate + } + + pub fn name(self, db: &dyn DefDatabase) -> Option<Name> { + let def_map = self.def_map(db); + let parent = def_map[self.local_id].parent?; + def_map[parent].children.iter().find_map(|(name, module_id)| { + if *module_id == self.local_id { + Some(name.clone()) + } else { + None + } + }) + } + + pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> { + self.def_map(db).containing_module(self.local_id) + } + + pub fn containing_block(self) -> Option<BlockId> { + self.block + } + + pub fn is_block_module(self) -> bool { + self.block.is_some() && self.local_id == DefMap::ROOT + } +} + +impl PartialEq<CrateRootModuleId> for ModuleId { + fn eq(&self, other: &CrateRootModuleId) -> bool { + other == self + } +} + +impl From<CrateRootModuleId> for ModuleId { + fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self { + ModuleId { krate, block: None, local_id: DefMap::ROOT } + } +} + +impl From<CrateRootModuleId> for ModuleDefId { + fn from(value: CrateRootModuleId) -> Self { + ModuleDefId::ModuleId(value.into()) + } +} + +/// An ID of a module, **local** to a `DefMap`. +pub type LocalModuleId = Idx<nameres::ModuleData>; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct FieldId { + pub parent: VariantId, + pub local_id: LocalFieldId, +} + +pub type LocalFieldId = Idx<data::adt::FieldData>; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct TupleId(pub u32); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct TupleFieldId { + pub tuple: TupleId, + pub index: u32, +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TypeOrConstParamId { pub parent: GenericDefId, @@ -611,20 +625,6 @@ impl_from!( for ModuleDefId ); -/// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and -/// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -pub struct ConstBlockId(salsa::InternId); -impl_intern!(ConstBlockId, ConstBlockLoc, intern_anonymous_const, lookup_intern_anonymous_const); - -#[derive(Debug, Hash, PartialEq, Eq, Clone)] -pub struct ConstBlockLoc { - /// The parent of the anonymous const block. - pub parent: DefWithBodyId, - /// The root expression of this const block in the parent body. - pub root: hir::ExprId, -} - /// Something that holds types, required for the current const arg lowering implementation as they /// need to be able to query where they are defined. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] @@ -1257,6 +1257,34 @@ impl HasModule for GenericDefId { } } +impl HasModule for AttrDefId { + fn module(&self, db: &dyn DefDatabase) -> ModuleId { + match self { + AttrDefId::ModuleId(it) => *it, + AttrDefId::FieldId(it) => it.parent.module(db), + AttrDefId::AdtId(it) => it.module(db), + AttrDefId::FunctionId(it) => it.module(db), + AttrDefId::EnumVariantId(it) => it.module(db), + AttrDefId::StaticId(it) => it.module(db), + AttrDefId::ConstId(it) => it.module(db), + AttrDefId::TraitId(it) => it.module(db), + AttrDefId::TraitAliasId(it) => it.module(db), + AttrDefId::TypeAliasId(it) => it.module(db), + AttrDefId::ImplId(it) => it.module(db), + AttrDefId::ExternBlockId(it) => it.module(db), + AttrDefId::GenericParamId(it) => match it { + GenericParamId::TypeParamId(it) => it.parent(), + GenericParamId::ConstParamId(it) => it.parent(), + GenericParamId::LifetimeParamId(it) => it.parent, + } + .module(db), + AttrDefId::MacroId(it) => it.module(db), + AttrDefId::ExternCrateId(it) => it.module(db), + AttrDefId::UseId(it) => it.module(db), + } + } +} + impl ModuleDefId { /// Returns the module containing `self` (or `self`, if `self` is itself a module). /// @@ -1278,34 +1306,6 @@ impl ModuleDefId { } } -impl AttrDefId { - pub fn krate(&self, db: &dyn DefDatabase) -> CrateId { - match *self { - AttrDefId::ModuleId(it) => it.krate, - AttrDefId::FieldId(it) => it.parent.krate(db), - AttrDefId::AdtId(it) => it.krate(db), - AttrDefId::FunctionId(it) => it.krate(db), - AttrDefId::EnumVariantId(it) => it.krate(db), - AttrDefId::StaticId(it) => it.krate(db), - AttrDefId::ConstId(it) => it.krate(db), - AttrDefId::TraitId(it) => it.krate(db), - AttrDefId::TraitAliasId(it) => it.krate(db), - AttrDefId::TypeAliasId(it) => it.krate(db), - AttrDefId::ImplId(it) => it.krate(db), - AttrDefId::ExternBlockId(it) => it.krate(db), - AttrDefId::GenericParamId(it) => match it { - GenericParamId::TypeParamId(it) => it.parent(), - GenericParamId::ConstParamId(it) => it.parent(), - GenericParamId::LifetimeParamId(it) => it.parent, - } - .krate(db), - AttrDefId::MacroId(it) => it.krate(db), - AttrDefId::ExternCrateId(it) => it.krate(db), - AttrDefId::UseId(it) => it.krate(db), - } - } -} - /// A helper trait for converting to MacroCallId pub trait AsMacroCall { fn as_call_id( |