diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 1928cfd90482b..25ec540111117 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1,3 +1,4 @@ +use std::any::Any; use std::default::Default; use std::iter; use std::path::Component::Prefix; @@ -361,17 +362,13 @@ where } /// Represents a thing that maps token trees to Macro Results -pub trait TTMacroExpander { +pub trait TTMacroExpander: Any { fn expand<'cx>( &self, ecx: &'cx mut ExtCtxt<'_>, span: Span, input: TokenStream, ) -> MacroExpanderResult<'cx>; - - fn get_unused_rule(&self, _rule_i: usize) -> Option<(&Ident, Span)> { - None - } } pub type MacroExpanderResult<'cx> = ExpandResult, ()>; @@ -379,7 +376,7 @@ pub type MacroExpanderResult<'cx> = ExpandResult, ()>; pub type MacroExpanderFn = for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>; -impl TTMacroExpander for F +impl TTMacroExpander for F where F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>, { diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 64be7649775f3..b54dabbb8e26f 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -22,7 +22,7 @@ mod placeholders; mod proc_macro_server; mod stats; -pub use mbe::macro_rules::compile_declarative_macro; +pub use mbe::macro_rules::{MacroRulesMacroExpander, compile_declarative_macro}; pub mod base; pub mod config; pub mod expand; diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 2d792355b2788..2f713a09b95e6 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -128,7 +128,7 @@ pub(super) struct MacroRule { rhs: mbe::TokenTree, } -struct MacroRulesMacroExpander { +pub struct MacroRulesMacroExpander { node_id: NodeId, name: Ident, span: Span, @@ -136,6 +136,14 @@ struct MacroRulesMacroExpander { rules: Vec, } +impl MacroRulesMacroExpander { + pub fn get_unused_rule(&self, rule_i: usize) -> Option<(&Ident, Span)> { + // If the rhs contains an invocation like `compile_error!`, don't report it as unused. + let rule = &self.rules[rule_i]; + if has_compile_error_macro(&rule.rhs) { None } else { Some((&self.name, rule.lhs_span)) } + } +} + impl TTMacroExpander for MacroRulesMacroExpander { fn expand<'cx>( &self, @@ -154,12 +162,6 @@ impl TTMacroExpander for MacroRulesMacroExpander { &self.rules, )) } - - fn get_unused_rule(&self, rule_i: usize) -> Option<(&Ident, Span)> { - // If the rhs contains an invocation like `compile_error!`, don't report it as unused. - let rule = &self.rules[rule_i]; - if has_compile_error_macro(&rule.rhs) { None } else { Some((&self.name, rule.lhs_span)) } - } } struct DummyExpander(ErrorGuaranteed); diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 77ef7f56c094c..333fc808d1b80 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1,6 +1,7 @@ //! A bunch of methods and structures more or less related to resolving macros and //! interface provided by `Resolver` to macro expander. +use std::any::Any; use std::cell::Cell; use std::mem; use std::sync::Arc; @@ -13,10 +14,10 @@ use rustc_expand::base::{ Annotatable, DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension, SyntaxExtensionKind, }; -use rustc_expand::compile_declarative_macro; use rustc_expand::expand::{ AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion, }; +use rustc_expand::{MacroRulesMacroExpander, compile_declarative_macro}; use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_middle::middle::stability; @@ -357,8 +358,12 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { let SyntaxExtensionKind::LegacyBang(ref ext) = m.ext.kind else { continue; }; + let ext: &dyn Any = ext.as_ref(); + let Some(m) = ext.downcast_ref::() else { + continue; + }; for arm_i in unused_arms.iter() { - if let Some((ident, rule_span)) = ext.get_unused_rule(arm_i) { + if let Some((ident, rule_span)) = m.get_unused_rule(arm_i) { self.lint_buffer.buffer_lint( UNUSED_MACRO_RULES, node_id,