Unnamed repository; edit this file 'description' to name the repository.
Fix ProcMacroData recording wrong name for derives
Lukas Wirth 2022-03-09
parent c37fe77 · commit 4e94fb7
-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 68f3e3ae61..1c52ed5795 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 5cef7ecb37..bb3a34a7c1 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 cb4c5a9f55..279784952d 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 59ed617888..a8928d07e7 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 920df7cec2..5089ef2d81 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 e7fad48080..2ec7802394 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