Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/lib.rs')
-rw-r--r--crates/hir-def/src/lib.rs405
1 files changed, 219 insertions, 186 deletions
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index df1f61ae5f..589e57cb6b 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -87,7 +87,7 @@ use hir_expand::{
use item_tree::ExternBlock;
use la_arena::Idx;
use nameres::DefMap;
-use span::Span;
+use span::{FileId, Span};
use stdx::impl_from;
use syntax::{ast, AstNode};
@@ -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)]
@@ -892,6 +892,39 @@ impl_from!(
for GenericDefId
);
+impl GenericDefId {
+ fn file_id_and_params_of(
+ self,
+ db: &dyn DefDatabase,
+ ) -> (HirFileId, Option<ast::GenericParamList>) {
+ fn file_id_and_params_of_item_loc<Loc>(
+ db: &dyn DefDatabase,
+ def: impl for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Loc>,
+ ) -> (HirFileId, Option<ast::GenericParamList>)
+ where
+ Loc: src::HasSource,
+ Loc::Value: ast::HasGenericParams,
+ {
+ let src = def.lookup(db).source(db);
+ (src.file_id, ast::HasGenericParams::generic_param_list(&src.value))
+ }
+
+ match self {
+ GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::ConstId(_) => (FileId::BOGUS.into(), None),
+ GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
+ GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
+ // We won't be using this ID anyway
+ GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
+ }
+ }
+}
+
impl From<AssocItemId> for GenericDefId {
fn from(item: AssocItemId) -> Self {
match item {
@@ -1224,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).
///
@@ -1245,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(