diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs index c6a90932015..5fe1f0ebd1f 100644 --- a/crates/hir-def/src/body/lower.rs +++ b/crates/hir-def/src/body/lower.rs @@ -959,20 +959,29 @@ impl ExprCollector<'_> { // File containing the macro call. Expansion errors will be attached here. let outer_file = self.expander.current_file_id; - let macro_call_ptr = self.expander.to_source(AstPtr::new(&mcall)); + let macro_call_ptr = self.expander.to_source(syntax_ptr); let module = self.expander.module.local_id; - let res = self.expander.enter_expand(self.db, mcall, |path| { - self.def_map - .resolve_path( - self.db, - module, - &path, - crate::item_scope::BuiltinShadowMode::Other, - Some(MacroSubNs::Bang), - ) - .0 - .take_macros() - }); + + let res = match self.def_map.modules[module] + .scope + .macro_invocations + .get(&InFile::new(outer_file, self.ast_id_map.ast_id_for_ptr(syntax_ptr))) + { + // fast path, macro call is in a block module + Some(&call) => Ok(self.expander.enter_expand_id(self.db, call)), + None => self.expander.enter_expand(self.db, mcall, |path| { + self.def_map + .resolve_path( + self.db, + module, + &path, + crate::item_scope::BuiltinShadowMode::Other, + Some(MacroSubNs::Bang), + ) + .0 + .take_macros() + }), + }; let res = match res { Ok(res) => res, @@ -986,7 +995,6 @@ impl ExprCollector<'_> { return collector(self, None); } }; - if record_diagnostics { match &res.err { Some(ExpandError::UnresolvedProcMacro(krate)) => { diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs index 635d13f24ad..9c183c9332b 100644 --- a/crates/hir-def/src/data.rs +++ b/crates/hir-def/src/data.rs @@ -16,7 +16,7 @@ use crate::{ db::DefDatabase, expander::{Expander, Mark}, item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId}, - macro_call_as_call_id, macro_id_to_def_id, + macro_call_as_call_id, nameres::{ attr_resolution::ResolvedAttr, diagnostics::DefDiagnostic, @@ -720,7 +720,7 @@ impl<'a> AssocItemCollector<'a> { ) .0 .take_macros() - .map(|it| macro_id_to_def_id(self.db, it)) + .map(|it| self.db.macro_def(it)) }; match macro_call_as_call_id( self.db.upcast(), diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index 31c1a713031..d42f4efa1f7 100644 --- a/crates/hir-def/src/db.rs +++ b/crates/hir-def/src/db.rs @@ -1,7 +1,7 @@ //! Defines database & queries for name resolution. use base_db::{salsa, CrateId, SourceDatabase, Upcast}; use either::Either; -use hir_expand::{db::ExpandDatabase, HirFileId}; +use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId}; use intern::Interned; use la_arena::ArenaMap; use syntax::{ast, AstPtr}; @@ -24,9 +24,9 @@ use crate::{ AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, InTypeConstId, InTypeConstLoc, LocalEnumVariantId, - LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId, MacroRulesLoc, ProcMacroId, ProcMacroLoc, - StaticId, StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, - TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, + LocalFieldId, Macro2Id, Macro2Loc, MacroId, MacroRulesId, MacroRulesLoc, ProcMacroId, + ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId, + TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -110,6 +110,8 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast Arc; + fn macro_def(&self, m: MacroId) -> MacroDefId; + // region:data #[salsa::invoke(StructData::struct_data_query)] @@ -305,3 +307,63 @@ fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool { false } + +fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { + use hir_expand::InFile; + + use crate::{Lookup, MacroDefKind, MacroExpander}; + + let kind = |expander, file_id, m| { + let in_file = InFile::new(file_id, m); + match expander { + MacroExpander::Declarative => MacroDefKind::Declarative(in_file), + MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file), + MacroExpander::BuiltInAttr(it) => MacroDefKind::BuiltInAttr(it, in_file), + MacroExpander::BuiltInDerive(it) => MacroDefKind::BuiltInDerive(it, in_file), + MacroExpander::BuiltInEager(it) => MacroDefKind::BuiltInEager(it, in_file), + } + }; + + 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]; + MacroDefId { + krate: loc.container.krate, + kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()), + local_inner: false, + allow_internal_unsafe: loc.allow_internal_unsafe, + } + } + MacroId::MacroRulesId(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: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()), + local_inner: loc.local_inner, + allow_internal_unsafe: loc.allow_internal_unsafe, + } + } + 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, + allow_internal_unsafe: false, + } + } + } +} diff --git a/crates/hir-def/src/expander.rs b/crates/hir-def/src/expander.rs index 490fd5382cd..c1936eb1893 100644 --- a/crates/hir-def/src/expander.rs +++ b/crates/hir-def/src/expander.rs @@ -11,8 +11,8 @@ use limit::Limit; use syntax::{ast, Parse, SyntaxNode}; use crate::{ - attr::Attrs, db::DefDatabase, lower::LowerCtx, macro_id_to_def_id, path::Path, AsMacroCall, - MacroId, ModuleId, UnresolvedMacro, + attr::Attrs, db::DefDatabase, lower::LowerCtx, path::Path, AsMacroCall, MacroId, ModuleId, + UnresolvedMacro, }; #[derive(Debug)] @@ -58,7 +58,7 @@ impl Expander { let result = self.within_limit(db, |this| { let macro_call = InFile::new(this.current_file_id, ¯o_call); match macro_call.as_call_id_with_errors(db.upcast(), this.module.krate(), |path| { - resolver(path).map(|it| macro_id_to_def_id(db, it)) + resolver(path).map(|it| db.macro_def(it)) }) { Ok(call_id) => call_id, Err(resolve_err) => { diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index ce83cb435e2..4902f24e2e3 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -102,8 +102,10 @@ pub struct ItemScope { // 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>, - /// The derive macro invocations in this scope. + /// The attribute macro invocations in this scope. attr_macros: FxHashMap, MacroCallId>, + /// The macro invocations in this scope. + pub macro_invocations: FxHashMap, 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. derive_macros: FxHashMap, SmallVec<[DeriveMacroInvocation; 1]>>, @@ -345,6 +347,10 @@ impl ItemScope { self.attr_macros.insert(item, call); } + pub(crate) fn add_macro_invoc(&mut self, call: AstId, call_id: MacroCallId) { + self.macro_invocations.insert(call, call_id); + } + pub(crate) fn attr_macro_invocs( &self, ) -> impl Iterator, MacroCallId)> + '_ { @@ -692,6 +698,7 @@ impl ItemScope { use_imports_values, use_imports_types, use_imports_macros, + macro_invocations, } = self; types.shrink_to_fit(); values.shrink_to_fit(); @@ -709,6 +716,7 @@ impl ItemScope { derive_macros.shrink_to_fit(); extern_crate_decls.shrink_to_fit(); use_decls.shrink_to_fit(); + macro_invocations.shrink_to_fit(); } } diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index cf087613bf4..20e4e44339e 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -29,6 +29,9 @@ //! //! In general, any item in the `ItemTree` stores its `AstId`, which allows mapping it back to its //! surface syntax. +//! +//! Note that we cannot store [`span::Span`]s inside of this, as typing in an item invalidates its +//! encompassing span! mod lower; mod pretty; @@ -281,7 +284,7 @@ struct ItemTreeData { mods: Arena, macro_calls: Arena, macro_rules: Arena, - macro_defs: Arena, + macro_defs: Arena, vis: ItemVisibilities, } @@ -514,7 +517,7 @@ mod_items! { Mod in mods -> ast::Module, MacroCall in macro_calls -> ast::MacroCall, MacroRules in macro_rules -> ast::MacroRules, - MacroDef in macro_defs -> ast::MacroDef, + Macro2 in macro_defs -> ast::MacroDef, } macro_rules! impl_index { @@ -747,6 +750,7 @@ pub struct MacroCall { pub path: Interned, pub ast_id: FileAstId, pub expand_to: ExpandTo, + // FIXME: We need to move this out. It invalidates the item tree when typing inside the macro call. pub call_site: Span, } @@ -759,7 +763,7 @@ pub struct MacroRules { /// "Macros 2.0" macro definition. #[derive(Debug, Clone, Eq, PartialEq)] -pub struct MacroDef { +pub struct Macro2 { pub name: Name, pub visibility: RawVisibilityId, pub ast_id: FileAstId, @@ -918,7 +922,7 @@ impl ModItem { | ModItem::Impl(_) | ModItem::Mod(_) | ModItem::MacroRules(_) - | ModItem::MacroDef(_) => None, + | ModItem::Macro2(_) => None, ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), ModItem::Const(konst) => Some(AssocItem::Const(*konst)), ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), @@ -944,7 +948,7 @@ impl ModItem { ModItem::Mod(it) => tree[it.index()].ast_id().upcast(), ModItem::MacroCall(it) => tree[it.index()].ast_id().upcast(), ModItem::MacroRules(it) => tree[it.index()].ast_id().upcast(), - ModItem::MacroDef(it) => tree[it.index()].ast_id().upcast(), + ModItem::Macro2(it) => tree[it.index()].ast_id().upcast(), } } } diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index d1043a5bd0b..8e2fafe81b5 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -562,13 +562,13 @@ impl<'a> Ctx<'a> { Some(id(self.data().macro_rules.alloc(res))) } - fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option> { + fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option> { let name = m.name().map(|it| it.as_name())?; let ast_id = self.source_ast_id_map.ast_id(m); let visibility = self.lower_visibility(m); - let res = MacroDef { name, ast_id, visibility }; + let res = Macro2 { name, ast_id, visibility }; Some(id(self.data().macro_defs.alloc(res))) } diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs index 244111d202c..6d92fce0727 100644 --- a/crates/hir-def/src/item_tree/pretty.rs +++ b/crates/hir-def/src/item_tree/pretty.rs @@ -464,8 +464,8 @@ impl Printer<'_> { let MacroRules { name, ast_id: _ } = &self.tree[it]; wln!(self, "macro_rules! {} {{ ... }}", name.display(self.db.upcast())); } - ModItem::MacroDef(it) => { - let MacroDef { name, visibility, ast_id: _ } = &self.tree[it]; + ModItem::Macro2(it) => { + let Macro2 { name, visibility, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); wln!(self, "macro {} {{ ... }}", name.display(self.db.upcast())); } diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 9a7d406dfd5..37f96df2699 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -92,7 +92,7 @@ use crate::{ data::adt::VariantData, db::DefDatabase, item_tree::{ - Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, + Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, Macro2, MacroRules, Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, }, }; @@ -366,7 +366,7 @@ pub struct Macro2Id(salsa::InternId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Macro2Loc { pub container: ModuleId, - pub id: ItemTreeId, + pub id: ItemTreeId, pub expander: MacroExpander, pub allow_internal_unsafe: bool, } @@ -1223,77 +1223,6 @@ fn macro_call_as_call_id_with_eager( Ok(res) } -pub fn macro_id_to_def_id(db: &dyn 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| 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, - allow_internal_unsafe: loc.allow_internal_unsafe, - } - } - 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| 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, - allow_internal_unsafe: loc.allow_internal_unsafe, - } - } - 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, - allow_internal_unsafe: false, - } - } - } -} - fn derive_macro_as_call_id( db: &dyn DefDatabase, item_attr: &AstIdWithPath, diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs index a25f2d29220..ee806361237 100644 --- a/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -36,7 +36,6 @@ use test_fixture::WithFixture; use crate::{ db::DefDatabase, - macro_id_to_def_id, nameres::{DefMap, MacroSubNs, ModuleSource}, resolver::HasResolver, src::HasSource, @@ -97,7 +96,7 @@ 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, Some(MacroSubNs::Bang)) - .map(|(it, _)| macro_id_to_def_id(&db, it)) + .map(|(it, _)| db.macro_def(it)) }) .unwrap(); let macro_call_id = res.value.unwrap(); diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 41560c05451..31b87a81e88 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -100,7 +100,7 @@ pub struct DefMap { /// contains this block. block: Option, /// The modules and their data declared in this crate. - modules: Arena, + pub modules: Arena, krate: CrateId, /// The prelude module for this crate. This either comes from an import /// marked with the `prelude_import` attribute, or (in the normal case) from diff --git a/crates/hir-def/src/nameres/attr_resolution.rs b/crates/hir-def/src/nameres/attr_resolution.rs index a7abf445918..6288b8366bf 100644 --- a/crates/hir-def/src/nameres/attr_resolution.rs +++ b/crates/hir-def/src/nameres/attr_resolution.rs @@ -8,7 +8,6 @@ use crate::{ attr_macro_as_call_id, db::DefDatabase, item_scope::BuiltinShadowMode, - macro_id_to_def_id, nameres::path_resolution::ResolveMode, path::{ModPath, PathKind}, AstIdWithPath, LocalModuleId, UnresolvedMacro, @@ -63,7 +62,7 @@ impl DefMap { &ast_id, attr, self.krate, - macro_id_to_def_id(db, def), + db.macro_def(def), ))) } diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index 541edf0845d..095534058cc 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -36,9 +36,9 @@ use crate::{ item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports}, item_tree::{ self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode, - MacroCall, MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId, + Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, }, - macro_call_as_call_id, macro_call_as_call_id_with_eager, macro_id_to_def_id, + macro_call_as_call_id, macro_call_as_call_id_with_eager, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, @@ -618,9 +618,7 @@ impl DefCollector<'_> { self.define_proc_macro(def.name.clone(), proc_macro_id); let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap(); if let ProcMacroKind::CustomDerive { helpers } = def.kind { - crate_data - .exported_derives - .insert(macro_id_to_def_id(self.db, proc_macro_id.into()), helpers); + crate_data.exported_derives.insert(self.db.macro_def(proc_macro_id.into()), helpers); } crate_data.fn_proc_macro_mapping.insert(fn_id, proc_macro_id); } @@ -1131,10 +1129,7 @@ impl DefCollector<'_> { BuiltinShadowMode::Module, Some(subns), ); - resolved_res - .resolved_def - .take_macros() - .map(|it| (it, macro_id_to_def_id(self.db, it))) + resolved_res.resolved_def.take_macros().map(|it| (it, self.db.macro_def(it))) }; let resolver_def_id = |path| resolver(path).map(|(_, it)| it); @@ -1149,6 +1144,9 @@ impl DefCollector<'_> { resolver_def_id, ); if let Ok(Some(call_id)) = call_id { + self.def_map.modules[directive.module_id] + .scope + .add_macro_invoc(ast_id.ast_id, call_id); push_resolved(directive, call_id); res = ReachedFixedPoint::No; @@ -1441,10 +1439,7 @@ impl DefCollector<'_> { BuiltinShadowMode::Module, Some(MacroSubNs::Bang), ); - resolved_res - .resolved_def - .take_macros() - .map(|it| macro_id_to_def_id(self.db, it)) + resolved_res.resolved_def.take_macros().map(|it| self.db.macro_def(it)) }, ); if let Err(UnresolvedMacro { path }) = macro_call_as_call_id { @@ -1650,7 +1645,7 @@ impl ModCollector<'_, '_> { ), ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container), ModItem::MacroRules(id) => self.collect_macro_rules(id, module), - ModItem::MacroDef(id) => self.collect_macro_def(id, module), + ModItem::Macro2(id) => self.collect_macro_def(id, module), ModItem::Impl(imp) => { let impl_id = ImplLoc { container: module, id: ItemTreeId::new(self.tree_id, imp) } @@ -2157,7 +2152,7 @@ impl ModCollector<'_, '_> { ); } - fn collect_macro_def(&mut self, id: FileItemTreeId, module: ModuleId) { + fn collect_macro_def(&mut self, id: FileItemTreeId, 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()); @@ -2225,7 +2220,7 @@ impl ModCollector<'_, '_> { Arc::get_mut(&mut self.def_collector.def_map.data) .unwrap() .exported_derives - .insert(macro_id_to_def_id(self.def_collector.db, macro_id.into()), helpers); + .insert(self.def_collector.db.macro_def(macro_id.into()), helpers); } } } @@ -2264,7 +2259,7 @@ impl ModCollector<'_, '_> { Some(MacroSubNs::Bang), ) }) - .map(|it| macro_id_to_def_id(self.def_collector.db, it)) + .map(|it| self.def_collector.db.macro_def(it)) }) }, |path| { @@ -2276,7 +2271,7 @@ impl ModCollector<'_, '_> { BuiltinShadowMode::Module, Some(MacroSubNs::Bang), ); - resolved_res.resolved_def.take_macros().map(|it| macro_id_to_def_id(db, it)) + resolved_res.resolved_def.take_macros().map(|it| db.macro_def(it)) }, ) { // FIXME: if there were errors, this mightve been in the eager expansion from an @@ -2284,10 +2279,13 @@ impl ModCollector<'_, '_> { if res.err.is_none() { // Legacy macros need to be expanded immediately, so that any macros they produce // are in scope. - if let Some(val) = res.value { + if let Some(call_id) = res.value { + self.def_collector.def_map.modules[self.module_id] + .scope + .add_macro_invoc(ast_id.ast_id, call_id); self.def_collector.collect_macro_expansion( self.module_id, - val, + call_id, self.macro_depth + 1, container, ); @@ -2301,7 +2299,7 @@ impl ModCollector<'_, '_> { self.def_collector.unresolved_macros.push(MacroDirective { module_id: self.module_id, depth: self.macro_depth + 1, - kind: MacroDirectiveKind::FnLike { ast_id, expand_to: expand_to, call_site }, + kind: MacroDirectiveKind::FnLike { ast_id, expand_to, call_site }, container, }); } diff --git a/crates/hir-expand/src/ast_id_map.rs b/crates/hir-expand/src/ast_id_map.rs index 2abeaaeec45..d0d229e1319 100644 --- a/crates/hir-expand/src/ast_id_map.rs +++ b/crates/hir-expand/src/ast_id_map.rs @@ -199,6 +199,19 @@ impl AstIdMap { FileAstId { raw, covariant: PhantomData } } + pub fn ast_id_for_ptr(&self, ptr: AstPtr) -> FileAstId { + let ptr = ptr.syntax_node_ptr(); + let hash = hash_ptr(&ptr); + match self.map.raw_entry().from_hash(hash, |&idx| self.arena[idx] == ptr) { + Some((&raw, &())) => FileAstId { raw, covariant: PhantomData }, + None => panic!( + "Can't find {:?} in AstIdMap:\n{:?}", + ptr, + self.arena.iter().map(|(_id, i)| i).collect::>(), + ), + } + } + pub fn get(&self, id: FileAstId) -> AstPtr { AstPtr::try_from_raw(self.arena[id.raw].clone()).unwrap() } diff --git a/crates/hir-expand/src/builtin_derive_macro.rs b/crates/hir-expand/src/builtin_derive_macro.rs index 75720d36f9f..8f240ef0732 100644 --- a/crates/hir-expand/src/builtin_derive_macro.rs +++ b/crates/hir-expand/src/builtin_derive_macro.rs @@ -36,7 +36,7 @@ macro_rules! register_builtin { $( BuiltinDeriveExpander::$trait => $expand, )* }; - let span = db.lookup_intern_macro_call(id).span(db); + let span = db.lookup_intern_macro_call(id).call_site; let span = span_with_def_site_ctxt(db, span, id); expander(db, id, span, tt, token_map) } diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs index 7629d31a221..2d7531d56d0 100644 --- a/crates/hir-expand/src/builtin_fn_macro.rs +++ b/crates/hir-expand/src/builtin_fn_macro.rs @@ -42,7 +42,7 @@ macro_rules! register_builtin { $( BuiltinFnLikeExpander::$kind => $expand, )* }; - let span = db.lookup_intern_macro_call(id).span(db); + let span = db.lookup_intern_macro_call(id).call_site; let span = span_with_def_site_ctxt(db, span, id); expander(db, id, tt, span) } @@ -59,7 +59,7 @@ macro_rules! register_builtin { $( EagerExpander::$e_kind => $e_expand, )* }; - let span = db.lookup_intern_macro_call(id).span(db); + let span = db.lookup_intern_macro_call(id).call_site; let span = span_with_def_site_ctxt(db, span, id); expander(db, id, tt, span) } diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs index dcfa53bfbe2..df5760724c7 100644 --- a/crates/hir-expand/src/db.rs +++ b/crates/hir-expand/src/db.rs @@ -301,16 +301,15 @@ pub fn expand_speculative( let mut speculative_expansion = match loc.def.kind { MacroDefKind::ProcMacro(expander, ..) => { tt.delimiter = tt::Delimiter::invisible_spanned(loc.call_site); - let call_site = loc.span(db); expander.expand( db, loc.def.krate, loc.krate, &tt, attr_arg.as_ref(), - call_site, - call_site, - call_site, + loc.call_site, + loc.call_site, + loc.call_site, ) } MacroDefKind::BuiltInAttr(BuiltinAttrExpander::Derive, _) => { @@ -782,7 +781,6 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult None, }; - let call_site = loc.span(db); let ExpandResult { value: mut tt, err } = expander.expand( db, loc.def.krate, @@ -790,10 +788,10 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult Span { - let ast_id = self.kind.erased_ast_id(); - let file_id = self.kind.file_id(); - let range = db.ast_id_map(file_id).get_erased(ast_id).text_range(); - match file_id.repr() { - HirFileIdRepr::FileId(file_id) => db.real_span_map(file_id).span_for_range(range), - HirFileIdRepr::MacroFile(m) => { - db.parse_macro_expansion(m).value.1.span_at(range.start()) - } - } - } - pub fn to_node(&self, db: &dyn ExpandDatabase) -> InFile { match self.kind { MacroCallKind::FnLike { ast_id, .. } => { @@ -546,7 +533,7 @@ impl MacroCallKind { } } - fn erased_ast_id(&self) -> ErasedFileAstId { + pub fn erased_ast_id(&self) -> ErasedFileAstId { match *self { MacroCallKind::FnLike { ast_id: InFile { value, .. }, .. } => value.erase(), MacroCallKind::Derive { ast_id: InFile { value, .. }, .. } => value.erase(), diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index f74aeb8a8ff..85762603ed1 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -47,7 +47,6 @@ use hir_def::{ item_tree::ItemTreeNode, lang_item::LangItemTarget, layout::{self, ReprOptions, TargetDataLayout}, - macro_id_to_def_id, nameres::{self, diagnostics::DefDiagnostic}, path::ImportAlias, per_ns::PerNs, @@ -810,7 +809,7 @@ impl Module { } fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec, m: Macro) { - let id = macro_id_to_def_id(db.upcast(), m.id); + let id = db.macro_def(m.id); if let hir_expand::db::TokenExpander::DeclarativeMacro(expander) = db.macro_expander(id) { if let Some(e) = expander.mac.err() { let Some(ast) = id.ast_id().left() else { diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 95ed83a49ab..34feb00c9b7 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -13,7 +13,6 @@ use either::Either; use hir_def::{ hir::Expr, lower::LowerCtx, - macro_id_to_def_id, nameres::MacroSubNs, resolver::{self, HasResolver, Resolver, TypeNs}, type_ref::Mutability, @@ -343,7 +342,7 @@ impl<'db> SemanticsImpl<'db> { let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| { resolver .resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang)) - .map(|(it, _)| macro_id_to_def_id(self.db.upcast(), it)) + .map(|(it, _)| self.db.macro_def(it)) })?; hir_expand::db::expand_speculative( self.db.upcast(), diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index d05118bbc28..5fbc860a4b3 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -16,7 +16,6 @@ use hir_def::{ hir::{BindingId, ExprId, Pat, PatId}, lang_item::LangItem, lower::LowerCtx, - macro_id_to_def_id, nameres::MacroSubNs, path::{ModPath, Path, PathKind}, resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs}, @@ -773,7 +772,7 @@ impl SourceAnalyzer { let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| { self.resolver .resolve_path_as_macro(db.upcast(), &path, Some(MacroSubNs::Bang)) - .map(|(it, _)| macro_id_to_def_id(db.upcast(), it)) + .map(|(it, _)| db.macro_def(it)) })?; // why the 64? Some(macro_call_id.as_macro_file()).filter(|it| it.expansion_level(db.upcast()) < 64)