Unnamed repository; edit this file 'description' to name the repository.
Add MacroId to hir_def in attempt to unify Macros with ModuleDefId
| -rw-r--r-- | crates/hir_def/src/body.rs | 9 | ||||
| -rw-r--r-- | crates/hir_def/src/child_by_source.rs | 20 | ||||
| -rw-r--r-- | crates/hir_def/src/db.rs | 11 | ||||
| -rw-r--r-- | crates/hir_def/src/find_path.rs | 1 | ||||
| -rw-r--r-- | crates/hir_def/src/import_map.rs | 2 | ||||
| -rw-r--r-- | crates/hir_def/src/item_scope.rs | 38 | ||||
| -rw-r--r-- | crates/hir_def/src/keys.rs | 11 | ||||
| -rw-r--r-- | crates/hir_def/src/lib.rs | 155 | ||||
| -rw-r--r-- | crates/hir_def/src/macro_expansion_tests.rs | 8 | ||||
| -rw-r--r-- | crates/hir_def/src/nameres/attr_resolution.rs | 12 | ||||
| -rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 182 | ||||
| -rw-r--r-- | crates/hir_def/src/nameres/path_resolution.rs | 2 | ||||
| -rw-r--r-- | crates/hir_def/src/nameres/tests/incremental.rs | 1 | ||||
| -rw-r--r-- | crates/hir_def/src/per_ns.rs | 10 | ||||
| -rw-r--r-- | crates/hir_def/src/resolver.rs | 33 | ||||
| -rw-r--r-- | crates/hir_def/src/src.rs | 45 | ||||
| -rw-r--r-- | crates/hir_expand/src/builtin_attr_macro.rs | 19 | ||||
| -rw-r--r-- | crates/hir_expand/src/builtin_derive_macro.rs | 18 | ||||
| -rw-r--r-- | crates/hir_expand/src/builtin_fn_macro.rs | 24 |
19 files changed, 386 insertions, 215 deletions
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 6d3c2c2c46..71375fe4a6 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs @@ -13,7 +13,7 @@ use drop_bomb::DropBomb; use either::Either; use hir_expand::{ ast_id_map::AstIdMap, hygiene::Hygiene, AstId, ExpandError, ExpandResult, HirFileId, InFile, - MacroCallId, MacroDefId, + MacroCallId, }; use la_arena::{Arena, ArenaMap}; use limit::Limit; @@ -26,10 +26,11 @@ use crate::{ db::DefDatabase, expr::{Expr, ExprId, Label, LabelId, Pat, PatId}, item_scope::BuiltinShadowMode, + macro_id_to_def_id, nameres::DefMap, path::{ModPath, Path}, src::HasSource, - AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleId, + AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, MacroId, ModuleId, UnresolvedMacro, }; @@ -105,7 +106,7 @@ impl Expander { let macro_call = InFile::new(self.current_file_id, ¯o_call); let resolver = - |path: ModPath| -> Option<MacroDefId> { self.resolve_path_as_macro(db, &path) }; + |path| self.resolve_path_as_macro(db, &path).map(|it| macro_id_to_def_id(db, it)); let mut err = None; let call_id = @@ -208,7 +209,7 @@ impl Expander { Path::from_src(path, &ctx) } - fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroDefId> { + fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroId> { self.def_map.resolve_path(db, self.module, path, BuiltinShadowMode::Other).0.take_macros() } diff --git a/crates/hir_def/src/child_by_source.rs b/crates/hir_def/src/child_by_source.rs index 1e1573d4ae..e04d26fbab 100644 --- a/crates/hir_def/src/child_by_source.rs +++ b/crates/hir_def/src/child_by_source.rs @@ -14,8 +14,8 @@ use crate::{ item_scope::ItemScope, keys, src::{HasChildSource, HasSource}, - AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, ModuleDefId, - ModuleId, TraitId, VariantId, + AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, MacroId, + ModuleDefId, ModuleId, TraitId, VariantId, }; pub trait ChildBySource { @@ -97,17 +97,6 @@ impl ChildBySource for ItemScope { res[keys::CONST].insert(loc.source(db).value, konst); } }); - self.macros().for_each(|(_, makro)| { - let ast_id = makro.ast_id(); - if ast_id.either(|it| it.file_id, |it| it.file_id) == file_id { - let src = match ast_id { - Either::Left(ast_id) => ast_id.to_node(db.upcast()), - // FIXME: Do we need to add proc-macros into a PROCMACRO dynmap here? - Either::Right(_fn) => return, - }; - res[keys::MACRO].insert(src, makro); - } - }); self.attr_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each( |(ast_id, call_id)| { res[keys::ATTR_MACRO_CALL].insert(ast_id.to_node(db.upcast()), call_id); @@ -151,6 +140,11 @@ impl ChildBySource for ItemScope { AdtId::UnionId(id) => insert!(map[keys::UNION].insert(id)), AdtId::EnumId(id) => insert!(map[keys::ENUM].insert(id)), }, + ModuleDefId::MacroId(id) => match id { + MacroId::Macro2Id(id) => insert!(map[keys::MACRO2].insert(id)), + MacroId::MacroRulesId(id) => insert!(map[keys::MACRO_RULES].insert(id)), + MacroId::ProcMacroId(id) => insert!(map[keys::PROC_MACRO].insert(id)), + }, _ => (), } } diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs index f9dd935c4b..830ef77692 100644 --- a/crates/hir_def/src/db.rs +++ b/crates/hir_def/src/db.rs @@ -21,8 +21,9 @@ use crate::{ visibility::{self, Visibility}, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId, ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, - LocalFieldId, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, - TypeAliasLoc, UnionId, UnionLoc, VariantId, + LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId, MacroRulesLoc, ProcMacroId, ProcMacroLoc, + StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, + UnionId, UnionLoc, VariantId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -49,6 +50,12 @@ pub trait InternDatabase: SourceDatabase { fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId; #[salsa::interned] fn intern_block(&self, loc: BlockLoc) -> BlockId; + #[salsa::interned] + fn intern_macro2(&self, loc: Macro2Loc) -> Macro2Id; + #[salsa::interned] + fn intern_proc_macro(&self, loc: ProcMacroLoc) -> ProcMacroId; + #[salsa::interned] + fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId; } #[salsa::query_group(DefDatabaseStorage)] diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs index 22d593a7d9..e1e5ded52a 100644 --- a/crates/hir_def/src/find_path.rs +++ b/crates/hir_def/src/find_path.rs @@ -98,6 +98,7 @@ impl PrefixKind { } } +/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId fn find_path_inner( db: &dyn DefDatabase, item: ItemInNs, diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs index 5e91a3df0a..0cca14a9f2 100644 --- a/crates/hir_def/src/import_map.rs +++ b/crates/hir_def/src/import_map.rs @@ -271,6 +271,7 @@ pub enum ImportKind { TypeAlias, BuiltinType, AssociatedItem, + Macro, } /// A way to match import map contents against the search query. @@ -464,6 +465,7 @@ fn item_import_kind(item: ItemInNs) -> Option<ImportKind> { ModuleDefId::TraitId(_) => ImportKind::Trait, ModuleDefId::TypeAliasId(_) => ImportKind::TypeAlias, ModuleDefId::BuiltinType(_) => ImportKind::BuiltinType, + ModuleDefId::MacroId(_) => ImportKind::Macro, }) } diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index fffec96bab..1293319561 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs @@ -4,7 +4,7 @@ use std::collections::hash_map::Entry; use base_db::CrateId; -use hir_expand::{name::Name, AstId, MacroCallId, MacroDefKind}; +use hir_expand::{name::Name, AstId, MacroCallId}; use once_cell::sync::Lazy; use profile::Count; use rustc_hash::{FxHashMap, FxHashSet}; @@ -14,7 +14,8 @@ use syntax::ast; use crate::{ attr::AttrId, db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, - ConstId, ImplId, LocalModuleId, MacroDefId, ModuleDefId, ModuleId, TraitId, + ConstId, HasModule, ImplId, LocalModuleId, MacroId, MacroRulesId, ModuleDefId, ModuleId, + TraitId, }; #[derive(Copy, Clone)] @@ -38,13 +39,13 @@ pub struct ItemScope { /// imports. types: FxHashMap<Name, (ModuleDefId, Visibility)>, values: FxHashMap<Name, (ModuleDefId, Visibility)>, - macros: FxHashMap<Name, (MacroDefId, Visibility)>, + macros: FxHashMap<Name, (MacroId, Visibility)>, unresolved: FxHashSet<Name>, /// The defs declared in this scope. Each def has a single scope where it is /// declared. declarations: Vec<ModuleDefId>, - macro_declarations: Vec<MacroDefId>, + macro_declarations: Vec<MacroId>, impls: Vec<ImplId>, unnamed_consts: Vec<ConstId>, @@ -62,7 +63,7 @@ pub struct ItemScope { /// Module scoped macros will be inserted into `items` instead of here. // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will // be all resolved to the last one defined if shadowing happens. - legacy_macros: FxHashMap<Name, MacroDefId>, + legacy_macros: FxHashMap<Name, MacroRulesId>, attr_macros: FxHashMap<AstId<ast::Item>, MacroCallId>, /// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes /// paired with the derive macro invocations for the specific attribute. @@ -108,7 +109,7 @@ impl ItemScope { self.declarations.iter().copied() } - pub fn macro_declarations(&self) -> impl Iterator<Item = MacroDefId> + '_ { + pub fn macro_declarations(&self) -> impl Iterator<Item = MacroId> + '_ { self.macro_declarations.iter().copied() } @@ -127,12 +128,14 @@ impl ItemScope { } /// Iterate over all module scoped macros - pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { + pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroId)> + 'a { self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_))) } /// Iterate over all legacy textual scoped macros visible at the end of the module - pub(crate) fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { + pub(crate) fn legacy_macros<'a>( + &'a self, + ) -> impl Iterator<Item = (&'a Name, MacroRulesId)> + 'a { self.legacy_macros.iter().map(|(name, def)| (name, *def)) } @@ -163,8 +166,8 @@ impl ItemScope { pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a { self.types .values() - .filter_map(|(def, _)| match def { - ModuleDefId::TraitId(t) => Some(*t), + .filter_map(|&(def, _)| match def { + ModuleDefId::TraitId(t) => Some(t), _ => None, }) .chain(self.unnamed_trait_imports.keys().copied()) @@ -174,11 +177,11 @@ impl ItemScope { self.declarations.push(def) } - pub(crate) fn declare_macro(&mut self, def: MacroDefId) { + pub(crate) fn declare_macro(&mut self, def: MacroId) { self.macro_declarations.push(def); } - pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> { + pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<MacroRulesId> { self.legacy_macros.get(name).copied() } @@ -190,7 +193,7 @@ impl ItemScope { self.unnamed_consts.push(konst); } - pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroDefId) { + pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroRulesId) { self.legacy_macros.insert(name, mac); } @@ -320,7 +323,7 @@ impl ItemScope { ) } - pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroDefId> { + pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroRulesId> { self.legacy_macros.clone() } @@ -334,7 +337,7 @@ impl ItemScope { .for_each(|vis| *vis = Visibility::Module(this_module)); for (mac, vis) in self.macros.values_mut() { - if let MacroDefKind::ProcMacro(..) = mac.kind { + if let MacroId::ProcMacroId(_) = mac { // FIXME: Technically this is insufficient since reexports of proc macros are also // forbidden. Practically nobody does that. continue; @@ -421,6 +424,7 @@ impl PerNs { ModuleDefId::TraitId(_) => PerNs::types(def, v), ModuleDefId::TypeAliasId(_) => PerNs::types(def, v), ModuleDefId::BuiltinType(_) => PerNs::types(def, v), + ModuleDefId::MacroId(mac) => PerNs::macros(mac, v), } } } @@ -429,7 +433,7 @@ impl PerNs { pub enum ItemInNs { Types(ModuleDefId), Values(ModuleDefId), - Macros(MacroDefId), + Macros(MacroId), } impl ItemInNs { @@ -444,7 +448,7 @@ impl ItemInNs { pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> { match self { ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate), - ItemInNs::Macros(id) => Some(id.krate), + ItemInNs::Macros(id) => Some(id.module(db).krate), } } } diff --git a/crates/hir_def/src/keys.rs b/crates/hir_def/src/keys.rs index 5f21914305..c5cb9a2af5 100644 --- a/crates/hir_def/src/keys.rs +++ b/crates/hir_def/src/keys.rs @@ -2,15 +2,16 @@ use std::marker::PhantomData; -use hir_expand::{MacroCallId, MacroDefId}; +use hir_expand::MacroCallId; use rustc_hash::FxHashMap; use syntax::{ast, AstNode, AstPtr}; use crate::{ attr::AttrId, dyn_map::{DynMap, Policy}, - ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, StaticId, - StructId, TraitId, TypeAliasId, TypeOrConstParamId, UnionId, + ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, Macro2Id, + MacroRulesId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, + UnionId, }; pub type Key<K, V> = crate::dyn_map::Key<K, V, AstPtrPolicy<K, V>>; @@ -32,7 +33,9 @@ pub const TYPE_PARAM: Key<ast::TypeParam, TypeOrConstParamId> = Key::new(); pub const CONST_PARAM: Key<ast::ConstParam, TypeOrConstParamId> = Key::new(); pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new(); -pub const MACRO: Key<ast::Macro, MacroDefId> = Key::new(); +pub const MACRO_RULES: Key<ast::MacroRules, MacroRulesId> = Key::new(); +pub const MACRO2: Key<ast::MacroDef, Macro2Id> = Key::new(); +pub const PROC_MACRO: Key<ast::Fn, ProcMacroId> = Key::new(); pub const ATTR_MACRO_CALL: Key<ast::Item, MacroCallId> = Key::new(); pub const DERIVE_MACRO_CALL: Key<ast::Attr, (AttrId, MacroCallId, Box<[Option<MacroCallId>]>)> = Key::new(); diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 21096166d7..481a69c5b1 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs @@ -58,11 +58,15 @@ use std::{ }; use attr::Attr; -use base_db::{impl_intern_key, salsa, CrateId}; +use base_db::{impl_intern_key, salsa, CrateId, ProcMacroKind}; use hir_expand::{ ast_id_map::FileAstId, + builtin_attr_macro::BuiltinAttrExpander, + builtin_derive_macro::BuiltinDeriveExpander, + builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander}, eager::{expand_eager_macro, ErrorEmitted, ErrorSink}, hygiene::Hygiene, + proc_macro::ProcMacroExpander, AstId, ExpandError, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, UnresolvedMacro, }; @@ -77,8 +81,8 @@ use crate::{ attr::AttrId, builtin_type::BuiltinType, item_tree::{ - Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait, - TypeAlias, Union, + Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, ModItem, + Static, Struct, Trait, TypeAlias, Union, }, }; @@ -268,6 +272,48 @@ pub struct ExternBlockId(salsa::InternId); type ExternBlockLoc = ItemLoc<ExternBlock>; impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block); +#[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 Macro2Id(salsa::InternId); +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Macro2Loc { + pub container: ModuleId, + pub id: ItemTreeId<MacroDef>, + pub expander: MacroExpander, +} +impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct MacroRulesId(salsa::InternId); +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct MacroRulesLoc { + pub container: ModuleId, + pub id: ItemTreeId<MacroRules>, + pub local_inner: bool, + pub expander: MacroExpander, +} +impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct ProcMacroId(salsa::InternId); +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct ProcMacroLoc { + // FIXME: this should be a crate? or just a crate-root module + pub container: ModuleId, + pub id: ItemTreeId<Function>, + pub expander: ProcMacroExpander, + pub kind: ProcMacroKind, +} +impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro); + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct BlockId(salsa::InternId); #[derive(Debug, Hash, PartialEq, Eq, Clone)] @@ -284,8 +330,8 @@ pub struct TypeOrConstParamId { pub local_id: LocalTypeOrConstParamId, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] /// A TypeOrConstParamId with an invariant that it actually belongs to a type +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TypeParamId(TypeOrConstParamId); impl TypeParamId { @@ -359,6 +405,24 @@ pub enum AdtId { } impl_from!(StructId, UnionId, EnumId for AdtId); +/// A macro +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum MacroId { + Macro2Id(Macro2Id), + MacroRulesId(MacroRulesId), + ProcMacroId(ProcMacroId), +} +impl_from!(Macro2Id, MacroRulesId, ProcMacroId for MacroId); + +impl MacroId { + pub fn is_attribute(self, db: &dyn db::DefDatabase) -> bool { + match self { + MacroId::ProcMacroId(it) => it.lookup(db).kind == ProcMacroKind::Attr, + _ => false, + } + } +} + /// A generic param #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum GenericParamId { @@ -381,8 +445,10 @@ pub enum ModuleDefId { TraitId(TraitId), TypeAliasId(TypeAliasId), BuiltinType(BuiltinType), + MacroId(MacroId), } impl_from!( + MacroId, ModuleId, FunctionId, AdtId(StructId, EnumId, UnionId), @@ -592,6 +658,16 @@ impl HasModule for VariantId { } } +impl HasModule for MacroId { + fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { + match self { + MacroId::MacroRulesId(it) => it.lookup(db).container, + MacroId::Macro2Id(it) => it.lookup(db).container, + MacroId::ProcMacroId(it) => it.lookup(db).container, + } + } +} + impl HasModule for DefWithBodyId { fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { match self { @@ -652,6 +728,7 @@ impl ModuleDefId { ModuleDefId::StaticId(id) => id.lookup(db).module(db), ModuleDefId::TraitId(id) => id.lookup(db).container, ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db), + ModuleDefId::MacroId(id) => id.module(db), ModuleDefId::BuiltinType(_) => return None, }) } @@ -762,7 +839,7 @@ fn macro_call_as_call_id( resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, error_sink: &mut dyn FnMut(ExpandError), ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> { - let def: MacroDefId = + let def = resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?; let res = if let MacroDefKind::BuiltInEager(..) = def.kind { @@ -779,6 +856,74 @@ fn macro_call_as_call_id( Ok(res) } +fn macro_id_to_def_id(db: &dyn db::DefDatabase, id: MacroId) -> MacroDefId { + match id { + MacroId::Macro2Id(it) => { + let loc = it.lookup(db); + + let item_tree = loc.id.item_tree(db); + let makro = &item_tree[loc.id.value]; + let in_file = |m: FileAstId<ast::MacroDef>| InFile::new(loc.id.file_id(), m.upcast()); + MacroDefId { + krate: loc.container.krate, + kind: match loc.expander { + MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)), + MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)), + MacroExpander::BuiltInAttr(it) => { + MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id)) + } + MacroExpander::BuiltInDerive(it) => { + MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id)) + } + MacroExpander::BuiltInEager(it) => { + MacroDefKind::BuiltInEager(it, in_file(makro.ast_id)) + } + }, + local_inner: false, + } + } + MacroId::MacroRulesId(it) => { + let loc = it.lookup(db); + + let item_tree = loc.id.item_tree(db); + let makro = &item_tree[loc.id.value]; + let in_file = |m: FileAstId<ast::MacroRules>| InFile::new(loc.id.file_id(), m.upcast()); + MacroDefId { + krate: loc.container.krate, + kind: match loc.expander { + MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)), + MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)), + MacroExpander::BuiltInAttr(it) => { + MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id)) + } + MacroExpander::BuiltInDerive(it) => { + MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id)) + } + MacroExpander::BuiltInEager(it) => { + MacroDefKind::BuiltInEager(it, in_file(makro.ast_id)) + } + }, + local_inner: loc.local_inner, + } + } + MacroId::ProcMacroId(it) => { + let loc = it.lookup(db); + + let item_tree = loc.id.item_tree(db); + let makro = &item_tree[loc.id.value]; + MacroDefId { + krate: loc.container.krate, + kind: MacroDefKind::ProcMacro( + loc.expander, + loc.kind, + InFile::new(loc.id.file_id(), makro.ast_id), + ), + local_inner: false, + } + } + } +} + fn derive_macro_as_call_id( db: &dyn db::DefDatabase, item_attr: &AstIdWithPath<ast::Adt>, diff --git a/crates/hir_def/src/macro_expansion_tests.rs b/crates/hir_def/src/macro_expansion_tests.rs index f86d87d5cc..7e0598f4a0 100644 --- a/crates/hir_def/src/macro_expansion_tests.rs +++ b/crates/hir_def/src/macro_expansion_tests.rs @@ -33,8 +33,8 @@ use syntax::{ use tt::{Subtree, TokenId}; use crate::{ - db::DefDatabase, nameres::ModuleSource, resolver::HasResolver, src::HasSource, test_db::TestDB, - AdtId, AsMacroCall, Lookup, ModuleDefId, + db::DefDatabase, macro_id_to_def_id, nameres::ModuleSource, resolver::HasResolver, + src::HasSource, test_db::TestDB, AdtId, AsMacroCall, Lookup, ModuleDefId, }; #[track_caller] @@ -128,7 +128,9 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream .as_call_id_with_errors( &db, krate, - |path| resolver.resolve_path_as_macro(&db, &path), + |path| { + resolver.resolve_path_as_macro(&db, &path).map(|it| macro_id_to_def_id(&db, it)) + }, &mut |err| error = Some(err), ) .unwrap() diff --git a/crates/hir_def/src/nameres/attr_resolution.rs b/crates/hir_def/src/nameres/attr_resolution.rs index 4c436250db..a7e2c3e8ad 100644 --- a/crates/hir_def/src/nameres/attr_resolution.rs +++ b/crates/hir_def/src/nameres/attr_resolution.rs @@ -8,6 +8,7 @@ use crate::{ attr_macro_as_call_id, builtin_attr, db::DefDatabase, item_scope::BuiltinShadowMode, + macro_id_to_def_id, nameres::path_resolution::ResolveMode, path::{ModPath, PathKind}, AstIdWithPath, LocalModuleId, UnresolvedMacro, @@ -45,7 +46,7 @@ impl DefMap { ); let def = match resolved_res.resolved_def.take_macros() { Some(def) => { - if def.is_attribute() { + if def.is_attribute(db) { def } else { return Ok(ResolvedAttr::Other); @@ -54,7 +55,14 @@ impl DefMap { None => return Err(UnresolvedMacro { path: ast_id.path.clone() }), }; - Ok(ResolvedAttr::Macro(attr_macro_as_call_id(db, &ast_id, attr, self.krate, def, false))) + Ok(ResolvedAttr::Macro(attr_macro_as_call_id( + db, + &ast_id, + attr, + self.krate, + macro_id_to_def_id(db, def), + false, + ))) } pub(crate) fn is_builtin_or_registered_attr(&self, path: &ModPath) -> bool { diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 9176c90ae9..a6a90117f2 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -5,8 +5,9 @@ use std::iter; -use base_db::{CrateId, Edition, FileId, ProcMacroId}; +use base_db::{CrateId, Edition, FileId}; use cfg::{CfgExpr, CfgOptions}; +use either::Either; use hir_expand::{ ast_id_map::FileAstId, builtin_attr_macro::find_builtin_attr, @@ -34,7 +35,7 @@ use crate::{ self, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode, MacroCall, MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId, }, - macro_call_as_call_id, + macro_call_as_call_id, macro_id_to_def_id, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, @@ -46,8 +47,9 @@ use crate::{ per_ns::PerNs, visibility::{RawVisibility, Visibility}, AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, ExternBlockLoc, FunctionLoc, - ImplLoc, Intern, ItemContainerId, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, - TypeAliasLoc, UnionLoc, UnresolvedMacro, + ImplLoc, Intern, ItemContainerId, LocalModuleId, Macro2Id, Macro2Loc, MacroExpander, MacroId, + MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, + StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, }; static GLOB_RECURSION_LIMIT: Limit = Limit::new(100); @@ -79,7 +81,10 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T .map(|(idx, it)| { // FIXME: a hacky way to create a Name from string. let name = tt::Ident { text: it.name.clone(), id: tt::TokenId::unspecified() }; - (name.as_name(), ProcMacroExpander::new(def_map.krate, ProcMacroId(idx as u32))) + ( + name.as_name(), + ProcMacroExpander::new(def_map.krate, base_db::ProcMacroId(idx as u32)), + ) }) .collect(); @@ -543,28 +548,26 @@ impl DefCollector<'_> { /// use a dummy expander that always errors. This comes with the drawback of macros potentially /// going out of sync with what the build system sees (since we resolve using VFS state, but /// Cargo builds only on-disk files). We could and probably should add diagnostics for that. - fn export_proc_macro(&mut self, def: ProcMacroDef, ast_id: AstId<ast::Fn>) { + fn export_proc_macro( + &mut self, + def: ProcMacroDef, + id: ItemTreeId<item_tree::Function>, + module_id: ModuleId, + ) { let kind = def.kind.to_basedb_kind(); self.exports_proc_macros = true; - let macro_def = match self.proc_macros.iter().find(|(n, _)| n == &def.name) { - Some(&(_, expander)) => MacroDefId { - krate: self.def_map.krate, - kind: MacroDefKind::ProcMacro(expander, kind, ast_id), - local_inner: false, - }, - None => MacroDefId { - krate: self.def_map.krate, - kind: MacroDefKind::ProcMacro( - ProcMacroExpander::dummy(self.def_map.krate), - kind, - ast_id, - ), - local_inner: false, - }, + + let (expander, kind) = match self.proc_macros.iter().find(|(n, _)| n == &def.name) { + Some(&(_, expander)) => (expander, kind), + None => (ProcMacroExpander::dummy(self.def_map.krate), kind), }; - self.define_proc_macro(def.name.clone(), macro_def); - self.def_map.exported_proc_macros.insert(macro_def, def); + let proc_macro_id = + ProcMacroLoc { container: module_id, id, expander, kind }.intern(self.db); + self.define_proc_macro(def.name.clone(), proc_macro_id.into()); + self.def_map + .exported_proc_macros + .insert(macro_id_to_def_id(self.db, proc_macro_id.into()), def); } /// Define a macro with `macro_rules`. @@ -596,11 +599,12 @@ impl DefCollector<'_> { &mut self, module_id: LocalModuleId, name: Name, - macro_: MacroDefId, + macro_: MacroRulesId, export: bool, ) { // Textual scoping self.define_legacy_macro(module_id, name.clone(), macro_); + let macro_ = macro_.into(); self.def_map.modules[module_id].scope.declare_macro(macro_); // Module scoping @@ -623,7 +627,7 @@ impl DefCollector<'_> { /// the definition of current module. /// And also, `macro_use` on a module will import all legacy macros visible inside to /// current legacy scope, with possible shadowing. - fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroDefId) { + fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroRulesId) { // Always shadowing self.def_map.modules[module_id].scope.define_legacy_macro(name, mac); } @@ -635,11 +639,12 @@ impl DefCollector<'_> { &mut self, module_id: LocalModuleId, name: Name, - macro_: MacroDefId, + macro_: Macro2Id, vis: &RawVisibility, ) { let vis = self.def_map.resolve_visibility(self.db, module_id, vis).unwrap_or(Visibility::Public); + let macro_ = macro_.into(); self.def_map.modules[module_id].scope.declare_macro(macro_); self.update(module_id, &[(Some(name), PerNs::macros(macro_, vis))], vis, ImportType::Named); } @@ -648,7 +653,8 @@ impl DefCollector<'_> { /// /// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped. /// And unconditionally exported. - fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) { + fn define_proc_macro(&mut self, name: Name, macro_: ProcMacroId) { + let macro_ = macro_.into(); self.def_map.modules[self.def_map.root].scope.declare_macro(macro_); self.update( self.def_map.root, @@ -691,8 +697,10 @@ impl DefCollector<'_> { fn import_all_macros_exported(&mut self, current_module_id: LocalModuleId, krate: CrateId) { let def_map = self.db.crate_def_map(krate); for (name, def) in def_map[def_map.root].scope.macros() { - // `macro_use` only bring things into legacy scope. - self.define_legacy_macro(current_module_id, name.clone(), def); + if let MacroId::MacroRulesId(def) = def { + // `macro_use` only bring things into legacy scope. + self.define_legacy_macro(current_module_id, name.clone(), def); + } } } @@ -1049,7 +1057,7 @@ impl DefCollector<'_> { &path, BuiltinShadowMode::Module, ); - resolved_res.resolved_def.take_macros() + resolved_res.resolved_def.take_macros().map(|it| macro_id_to_def_id(self.db, it)) }; match &directive.kind { @@ -1339,7 +1347,10 @@ impl DefCollector<'_> { &path, BuiltinShadowMode::Module, ); - resolved_res.resolved_def.take_macros() + resolved_res + .resolved_def + .take_macros() + .map(|it| macro_id_to_def_id(self.db, it)) }, &mut |_| (), ); @@ -1525,10 +1536,9 @@ impl ModCollector<'_, '_> { ), ), ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container), - ModItem::MacroRules(id) => self.collect_macro_rules(id), - ModItem::MacroDef(id) => self.collect_macro_def(id), + ModItem::MacroRules(id) => self.collect_macro_rules(id, module), + ModItem::MacroDef(id) => self.collect_macro_def(id, module), ModItem::Impl(imp) => { - let module = self.def_collector.def_map.module_id(self.module_id); let impl_id = ImplLoc { container: module, id: ItemTreeId::new(self.tree_id, imp) } .intern(db); @@ -1541,9 +1551,13 @@ impl ModCollector<'_, '_> { let vis = match is_proc_macro { Some(proc_macro) => { // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere - let ast_id = InFile::new(self.tree_id.file_id(), it.ast_id); let module_id = def_map.module_id(def_map.root()); - self.def_collector.export_proc_macro(proc_macro, ast_id); + + self.def_collector.export_proc_macro( + proc_macro, + ItemTreeId::new(self.tree_id, id), + module_id, + ); Visibility::Module(module_id) } None => resolve_vis(def_map, &self.item_tree[it.visibility]), @@ -1845,7 +1859,7 @@ impl ModCollector<'_, '_> { Ok(()) } - fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { + fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>, module: ModuleId) { let krate = self.def_collector.def_map.krate; let mac = &self.item_tree[id]; let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); @@ -1854,7 +1868,7 @@ impl ModCollector<'_, '_> { let export_attr = attrs.by_key("macro_export"); let is_export = export_attr.exists(); - let is_local_inner = if is_export { + let local_inner = if is_export { export_attr.tt_values().flat_map(|it| &it.token_trees).any(|it| match it { tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { ident.text.contains("local_inner_macros") @@ -1866,7 +1880,7 @@ impl ModCollector<'_, '_> { }; // Case 1: builtin macros - if attrs.by_key("rustc_builtin_macro").exists() { + let expander = if attrs.by_key("rustc_builtin_macro").exists() { // `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name. let name; let name = match attrs.by_key("rustc_builtin_macro").string_value() { @@ -1892,32 +1906,29 @@ impl ModCollector<'_, '_> { } } }; - let krate = self.def_collector.def_map.krate; - match find_builtin_macro(name, krate, ast_id) { - Some(macro_id) => { - self.def_collector.define_macro_rules( - self.module_id, - mac.name.clone(), - macro_id, - is_export, - ); - return; - } + match find_builtin_macro(name) { + Some(Either::Left(it)) => MacroExpander::BuiltIn(it), + Some(Either::Right(it)) => MacroExpander::BuiltInEager(it), None => { self.def_collector .def_map .diagnostics .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id)); + return; } } - } - - // Case 2: normal `macro_rules!` macro - let macro_id = MacroDefId { - krate: self.def_collector.def_map.krate, - kind: MacroDefKind::Declarative(ast_id), - local_inner: is_local_inner, + } else { + // Case 2: normal `macro_rules!` macro + MacroExpander::Declarative }; + + let macro_id = MacroRulesLoc { + container: module, + id: ItemTreeId::new(self.tree_id, id), + local_inner, + expander, + } + .intern(self.def_collector.db); self.def_collector.define_macro_rules( self.module_id, mac.name.clone(), @@ -1926,44 +1937,38 @@ impl ModCollector<'_, '_> { ); } - fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>) { + fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>, module: ModuleId) { let krate = self.def_collector.def_map.krate; let mac = &self.item_tree[id]; let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast()); // Case 1: builtin macros let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); - if attrs.by_key("rustc_builtin_macro").exists() { - let macro_id = find_builtin_macro(&mac.name, krate, ast_id) - .or_else(|| find_builtin_derive(&mac.name, krate, ast_id)) - .or_else(|| find_builtin_attr(&mac.name, krate, ast_id)); - - match macro_id { - Some(macro_id) => { - self.def_collector.define_macro_def( - self.module_id, - mac.name.clone(), - macro_id, - &self.item_tree[mac.visibility], - ); - return; - } - None => { - self.def_collector - .def_map - .diagnostics - .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id)); + let expander = if attrs.by_key("rustc_builtin_macro").exists() { + if let Some(expander) = find_builtin_macro(&mac.name) { + match expander { + Either::Left(it) => MacroExpander::BuiltIn(it), + Either::Right(it) => MacroExpander::BuiltInEager(it), } + } else if let Some(expander) = find_builtin_derive(&mac.name) { + MacroExpander::BuiltInDerive(expander) + } else if let Some(expander) = find_builtin_attr(&mac.name) { + MacroExpander::BuiltInAttr(expander) + } else { + self.def_collector + .def_map + .diagnostics + .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id)); + return; } - } - - // Case 2: normal `macro` - let macro_id = MacroDefId { - krate: self.def_collector.def_map.krate, - kind: MacroDefKind::Declarative(ast_id), - local_inner: false, + } else { + // Case 2: normal `macro` + MacroExpander::Declarative }; + let macro_id = + Macro2Loc { container: module, id: ItemTreeId::new(self.tree_id, id), expander } + .intern(self.def_collector.db); self.def_collector.define_macro_def( self.module_id, mac.name.clone(), @@ -1987,7 +1992,12 @@ impl ModCollector<'_, '_> { self.def_collector.def_map.with_ancestor_maps( self.def_collector.db, self.module_id, - &mut |map, module| map[module].scope.get_legacy_macro(name), + &mut |map, module| { + map[module] + .scope + .get_legacy_macro(name) + .map(|it| macro_id_to_def_id(self.def_collector.db, it.into())) + }, ) }) }, diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index 30f11cc694..809c6e0289 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs @@ -389,7 +389,7 @@ impl DefMap { let from_legacy_macro = self[module] .scope .get_legacy_macro(name) - .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public)); + .map_or_else(PerNs::none, |m| PerNs::macros(m.into(), Visibility::Public)); let from_scope = self[module].scope.get(name); let from_builtin = match self.block { Some(_) => { diff --git a/crates/hir_def/src/nameres/tests/incremental.rs b/crates/hir_def/src/nameres/tests/incremental.rs index b2828831a1..2e8cb3621f 100644 --- a/crates/hir_def/src/nameres/tests/incremental.rs +++ b/crates/hir_def/src/nameres/tests/incremental.rs @@ -226,6 +226,7 @@ pub type Ty = (); ModuleDefId::TypeAliasId(it) => drop(db.type_alias_data(it)), ModuleDefId::EnumVariantId(_) | ModuleDefId::ModuleId(_) + | ModuleDefId::MacroId(_) | ModuleDefId::BuiltinType(_) => unreachable!(), } } diff --git a/crates/hir_def/src/per_ns.rs b/crates/hir_def/src/per_ns.rs index a9f13cb820..bf5bf10c4c 100644 --- a/crates/hir_def/src/per_ns.rs +++ b/crates/hir_def/src/per_ns.rs @@ -3,15 +3,13 @@ //! //! `PerNs` (per namespace) captures this. -use hir_expand::MacroDefId; - -use crate::{item_scope::ItemInNs, visibility::Visibility, ModuleDefId}; +use crate::{item_scope::ItemInNs, visibility::Visibility, MacroId, ModuleDefId}; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct PerNs { pub types: Option<(ModuleDefId, Visibility)>, pub values: Option<(ModuleDefId, Visibility)>, - pub macros: Option<(MacroDefId, Visibility)>, + pub macros: Option<(MacroId, Visibility)>, } impl Default for PerNs { @@ -37,7 +35,7 @@ impl PerNs { PerNs { types: Some((types, v)), values: Some((values, v)), macros: None } } - pub fn macros(macro_: MacroDefId, v: Visibility) -> PerNs { + pub fn macros(macro_: MacroId, v: Visibility) -> PerNs { PerNs { types: None, values: None, macros: Some((macro_, v)) } } @@ -57,7 +55,7 @@ impl PerNs { self.values.map(|it| it.0) } - pub fn take_macros(self) -> Option<MacroDefId> { + pub fn take_macros(self) -> Option<MacroId> { self.macros.map(|it| it.0) } diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index d5e62f226a..fcca84538a 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs @@ -2,10 +2,7 @@ use std::sync::Arc; use base_db::CrateId; -use hir_expand::{ - name::{name, Name}, - MacroDefId, -}; +use hir_expand::name::{name, Name}; use indexmap::IndexMap; use rustc_hash::FxHashSet; use smallvec::{smallvec, SmallVec}; @@ -24,8 +21,8 @@ use crate::{ visibility::{RawVisibility, Visibility}, AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, - LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, - TypeOrConstParamId, TypeParamId, VariantId, + LocalModuleId, Lookup, MacroId, ModuleDefId, ModuleId, StaticId, StructId, TraitId, + TypeAliasId, TypeOrConstParamId, TypeParamId, VariantId, }; #[derive(Debug, Clone, Default)] @@ -347,11 +344,7 @@ impl Resolver { } } - pub fn resolve_path_as_macro( - &self, - db: &dyn DefDatabase, - path: &ModPath, - ) -> Option<MacroDefId> { + pub fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroId> { let (item_map, module) = self.module_scope()?; item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros() } @@ -485,7 +478,6 @@ impl Resolver { #[derive(Debug, PartialEq, Eq)] pub enum ScopeDef { ModuleDef(ModuleDefId), - MacroDef(MacroDefId), Unknown, ImplSelfType(ImplId), AdtSelfType(AdtId), @@ -509,7 +501,7 @@ impl Scope { acc.add_per_ns(name, def); }); m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, mac)| { - acc.add(name, ScopeDef::MacroDef(mac)); + acc.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac)))); }); m.def_map.extern_prelude().for_each(|(name, &def)| { acc.add(name, ScopeDef::ModuleDef(def)); @@ -651,6 +643,7 @@ impl ModuleItemMap { | ModuleDefId::FunctionId(_) | ModuleDefId::EnumVariantId(_) | ModuleDefId::ConstId(_) + | ModuleDefId::MacroId(_) | ModuleDefId::StaticId(_) => return None, }; Some(ResolveValueResult::Partial(ty, idx)) @@ -682,6 +675,7 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> { | ModuleDefId::TraitId(_) | ModuleDefId::TypeAliasId(_) | ModuleDefId::BuiltinType(_) + | ModuleDefId::MacroId(_) | ModuleDefId::ModuleId(_) => return None, }; Some(res) @@ -699,6 +693,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> { ModuleDefId::FunctionId(_) | ModuleDefId::ConstId(_) + | ModuleDefId::MacroId(_) | ModuleDefId::StaticId(_) | ModuleDefId::ModuleId(_) => return None, }; @@ -718,14 +713,14 @@ impl ScopeNames { } } fn add_per_ns(&mut self, name: &Name, def: PerNs) { - if let Some(ty) = &def.types { - self.add(name, ScopeDef::ModuleDef(ty.0)) + if let &Some((ty, _)) = &def.types { + self.add(name, ScopeDef::ModuleDef(ty)) } - if let Some(val) = &def.values { - self.add(name, ScopeDef::ModuleDef(val.0)) + if let &Some((def, _)) = &def.values { + self.add(name, ScopeDef::ModuleDef(def)) } - if let Some(mac) = &def.macros { - self.add(name, ScopeDef::MacroDef(mac.0)) + if let &Some((mac, _)) = &def.macros { + self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac))) } if def.is_none() { self.add(name, ScopeDef::Unknown) diff --git a/crates/hir_def/src/src.rs b/crates/hir_def/src/src.rs index 24e57b4692..f69356cac8 100644 --- a/crates/hir_def/src/src.rs +++ b/crates/hir_def/src/src.rs @@ -2,8 +2,12 @@ use hir_expand::InFile; use la_arena::ArenaMap; +use syntax::ast; -use crate::{db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc}; +use crate::{ + db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc, Macro2Loc, MacroRulesLoc, + ProcMacroLoc, +}; pub trait HasSource { type Value; @@ -36,6 +40,45 @@ impl<N: ItemTreeNode> HasSource for ItemLoc<N> { } } +impl HasSource for Macro2Loc { + type Value = ast::MacroDef; + + fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> { + let tree = self.id.item_tree(db); + let ast_id_map = db.ast_id_map(self.id.file_id()); + let root = db.parse_or_expand(self.id.file_id()).unwrap(); + let node = &tree[self.id.value]; + + InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root)) + } +} + +impl HasSource for MacroRulesLoc { + type Value = ast::MacroRules; + + fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> { + let tree = self.id.item_tree(db); + let ast_id_map = db.ast_id_map(self.id.file_id()); + let root = db.parse_or_expand(self.id.file_id()).unwrap(); + let node = &tree[self.id.value]; + + InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root)) + } +} + +impl HasSource for ProcMacroLoc { + type Value = ast::Fn; + + fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> { + let tree = self.id.item_tree(db); + let ast_id_map = db.ast_id_map(self.id.file_id()); + let root = db.parse_or_expand(self.id.file_id()).unwrap(); + let node = &tree[self.id.value]; + + InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root)) + } +} + pub trait HasChildSource<ChildId> { type Value; fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<ChildId, Self::Value>>; diff --git a/crates/hir_expand/src/builtin_attr_macro.rs b/crates/hir_expand/src/builtin_attr_macro.rs index 6301da1c83..6535f27a63 100644 --- a/crates/hir_expand/src/builtin_attr_macro.rs +++ b/crates/hir_expand/src/builtin_attr_macro.rs @@ -1,12 +1,8 @@ //! Builtin attributes. use itertools::Itertools; -use syntax::ast; -use crate::{ - db::AstDatabase, name, AstId, CrateId, ExpandResult, MacroCallId, MacroCallKind, MacroDefId, - MacroDefKind, -}; +use crate::{db::AstDatabase, name, ExpandResult, MacroCallId, MacroCallKind}; macro_rules! register_builtin { ( $(($name:ident, $variant:ident) => $expand:ident),* ) => { @@ -61,17 +57,8 @@ register_builtin! { (test_case, TestCase) => dummy_attr_expand } -pub fn find_builtin_attr( - ident: &name::Name, - krate: CrateId, - ast_id: AstId<ast::Macro>, -) -> Option<MacroDefId> { - let expander = BuiltinAttrExpander::find_by_name(ident)?; - Some(MacroDefId { - krate, - kind: MacroDefKind::BuiltInAttr(expander, ast_id), - local_inner: false, - }) +pub fn find_builtin_attr(ident: &name::Name) -> Option<BuiltinAttrExpander> { + BuiltinAttrExpander::find_by_name(ident) } fn dummy_attr_expand( diff --git a/crates/hir_expand/src/builtin_derive_macro.rs b/crates/hir_expand/src/builtin_derive_macro.rs index d56cd99269..5a909e9a50 100644 --- a/crates/hir_expand/src/builtin_derive_macro.rs +++ b/crates/hir_expand/src/builtin_derive_macro.rs @@ -8,10 +8,7 @@ use syntax::{ }; use tt::TokenId; -use crate::{ - db::AstDatabase, name, quote, AstId, CrateId, ExpandError, ExpandResult, MacroCallId, - MacroDefId, MacroDefKind, -}; +use crate::{db::AstDatabase, name, quote, ExpandError, ExpandResult, MacroCallId}; macro_rules! register_builtin { ( $($trait:ident => $expand:ident),* ) => { @@ -56,17 +53,8 @@ register_builtin! { PartialEq => partial_eq_expand } -pub fn find_builtin_derive( - ident: &name::Name, - krate: CrateId, - ast_id: AstId<ast::Macro>, -) -> Option<MacroDefId> { - let expander = BuiltinDeriveExpander::find_by_name(ident)?; - Some(MacroDefId { - krate, - kind: MacroDefKind::BuiltInDerive(expander, ast_id), - local_inner: false, - }) +pub fn find_builtin_derive(ident: &name::Name) -> Option<BuiltinDeriveExpander> { + BuiltinDeriveExpander::find_by_name(ident) } struct BasicAdtInfo { diff --git a/crates/hir_expand/src/builtin_fn_macro.rs b/crates/hir_expand/src/builtin_fn_macro.rs index f69742971e..bdea31a166 100644 --- a/crates/hir_expand/src/builtin_fn_macro.rs +++ b/crates/hir_expand/src/builtin_fn_macro.rs @@ -9,10 +9,7 @@ use syntax::{ SmolStr, }; -use crate::{ - db::AstDatabase, name, quote, AstId, CrateId, ExpandError, ExpandResult, MacroCallId, - MacroCallLoc, MacroDefId, MacroDefKind, -}; +use crate::{db::AstDatabase, name, quote, ExpandError, ExpandResult, MacroCallId, MacroCallLoc}; macro_rules! register_builtin { ( LAZY: $(($name:ident, $kind: ident) => $expand:ident),* , EAGER: $(($e_name:ident, $e_kind: ident) => $e_expand:ident),* ) => { @@ -79,23 +76,8 @@ impl ExpandedEager { pub fn find_builtin_macro( ident: &name::Name, - krate: CrateId, - ast_id: AstId<ast::Macro>, -) -> Option<MacroDefId> { - let kind = find_by_name(ident)?; - - match kind { - Either::Left(kind) => Some(MacroDefId { - krate, - kind: MacroDefKind::BuiltIn(kind, ast_id), - local_inner: false, - }), - Either::Right(kind) => Some(MacroDefId { - krate, - kind: MacroDefKind::BuiltInEager(kind, ast_id), - local_inner: false, - }), - } +) -> Option<Either<BuiltinFnLikeExpander, EagerExpander>> { + find_by_name(ident) } register_builtin! { |