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.rs | 310 |
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] |