mbe: Use concrete type for get_unused_rule

Rather than adding `get_unused_rule` to the `TTMacroExpander` trait, put
it on the concrete `MacroRulesMacroExpander`, and downcast to that type
via `Any` in order to call it.

Suggested-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
This commit is contained in:
Josh Triplett
2025-07-22 00:32:59 -07:00
parent 9748d87dc7
commit 551cb9f1f4
4 changed files with 20 additions and 16 deletions

View File

@@ -1,3 +1,4 @@
use std::any::Any;
use std::default::Default; use std::default::Default;
use std::iter; use std::iter;
use std::path::Component::Prefix; use std::path::Component::Prefix;
@@ -361,17 +362,13 @@ where
} }
/// Represents a thing that maps token trees to Macro Results /// Represents a thing that maps token trees to Macro Results
pub trait TTMacroExpander { pub trait TTMacroExpander: Any {
fn expand<'cx>( fn expand<'cx>(
&self, &self,
ecx: &'cx mut ExtCtxt<'_>, ecx: &'cx mut ExtCtxt<'_>,
span: Span, span: Span,
input: TokenStream, input: TokenStream,
) -> MacroExpanderResult<'cx>; ) -> MacroExpanderResult<'cx>;
fn get_unused_rule(&self, _rule_i: usize) -> Option<(&Ident, Span)> {
None
}
} }
pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>; pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>;
@@ -379,7 +376,7 @@ pub type MacroExpanderResult<'cx> = ExpandResult<Box<dyn MacResult + 'cx>, ()>;
pub type MacroExpanderFn = pub type MacroExpanderFn =
for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>; for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>;
impl<F> TTMacroExpander for F impl<F: 'static> TTMacroExpander for F
where where
F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>, F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream) -> MacroExpanderResult<'cx>,
{ {

View File

@@ -22,7 +22,7 @@ mod placeholders;
mod proc_macro_server; mod proc_macro_server;
mod stats; mod stats;
pub use mbe::macro_rules::compile_declarative_macro; pub use mbe::macro_rules::{MacroRulesMacroExpander, compile_declarative_macro};
pub mod base; pub mod base;
pub mod config; pub mod config;
pub mod expand; pub mod expand;

View File

@@ -128,7 +128,7 @@ pub(super) struct MacroRule {
rhs: mbe::TokenTree, rhs: mbe::TokenTree,
} }
struct MacroRulesMacroExpander { pub struct MacroRulesMacroExpander {
node_id: NodeId, node_id: NodeId,
name: Ident, name: Ident,
span: Span, span: Span,
@@ -136,6 +136,14 @@ struct MacroRulesMacroExpander {
rules: Vec<MacroRule>, rules: Vec<MacroRule>,
} }
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 { impl TTMacroExpander for MacroRulesMacroExpander {
fn expand<'cx>( fn expand<'cx>(
&self, &self,
@@ -154,12 +162,6 @@ impl TTMacroExpander for MacroRulesMacroExpander {
&self.rules, &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); struct DummyExpander(ErrorGuaranteed);

View File

@@ -1,6 +1,7 @@
//! A bunch of methods and structures more or less related to resolving macros and //! A bunch of methods and structures more or less related to resolving macros and
//! interface provided by `Resolver` to macro expander. //! interface provided by `Resolver` to macro expander.
use std::any::Any;
use std::cell::Cell; use std::cell::Cell;
use std::mem; use std::mem;
use std::sync::Arc; use std::sync::Arc;
@@ -13,10 +14,10 @@ use rustc_expand::base::{
Annotatable, DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension, Annotatable, DeriveResolution, Indeterminate, ResolverExpand, SyntaxExtension,
SyntaxExtensionKind, SyntaxExtensionKind,
}; };
use rustc_expand::compile_declarative_macro;
use rustc_expand::expand::{ use rustc_expand::expand::{
AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion, AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion,
}; };
use rustc_expand::{MacroRulesMacroExpander, compile_declarative_macro};
use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind}; use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
use rustc_middle::middle::stability; 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 { let SyntaxExtensionKind::LegacyBang(ref ext) = m.ext.kind else {
continue; continue;
}; };
let ext: &dyn Any = ext.as_ref();
let Some(m) = ext.downcast_ref::<MacroRulesMacroExpander>() else {
continue;
};
for arm_i in unused_arms.iter() { 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( self.lint_buffer.buffer_lint(
UNUSED_MACRO_RULES, UNUSED_MACRO_RULES,
node_id, node_id,