diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index d3f436be0b..30d52d87f1 100644 --- a/crates/hir-def/src/db.rs +++ b/crates/hir-def/src/db.rs @@ -309,7 +309,6 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()), local_inner: false, allow_internal_unsafe: loc.allow_internal_unsafe, - span: makro.def_site, edition: loc.edition, } } @@ -325,7 +324,6 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { allow_internal_unsafe: loc .flags .contains(MacroRulesLocFlags::ALLOW_INTERNAL_UNSAFE), - span: makro.def_site, edition: loc.edition, } } @@ -343,10 +341,6 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId { ), local_inner: false, allow_internal_unsafe: false, - // FIXME: This is wrong, this should point to the name - span: db - .span_map(loc.id.file_id()) - .span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()), edition: loc.edition, } } diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 6450e3a255..eb665f1941 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -798,7 +798,6 @@ pub struct MacroRules { /// The name of the declared macro. pub name: Name, pub ast_id: FileAstId, - pub def_site: Span, } /// "Macros 2.0" macro definition. @@ -807,7 +806,6 @@ pub struct Macro2 { pub name: Name, pub visibility: RawVisibilityId, pub ast_id: FileAstId, - pub def_site: Span, } impl Use { diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index a1755b110e..350593d7dc 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -573,21 +573,19 @@ impl<'a> Ctx<'a> { fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option> { let name = m.name()?; - let def_site = self.span_map().span_for_range(name.syntax().text_range()); let ast_id = self.source_ast_id_map.ast_id(m); - let res = MacroRules { name: name.as_name(), ast_id, def_site }; + let res = MacroRules { name: name.as_name(), ast_id }; Some(id(self.data().macro_rules.alloc(res))) } fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option> { let name = m.name()?; - let def_site = self.span_map().span_for_range(name.syntax().text_range()); let ast_id = self.source_ast_id_map.ast_id(m); let visibility = self.lower_visibility(m); - let res = Macro2 { name: name.as_name(), ast_id, visibility, def_site }; + let res = Macro2 { name: name.as_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 7d5fdf056b..87c90a4c6a 100644 --- a/crates/hir-def/src/item_tree/pretty.rs +++ b/crates/hir-def/src/item_tree/pretty.rs @@ -498,23 +498,13 @@ impl Printer<'_> { wln!(self, "{}!(...);", path.display(self.db.upcast())); } ModItem::MacroRules(it) => { - let MacroRules { name, ast_id, def_site } = &self.tree[it]; - let _ = writeln!( - self, - "// AstId: {:?}, Span: {}", - ast_id.erase().into_raw(), - def_site, - ); + let MacroRules { name, ast_id } = &self.tree[it]; + self.print_ast_id(ast_id.erase()); wln!(self, "macro_rules! {} {{ ... }}", name.display(self.db.upcast())); } ModItem::Macro2(it) => { - let Macro2 { name, visibility, ast_id, def_site } = &self.tree[it]; - let _ = writeln!( - self, - "// AstId: {:?}, Span: {}", - ast_id.erase().into_raw(), - def_site, - ); + let Macro2 { name, visibility, ast_id } = &self.tree[it]; + self.print_ast_id(ast_id.erase()); self.print_visibility(*visibility); wln!(self, "macro {} {{ ... }}", name.display(self.db.upcast())); } diff --git a/crates/hir-def/src/item_tree/tests.rs b/crates/hir-def/src/item_tree/tests.rs index 0c11f34841..b294d288ac 100644 --- a/crates/hir-def/src/item_tree/tests.rs +++ b/crates/hir-def/src/item_tree/tests.rs @@ -272,10 +272,10 @@ pub macro m2() {} m!(); "#, expect![[r#" - // AstId: 1, Span: 0:1@13..14#0 + // AstId: 1 macro_rules! m { ... } - // AstId: 2, Span: 0:2@10..12#0 + // AstId: 2 pub macro m2 { ... } // AstId: 3, Span: 0:3@0..1#0, ExpandTo: Items diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs index 40cbb6912d..51f6da76cb 100644 --- a/crates/hir-expand/src/db.rs +++ b/crates/hir-expand/src/db.rs @@ -5,7 +5,7 @@ use either::Either; use limit::Limit; use mbe::{syntax_node_to_token_tree, ValueResult}; use rustc_hash::FxHashSet; -use span::{AstIdMap, SyntaxContextData, SyntaxContextId}; +use span::{AstIdMap, Span, SyntaxContextData, SyntaxContextId}; use syntax::{ast, AstNode, Parse, SyntaxElement, SyntaxError, SyntaxNode, SyntaxToken, T}; use triomphe::Arc; @@ -118,6 +118,12 @@ pub trait ExpandDatabase: SourceDatabase { /// non-determinism breaks salsa in a very, very, very bad way. /// @edwin0cheng heroically debugged this once! See #4315 for details fn expand_proc_macro(&self, call: MacroCallId) -> ExpandResult>; + /// Retrieves the span to be used for a proc-macro expansions spans. + /// This is a firewall query as it requires parsing the file, which we don't want proc-macros to + /// directly depend on as that would cause to frequent invalidations, mainly because of the + /// parse queries being LRU cached. If they weren't the invalidations would only happen if the + /// user wrote in the file that defines the proc-macro. + fn proc_macro_span(&self, fun: AstId) -> Span; /// Firewall query that returns the errors from the `parse_macro_expansion` query. fn parse_macro_expansion_error( &self, @@ -137,6 +143,7 @@ pub fn expand_speculative( ) -> Option<(SyntaxNode, SyntaxToken)> { let loc = db.lookup_intern_macro_call(actual_macro_call); + // FIXME: This BOGUS here is dangerous once the proc-macro server can call back into the database! let span_map = RealSpanMap::absolute(FileId::BOGUS); let span_map = SpanMapRef::RealSpanMap(&span_map); @@ -211,17 +218,18 @@ pub fn expand_speculative( // Do the actual expansion, we need to directly expand the proc macro due to the attribute args // Otherwise the expand query will fetch the non speculative attribute args and pass those instead. let mut speculative_expansion = match loc.def.kind { - MacroDefKind::ProcMacro(expander, ..) => { + MacroDefKind::ProcMacro(expander, _, ast) => { tt.delimiter = tt::Delimiter::invisible_spanned(loc.call_site); + let span = db.proc_macro_span(ast); expander.expand( db, loc.def.krate, loc.krate, &tt, attr_arg.as_ref(), - span_with_def_site_ctxt(db, loc.def.span, actual_macro_call), - span_with_call_site_ctxt(db, loc.def.span, actual_macro_call), - span_with_mixed_site_ctxt(db, loc.def.span, actual_macro_call), + span_with_def_site_ctxt(db, span, actual_macro_call), + span_with_call_site_ctxt(db, span, actual_macro_call), + span_with_mixed_site_ctxt(db, span, actual_macro_call), ) } MacroDefKind::BuiltInAttr(BuiltinAttrExpander::Derive, _) => { @@ -610,12 +618,23 @@ fn macro_expand( ExpandResult { value: CowArc::Owned(tt), err } } +fn proc_macro_span(db: &dyn ExpandDatabase, ast: AstId) -> Span { + let root = db.parse_or_expand(ast.file_id); + let ast_id_map = &db.ast_id_map(ast.file_id); + let span_map = &db.span_map(ast.file_id); + + let node = ast_id_map.get(ast.value).to_node(&root); + let range = ast::HasName::name(&node) + .map_or_else(|| node.syntax().text_range(), |name| name.syntax().text_range()); + span_map.span_for_range(range) +} + fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult> { let loc = db.lookup_intern_macro_call(id); let (macro_arg, undo_info) = db.macro_arg(id).value; - let expander = match loc.def.kind { - MacroDefKind::ProcMacro(expander, ..) => expander, + let (expander, ast) = match loc.def.kind { + MacroDefKind::ProcMacro(expander, _, ast) => (expander, ast), _ => unreachable!(), }; @@ -624,15 +643,16 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult None, }; + let span = db.proc_macro_span(ast); let ExpandResult { value: mut tt, err } = expander.expand( db, loc.def.krate, loc.krate, ¯o_arg, attr_arg, - span_with_def_site_ctxt(db, loc.def.span, id), - span_with_call_site_ctxt(db, loc.def.span, id), - span_with_mixed_site_ctxt(db, loc.def.span, id), + span_with_def_site_ctxt(db, span, id), + span_with_call_site_ctxt(db, span, id), + span_with_mixed_site_ctxt(db, span, id), ); // Set a hard limit for the expanded tt diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs index 91273a3ff0..a03d9a60d9 100644 --- a/crates/hir-expand/src/lib.rs +++ b/crates/hir-expand/src/lib.rs @@ -183,7 +183,6 @@ pub struct MacroDefId { pub kind: MacroDefKind, pub local_inner: bool, pub allow_internal_unsafe: bool, - pub span: Span, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]