about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-03-09 01:13:38 +0100
committerLukas Wirth <lukastw97@gmail.com>2022-03-09 01:13:38 +0100
commit4e94fb7028cc7d54eb2b1d3b49a2282faa0f80be (patch)
treee25ced5739d1bb05ecde17f26984af929b7c4f56
parentc37fe779c657091ac4cb0fcfff43659972987303 (diff)
downloadrust-4e94fb7028cc7d54eb2b1d3b49a2282faa0f80be.tar.gz
rust-4e94fb7028cc7d54eb2b1d3b49a2282faa0f80be.zip
Fix ProcMacroData recording wrong name for derives
-rw-r--r--crates/hir/src/lib.rs34
-rw-r--r--crates/hir_def/src/data.rs13
-rw-r--r--crates/hir_def/src/nameres.rs13
-rw-r--r--crates/hir_def/src/nameres/collector.rs1
-rw-r--r--crates/hir_def/src/nameres/proc_macro.rs10
-rw-r--r--crates/ide/src/hover/tests.rs2
6 files changed, 43 insertions, 30 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 68f3e3ae61f..1c52ed57955 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1383,27 +1383,19 @@ impl Function {
         db.function_data(self.id).has_body()
     }
 
-    pub fn as_proc_macro(self, _db: &dyn HirDatabase) -> Option<Macro> {
-        // let function_data = db.function_data(self.id);
-        // let attrs = &function_data.attrs;
-        // if !(attrs.is_proc_macro()
-        //     || attrs.is_proc_macro_attribute()
-        //     || attrs.is_proc_macro_derive())
-        // {
-        //     return None;
-        // }
-        // let loc = self.id.lookup(db.upcast());
-        // let krate = loc.krate(db);
-        // let def_map = db.crate_def_map(krate.into());
-        // let ast_id =
-        //     InFile::new(loc.id.file_id(), loc.id.item_tree(db.upcast())[loc.id.value].ast_id);
-
-        // let mut exported_proc_macros = def_map.exported_proc_macros();
-        // exported_proc_macros
-        //     .find(|&(id, _)| matches!(id.kind, MacroDefKind::ProcMacro(_, _, id) if id == ast_id))
-        //     .map(|(id, _)| Macro { id })
-        // FIXME
-        None
+    pub fn as_proc_macro(self, db: &dyn HirDatabase) -> Option<Macro> {
+        let function_data = db.function_data(self.id);
+        let attrs = &function_data.attrs;
+        // FIXME: Store this in FunctionData flags?
+        if !(attrs.is_proc_macro()
+            || attrs.is_proc_macro_attribute()
+            || attrs.is_proc_macro_derive())
+        {
+            return None;
+        }
+        let loc = self.id.lookup(db.upcast());
+        let def_map = db.crate_def_map(loc.krate(db).into());
+        def_map.fn_as_proc_macro(loc.id).map(|id| Macro { id: id.into() })
     }
 
     /// A textual representation of the HIR of this function for debugging purposes.
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index 5cef7ecb374..bb3a34a7c1e 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -332,6 +332,7 @@ impl MacroRulesData {
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ProcMacroData {
     pub name: Name,
+    // FIXME: Record deriver helper here?
 }
 
 impl ProcMacroData {
@@ -343,7 +344,17 @@ impl ProcMacroData {
         let item_tree = loc.id.item_tree(db);
         let makro = &item_tree[loc.id.value];
 
-        Arc::new(ProcMacroData { name: makro.name.clone() })
+        let name = if let Some(def) = item_tree
+            .attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into())
+            .parse_proc_macro_decl(&makro.name)
+        {
+            def.name
+        } else {
+            // eeeh...
+            stdx::never!("proc macro declaration is not a proc macro");
+            makro.name.clone()
+        };
+        Arc::new(ProcMacroData { name })
     }
 }
 
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index cb4c5a9f552..279784952d3 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -70,12 +70,12 @@ use syntax::{ast, SmolStr};
 use crate::{
     db::DefDatabase,
     item_scope::{BuiltinShadowMode, ItemScope},
-    item_tree::TreeId,
+    item_tree::{self, ItemTreeId, TreeId},
     nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
     path::ModPath,
     per_ns::PerNs,
     visibility::Visibility,
-    AstId, BlockId, BlockLoc, LocalModuleId, ModuleDefId, ModuleId,
+    AstId, BlockId, BlockLoc, LocalModuleId, ModuleDefId, ModuleId, ProcMacroId,
 };
 
 /// Contains the results of (early) name resolution.
@@ -102,6 +102,7 @@ pub struct DefMap {
 
     /// Side table for resolving derive helpers.
     exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
+    fn_proc_macro_mapping: FxHashMap<ItemTreeId<item_tree::Function>, ProcMacroId>,
 
     /// Custom attributes registered with `#![register_attr]`.
     registered_attrs: Vec<SmolStr>,
@@ -271,6 +272,7 @@ impl DefMap {
             recursion_limit: None,
             extern_prelude: FxHashMap::default(),
             exported_derives: FxHashMap::default(),
+            fn_proc_macro_mapping: FxHashMap::default(),
             prelude: None,
             root,
             modules,
@@ -300,6 +302,11 @@ impl DefMap {
         self.root
     }
 
+    // FIXME: This is an odd interface....
+    pub fn fn_as_proc_macro(&self, id: ItemTreeId<item_tree::Function>) -> Option<ProcMacroId> {
+        self.fn_proc_macro_mapping.get(&id).copied()
+    }
+
     pub(crate) fn krate(&self) -> CrateId {
         self.krate
     }
@@ -453,6 +460,7 @@ impl DefMap {
             modules,
             registered_attrs,
             registered_tools,
+            fn_proc_macro_mapping,
             block: _,
             edition: _,
             recursion_limit: _,
@@ -467,6 +475,7 @@ impl DefMap {
         modules.shrink_to_fit();
         registered_attrs.shrink_to_fit();
         registered_tools.shrink_to_fit();
+        fn_proc_macro_mapping.shrink_to_fit();
         for (_, module) in modules.iter_mut() {
             module.children.shrink_to_fit();
             module.scope.shrink_to_fit();
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 59ed617888c..a8928d07e79 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -570,6 +570,7 @@ impl DefCollector<'_> {
                 .exported_derives
                 .insert(macro_id_to_def_id(self.db, proc_macro_id.into()), helpers);
         }
+        self.def_map.fn_proc_macro_mapping.insert(id, proc_macro_id);
     }
 
     /// Define a macro with `macro_rules`.
diff --git a/crates/hir_def/src/nameres/proc_macro.rs b/crates/hir_def/src/nameres/proc_macro.rs
index 920df7cec20..5089ef2d817 100644
--- a/crates/hir_def/src/nameres/proc_macro.rs
+++ b/crates/hir_def/src/nameres/proc_macro.rs
@@ -6,13 +6,13 @@ use tt::{Leaf, TokenTree};
 use crate::attr::Attrs;
 
 #[derive(Debug, PartialEq, Eq)]
-pub(super) struct ProcMacroDef {
-    pub(super) name: Name,
-    pub(super) kind: ProcMacroKind,
+pub struct ProcMacroDef {
+    pub name: Name,
+    pub kind: ProcMacroKind,
 }
 
 #[derive(Debug, PartialEq, Eq)]
-pub(super) enum ProcMacroKind {
+pub enum ProcMacroKind {
     CustomDerive { helpers: Box<[Name]> },
     FnLike,
     Attr,
@@ -30,7 +30,7 @@ impl ProcMacroKind {
 
 impl Attrs {
     #[rustfmt::skip]
-    pub(super) fn parse_proc_macro_decl(&self, func_name: &Name) -> Option<ProcMacroDef> {
+    pub fn parse_proc_macro_decl(&self, func_name: &Name) -> Option<ProcMacroDef> {
         if self.is_proc_macro() {
             Some(ProcMacroDef { name: func_name.clone(), kind: ProcMacroKind::FnLike })
         } else if self.is_proc_macro_attribute() {
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index e7fad48080d..2ec7802394f 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -4151,7 +4151,7 @@ struct Foo;
                 *Copy*
 
                 ```rust
-                test
+                test::foo
                 ```
 
                 ```rust