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.rs310
1 files changed, 103 insertions, 207 deletions
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index e5c213ca93..8d6c418d75 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -19,7 +19,7 @@ extern crate ra_ap_rustc_abi as rustc_abi;
pub mod db;
-pub mod attr;
+pub mod attrs;
pub mod builtin_type;
pub mod item_scope;
pub mod per_ns;
@@ -30,6 +30,7 @@ pub mod dyn_map;
pub mod item_tree;
+pub mod builtin_derive;
pub mod lang_item;
pub mod hir;
@@ -45,7 +46,7 @@ pub mod find_path;
pub mod import_map;
pub mod visibility;
-use intern::{Interned, Symbol, sym};
+use intern::{Interned, Symbol};
pub use rustc_abi as layout;
use thin_vec::ThinVec;
use triomphe::Arc;
@@ -61,8 +62,9 @@ use std::hash::{Hash, Hasher};
use base_db::{Crate, impl_intern_key};
use hir_expand::{
- AstId, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId,
- MacroDefKind,
+ AstId, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroCallStyles,
+ MacroDefId, MacroDefKind,
+ attrs::AttrId,
builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
db::ExpandDatabase,
eager::expand_eager_macro_input,
@@ -71,7 +73,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;
@@ -80,7 +81,8 @@ use syntax::{AstNode, ast};
pub use hir_expand::{Intern, Lookup, tt};
use crate::{
- attr::Attrs,
+ attrs::AttrFlags,
+ builtin_derive::BuiltinDeriveImplTrait,
builtin_type::BuiltinType,
db::DefDatabase,
expr_store::ExpressionStoreSourceMap,
@@ -332,6 +334,21 @@ impl ImplId {
}
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct BuiltinDeriveImplLoc {
+ pub adt: AdtId,
+ pub trait_: BuiltinDeriveImplTrait,
+ pub derive_attr_id: AttrId,
+ pub derive_index: u32,
+}
+
+#[salsa::interned(debug, no_lifetime)]
+#[derive(PartialOrd, Ord)]
+pub struct BuiltinDeriveImplId {
+ #[returns(ref)]
+ pub loc: BuiltinDeriveImplLoc,
+}
+
type UseLoc = ItemLoc<ast::Use>;
impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use);
@@ -403,7 +420,7 @@ bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum MacroExpander {
- Declarative,
+ Declarative { styles: MacroCallStyles },
BuiltIn(BuiltinFnLikeExpander),
BuiltInAttr(BuiltinAttrExpander),
BuiltInDerive(BuiltinDeriveExpander),
@@ -412,14 +429,14 @@ 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 {
@@ -429,164 +446,75 @@ pub struct BlockLoc {
}
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 }
- }
-}
-
-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 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: 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<BlockId>,
}
+pub type ModuleId = ModuleIdLt<'static>;
+impl ModuleIdLt<'_> {
+ /// # 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) }
+ }
+}
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) }
+ }
+
pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap {
- match self.block {
+ 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 {
+ 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)
+ crate_local_def_map(db, self.krate(db)).local(db)
}
pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap {
- crate_def_map(db, self.krate)
- }
-
- pub fn krate(self) -> Crate {
- self.krate
+ crate_def_map(db, self.krate(db))
}
pub fn name(self, 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 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 }
+ self.def_map(db).containing_module(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()
+ pub fn is_block_module(self, db: &dyn DefDatabase) -> bool {
+ self.block(db).is_some() && self.def_map(db).root_module_id() == self
}
}
@@ -597,20 +525,17 @@ 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)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
pub struct FieldId {
// FIXME: Store this as an erased `salsa::Id` to save space
pub parent: VariantId,
pub local_id: LocalFieldId,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
pub struct TupleId(pub u32);
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Update)]
pub struct TupleFieldId {
pub tuple: TupleId,
pub index: u32,
@@ -682,7 +607,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),
@@ -753,6 +678,18 @@ impl_from!(
for ModuleDefId
);
+impl From<DefWithBodyId> for ModuleDefId {
+ #[inline]
+ fn from(value: DefWithBodyId) -> Self {
+ match value {
+ DefWithBodyId::FunctionId(id) => id.into(),
+ DefWithBodyId::StaticId(id) => id.into(),
+ DefWithBodyId::ConstId(id) => id.into(),
+ DefWithBodyId::VariantId(id) => id.into(),
+ }
+ }
+}
+
/// A constant, which might appears as a const item, an anonymous const block in expressions
/// or patterns, or as a constant in types with const generics.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
@@ -956,10 +893,9 @@ impl CallableDefId {
}
}
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, salsa_macros::Supertype)]
pub enum AttrDefId {
ModuleId(ModuleId),
- FieldId(FieldId),
AdtId(AdtId),
FunctionId(FunctionId),
EnumVariantId(EnumVariantId),
@@ -969,15 +905,12 @@ pub enum AttrDefId {
TypeAliasId(TypeAliasId),
MacroId(MacroId),
ImplId(ImplId),
- GenericParamId(GenericParamId),
ExternBlockId(ExternBlockId),
ExternCrateId(ExternCrateId),
UseId(UseId),
}
impl_from!(
- ModuleId,
- FieldId,
AdtId(StructId, EnumId, UnionId),
EnumVariantId,
StaticId,
@@ -987,41 +920,11 @@ impl_from!(
TypeAliasId,
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
ImplId,
- GenericParamId,
ExternCrateId,
UseId
for AttrDefId
);
-impl TryFrom<ModuleDefId> for AttrDefId {
- type Error = ();
-
- fn try_from(value: ModuleDefId) -> Result<Self, Self::Error> {
- match value {
- ModuleDefId::ModuleId(it) => Ok(it.into()),
- ModuleDefId::FunctionId(it) => Ok(it.into()),
- ModuleDefId::AdtId(it) => Ok(it.into()),
- ModuleDefId::EnumVariantId(it) => Ok(it.into()),
- ModuleDefId::ConstId(it) => Ok(it.into()),
- ModuleDefId::StaticId(it) => Ok(it.into()),
- ModuleDefId::TraitId(it) => Ok(it.into()),
- ModuleDefId::TypeAliasId(it) => Ok(it.into()),
- ModuleDefId::MacroId(id) => Ok(id.into()),
- ModuleDefId::BuiltinType(_) => Err(()),
- }
- }
-}
-
-impl From<ItemContainerId> for AttrDefId {
- fn from(acid: ItemContainerId) -> Self {
- match acid {
- ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
- ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
- ItemContainerId::TraitId(tid) => AttrDefId::TraitId(tid),
- ItemContainerId::ExternBlockId(id) => AttrDefId::ExternBlockId(id),
- }
- }
-}
impl From<AssocItemId> for AttrDefId {
fn from(assoc: AssocItemId) -> Self {
match assoc {
@@ -1041,7 +944,7 @@ impl From<VariantId> for AttrDefId {
}
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype, salsa::Update)]
pub enum VariantId {
EnumVariantId(EnumVariantId),
StructId(StructId),
@@ -1085,7 +988,7 @@ pub trait HasModule {
#[inline]
#[doc(alias = "crate")]
fn krate(&self, db: &dyn DefDatabase) -> Crate {
- self.module(db).krate
+ self.module(db).krate(db)
}
}
@@ -1136,6 +1039,20 @@ fn module_for_assoc_item_loc<'db>(
id.lookup(db).container.module(db)
}
+impl HasModule for BuiltinDeriveImplLoc {
+ #[inline]
+ fn module(&self, db: &dyn DefDatabase) -> ModuleId {
+ self.adt.module(db)
+ }
+}
+
+impl HasModule for BuiltinDeriveImplId {
+ #[inline]
+ fn module(&self, db: &dyn DefDatabase) -> ModuleId {
+ self.loc(db).module(db)
+ }
+}
+
impl HasModule for FunctionId {
#[inline]
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
@@ -1189,7 +1106,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
}
}
@@ -1263,7 +1180,6 @@ 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),
@@ -1273,12 +1189,6 @@ impl HasModule for AttrDefId {
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),
@@ -1402,32 +1312,18 @@ pub enum Complete {
}
impl Complete {
- pub fn extract(is_trait: bool, attrs: &Attrs) -> Complete {
- let mut do_not_complete = Complete::Yes;
- for ra_attr in attrs.rust_analyzer_tool() {
- let segments = ra_attr.path.segments();
- if segments.len() != 2 {
- continue;
- }
- let action = segments[1].symbol();
- if *action == sym::completions {
- match ra_attr.token_tree_value().map(|tt| tt.token_trees().flat_tokens()) {
- Some([tt::TokenTree::Leaf(tt::Leaf::Ident(ident))]) => {
- if ident.sym == sym::ignore_flyimport {
- do_not_complete = Complete::IgnoreFlyimport;
- } else if is_trait {
- if ident.sym == sym::ignore_methods {
- do_not_complete = Complete::IgnoreMethods;
- } else if ident.sym == sym::ignore_flyimport_methods {
- do_not_complete = Complete::IgnoreFlyimportMethods;
- }
- }
- }
- _ => {}
- }
+ #[inline]
+ pub fn extract(is_trait: bool, attrs: AttrFlags) -> Complete {
+ if attrs.contains(AttrFlags::COMPLETE_IGNORE_FLYIMPORT) {
+ return Complete::IgnoreFlyimport;
+ } else if is_trait {
+ if attrs.contains(AttrFlags::COMPLETE_IGNORE_METHODS) {
+ return Complete::IgnoreMethods;
+ } else if attrs.contains(AttrFlags::COMPLETE_IGNORE_FLYIMPORT_METHODS) {
+ return Complete::IgnoreFlyimportMethods;
}
}
- do_not_complete
+ Complete::Yes
}
#[inline]