aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres/collector.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r--crates/hir_def/src/nameres/collector.rs50
1 files changed, 48 insertions, 2 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 4c3993ff0..42c0f0536 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -16,10 +16,10 @@ use hir_expand::{
16 proc_macro::ProcMacroExpander, 16 proc_macro::ProcMacroExpander,
17 HirFileId, MacroCallId, MacroDefId, MacroDefKind, 17 HirFileId, MacroCallId, MacroDefId, MacroDefKind,
18}; 18};
19use rustc_hash::FxHashMap; 19use rustc_hash::{FxHashMap, FxHashSet};
20use rustc_hash::FxHashSet;
21use syntax::ast; 20use syntax::ast;
22use test_utils::mark; 21use test_utils::mark;
22use tt::{Leaf, TokenTree};
23 23
24use crate::{ 24use crate::{
25 attr::Attrs, 25 attr::Attrs,
@@ -281,6 +281,25 @@ impl DefCollector<'_> {
281 } 281 }
282 } 282 }
283 283
284 fn resolve_proc_macro(&mut self, name: &Name) {
285 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) {
286 Some((_, expander)) => MacroDefId {
287 ast_id: None,
288 krate: Some(self.def_map.krate),
289 kind: MacroDefKind::ProcMacro(*expander),
290 local_inner: false,
291 },
292 None => MacroDefId {
293 ast_id: None,
294 krate: Some(self.def_map.krate),
295 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)),
296 local_inner: false,
297 },
298 };
299
300 self.define_proc_macro(name.clone(), macro_def);
301 }
302
284 /// Define a macro with `macro_rules`. 303 /// Define a macro with `macro_rules`.
285 /// 304 ///
286 /// It will define the macro in legacy textual scope, and if it has `#[macro_export]`, 305 /// It will define the macro in legacy textual scope, and if it has `#[macro_export]`,
@@ -917,6 +936,9 @@ impl ModCollector<'_, '_> {
917 } 936 }
918 ModItem::Function(id) => { 937 ModItem::Function(id) => {
919 let func = &self.item_tree[id]; 938 let func = &self.item_tree[id];
939
940 self.collect_proc_macro_def(&func.name, attrs);
941
920 def = Some(DefData { 942 def = Some(DefData {
921 id: FunctionLoc { 943 id: FunctionLoc {
922 container: container.into(), 944 container: container.into(),
@@ -1177,6 +1199,30 @@ impl ModCollector<'_, '_> {
1177 } 1199 }
1178 } 1200 }
1179 1201
1202 /// If `attrs` registers a procedural macro, collects its definition.
1203 fn collect_proc_macro_def(&mut self, func_name: &Name, attrs: &Attrs) {
1204 // FIXME: this should only be done in the root module of `proc-macro` crates, not everywhere
1205 // FIXME: distinguish the type of macro
1206 let macro_name = if attrs.by_key("proc_macro").exists()
1207 || attrs.by_key("proc_macro_attribute").exists()
1208 {
1209 func_name.clone()
1210 } else {
1211 let derive = attrs.by_key("proc_macro_derive");
1212 if let Some(arg) = derive.tt_values().next() {
1213 if let [TokenTree::Leaf(Leaf::Ident(trait_name))] = &*arg.token_trees {
1214 trait_name.as_name()
1215 } else {
1216 return;
1217 }
1218 } else {
1219 return;
1220 }
1221 };
1222
1223 self.def_collector.resolve_proc_macro(&macro_name);
1224 }
1225
1180 fn collect_macro(&mut self, mac: &MacroCall) { 1226 fn collect_macro(&mut self, mac: &MacroCall) {
1181 let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); 1227 let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone());
1182 1228