Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/nameres/collector.rs')
-rw-r--r--crates/hir-def/src/nameres/collector.rs28
1 files changed, 27 insertions, 1 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index b0dd01f9db..f21d674f20 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -40,7 +40,7 @@ use crate::{
diagnostics::DefDiagnostic,
mod_resolution::ModDir,
path_resolution::ReachedFixedPoint,
- proc_macro::{ProcMacroDef, ProcMacroKind},
+ proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroDef, ProcMacroKind},
BuiltinShadowMode, DefMap, ModuleData, ModuleOrigin, ResolveMode,
},
path::{ImportAlias, ModPath, PathKind},
@@ -2005,6 +2005,7 @@ impl ModCollector<'_, '_> {
let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast());
// Case 1: builtin macros
+ let mut helpers_opt = None;
let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
let expander = if attrs.by_key("rustc_builtin_macro").exists() {
if let Some(expander) = find_builtin_macro(&mac.name) {
@@ -2013,6 +2014,25 @@ impl ModCollector<'_, '_> {
Either::Right(it) => MacroExpander::BuiltInEager(it),
}
} else if let Some(expander) = find_builtin_derive(&mac.name) {
+ if let Some(attr) = attrs.by_key("rustc_builtin_macro").tt_values().next() {
+ // NOTE: The item *may* have both `#[rustc_builtin_macro]` and `#[proc_macro_derive]`,
+ // in which case rustc ignores the helper attributes from the latter, but it
+ // "doesn't make sense in practice" (see rust-lang/rust#87027).
+ if let Some((name, helpers)) =
+ parse_macro_name_and_helper_attrs(&attr.token_trees)
+ {
+ // NOTE: rustc overrides the name if the macro name if it's different from the
+ // macro name, but we assume it isn't as there's no such case yet. FIXME if
+ // the following assertion fails.
+ stdx::always!(
+ name == mac.name,
+ "built-in macro {} has #[rustc_builtin_macro] which declares different name {}",
+ mac.name,
+ name
+ );
+ helpers_opt = Some(helpers);
+ }
+ }
MacroExpander::BuiltInDerive(expander)
} else if let Some(expander) = find_builtin_attr(&mac.name) {
MacroExpander::BuiltInAttr(expander)
@@ -2037,6 +2057,12 @@ impl ModCollector<'_, '_> {
macro_id,
&self.item_tree[mac.visibility],
);
+ if let Some(helpers) = helpers_opt {
+ self.def_collector
+ .def_map
+ .exported_derives
+ .insert(macro_id_to_def_id(self.def_collector.db, macro_id.into()), helpers);
+ }
}
fn collect_macro_call(&mut self, mac: &MacroCall, container: ItemContainerId) {