diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-12-23 06:22:28 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-12-23 06:22:28 +0000 |
commit | 493e29d7132a25ce13c10393c581c2f9e1116320 (patch) | |
tree | dd47c0cf344ccf6df3bd434b4deb7d64a6ae3c96 /crates | |
parent | 4a2f60cb7b83e9ef95d97201d210ff6943b660eb (diff) | |
parent | 26f604b907f5c23404acec96b14e80064857cd17 (diff) |
Merge #7000
7000: Store invocation site for eager macros r=edwin0cheng a=jonas-schievink
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/6992
r? @edwin0cheng
I'm not sure if this is totally correct, it looks like we create **two** `EagerCallLoc`s per macro invocation, one for the arguments (?), and one for the actual macro call. I gave both the same `AstId`, hopefully that's correct.
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir_expand/src/builtin_macro.rs | 5 | ||||
-rw-r--r-- | crates/hir_expand/src/db.rs | 9 | ||||
-rw-r--r-- | crates/hir_expand/src/eager.rs | 14 | ||||
-rw-r--r-- | crates/hir_expand/src/lib.rs | 27 | ||||
-rw-r--r-- | 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 { | |||
563 | 563 | ||
564 | let args = macro_call.token_tree().unwrap(); | 564 | let args = macro_call.token_tree().unwrap(); |
565 | let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; | 565 | let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; |
566 | let call_id = AstId::new(file_id.into(), ast_id_map.ast_id(¯o_call)); | ||
566 | 567 | ||
567 | let arg_id = db.intern_eager_expansion({ | 568 | let arg_id = db.intern_eager_expansion({ |
568 | EagerCallLoc { | 569 | EagerCallLoc { |
@@ -570,7 +571,7 @@ mod tests { | |||
570 | fragment: FragmentKind::Expr, | 571 | fragment: FragmentKind::Expr, |
571 | subtree: Arc::new(parsed_args.clone()), | 572 | subtree: Arc::new(parsed_args.clone()), |
572 | krate, | 573 | krate, |
573 | file_id: file_id.into(), | 574 | call: call_id, |
574 | } | 575 | } |
575 | }); | 576 | }); |
576 | 577 | ||
@@ -580,7 +581,7 @@ mod tests { | |||
580 | fragment, | 581 | fragment, |
581 | subtree: Arc::new(subtree), | 582 | subtree: Arc::new(subtree), |
582 | krate, | 583 | krate, |
583 | file_id: file_id.into(), | 584 | call: call_id, |
584 | }; | 585 | }; |
585 | 586 | ||
586 | let id: MacroCallId = db.intern_eager_expansion(eager).into(); | 587 | 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; | |||
5 | use base_db::{salsa, SourceDatabase}; | 5 | use base_db::{salsa, SourceDatabase}; |
6 | use mbe::{ExpandError, ExpandResult, MacroRules}; | 6 | use mbe::{ExpandError, ExpandResult, MacroRules}; |
7 | use parser::FragmentKind; | 7 | use parser::FragmentKind; |
8 | use syntax::{algo::diff, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode}; | 8 | use syntax::{algo::diff, ast::NameOwner, AstNode, GreenNode, Parse, SyntaxKind::*, SyntaxNode}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, | 11 | ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, |
@@ -129,11 +129,11 @@ fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> { | |||
129 | fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { | 129 | fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> { |
130 | match id.kind { | 130 | match id.kind { |
131 | MacroDefKind::Declarative => { | 131 | MacroDefKind::Declarative => { |
132 | let macro_call = match id.ast_id?.to_node(db) { | 132 | let macro_rules = match id.ast_id?.to_node(db) { |
133 | syntax::ast::Macro::MacroRules(mac) => mac, | 133 | syntax::ast::Macro::MacroRules(mac) => mac, |
134 | syntax::ast::Macro::MacroDef(_) => return None, | 134 | syntax::ast::Macro::MacroDef(_) => return None, |
135 | }; | 135 | }; |
136 | let arg = macro_call.token_tree()?; | 136 | let arg = macro_rules.token_tree()?; |
137 | let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { | 137 | let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { |
138 | log::warn!("fail on macro_def to token tree: {:#?}", arg); | 138 | log::warn!("fail on macro_def to token tree: {:#?}", arg); |
139 | None | 139 | None |
@@ -141,7 +141,8 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<(TokenExpander, | |||
141 | let rules = match MacroRules::parse(&tt) { | 141 | let rules = match MacroRules::parse(&tt) { |
142 | Ok(it) => it, | 142 | Ok(it) => it, |
143 | Err(err) => { | 143 | Err(err) => { |
144 | log::warn!("fail on macro_def parse: error: {:#?} {:#?}", err, tt); | 144 | let name = macro_rules.name().map(|n| n.to_string()).unwrap_or_default(); |
145 | log::warn!("fail on macro_def parse ({}): {:?} {:#?}", name, err, tt); | ||
145 | return None; | 146 | return None; |
146 | } | 147 | } |
147 | }; | 148 | }; |
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( | |||
110 | || err("malformed macro invocation"), | 110 | || err("malformed macro invocation"), |
111 | )?; | 111 | )?; |
112 | 112 | ||
113 | let ast_map = db.ast_id_map(macro_call.file_id); | ||
114 | let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(¯o_call.value)); | ||
115 | |||
113 | // Note: | 116 | // Note: |
114 | // When `lazy_expand` is called, its *parent* file must be already exists. | 117 | // When `lazy_expand` is called, its *parent* file must be already exists. |
115 | // Here we store an eager macro id for the argument expanded subtree here | 118 | // Here we store an eager macro id for the argument expanded subtree here |
@@ -120,7 +123,7 @@ pub fn expand_eager_macro( | |||
120 | fragment: FragmentKind::Expr, | 123 | fragment: FragmentKind::Expr, |
121 | subtree: Arc::new(parsed_args.clone()), | 124 | subtree: Arc::new(parsed_args.clone()), |
122 | krate, | 125 | krate, |
123 | file_id: macro_call.file_id, | 126 | call: call_id, |
124 | } | 127 | } |
125 | }); | 128 | }); |
126 | let arg_file_id: MacroCallId = arg_id.into(); | 129 | let arg_file_id: MacroCallId = arg_id.into(); |
@@ -141,13 +144,8 @@ pub fn expand_eager_macro( | |||
141 | let res = eager.expand(db, arg_id, &subtree); | 144 | let res = eager.expand(db, arg_id, &subtree); |
142 | 145 | ||
143 | let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?; | 146 | let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?; |
144 | let eager = EagerCallLoc { | 147 | let eager = |
145 | def, | 148 | EagerCallLoc { def, fragment, subtree: Arc::new(subtree), krate, call: call_id }; |
146 | fragment, | ||
147 | subtree: Arc::new(subtree), | ||
148 | krate, | ||
149 | file_id: macro_call.file_id, | ||
150 | }; | ||
151 | 149 | ||
152 | Ok(db.intern_eager_expansion(eager)) | 150 | Ok(db.intern_eager_expansion(eager)) |
153 | } else { | 151 | } 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 { | |||
83 | } | 83 | } |
84 | MacroCallId::EagerMacro(id) => { | 84 | MacroCallId::EagerMacro(id) => { |
85 | let loc = db.lookup_intern_eager_expansion(id); | 85 | let loc = db.lookup_intern_eager_expansion(id); |
86 | loc.file_id | 86 | loc.call.file_id |
87 | } | 87 | } |
88 | }; | 88 | }; |
89 | file_id.original_file(db) | 89 | file_id.original_file(db) |
@@ -103,7 +103,7 @@ impl HirFileId { | |||
103 | } | 103 | } |
104 | MacroCallId::EagerMacro(id) => { | 104 | MacroCallId::EagerMacro(id) => { |
105 | let loc = db.lookup_intern_eager_expansion(id); | 105 | let loc = db.lookup_intern_eager_expansion(id); |
106 | loc.file_id | 106 | loc.call.file_id |
107 | } | 107 | } |
108 | }; | 108 | }; |
109 | } | 109 | } |
@@ -114,17 +114,16 @@ impl HirFileId { | |||
114 | pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> { | 114 | pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> { |
115 | match self.0 { | 115 | match self.0 { |
116 | HirFileIdRepr::FileId(_) => None, | 116 | HirFileIdRepr::FileId(_) => None, |
117 | HirFileIdRepr::MacroFile(macro_file) => { | 117 | HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { |
118 | let lazy_id = match macro_file.macro_call_id { | 118 | MacroCallId::LazyMacro(lazy_id) => { |
119 | MacroCallId::LazyMacro(id) => id, | 119 | let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id); |
120 | MacroCallId::EagerMacro(_id) => { | 120 | Some(loc.kind.node(db)) |
121 | // FIXME: handle call node for eager macro | 121 | } |
122 | return None; | 122 | MacroCallId::EagerMacro(id) => { |
123 | } | 123 | let loc: EagerCallLoc = db.lookup_intern_eager_expansion(id); |
124 | }; | 124 | Some(loc.call.with_value(loc.call.to_node(db).syntax().clone())) |
125 | let loc = db.lookup_intern_macro(lazy_id); | 125 | } |
126 | Some(loc.kind.node(db)) | 126 | }, |
127 | } | ||
128 | } | 127 | } |
129 | } | 128 | } |
130 | 129 | ||
@@ -304,7 +303,7 @@ pub struct EagerCallLoc { | |||
304 | pub(crate) fragment: FragmentKind, | 303 | pub(crate) fragment: FragmentKind, |
305 | pub(crate) subtree: Arc<tt::Subtree>, | 304 | pub(crate) subtree: Arc<tt::Subtree>, |
306 | pub(crate) krate: CrateId, | 305 | pub(crate) krate: CrateId, |
307 | pub(crate) file_id: HirFileId, | 306 | pub(crate) call: AstId<ast::MacroCall>, |
308 | } | 307 | } |
309 | 308 | ||
310 | /// ExpansionInfo mainly describes how to map text range between src and expanded macro | 309 | /// 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 | |||
@@ -750,6 +750,31 @@ fn test() { | |||
750 | } | 750 | } |
751 | 751 | ||
752 | #[test] | 752 | #[test] |
753 | fn goto_through_included_file() { | ||
754 | check( | ||
755 | r#" | ||
756 | //- /main.rs | ||
757 | #[rustc_builtin_macro] | ||
758 | macro_rules! include {} | ||
759 | |||
760 | include!("foo.rs"); | ||
761 | //^^^^^^^^^^^^^^^^^^^ | ||
762 | |||
763 | fn f() { | ||
764 | foo<|>(); | ||
765 | } | ||
766 | |||
767 | mod confuse_index { | ||
768 | pub fn foo() {} | ||
769 | } | ||
770 | |||
771 | //- /foo.rs | ||
772 | fn foo() {} | ||
773 | "#, | ||
774 | ); | ||
775 | } | ||
776 | |||
777 | #[test] | ||
753 | fn goto_for_type_param() { | 778 | fn goto_for_type_param() { |
754 | check( | 779 | check( |
755 | r#" | 780 | r#" |