aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-06-03 17:17:25 +0100
committerGitHub <[email protected]>2021-06-03 17:17:25 +0100
commit14153671caaca852c94bd1d0d7f279acb8eb1913 (patch)
treeeb377999a5e8677c210791440b18593f909198e6 /crates/hir_def/src/nameres
parent7f9c4a59d9a84cd8c734286937439b5cd215be27 (diff)
parent17565f4deafab800d8d87208cff1e27d028e9b0e (diff)
Merge #9128
9128: feat: expand procedural attribute macros r=jonas-schievink a=jonas-schievink This adds experimental support for attribute macros. They can be enabled by setting `rust-analyzer.experimental.procAttrMacros` to `true`. Known issues: * Tokens aren't remapped, presumably because we edit the input syntax tree (this causes IDE features to not work inside items with attribute macros on them) * Macro errors aren't reported correctly Closes https://github.com/rust-analyzer/rust-analyzer/issues/8971 Fixes https://github.com/rust-analyzer/rust-analyzer/issues/8964 / https://github.com/la10736/rstest/issues/120 Fixes https://github.com/rust-analyzer/rust-analyzer/issues/2984 Fixes https://github.com/rust-analyzer/rust-analyzer/issues/5412 Fixes https://github.com/rust-analyzer/rust-analyzer/issues/6029 Fixes https://github.com/rust-analyzer/rust-analyzer/issues/6687 https://github.com/rust-analyzer/rust-analyzer/issues/6740 is still not fixed – we now expand `#[proc_macro_hack]`, but fail to expand the resulting `proc_macro_call!()` macro. Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r--crates/hir_def/src/nameres/collector.rs60
1 files changed, 54 insertions, 6 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 6b41921ae..b2ce739bd 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -23,7 +23,7 @@ use syntax::ast;
23 23
24use crate::{ 24use crate::{
25 attr::{Attr, AttrId, AttrInput, Attrs}, 25 attr::{Attr, AttrId, AttrInput, Attrs},
26 builtin_attr, 26 attr_macro_as_call_id, builtin_attr,
27 db::DefDatabase, 27 db::DefDatabase,
28 derive_macro_as_call_id, 28 derive_macro_as_call_id,
29 intern::Interned, 29 intern::Interned,
@@ -223,7 +223,7 @@ struct MacroDirective {
223enum MacroDirectiveKind { 223enum MacroDirectiveKind {
224 FnLike { ast_id: AstIdWithPath<ast::MacroCall>, fragment: FragmentKind }, 224 FnLike { ast_id: AstIdWithPath<ast::MacroCall>, fragment: FragmentKind },
225 Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId }, 225 Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId },
226 Attr { ast_id: AstIdWithPath<ast::Item>, attr: AttrId, mod_item: ModItem }, 226 Attr { ast_id: AstIdWithPath<ast::Item>, attr: Attr, mod_item: ModItem },
227} 227}
228 228
229struct DefData<'a> { 229struct DefData<'a> {
@@ -419,7 +419,7 @@ impl DefCollector<'_> {
419 let mut unresolved_macros = std::mem::replace(&mut self.unresolved_macros, Vec::new()); 419 let mut unresolved_macros = std::mem::replace(&mut self.unresolved_macros, Vec::new());
420 let pos = unresolved_macros.iter().position(|directive| { 420 let pos = unresolved_macros.iter().position(|directive| {
421 if let MacroDirectiveKind::Attr { ast_id, mod_item, attr } = &directive.kind { 421 if let MacroDirectiveKind::Attr { ast_id, mod_item, attr } = &directive.kind {
422 self.skip_attrs.insert(ast_id.ast_id.with_value(*mod_item), *attr); 422 self.skip_attrs.insert(ast_id.ast_id.with_value(*mod_item), attr.id);
423 423
424 let file_id = ast_id.ast_id.file_id; 424 let file_id = ast_id.ast_id.file_id;
425 let item_tree = self.db.file_item_tree(file_id); 425 let item_tree = self.db.file_item_tree(file_id);
@@ -1050,7 +1050,7 @@ impl DefCollector<'_> {
1050 let file_id = ast_id.ast_id.file_id; 1050 let file_id = ast_id.ast_id.file_id;
1051 let item_tree = self.db.file_item_tree(file_id); 1051 let item_tree = self.db.file_item_tree(file_id);
1052 let mod_dir = self.mod_dirs[&directive.module_id].clone(); 1052 let mod_dir = self.mod_dirs[&directive.module_id].clone();
1053 self.skip_attrs.insert(InFile::new(file_id, *mod_item), *attr); 1053 self.skip_attrs.insert(InFile::new(file_id, *mod_item), attr.id);
1054 ModCollector { 1054 ModCollector {
1055 def_collector: &mut *self, 1055 def_collector: &mut *self,
1056 macro_depth: directive.depth, 1056 macro_depth: directive.depth,
@@ -1067,8 +1067,56 @@ impl DefCollector<'_> {
1067 } 1067 }
1068 } 1068 }
1069 1069
1070 if !self.db.enable_proc_attr_macros() {
1071 return true;
1072 }
1073
1070 // Not resolved to a derive helper, so try to resolve as a macro. 1074 // Not resolved to a derive helper, so try to resolve as a macro.
1071 // FIXME: not yet :) 1075 match attr_macro_as_call_id(
1076 ast_id,
1077 attr,
1078 self.db,
1079 self.def_map.krate,
1080 &resolver,
1081 ) {
1082 Ok(call_id) => {
1083 let loc: MacroCallLoc = self.db.lookup_intern_macro(call_id);
1084 if let MacroDefKind::ProcMacro(exp, ..) = &loc.def.kind {
1085 if exp.is_dummy() {
1086 // Proc macros that cannot be expanded are treated as not
1087 // resolved, in order to fall back later.
1088 self.def_map.diagnostics.push(
1089 DefDiagnostic::unresolved_proc_macro(
1090 directive.module_id,
1091 loc.kind,
1092 ),
1093 );
1094
1095 let file_id = ast_id.ast_id.file_id;
1096 let item_tree = self.db.file_item_tree(file_id);
1097 let mod_dir = self.mod_dirs[&directive.module_id].clone();
1098 self.skip_attrs
1099 .insert(InFile::new(file_id, *mod_item), attr.id);
1100 ModCollector {
1101 def_collector: &mut *self,
1102 macro_depth: directive.depth,
1103 module_id: directive.module_id,
1104 file_id,
1105 item_tree: &item_tree,
1106 mod_dir,
1107 }
1108 .collect(&[*mod_item]);
1109
1110 // Remove the macro directive.
1111 return false;
1112 }
1113 }
1114 resolved.push((directive.module_id, call_id, directive.depth));
1115 res = ReachedFixedPoint::No;
1116 return false;
1117 }
1118 Err(UnresolvedMacro { .. }) => (),
1119 }
1072 } 1120 }
1073 } 1121 }
1074 1122
@@ -1628,7 +1676,7 @@ impl ModCollector<'_, '_> {
1628 self.def_collector.unresolved_macros.push(MacroDirective { 1676 self.def_collector.unresolved_macros.push(MacroDirective {
1629 module_id: self.module_id, 1677 module_id: self.module_id,
1630 depth: self.macro_depth + 1, 1678 depth: self.macro_depth + 1,
1631 kind: MacroDirectiveKind::Attr { ast_id, attr: attr.id, mod_item }, 1679 kind: MacroDirectiveKind::Attr { ast_id, attr: attr.clone(), mod_item },
1632 }); 1680 });
1633 1681
1634 return Err(()); 1682 return Err(());