diff options
author | Jonas Schievink <[email protected]> | 2021-05-31 12:37:11 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2021-06-03 17:09:21 +0100 |
commit | e5a2c6596ddd11b0d57042224ac7c1d7691ec33b (patch) | |
tree | f0476ad40103b5d3dea60f81fca32c63fe9618d7 /crates/hir_def/src/nameres/collector.rs | |
parent | 7f9c4a59d9a84cd8c734286937439b5cd215be27 (diff) |
Expand procedural attribute macros
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 6b41921ae..874a4ebb1 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 | ||
24 | use crate::{ | 24 | use 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 { | |||
223 | enum MacroDirectiveKind { | 223 | enum 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 | ||
229 | struct DefData<'a> { | 229 | struct 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, |
@@ -1068,7 +1068,51 @@ impl DefCollector<'_> { | |||
1068 | } | 1068 | } |
1069 | 1069 | ||
1070 | // Not resolved to a derive helper, so try to resolve as a macro. | 1070 | // Not resolved to a derive helper, so try to resolve as a macro. |
1071 | // FIXME: not yet :) | 1071 | match attr_macro_as_call_id( |
1072 | ast_id, | ||
1073 | attr, | ||
1074 | self.db, | ||
1075 | self.def_map.krate, | ||
1076 | &resolver, | ||
1077 | ) { | ||
1078 | Ok(call_id) => { | ||
1079 | let loc: MacroCallLoc = self.db.lookup_intern_macro(call_id); | ||
1080 | if let MacroDefKind::ProcMacro(exp, ..) = &loc.def.kind { | ||
1081 | if exp.is_dummy() { | ||
1082 | // Proc macros that cannot be expanded are treated as not | ||
1083 | // resolved, in order to fall back later. | ||
1084 | self.def_map.diagnostics.push( | ||
1085 | DefDiagnostic::unresolved_proc_macro( | ||
1086 | directive.module_id, | ||
1087 | loc.kind, | ||
1088 | ), | ||
1089 | ); | ||
1090 | |||
1091 | let file_id = ast_id.ast_id.file_id; | ||
1092 | let item_tree = self.db.file_item_tree(file_id); | ||
1093 | let mod_dir = self.mod_dirs[&directive.module_id].clone(); | ||
1094 | self.skip_attrs | ||
1095 | .insert(InFile::new(file_id, *mod_item), attr.id); | ||
1096 | ModCollector { | ||
1097 | def_collector: &mut *self, | ||
1098 | macro_depth: directive.depth, | ||
1099 | module_id: directive.module_id, | ||
1100 | file_id, | ||
1101 | item_tree: &item_tree, | ||
1102 | mod_dir, | ||
1103 | } | ||
1104 | .collect(&[*mod_item]); | ||
1105 | |||
1106 | // Remove the macro directive. | ||
1107 | return false; | ||
1108 | } | ||
1109 | } | ||
1110 | resolved.push((directive.module_id, call_id, directive.depth)); | ||
1111 | res = ReachedFixedPoint::No; | ||
1112 | return false; | ||
1113 | } | ||
1114 | Err(UnresolvedMacro { .. }) => (), | ||
1115 | } | ||
1072 | } | 1116 | } |
1073 | } | 1117 | } |
1074 | 1118 | ||
@@ -1628,7 +1672,7 @@ impl ModCollector<'_, '_> { | |||
1628 | self.def_collector.unresolved_macros.push(MacroDirective { | 1672 | self.def_collector.unresolved_macros.push(MacroDirective { |
1629 | module_id: self.module_id, | 1673 | module_id: self.module_id, |
1630 | depth: self.macro_depth + 1, | 1674 | depth: self.macro_depth + 1, |
1631 | kind: MacroDirectiveKind::Attr { ast_id, attr: attr.id, mod_item }, | 1675 | kind: MacroDirectiveKind::Attr { ast_id, attr: attr.clone(), mod_item }, |
1632 | }); | 1676 | }); |
1633 | 1677 | ||
1634 | return Err(()); | 1678 | return Err(()); |