diff options
| author | Josh Triplett <josh@joshtriplett.org> | 2025-08-09 23:56:00 -0700 |
|---|---|---|
| committer | Josh Triplett <josh@joshtriplett.org> | 2025-08-14 14:23:05 -0700 |
| commit | 354fcf2b52119d938b3181bd6cbc3be1929138df (patch) | |
| tree | 6ef9a562d362b3db77d85520820570bcc342c73b /compiler/rustc_expand/src/expand.rs | |
| parent | 8fb98ef36846f74c8a642e856808ad5600ae4110 (diff) | |
| download | rust-354fcf2b52119d938b3181bd6cbc3be1929138df.tar.gz rust-354fcf2b52119d938b3181bd6cbc3be1929138df.zip | |
mbe: Handle applying `macro_rules` derives
Add infrastructure to apply a derive macro to arguments, consuming and returning a `TokenTree` only. Handle `SyntaxExtensionKind::MacroRules` when expanding a derive, if the macro's kinds support derive. Add tests covering various cases of `macro_rules` derives. Note that due to a pre-existing FIXME in `expand.rs`, derives are re-queued and some errors get emitted twice. Duplicate diagnostic suppression makes them not visible, but the FIXME should still get fixed.
Diffstat (limited to 'compiler/rustc_expand/src/expand.rs')
| -rw-r--r-- | compiler/rustc_expand/src/expand.rs | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 670f5c91bb9..1f7f4c7d856 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -16,6 +16,7 @@ use rustc_attr_parsing::{EvalConfigResult, ShouldEmit}; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_errors::PResult; use rustc_feature::Features; +use rustc_hir::def::MacroKinds; use rustc_parse::parser::{ AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser, RecoverColon, RecoverComma, token_descr, @@ -565,6 +566,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { .map(|DeriveResolution { path, item, exts: _, is_const }| { // FIXME: Consider using the derive resolutions (`_exts`) // instead of enqueuing the derives to be resolved again later. + // Note that this can result in duplicate diagnostics. let expn_id = LocalExpnId::fresh_empty(); derive_invocations.push(( Invocation { @@ -922,6 +924,35 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } fragment } + SyntaxExtensionKind::MacroRules(expander) + if expander.kinds().contains(MacroKinds::DERIVE) => + { + if is_const { + let guar = self + .cx + .dcx() + .span_err(span, "macro `derive` does not support const derives"); + return ExpandResult::Ready(fragment_kind.dummy(span, guar)); + } + let body = item.to_tokens(); + match expander.expand_derive(self.cx, span, &body) { + Ok(tok_result) => { + let fragment = + self.parse_ast_fragment(tok_result, fragment_kind, &path, span); + if macro_stats { + update_derive_macro_stats( + self.cx, + fragment_kind, + span, + &path, + &fragment, + ); + } + fragment + } + Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)), + } + } _ => unreachable!(), }, InvocationKind::GlobDelegation { item, of_trait } => { |
