diff options
| author | Trevor Gross <t.gross35@gmail.com> | 2025-08-08 14:22:45 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-08 14:22:45 -0500 |
| commit | 804d1a194e8aafc4fbf3fc24250d77f2025f075e (patch) | |
| tree | fa603908157012890b785a7c4ce13c0655002850 /compiler/rustc_resolve/src | |
| parent | 18abf3aa44c53652c017752eda43f0405cd22c13 (diff) | |
| parent | f88839d2abc1c190c3072638518ff06b79686de1 (diff) | |
| download | rust-804d1a194e8aafc4fbf3fc24250d77f2025f075e.tar.gz rust-804d1a194e8aafc4fbf3fc24250d77f2025f075e.zip | |
Rollup merge of #144579 - joshtriplett:mbe-attr, r=petrochenkov
Implement declarative (`macro_rules!`) attribute macros (RFC 3697) This implements [RFC 3697](https://github.com/rust-lang/rust/issues/143547), "Declarative (`macro_rules!`) attribute macros". I would suggest reading this commit-by-commit. This first introduces the feature gate, then adds parsing for attribute rules (doing nothing with them), then adds the ability to look up and apply `macro_rules!` attributes by path, then adds support for local attributes, then adds a test, and finally makes various improvements to errors.
Diffstat (limited to 'compiler/rustc_resolve/src')
| -rw-r--r-- | compiler/rustc_resolve/src/ident.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 10 |
3 files changed, 25 insertions, 8 deletions
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 80e57a4fa3d..092bb6fc4f9 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -631,9 +631,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; match result { - Ok((binding, flags)) - if sub_namespace_match(binding.macro_kind(), macro_kind) => - { + Ok((binding, flags)) => { + let binding_macro_kind = binding.macro_kind(); + // If we're looking for an attribute, that might be supported by a + // `macro_rules!` macro. + // FIXME: Replace this with tracking multiple macro kinds for one Def. + if !(sub_namespace_match(binding_macro_kind, macro_kind) + || (binding_macro_kind == Some(MacroKind::Bang) + && macro_kind == Some(MacroKind::Attr) + && this + .get_macro(binding.res()) + .is_some_and(|macro_data| macro_data.attr_ext.is_some()))) + { + return None; + } + if finalize.is_none() || matches!(scope_set, ScopeSet::Late(..)) { return Some(Ok(binding)); } @@ -710,7 +722,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { innermost_result = Some((binding, flags)); } } - Ok(..) | Err(Determinacy::Determined) => {} + Err(Determinacy::Determined) => {} Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined, } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index e5df23a86cb..23f44ff1658 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1029,13 +1029,14 @@ struct DeriveData { struct MacroData { ext: Arc<SyntaxExtension>, + attr_ext: Option<Arc<SyntaxExtension>>, nrules: usize, macro_rules: bool, } impl MacroData { fn new(ext: Arc<SyntaxExtension>) -> MacroData { - MacroData { ext, nrules: 0, macro_rules: false } + MacroData { ext, attr_ext: None, nrules: 0, macro_rules: false } } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index dae3c9dfad5..9173d0d3ea5 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -842,7 +842,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } _ => None, }, - None => self.get_macro(res).map(|macro_data| Arc::clone(¯o_data.ext)), + None => self.get_macro(res).map(|macro_data| match kind { + Some(MacroKind::Attr) if let Some(ref ext) = macro_data.attr_ext => Arc::clone(ext), + _ => Arc::clone(¯o_data.ext), + }), }; Ok((ext, res)) } @@ -1178,7 +1181,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { node_id: NodeId, edition: Edition, ) -> MacroData { - let (mut ext, mut nrules) = compile_declarative_macro( + let (mut ext, mut attr_ext, mut nrules) = compile_declarative_macro( self.tcx.sess, self.tcx.features(), macro_def, @@ -1195,13 +1198,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // The macro is a built-in, replace its expander function // while still taking everything else from the source code. ext.kind = builtin_ext_kind.clone(); + attr_ext = None; nrules = 0; } else { self.dcx().emit_err(errors::CannotFindBuiltinMacroWithName { span, ident }); } } - MacroData { ext: Arc::new(ext), nrules, macro_rules: macro_def.macro_rules } + MacroData { ext: Arc::new(ext), attr_ext, nrules, macro_rules: macro_def.macro_rules } } fn path_accessible( |
