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.rs207
1 files changed, 63 insertions, 144 deletions
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index ad247e0d68..e58cb7bad7 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -71,7 +71,6 @@ use hir_expand::{
name::Name,
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
};
-use la_arena::Idx;
use nameres::DefMap;
use span::{AstIdNode, Edition, FileAstId, SyntaxContext};
use stdx::impl_from;
@@ -412,181 +411,111 @@ pub enum MacroExpander {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ProcMacroLoc {
- pub container: CrateRootModuleId,
+ pub container: ModuleId,
pub id: AstId<ast::Fn>,
pub expander: CustomProcMacroExpander,
pub kind: ProcMacroKind,
pub edition: Edition,
}
impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
-impl_loc!(ProcMacroLoc, id: Fn, container: CrateRootModuleId);
+impl_loc!(ProcMacroLoc, id: Fn, container: ModuleId);
-#[derive(Debug, Hash, PartialEq, Eq, Clone)]
-pub struct BlockLoc {
+#[salsa_macros::tracked(debug)]
+#[derive(PartialOrd, Ord)]
+pub struct BlockIdLt<'db> {
pub ast_id: AstId<ast::BlockExpr>,
/// The containing module.
- pub module: ModuleId,
-}
-impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
-
-/// A `ModuleId` that is always a crate's root module.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct CrateRootModuleId {
- krate: Crate,
-}
-
-impl CrateRootModuleId {
- pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap {
- crate_def_map(db, self.krate)
- }
-
- pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) {
- let def_map = crate_local_def_map(db, self.krate);
- (def_map.def_map(db), def_map.local(db))
- }
-
- pub fn krate(self) -> Crate {
- self.krate
- }
-}
-
-impl HasModule for CrateRootModuleId {
- #[inline]
- fn module(&self, _db: &dyn DefDatabase) -> ModuleId {
- ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT }
- }
-
- #[inline]
- fn krate(&self, _db: &dyn DefDatabase) -> Crate {
- 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 }
- }
+ pub module: ModuleIdLt<'db>,
}
+pub type BlockId = BlockIdLt<'static>;
-impl From<CrateRootModuleId> for ModuleDefId {
- fn from(value: CrateRootModuleId) -> Self {
- ModuleDefId::ModuleId(value.into())
- }
-}
-
-impl From<Crate> for CrateRootModuleId {
- fn from(krate: Crate) -> Self {
- CrateRootModuleId { krate }
+impl BlockIdLt<'_> {
+ /// # Safety
+ ///
+ /// The caller must ensure that the `ModuleId` is not leaked outside of query computations.
+ pub unsafe fn to_static(self) -> BlockId {
+ unsafe { std::mem::transmute(self) }
}
}
-
-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(())
- }
+impl BlockId {
+ /// # Safety
+ ///
+ /// The caller must ensure that the `BlockId` comes from the given database.
+ pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> BlockIdLt<'db> {
+ unsafe { std::mem::transmute(self) }
}
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub struct ModuleId {
- krate: Crate,
+#[salsa_macros::tracked(debug)]
+#[derive(PartialOrd, Ord)]
+pub struct ModuleIdLt<'db> {
+ /// The crate this module belongs to.
+ pub krate: Crate,
/// 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,
+ pub block: Option<BlockIdLt<'db>>,
}
+pub type ModuleId = ModuleIdLt<'static>;
-impl ModuleId {
- pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap {
- match self.block {
+impl<'db> ModuleIdLt<'db> {
+ /// # Safety
+ ///
+ /// The caller must ensure that the `ModuleId` is not leaked outside of query computations.
+ pub unsafe fn to_static(self) -> ModuleId {
+ unsafe { std::mem::transmute(self) }
+ }
+
+ pub fn def_map(self, db: &'db dyn DefDatabase) -> &'db DefMap {
+ match self.block(db) {
Some(block) => block_def_map(db, block),
- None => crate_def_map(db, self.krate),
+ None => crate_def_map(db, self.krate(db)),
}
}
- pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) {
- match self.block {
+ pub(crate) fn local_def_map(self, db: &'db dyn DefDatabase) -> (&'db DefMap, &'db LocalDefMap) {
+ match self.block(db) {
Some(block) => (block_def_map(db, block), self.only_local_def_map(db)),
None => {
- let def_map = crate_local_def_map(db, self.krate);
+ let def_map = crate_local_def_map(db, self.krate(db));
(def_map.def_map(db), def_map.local(db))
}
}
}
- pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> &LocalDefMap {
- crate_local_def_map(db, self.krate).local(db)
- }
-
- pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap {
- crate_def_map(db, self.krate)
+ pub(crate) fn only_local_def_map(self, db: &'db dyn DefDatabase) -> &'db LocalDefMap {
+ crate_local_def_map(db, self.krate(db)).local(db)
}
- pub fn krate(self) -> Crate {
- self.krate
+ pub fn crate_def_map(self, db: &'db dyn DefDatabase) -> &'db DefMap {
+ crate_def_map(db, self.krate(db))
}
- pub fn name(self, db: &dyn DefDatabase) -> Option<Name> {
+ pub fn name(self, db: &'db dyn DefDatabase) -> Option<Name> {
let def_map = self.def_map(db);
- let parent = def_map[self.local_id].parent?;
+ let parent = def_map[self].parent?;
def_map[parent].children.iter().find_map(|(name, module_id)| {
- if *module_id == self.local_id { Some(name.clone()) } else { None }
+ if *module_id == self { Some(name.clone()) } else { None }
})
}
/// Returns the module containing `self`, either the parent `mod`, or the module (or block) containing
/// the block, if `self` corresponds to a block expression.
- 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
+ pub fn containing_module(self, db: &'db dyn DefDatabase) -> Option<ModuleIdLt<'db>> {
+ self.def_map(db).containing_module(self)
}
- pub fn is_within_block(self) -> bool {
- self.block.is_some()
- }
-
- /// Returns the [`CrateRootModuleId`] for this module if it is the crate root module.
- pub fn as_crate_root(&self) -> Option<CrateRootModuleId> {
- if self.local_id == DefMap::ROOT && self.block.is_none() {
- Some(CrateRootModuleId { krate: self.krate })
- } else {
- None
- }
- }
-
- /// Returns the [`CrateRootModuleId`] for this module.
- pub fn derive_crate_root(&self) -> CrateRootModuleId {
- CrateRootModuleId { krate: self.krate }
+ pub fn is_block_module(self, db: &'db dyn DefDatabase) -> bool {
+ self.block(db).is_some() && self.def_map(db).root_module_id() == self
}
+}
- /// Whether this module represents the crate root module
- pub fn is_crate_root(&self) -> bool {
- self.local_id == DefMap::ROOT && self.block.is_none()
+impl ModuleId {
+ /// # Safety
+ ///
+ /// The caller must ensure that the `ModuleId` comes from the given database.
+ pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> {
+ unsafe { std::mem::transmute(self) }
}
}
@@ -597,9 +526,6 @@ impl HasModule for ModuleId {
}
}
-/// An ID of a module, **local** to a `DefMap`.
-pub type LocalModuleId = Idx<nameres::ModuleData>;
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
pub struct FieldId {
// FIXME: Store this as an erased `salsa::Id` to save space
@@ -682,7 +608,7 @@ pub struct LifetimeParamId {
pub local_id: LocalLifetimeParamId,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
pub enum ItemContainerId {
ExternBlockId(ExternBlockId),
ModuleId(ModuleId),
@@ -956,16 +882,9 @@ impl CallableDefId {
}
}
-// FIXME: We probably should use this in more places.
-/// This is used to avoid interning the whole `AttrDefId`, so we intern just modules and not everything.
-#[salsa_macros::interned(debug, no_lifetime)]
-pub struct InternedModuleId {
- pub loc: ModuleId,
-}
-
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, salsa_macros::Supertype)]
pub enum AttrDefId {
- ModuleId(InternedModuleId),
+ ModuleId(ModuleId),
AdtId(AdtId),
FunctionId(FunctionId),
EnumVariantId(EnumVariantId),
@@ -1058,7 +977,7 @@ pub trait HasModule {
#[inline]
#[doc(alias = "crate")]
fn krate(&self, db: &dyn DefDatabase) -> Crate {
- self.module(db).krate
+ self.module(db).krate(db)
}
}
@@ -1162,7 +1081,7 @@ impl HasModule for Macro2Id {
impl HasModule for ProcMacroId {
#[inline]
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
- self.lookup(db).container.into()
+ self.lookup(db).container
}
}
@@ -1235,7 +1154,7 @@ impl HasModule for GenericDefId {
impl HasModule for AttrDefId {
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
match self {
- AttrDefId::ModuleId(it) => it.loc(db),
+ AttrDefId::ModuleId(it) => *it,
AttrDefId::AdtId(it) => it.module(db),
AttrDefId::FunctionId(it) => it.module(db),
AttrDefId::EnumVariantId(it) => it.module(db),