From 26f604b907f5c23404acec96b14e80064857cd17 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 22 Dec 2020 14:42:28 +0100 Subject: Store invocation site for eager macros --- crates/hir_expand/src/builtin_macro.rs | 5 +++-- crates/hir_expand/src/db.rs | 9 +++++---- crates/hir_expand/src/eager.rs | 14 ++++++-------- crates/hir_expand/src/lib.rs | 27 +++++++++++++-------------- crates/ide/src/goto_definition.rs | 25 +++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 28 deletions(-) diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs index dddbbcdac..6382521fb 100644 --- a/crates/hir_expand/src/builtin_macro.rs +++ b/crates/hir_expand/src/builtin_macro.rs @@ -563,6 +563,7 @@ mod tests { let args = macro_call.token_tree().unwrap(); let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; + let call_id = AstId::new(file_id.into(), ast_id_map.ast_id(¯o_call)); let arg_id = db.intern_eager_expansion({ EagerCallLoc { @@ -570,7 +571,7 @@ mod tests { fragment: FragmentKind::Expr, subtree: Arc::new(parsed_args.clone()), krate, - file_id: file_id.into(), + call: call_id, } }); @@ -580,7 +581,7 @@ mod tests { fragment, subtree: Arc::new(subtree), krate, - file_id: file_id.into(), + call: call_id, }; let id: MacroCallId = db.intern_eager_expansion(eager).into(); diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 4477d867f..077de3727 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use base_db::{salsa, SourceDatabase}; use mbe::{ExpandError, ExpandResult, MacroRules}; use parser::FragmentKind; -use syntax::{algo::diff, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode}; +use syntax::{algo::diff, ast::NameOwner, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode}; use crate::{ ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, @@ -129,11 +129,11 @@ fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc { fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option> { match id.kind { MacroDefKind::Declarative => { - let macro_call = match id.ast_id?.to_node(db) { + let macro_rules = match id.ast_id?.to_node(db) { syntax::ast::Macro::MacroRules(mac) => mac, syntax::ast::Macro::MacroDef(_) => return None, }; - let arg = macro_call.token_tree()?; + let arg = macro_rules.token_tree()?; let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { log::warn!("fail on macro_def to token tree: {:#?}", arg); None @@ -141,7 +141,8 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option it, Err(err) => { - log::warn!("fail on macro_def parse: error: {:#?} {:#?}", err, tt); + let name = macro_rules.name().map(|n| n.to_string()).unwrap_or_default(); + log::warn!("fail on macro_def parse ({}): {:?} {:#?}", name, err, tt); return None; } }; diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs index 0229a836e..6354b090d 100644 --- a/crates/hir_expand/src/eager.rs +++ b/crates/hir_expand/src/eager.rs @@ -110,6 +110,9 @@ pub fn expand_eager_macro( || err("malformed macro invocation"), )?; + let ast_map = db.ast_id_map(macro_call.file_id); + let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(¯o_call.value)); + // Note: // When `lazy_expand` is called, its *parent* file must be already exists. // Here we store an eager macro id for the argument expanded subtree here @@ -120,7 +123,7 @@ pub fn expand_eager_macro( fragment: FragmentKind::Expr, subtree: Arc::new(parsed_args.clone()), krate, - file_id: macro_call.file_id, + call: call_id, } }); let arg_file_id: MacroCallId = arg_id.into(); @@ -141,13 +144,8 @@ pub fn expand_eager_macro( let res = eager.expand(db, arg_id, &subtree); let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?; - let eager = EagerCallLoc { - def, - fragment, - subtree: Arc::new(subtree), - krate, - file_id: macro_call.file_id, - }; + let eager = + EagerCallLoc { def, fragment, subtree: Arc::new(subtree), krate, call: call_id }; Ok(db.intern_eager_expansion(eager)) } else { diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index d486186e5..3fa1b1d77 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs @@ -83,7 +83,7 @@ impl HirFileId { } MacroCallId::EagerMacro(id) => { let loc = db.lookup_intern_eager_expansion(id); - loc.file_id + loc.call.file_id } }; file_id.original_file(db) @@ -103,7 +103,7 @@ impl HirFileId { } MacroCallId::EagerMacro(id) => { let loc = db.lookup_intern_eager_expansion(id); - loc.file_id + loc.call.file_id } }; } @@ -114,17 +114,16 @@ impl HirFileId { pub fn call_node(self, db: &dyn db::AstDatabase) -> Option> { match self.0 { HirFileIdRepr::FileId(_) => None, - HirFileIdRepr::MacroFile(macro_file) => { - let lazy_id = match macro_file.macro_call_id { - MacroCallId::LazyMacro(id) => id, - MacroCallId::EagerMacro(_id) => { - // FIXME: handle call node for eager macro - return None; - } - }; - let loc = db.lookup_intern_macro(lazy_id); - Some(loc.kind.node(db)) - } + HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { + MacroCallId::LazyMacro(lazy_id) => { + let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id); + Some(loc.kind.node(db)) + } + MacroCallId::EagerMacro(id) => { + let loc: EagerCallLoc = db.lookup_intern_eager_expansion(id); + Some(loc.call.with_value(loc.call.to_node(db).syntax().clone())) + } + }, } } @@ -304,7 +303,7 @@ pub struct EagerCallLoc { pub(crate) fragment: FragmentKind, pub(crate) subtree: Arc, pub(crate) krate: CrateId, - pub(crate) file_id: HirFileId, + pub(crate) call: AstId, } /// ExpansionInfo mainly describes how to map text range between src and expanded macro diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 431da5d9c..47dd85ceb 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -749,6 +749,31 @@ fn test() { ); } + #[test] + fn goto_through_included_file() { + check( + r#" +//- /main.rs +#[rustc_builtin_macro] +macro_rules! include {} + + include!("foo.rs"); +//^^^^^^^^^^^^^^^^^^^ + +fn f() { + foo<|>(); +} + +mod confuse_index { + pub fn foo() {} +} + +//- /foo.rs +fn foo() {} + "#, + ); + } + #[test] fn goto_for_type_param() { check( -- cgit v1.2.3