From 138dffa6385d9b5eff1c7799f3932ae35a8071f7 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 10 Apr 2026 16:23:20 +0200 Subject: [PATCH 01/14] Remove `Clone` from parser types --- compiler/rustc_attr_parsing/src/parser.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index a7daec6d6096c..1609e2eefc328 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -5,7 +5,7 @@ use std::borrow::Borrow; use std::fmt::{Debug, Display}; - +use std::sync::atomic::AtomicBool; use rustc_ast::token::{self, Delimiter, MetaVarKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ @@ -87,7 +87,7 @@ impl> Display for PathParser

{ } } -#[derive(Clone, Debug)] +#[derive(Debug)] #[must_use] pub enum ArgParser { NoArgs, @@ -215,7 +215,7 @@ impl ArgParser { /// This enum represents that. /// /// Choose which one you want using the provided methods. -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum MetaItemOrLitParser { MetaItemParser(MetaItemParser), Lit(MetaItemLit), @@ -268,7 +268,6 @@ impl MetaItemOrLitParser { /// `= value` part /// /// The syntax of MetaItems can be found at -#[derive(Clone)] pub struct MetaItemParser { path: OwnedPathParser, args: ArgParser, @@ -655,7 +654,7 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { } } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct MetaItemListParser { sub_parsers: ThinVec, pub span: Span, From ed6e1ceda7c3b7301c5fbea08d14208bed1472b0 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Fri, 10 Apr 2026 16:27:18 +0200 Subject: [PATCH 02/14] Add debug assertion to check usage of arguments of `MetaItemParser` --- .../src/attributes/diagnostic/on_const.rs | 1 + .../src/attributes/diagnostic/on_move.rs | 1 + .../src/attributes/diagnostic/on_unknown.rs | 1 + .../rustc_attr_parsing/src/attributes/doc.rs | 2 + .../src/attributes/dummy.rs | 3 +- compiler/rustc_attr_parsing/src/context.rs | 7 +++ compiler/rustc_attr_parsing/src/interface.rs | 41 ++++++++++++- compiler/rustc_attr_parsing/src/parser.rs | 60 ++++++++++++++++++- 8 files changed, 112 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs index 23db854252a37..7fa467a46068f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs @@ -18,6 +18,7 @@ impl AttributeParser for OnConstParser { |this, cx, args| { if !cx.features().diagnostic_on_const() { // `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs + args.ignore_args(); return; } diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs index a79b7d6afbcdc..e90ea58ffbcb4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs @@ -25,6 +25,7 @@ impl OnMoveParser { ) { if !cx.features().diagnostic_on_move() { // `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs + args.ignore_args(); return; } diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs index dcfba68a4cf8b..855eb4d894d29 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs @@ -19,6 +19,7 @@ impl OnUnknownParser { ) { if !cx.features().diagnostic_on_unknown() { // `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs + args.ignore_args(); return; } let span = cx.attr_span; diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 99f856684abd5..d14cc777e01d4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -204,6 +204,8 @@ impl DocParser { // FIXME: convert list into a Vec of `AttributeKind` because current code is awful. for attr in list.mixed() { + // Arguments of `attr` are checked via the span, so can be safely ignored + attr.ignore_args(); self.attribute.test_attrs.push(attr.span()); } } diff --git a/compiler/rustc_attr_parsing/src/attributes/dummy.rs b/compiler/rustc_attr_parsing/src/attributes/dummy.rs index ee5c507b62920..0c9e11fd23059 100644 --- a/compiler/rustc_attr_parsing/src/attributes/dummy.rs +++ b/compiler/rustc_attr_parsing/src/attributes/dummy.rs @@ -14,7 +14,8 @@ impl SingleAttributeParser for RustcDummyParser { const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really - fn convert(_: &mut AcceptContext<'_, '_, S>, _: &ArgParser) -> Option { + fn convert(_: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + args.ignore_args(); Some(AttributeKind::RustcDummy) } } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 51345162ee071..c946af6062eca 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -465,6 +465,8 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { kind: AttributeLintKind, span: M, ) { + #[cfg(debug_assertions)] + self.has_lint_been_emitted.store(true, std::sync::atomic::Ordering::Relaxed); if !matches!( self.stage.should_emit(), ShouldEmit::ErrorsAndLints { .. } | ShouldEmit::EarlyFatal { also_emit_lints: true } @@ -568,6 +570,11 @@ pub struct SharedContext<'p, 'sess, S: Stage> { /// The second argument of the closure is a [`NodeId`] if `S` is `Early` and a [`HirId`] if `S` /// is `Late` and is the ID of the syntactical component this attribute was applied to. pub(crate) emit_lint: &'p mut dyn FnMut(LintId, MultiSpan, AttributeLintKind), + + /// This atomic bool keeps track of whether any lint has been emitted. + /// This is used for the arguments-used check. + #[cfg(debug_assertions)] + pub(crate) has_lint_been_emitted: std::sync::atomic::AtomicBool, } /// Context given to every attribute parser during finalization. diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 68016d81c954c..9a1a8daa29814 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -207,6 +207,8 @@ impl<'sess> AttributeParser<'sess, Early> { target_span, target, emit_lint: &mut emit_lint, + #[cfg(debug_assertions)] + has_lint_been_emitted: std::sync::atomic::AtomicBool::new(false), }, attr_span, inner_span, @@ -372,6 +374,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { target_span, target, emit_lint: &mut emit_lint, + #[cfg(debug_assertions)] + has_lint_been_emitted: std::sync::atomic::AtomicBool::new(false), }, attr_span, inner_span: lower_span(n.item.span()), @@ -384,6 +388,14 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { (accept.accept_fn)(&mut cx, &args); finalizers.push(&accept.finalizer); + #[cfg(debug_assertions)] + if !cx + .shared + .has_lint_been_emitted + .load(std::sync::atomic::Ordering::Relaxed) + { + cx.shared.cx.check_args_used(&attr, &args) + } if !matches!(cx.stage.should_emit(), ShouldEmit::Nothing) { Self::check_target(&accept.allowed_targets, target, &mut cx); } @@ -423,7 +435,14 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { early_parsed_state.finalize_early_parsed_attributes(&mut attributes); for f in &finalizers { if let Some(attr) = f(&mut FinalizeContext { - shared: SharedContext { cx: self, target_span, target, emit_lint: &mut emit_lint }, + shared: SharedContext { + cx: self, + target_span, + target, + emit_lint: &mut emit_lint, + #[cfg(debug_assertions)] + has_lint_been_emitted: std::sync::atomic::AtomicBool::new(false), + }, all_attrs: &attr_paths, }) { attributes.push(Attribute::Parsed(attr)); @@ -439,6 +458,26 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attributes } + #[cfg(debug_assertions)] + /// Checks whether all `ArgParser`s were observed by an attribute parser at least once + /// This check exists because otherwise it is too easy to accidentally ignore the arguments of an attribute + fn check_args_used(&self, attr: &ast::Attribute, args: &ArgParser) { + if let ArgParser::List(items) = args { + for item in items.mixed() { + if let crate::parser::MetaItemOrLitParser::MetaItemParser(item) = item { + if !item.are_args_checked() { + self.dcx().span_delayed_bug( + item.span(), + "attribute args were not properly checked", + ); + return; + } + self.check_args_used(attr, item.args()); + } + } + } + } + /// Returns whether there is a parser for an attribute with this name pub fn is_parsed_attribute(path: &[Symbol]) -> bool { /// The list of attributes that are parsed attributes, diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 1609e2eefc328..bcdc42aa39af1 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -5,7 +5,7 @@ use std::borrow::Borrow; use std::fmt::{Debug, Display}; -use std::sync::atomic::AtomicBool; + use rustc_ast::token::{self, Delimiter, MetaVarKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ @@ -209,6 +209,19 @@ impl ArgParser { Self::NameValue(args) => Err(args.args_span()), } } + + /// Explicitly ignore the arguments, disarming the arguments-used check + pub fn ignore_args(&self) { + #[cfg(debug_assertions)] + match self { + ArgParser::List(list) => { + for item in list.mixed() { + item.ignore_args(); + } + } + _ => {} + } + } } /// Inside lists, values could be either literals, or more deeply nested meta items. @@ -253,6 +266,26 @@ impl MetaItemOrLitParser { MetaItemOrLitParser::Lit(_) => None, } } + + /// Returns some if this `MetaItemOrLitParser` is a `MetaItem` with no arguments + pub fn meta_item_no_args(&self) -> Option<&MetaItemParser> { + let meta_item = self.meta_item()?; + match meta_item.args().no_args() { + Ok(_) => Some(meta_item), + Err(_) => None, + } + } + + /// Explicitly ignore the arguments, disarming the arguments-used check + pub fn ignore_args(&self) { + #[cfg(debug_assertions)] + match self { + MetaItemOrLitParser::MetaItemParser(meta_item) => { + meta_item.ignore_args(); + } + MetaItemOrLitParser::Lit(_) => {} + } + } } /// Utility that deconstructs a MetaItem into usable parts. @@ -271,6 +304,11 @@ impl MetaItemOrLitParser { pub struct MetaItemParser { path: OwnedPathParser, args: ArgParser, + + /// Whether the `args` of this meta item have been looked at. + /// This is tracked because if the arguments of a `MetaItemParser` are ignored, this is probably a mistake + #[cfg(debug_assertions)] + args_checked: std::sync::atomic::AtomicBool, } impl Debug for MetaItemParser { @@ -307,6 +345,8 @@ impl MetaItemParser { /// Gets just the args parser, without caring about the path. pub fn args(&self) -> &ArgParser { + #[cfg(debug_assertions)] + self.args_checked.store(true, std::sync::atomic::Ordering::Relaxed); &self.args } @@ -319,6 +359,17 @@ impl MetaItemParser { pub fn word_is(&self, sym: Symbol) -> Option<&ArgParser> { self.path().word_is(sym).then(|| self.args()) } + + /// Explicitly ignore the arguments, disarming the arguments-used check + pub fn ignore_args(&self) { + #[cfg(debug_assertions)] + self.args().ignore_args(); + } + + #[cfg(debug_assertions)] + pub fn are_args_checked(&self) -> bool { + self.args_checked.load(std::sync::atomic::Ordering::Relaxed) + } } #[derive(Clone)] @@ -529,7 +580,12 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { ArgParser::NoArgs }; - Ok(MetaItemParser { path: PathParser(path), args }) + Ok(MetaItemParser { + path: PathParser(path), + args, + #[cfg(debug_assertions)] + args_checked: std::sync::atomic::AtomicBool::new(false), + }) } fn parse_meta_item_inner(&mut self) -> PResult<'sess, MetaItemOrLitParser> { From 10ff821686103f52ac54579ca4f4000c19736ffb Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:33:49 +0200 Subject: [PATCH 03/14] Properly check arguments of `#[inline]` --- .../src/attributes/inline.rs | 2 +- tests/ui/attributes/args-checked.rs | 7 +++ tests/ui/attributes/args-checked.stderr | 45 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/ui/attributes/args-checked.rs create mode 100644 tests/ui/attributes/args-checked.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index e5b2fb130a185..4c2e657ab80ff 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -42,7 +42,7 @@ impl SingleAttributeParser for InlineParser { return None; }; - match l.meta_item().and_then(|i| i.path().word_sym()) { + match l.meta_item_no_args().and_then(|i| i.path().word_sym()) { Some(sym::always) => { Some(AttributeKind::Inline(InlineAttr::Always, cx.attr_span)) } diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs new file mode 100644 index 0000000000000..8a512a7f2a849 --- /dev/null +++ b/tests/ui/attributes/args-checked.rs @@ -0,0 +1,7 @@ +#[inline(always = 5)] +//~^ ERROR malformed +#[inline(always(x, y, z))] +//~^ ERROR malformed +fn main() { + +} \ No newline at end of file diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr new file mode 100644 index 0000000000000..362a03ac68f5d --- /dev/null +++ b/tests/ui/attributes/args-checked.stderr @@ -0,0 +1,45 @@ +error[E0539]: malformed `inline` attribute input + --> $DIR/args-checked.rs:1:1 + | +LL | #[inline(always = 5)] + | ^^^^^^^^^----------^^ + | | + | valid arguments are `always` or `never` + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[inline(always = 5)] +LL + #[inline(always)] + | +LL - #[inline(always = 5)] +LL + #[inline(never)] + | +LL - #[inline(always = 5)] +LL + #[inline] + | + +error[E0539]: malformed `inline` attribute input + --> $DIR/args-checked.rs:3:1 + | +LL | #[inline(always(x, y, z))] + | ^^^^^^^^^---------------^^ + | | + | valid arguments are `always` or `never` + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[inline(always(x, y, z))] +LL + #[inline(always)] + | +LL - #[inline(always(x, y, z))] +LL + #[inline(never)] + | +LL - #[inline(always(x, y, z))] +LL + #[inline] + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0539`. From 5a6016d0e08cefe74d0ff231395352a91d3e13b4 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:35:05 +0200 Subject: [PATCH 04/14] Properly check arguments of `#[instruction_set]` --- .../src/attributes/instruction_set.rs | 2 +- tests/ui/attributes/args-checked.rs | 4 ++++ tests/ui/attributes/args-checked.stderr | 24 ++++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs index 4003aba76af8e..c02ac8959a77a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs +++ b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs @@ -22,7 +22,7 @@ impl SingleAttributeParser for InstructionSetParser { const POSSIBLE_ARM_SYMBOLS: &[Symbol] = &[sym::a32, sym::t32]; let maybe_meta_item = cx.single_element_list(args, cx.attr_span)?; - let Some(meta_item) = maybe_meta_item.meta_item() else { + let Some(meta_item) = maybe_meta_item.meta_item_no_args() else { cx.adcx().expected_specific_argument(maybe_meta_item.span(), POSSIBLE_SYMBOLS); return None; }; diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index 8a512a7f2a849..0f4d933e7be4e 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -2,6 +2,10 @@ //~^ ERROR malformed #[inline(always(x, y, z))] //~^ ERROR malformed +#[instruction_set(arm::a32 = 5)] +//~^ ERROR malformed +#[instruction_set(arm::a32(x, y, z))] +//~^ ERROR malformed fn main() { } \ No newline at end of file diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index 362a03ac68f5d..62a63faa1dd3f 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -40,6 +40,28 @@ LL - #[inline(always(x, y, z))] LL + #[inline] | -error: aborting due to 2 previous errors +error[E0539]: malformed `instruction_set` attribute input + --> $DIR/args-checked.rs:5:1 + | +LL | #[instruction_set(arm::a32 = 5)] + | ^^^^^^^^^^^^^^^^^^------------^^ + | | | + | | valid arguments are `arm::a32` or `arm::t32` + | help: must be of the form: `#[instruction_set(set)]` + | + = note: for more information, visit + +error[E0539]: malformed `instruction_set` attribute input + --> $DIR/args-checked.rs:7:1 + | +LL | #[instruction_set(arm::a32(x, y, z))] + | ^^^^^^^^^^^^^^^^^^-----------------^^ + | | | + | | valid arguments are `arm::a32` or `arm::t32` + | help: must be of the form: `#[instruction_set(set)]` + | + = note: for more information, visit + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0539`. From b5a42202849e86c6a9344b8373f9732bd7935b04 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:36:39 +0200 Subject: [PATCH 05/14] Properly check arguments of `#[macro_export]` --- .../src/attributes/macro_attrs.rs | 2 +- tests/ui/attributes/args-checked.rs | 10 +++++ tests/ui/attributes/args-checked.stderr | 43 ++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index a0ded93180eb0..2c0c9bbf60955 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -146,7 +146,7 @@ impl SingleAttributeParser for MacroExportParser { cx.adcx().warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS); return None; }; - match l.meta_item().and_then(|i| i.path().word_sym()) { + match l.meta_item_no_args().and_then(|i| i.path().word_sym()) { Some(sym::local_inner_macros) => true, _ => { cx.adcx().warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS); diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index 0f4d933e7be4e..c5abfd68ed66c 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -8,4 +8,14 @@ //~^ ERROR malformed fn main() { +} + +#[macro_export(local_inner_macros = 5)] +//~^ ERROR valid forms for the attribute are +//~| WARN previously accepted +#[macro_export(local_inner_macros(x, y, z))] +//~^ ERROR valid forms for the attribute are +//~| WARN previously accepted +macro_rules! m { + () => {}; } \ No newline at end of file diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index 62a63faa1dd3f..df4b0ea007b04 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -62,6 +62,47 @@ LL | #[instruction_set(arm::a32(x, y, z))] | = note: for more information, visit -error: aborting due to 4 previous errors +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` + --> $DIR/args-checked.rs:13:1 + | +LL | #[macro_export(local_inner_macros = 5)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default + +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` + --> $DIR/args-checked.rs:16:1 + | +LL | #[macro_export(local_inner_macros(x, y, z))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0539`. +Future incompatibility report: Future breakage diagnostic: +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` + --> $DIR/args-checked.rs:13:1 + | +LL | #[macro_export(local_inner_macros = 5)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default + +Future breakage diagnostic: +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` + --> $DIR/args-checked.rs:16:1 + | +LL | #[macro_export(local_inner_macros(x, y, z))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default + From 306597fd1024a88f7549bb9d6988b0e7c9137e38 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:39:09 +0200 Subject: [PATCH 06/14] Properly check arguments of `#[rustc_allow_const_fn_unstable]` --- .../src/attributes/allow_unstable.rs | 2 +- tests/ui/attributes/args-checked.rs | 10 ++++++- tests/ui/attributes/args-checked.stderr | 30 +++++++++++++------ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index c2511ac75d5d2..93f19922b4188 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -91,7 +91,7 @@ fn parse_unstable( for param in list.mixed() { let param_span = param.span(); - if let Some(ident) = param.meta_item().and_then(|i| i.path().word()) { + if let Some(ident) = param.meta_item_no_args().and_then(|i| i.path().word()) { res.push(ident.name); } else { cx.emit_err(session_diagnostics::ExpectsFeatures { diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index c5abfd68ed66c..462ca307b58a7 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -1,3 +1,5 @@ +#![feature(rustc_attrs)] + #[inline(always = 5)] //~^ ERROR malformed #[inline(always(x, y, z))] @@ -18,4 +20,10 @@ fn main() { //~| WARN previously accepted macro_rules! m { () => {}; -} \ No newline at end of file +} + +#[rustc_allow_const_fn_unstable(x = 5)] +//~^ ERROR `rustc_allow_const_fn_unstable` expects feature names +#[rustc_allow_const_fn_unstable(x(x, y, z))] +//~^ ERROR `rustc_allow_const_fn_unstable` expects feature names +const fn g() {} \ No newline at end of file diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index df4b0ea007b04..89cb1c1dfe006 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:1:1 + --> $DIR/args-checked.rs:3:1 | LL | #[inline(always = 5)] | ^^^^^^^^^----------^^ @@ -20,7 +20,7 @@ LL + #[inline] | error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:3:1 + --> $DIR/args-checked.rs:5:1 | LL | #[inline(always(x, y, z))] | ^^^^^^^^^---------------^^ @@ -41,7 +41,7 @@ LL + #[inline] | error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:5:1 + --> $DIR/args-checked.rs:7:1 | LL | #[instruction_set(arm::a32 = 5)] | ^^^^^^^^^^^^^^^^^^------------^^ @@ -52,7 +52,7 @@ LL | #[instruction_set(arm::a32 = 5)] = note: for more information, visit error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:7:1 + --> $DIR/args-checked.rs:9:1 | LL | #[instruction_set(arm::a32(x, y, z))] | ^^^^^^^^^^^^^^^^^^-----------------^^ @@ -62,8 +62,20 @@ LL | #[instruction_set(arm::a32(x, y, z))] | = note: for more information, visit +error: `rustc_allow_const_fn_unstable` expects feature names + --> $DIR/args-checked.rs:25:33 + | +LL | #[rustc_allow_const_fn_unstable(x = 5)] + | ^^^^^ + +error: `rustc_allow_const_fn_unstable` expects feature names + --> $DIR/args-checked.rs:27:33 + | +LL | #[rustc_allow_const_fn_unstable(x(x, y, z))] + | ^^^^^^^^^^ + error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:13:1 + --> $DIR/args-checked.rs:15:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +85,7 @@ LL | #[macro_export(local_inner_macros = 5)] = note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:16:1 + --> $DIR/args-checked.rs:18:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,12 +93,12 @@ LL | #[macro_export(local_inner_macros(x, y, z))] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:13:1 + --> $DIR/args-checked.rs:15:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -97,7 +109,7 @@ LL | #[macro_export(local_inner_macros = 5)] Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:16:1 + --> $DIR/args-checked.rs:18:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From e5634d49658c824a13458a5766caa1e6ca399cd7 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:40:19 +0200 Subject: [PATCH 07/14] Properly check arguments of `#[optimize]` --- .../src/attributes/codegen_attrs.rs | 2 +- tests/ui/attributes/args-checked.rs | 6 ++ tests/ui/attributes/args-checked.stderr | 62 +++++++++++++++---- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 73b2727fdab0a..0548360e1d739 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -25,7 +25,7 @@ impl SingleAttributeParser for OptimizeParser { fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let single = cx.single_element_list(args, cx.attr_span)?; - let res = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) { + let res = match single.meta_item_no_args().and_then(|i| i.path().word().map(|i| i.name)) { Some(sym::size) => OptimizeAttr::Size, Some(sym::speed) => OptimizeAttr::Speed, Some(sym::none) => OptimizeAttr::DoNotOptimize, diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index 462ca307b58a7..27bf172c55356 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -1,4 +1,6 @@ #![feature(rustc_attrs)] +#![feature(optimize_attribute)] +#![allow(unused_attributes)] #[inline(always = 5)] //~^ ERROR malformed @@ -8,6 +10,10 @@ //~^ ERROR malformed #[instruction_set(arm::a32(x, y, z))] //~^ ERROR malformed +#[optimize(size = 5)] +//~^ ERROR malformed +#[optimize(size(x, y, z))] +//~^ ERROR malformed fn main() { } diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index 89cb1c1dfe006..5cef1bf20be1f 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:3:1 + --> $DIR/args-checked.rs:5:1 | LL | #[inline(always = 5)] | ^^^^^^^^^----------^^ @@ -20,7 +20,7 @@ LL + #[inline] | error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:5:1 + --> $DIR/args-checked.rs:7:1 | LL | #[inline(always(x, y, z))] | ^^^^^^^^^---------------^^ @@ -41,7 +41,7 @@ LL + #[inline] | error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:7:1 + --> $DIR/args-checked.rs:9:1 | LL | #[instruction_set(arm::a32 = 5)] | ^^^^^^^^^^^^^^^^^^------------^^ @@ -52,7 +52,7 @@ LL | #[instruction_set(arm::a32 = 5)] = note: for more information, visit error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:9:1 + --> $DIR/args-checked.rs:11:1 | LL | #[instruction_set(arm::a32(x, y, z))] | ^^^^^^^^^^^^^^^^^^-----------------^^ @@ -62,20 +62,60 @@ LL | #[instruction_set(arm::a32(x, y, z))] | = note: for more information, visit +error[E0539]: malformed `optimize` attribute input + --> $DIR/args-checked.rs:13:1 + | +LL | #[optimize(size = 5)] + | ^^^^^^^^^^^--------^^ + | | + | valid arguments are `size`, `speed` or `none` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[optimize(size = 5)] +LL + #[optimize(none)] + | +LL - #[optimize(size = 5)] +LL + #[optimize(size)] + | +LL - #[optimize(size = 5)] +LL + #[optimize(speed)] + | + +error[E0539]: malformed `optimize` attribute input + --> $DIR/args-checked.rs:15:1 + | +LL | #[optimize(size(x, y, z))] + | ^^^^^^^^^^^-------------^^ + | | + | valid arguments are `size`, `speed` or `none` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[optimize(size(x, y, z))] +LL + #[optimize(none)] + | +LL - #[optimize(size(x, y, z))] +LL + #[optimize(size)] + | +LL - #[optimize(size(x, y, z))] +LL + #[optimize(speed)] + | + error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:25:33 + --> $DIR/args-checked.rs:31:33 | LL | #[rustc_allow_const_fn_unstable(x = 5)] | ^^^^^ error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:27:33 + --> $DIR/args-checked.rs:33:33 | LL | #[rustc_allow_const_fn_unstable(x(x, y, z))] | ^^^^^^^^^^ error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:15:1 + --> $DIR/args-checked.rs:21:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +125,7 @@ LL | #[macro_export(local_inner_macros = 5)] = note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:18:1 + --> $DIR/args-checked.rs:24:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,12 +133,12 @@ LL | #[macro_export(local_inner_macros(x, y, z))] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 -error: aborting due to 8 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:15:1 + --> $DIR/args-checked.rs:21:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,7 +149,7 @@ LL | #[macro_export(local_inner_macros = 5)] Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:18:1 + --> $DIR/args-checked.rs:24:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 6e9b743109c9c0ab67d0d9122043186b48a15122 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:41:06 +0200 Subject: [PATCH 08/14] Properly check arguments of `#[coverage]` --- .../src/attributes/codegen_attrs.rs | 2 +- tests/ui/attributes/args-checked.rs | 5 ++ tests/ui/attributes/args-checked.stderr | 60 +++++++++++++++---- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 0548360e1d739..c80f076e7eac9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -80,7 +80,7 @@ impl SingleAttributeParser for CoverageParser { let mut fail_incorrect_argument = |span| cx.adcx().expected_specific_argument(span, &[sym::on, sym::off]); - let Some(arg) = arg.meta_item() else { + let Some(arg) = arg.meta_item_no_args() else { fail_incorrect_argument(arg.span()); return None; }; diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index 27bf172c55356..8694db038e65f 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -1,5 +1,6 @@ #![feature(rustc_attrs)] #![feature(optimize_attribute)] +#![feature(coverage_attribute)] #![allow(unused_attributes)] #[inline(always = 5)] @@ -14,6 +15,10 @@ //~^ ERROR malformed #[optimize(size(x, y, z))] //~^ ERROR malformed +#[coverage(off = 5)] +//~^ ERROR malformed +#[coverage(off(x, y, z))] +//~^ ERROR malformed fn main() { } diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index 5cef1bf20be1f..9b085d0f8ac60 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:5:1 + --> $DIR/args-checked.rs:6:1 | LL | #[inline(always = 5)] | ^^^^^^^^^----------^^ @@ -20,7 +20,7 @@ LL + #[inline] | error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:7:1 + --> $DIR/args-checked.rs:8:1 | LL | #[inline(always(x, y, z))] | ^^^^^^^^^---------------^^ @@ -41,7 +41,7 @@ LL + #[inline] | error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:9:1 + --> $DIR/args-checked.rs:10:1 | LL | #[instruction_set(arm::a32 = 5)] | ^^^^^^^^^^^^^^^^^^------------^^ @@ -52,7 +52,7 @@ LL | #[instruction_set(arm::a32 = 5)] = note: for more information, visit error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:11:1 + --> $DIR/args-checked.rs:12:1 | LL | #[instruction_set(arm::a32(x, y, z))] | ^^^^^^^^^^^^^^^^^^-----------------^^ @@ -63,7 +63,7 @@ LL | #[instruction_set(arm::a32(x, y, z))] = note: for more information, visit error[E0539]: malformed `optimize` attribute input - --> $DIR/args-checked.rs:13:1 + --> $DIR/args-checked.rs:14:1 | LL | #[optimize(size = 5)] | ^^^^^^^^^^^--------^^ @@ -83,7 +83,7 @@ LL + #[optimize(speed)] | error[E0539]: malformed `optimize` attribute input - --> $DIR/args-checked.rs:15:1 + --> $DIR/args-checked.rs:16:1 | LL | #[optimize(size(x, y, z))] | ^^^^^^^^^^^-------------^^ @@ -102,20 +102,54 @@ LL - #[optimize(size(x, y, z))] LL + #[optimize(speed)] | +error[E0539]: malformed `coverage` attribute input + --> $DIR/args-checked.rs:18:1 + | +LL | #[coverage(off = 5)] + | ^^^^^^^^^^^-------^^ + | | + | valid arguments are `on` or `off` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[coverage(off = 5)] +LL + #[coverage(off)] + | +LL - #[coverage(off = 5)] +LL + #[coverage(on)] + | + +error[E0539]: malformed `coverage` attribute input + --> $DIR/args-checked.rs:20:1 + | +LL | #[coverage(off(x, y, z))] + | ^^^^^^^^^^^------------^^ + | | + | valid arguments are `on` or `off` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[coverage(off(x, y, z))] +LL + #[coverage(off)] + | +LL - #[coverage(off(x, y, z))] +LL + #[coverage(on)] + | + error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:31:33 + --> $DIR/args-checked.rs:36:33 | LL | #[rustc_allow_const_fn_unstable(x = 5)] | ^^^^^ error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:33:33 + --> $DIR/args-checked.rs:38:33 | LL | #[rustc_allow_const_fn_unstable(x(x, y, z))] | ^^^^^^^^^^ error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:21:1 + --> $DIR/args-checked.rs:26:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -125,7 +159,7 @@ LL | #[macro_export(local_inner_macros = 5)] = note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:24:1 + --> $DIR/args-checked.rs:29:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,12 +167,12 @@ LL | #[macro_export(local_inner_macros(x, y, z))] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:21:1 + --> $DIR/args-checked.rs:26:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -149,7 +183,7 @@ LL | #[macro_export(local_inner_macros = 5)] Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:24:1 + --> $DIR/args-checked.rs:29:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From bad8e4389601e974ddc767f44058367bbd435570 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:42:37 +0200 Subject: [PATCH 09/14] Properly check arguments of `#[used]` --- .../src/attributes/codegen_attrs.rs | 2 +- tests/ui/attributes/args-checked.rs | 8 +++- tests/ui/attributes/args-checked.stderr | 42 ++++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index c80f076e7eac9..043997371fb80 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -375,7 +375,7 @@ impl AttributeParser for UsedParser { return; }; - match l.meta_item().and_then(|i| i.path().word_sym()) { + match l.meta_item_no_args().and_then(|i| i.path().word_sym()) { Some(sym::compiler) => { if !cx.features().used_with_arg() { feature_err( diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index 8694db038e65f..c009e7d35aac3 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -37,4 +37,10 @@ macro_rules! m { //~^ ERROR `rustc_allow_const_fn_unstable` expects feature names #[rustc_allow_const_fn_unstable(x(x, y, z))] //~^ ERROR `rustc_allow_const_fn_unstable` expects feature names -const fn g() {} \ No newline at end of file +const fn g() {} + +#[used(always = 5)] +//~^ ERROR malformed +#[used(always(x, y, z))] +//~^ ERROR malformed +static H: u64 = 5; \ No newline at end of file diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index 9b085d0f8ac60..b9679a0c34d96 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -148,6 +148,46 @@ error: `rustc_allow_const_fn_unstable` expects feature names LL | #[rustc_allow_const_fn_unstable(x(x, y, z))] | ^^^^^^^^^^ +error[E0539]: malformed `used` attribute input + --> $DIR/args-checked.rs:42:1 + | +LL | #[used(always = 5)] + | ^^^^^^^----------^^ + | | + | valid arguments are `compiler` or `linker` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[used(always = 5)] +LL + #[used(compiler)] + | +LL - #[used(always = 5)] +LL + #[used(linker)] + | +LL - #[used(always = 5)] +LL + #[used] + | + +error[E0539]: malformed `used` attribute input + --> $DIR/args-checked.rs:44:1 + | +LL | #[used(always(x, y, z))] + | ^^^^^^^---------------^^ + | | + | valid arguments are `compiler` or `linker` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[used(always(x, y, z))] +LL + #[used(compiler)] + | +LL - #[used(always(x, y, z))] +LL + #[used(linker)] + | +LL - #[used(always(x, y, z))] +LL + #[used] + | + error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/args-checked.rs:26:1 | @@ -167,7 +207,7 @@ LL | #[macro_export(local_inner_macros(x, y, z))] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 -error: aborting due to 12 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: From c42ceed5f4c38cabf75b42f68d131ec7f2b3b757 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:44:39 +0200 Subject: [PATCH 10/14] Properly check arguments of `#[rustc_must_implement_one_of]` --- .../src/attributes/rustc_internal.rs | 2 +- tests/ui/attributes/args-checked.rs | 10 +++++++++- tests/ui/attributes/args-checked.stderr | 20 ++++++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 15bcffe529a0c..30776142fc627 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -49,7 +49,7 @@ impl SingleAttributeParser for RustcMustImplementOneOfParser { let mut errored = false; for argument in inputs { - let Some(meta) = argument.meta_item() else { + let Some(meta) = argument.meta_item_no_args() else { cx.adcx().expected_identifier(argument.span()); return None; }; diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index c009e7d35aac3..ab661c3e3e657 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -43,4 +43,12 @@ const fn g() {} //~^ ERROR malformed #[used(always(x, y, z))] //~^ ERROR malformed -static H: u64 = 5; \ No newline at end of file +static H: u64 = 5; + +#[rustc_must_implement_one_of(eq = 5, neq)] +//~^ ERROR malformed +#[rustc_must_implement_one_of(eq(x, y, z), neq)] +//~^ ERROR malformed +trait T { + +} \ No newline at end of file diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index b9679a0c34d96..792a74900d958 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -188,6 +188,24 @@ LL - #[used(always(x, y, z))] LL + #[used] | +error[E0539]: malformed `rustc_must_implement_one_of` attribute input + --> $DIR/args-checked.rs:48:1 + | +LL | #[rustc_must_implement_one_of(eq = 5, neq)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^^^^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` + +error[E0539]: malformed `rustc_must_implement_one_of` attribute input + --> $DIR/args-checked.rs:50:1 + | +LL | #[rustc_must_implement_one_of(eq(x, y, z), neq)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` + error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/args-checked.rs:26:1 | @@ -207,7 +225,7 @@ LL | #[macro_export(local_inner_macros(x, y, z))] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 -error: aborting due to 14 previous errors +error: aborting due to 16 previous errors For more information about this error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: From a934de874ba14f024da73bc179b12e9120f0fa0f Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:45:39 +0200 Subject: [PATCH 11/14] Properly check arguments of `#[rustc_dump_layout]` --- .../src/attributes/rustc_dump.rs | 2 +- tests/ui/attributes/args-checked.rs | 8 +++++++ tests/ui/attributes/args-checked.stderr | 21 +++++++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs index e1b8b3b29bf00..92f9585346877 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs @@ -110,7 +110,7 @@ impl CombineAttributeParser for RustcDumpLayoutParser { let mut result = Vec::new(); for item in items.mixed() { - let Some(arg) = item.meta_item() else { + let Some(arg) = item.meta_item_no_args() else { cx.adcx().expected_not_literal(item.span()); continue; }; diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index ab661c3e3e657..c7b40e73b7887 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -51,4 +51,12 @@ static H: u64 = 5; //~^ ERROR malformed trait T { +} + +#[rustc_dump_layout(debug = 5)] +//~^ ERROR malformed +#[rustc_dump_layout(debug(x, y, z))] +//~^ ERROR malformed +enum E { + } \ No newline at end of file diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index 792a74900d958..d553458f15cac 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -206,6 +206,22 @@ LL | #[rustc_must_implement_one_of(eq(x, y, z), neq)] | | expected a valid identifier here | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` +error[E0565]: malformed `rustc_dump_layout` attribute input + --> $DIR/args-checked.rs:56:1 + | +LL | #[rustc_dump_layout(debug = 5)] + | ^^^^^^^^^^^^^^^^^^^^---------^^ + | | + | didn't expect a literal here + +error[E0565]: malformed `rustc_dump_layout` attribute input + --> $DIR/args-checked.rs:58:1 + | +LL | #[rustc_dump_layout(debug(x, y, z))] + | ^^^^^^^^^^^^^^^^^^^^--------------^^ + | | + | didn't expect a literal here + error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/args-checked.rs:26:1 | @@ -225,9 +241,10 @@ LL | #[macro_export(local_inner_macros(x, y, z))] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 -error: aborting due to 16 previous errors +error: aborting due to 18 previous errors -For more information about this error, try `rustc --explain E0539`. +Some errors have detailed explanations: E0539, E0565. +For more information about an error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/args-checked.rs:26:1 From 3dcd5f4a7fd09718da0f4878aee432b39b6e4aa6 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:47:59 +0200 Subject: [PATCH 12/14] Properly check arguments of query dep graph attrs --- compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 30776142fc627..b85046433a360 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -945,7 +945,7 @@ impl SingleAttributeParser for RustcIfThisChangedParser { cx.adcx().expected_single_argument(attr_span, list.len()); return None; }; - let Some(ident) = item.meta_item().and_then(|item| item.ident()) else { + let Some(ident) = item.meta_item_no_args().and_then(|item| item.ident()) else { cx.adcx().expected_identifier(item.span()); return None; }; @@ -1003,7 +1003,7 @@ impl CombineAttributeParser for RustcThenThisWouldNeedParser { cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" }); } let item = cx.single_element_list(args, cx.attr_span)?; - let Some(ident) = item.meta_item().and_then(|item| item.ident()) else { + let Some(ident) = item.meta_item_no_args().and_then(|item| item.ident()) else { cx.adcx().expected_identifier(item.span()); return None; }; From 302710b7a7fde1466af0d06c92b77dd77e57469f Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:48:46 +0200 Subject: [PATCH 13/14] Properly check arguments of `#[rustc_abi]` --- .../src/attributes/test_attrs.rs | 2 +- tests/ui/attributes/args-checked.rs | 4 ++ tests/ui/attributes/args-checked.stderr | 60 +++++++++++++++---- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index 4fe0f079bc83c..df990341ab143 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -157,7 +157,7 @@ impl SingleAttributeParser for RustcAbiParser { let mut fail_incorrect_argument = |span| cx.adcx().expected_specific_argument(span, &[sym::assert_eq, sym::debug]); - let Some(arg) = arg.meta_item() else { + let Some(arg) = arg.meta_item_no_args() else { fail_incorrect_argument(args.span); return None; }; diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index c7b40e73b7887..ea060d6a4e68a 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -19,6 +19,10 @@ //~^ ERROR malformed #[coverage(off(x, y, z))] //~^ ERROR malformed +#[rustc_abi(debug = 5)] +//~^ ERROR malformed +#[rustc_abi(debug(x, y, z))] +//~^ ERROR malformed fn main() { } diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index d553458f15cac..127a0edb51491 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -136,20 +136,54 @@ LL - #[coverage(off(x, y, z))] LL + #[coverage(on)] | +error[E0539]: malformed `rustc_abi` attribute input + --> $DIR/args-checked.rs:22:1 + | +LL | #[rustc_abi(debug = 5)] + | ^^^^^^^^^^^-----------^ + | | + | valid arguments are `assert_eq` or `debug` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_abi(debug = 5)] +LL + #[rustc_abi(assert_eq)] + | +LL - #[rustc_abi(debug = 5)] +LL + #[rustc_abi(debug)] + | + +error[E0539]: malformed `rustc_abi` attribute input + --> $DIR/args-checked.rs:24:1 + | +LL | #[rustc_abi(debug(x, y, z))] + | ^^^^^^^^^^^----------------^ + | | + | valid arguments are `assert_eq` or `debug` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_abi(debug(x, y, z))] +LL + #[rustc_abi(assert_eq)] + | +LL - #[rustc_abi(debug(x, y, z))] +LL + #[rustc_abi(debug)] + | + error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:36:33 + --> $DIR/args-checked.rs:40:33 | LL | #[rustc_allow_const_fn_unstable(x = 5)] | ^^^^^ error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:38:33 + --> $DIR/args-checked.rs:42:33 | LL | #[rustc_allow_const_fn_unstable(x(x, y, z))] | ^^^^^^^^^^ error[E0539]: malformed `used` attribute input - --> $DIR/args-checked.rs:42:1 + --> $DIR/args-checked.rs:46:1 | LL | #[used(always = 5)] | ^^^^^^^----------^^ @@ -169,7 +203,7 @@ LL + #[used] | error[E0539]: malformed `used` attribute input - --> $DIR/args-checked.rs:44:1 + --> $DIR/args-checked.rs:48:1 | LL | #[used(always(x, y, z))] | ^^^^^^^---------------^^ @@ -189,7 +223,7 @@ LL + #[used] | error[E0539]: malformed `rustc_must_implement_one_of` attribute input - --> $DIR/args-checked.rs:48:1 + --> $DIR/args-checked.rs:52:1 | LL | #[rustc_must_implement_one_of(eq = 5, neq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^^^^^^ @@ -198,7 +232,7 @@ LL | #[rustc_must_implement_one_of(eq = 5, neq)] | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` error[E0539]: malformed `rustc_must_implement_one_of` attribute input - --> $DIR/args-checked.rs:50:1 + --> $DIR/args-checked.rs:54:1 | LL | #[rustc_must_implement_one_of(eq(x, y, z), neq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^ @@ -207,7 +241,7 @@ LL | #[rustc_must_implement_one_of(eq(x, y, z), neq)] | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` error[E0565]: malformed `rustc_dump_layout` attribute input - --> $DIR/args-checked.rs:56:1 + --> $DIR/args-checked.rs:60:1 | LL | #[rustc_dump_layout(debug = 5)] | ^^^^^^^^^^^^^^^^^^^^---------^^ @@ -215,7 +249,7 @@ LL | #[rustc_dump_layout(debug = 5)] | didn't expect a literal here error[E0565]: malformed `rustc_dump_layout` attribute input - --> $DIR/args-checked.rs:58:1 + --> $DIR/args-checked.rs:62:1 | LL | #[rustc_dump_layout(debug(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^--------------^^ @@ -223,7 +257,7 @@ LL | #[rustc_dump_layout(debug(x, y, z))] | didn't expect a literal here error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:26:1 + --> $DIR/args-checked.rs:30:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,7 +267,7 @@ LL | #[macro_export(local_inner_macros = 5)] = note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:29:1 + --> $DIR/args-checked.rs:33:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,13 +275,13 @@ LL | #[macro_export(local_inner_macros(x, y, z))] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 -error: aborting due to 18 previous errors +error: aborting due to 20 previous errors Some errors have detailed explanations: E0539, E0565. For more information about an error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:26:1 + --> $DIR/args-checked.rs:30:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -258,7 +292,7 @@ LL | #[macro_export(local_inner_macros = 5)] Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:29:1 + --> $DIR/args-checked.rs:33:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From e6fe0e79b9574b328f9e3393e56a8a318218b450 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sun, 12 Apr 2026 12:49:44 +0200 Subject: [PATCH 14/14] Properly check arguments of `#[test_runner]` --- .../src/attributes/test_attrs.rs | 2 +- tests/ui/attributes/args-checked.rs | 8 ++- tests/ui/attributes/args-checked.stderr | 64 ++++++++++++------- 3 files changed, 49 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index df990341ab143..f226bcd94bab6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -210,7 +210,7 @@ impl SingleAttributeParser for TestRunnerParser { fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let single = cx.single_element_list(args, cx.attr_span)?; - let Some(meta) = single.meta_item() else { + let Some(meta) = single.meta_item_no_args() else { cx.adcx().expected_not_literal(single.span()); return None; }; diff --git a/tests/ui/attributes/args-checked.rs b/tests/ui/attributes/args-checked.rs index ea060d6a4e68a..8eee5e2f91723 100644 --- a/tests/ui/attributes/args-checked.rs +++ b/tests/ui/attributes/args-checked.rs @@ -1,8 +1,14 @@ #![feature(rustc_attrs)] #![feature(optimize_attribute)] #![feature(coverage_attribute)] +#![feature(custom_test_frameworks)] #![allow(unused_attributes)] +#![test_runner(x = 5)] +//~^ ERROR malformed +#![test_runner(x(x,y,z))] +//~^ ERROR malformed + #[inline(always = 5)] //~^ ERROR malformed #[inline(always(x, y, z))] @@ -63,4 +69,4 @@ trait T { //~^ ERROR malformed enum E { -} \ No newline at end of file +} diff --git a/tests/ui/attributes/args-checked.stderr b/tests/ui/attributes/args-checked.stderr index 127a0edb51491..a3013dbf8db1d 100644 --- a/tests/ui/attributes/args-checked.stderr +++ b/tests/ui/attributes/args-checked.stderr @@ -1,5 +1,23 @@ +error[E0565]: malformed `test_runner` attribute input + --> $DIR/args-checked.rs:7:1 + | +LL | #![test_runner(x = 5)] + | ^^^^^^^^^^^^^^^-----^^ + | | | + | | didn't expect a literal here + | help: must be of the form: `#![test_runner(path)]` + +error[E0565]: malformed `test_runner` attribute input + --> $DIR/args-checked.rs:9:1 + | +LL | #![test_runner(x(x,y,z))] + | ^^^^^^^^^^^^^^^--------^^ + | | | + | | didn't expect a literal here + | help: must be of the form: `#![test_runner(path)]` + error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:6:1 + --> $DIR/args-checked.rs:12:1 | LL | #[inline(always = 5)] | ^^^^^^^^^----------^^ @@ -20,7 +38,7 @@ LL + #[inline] | error[E0539]: malformed `inline` attribute input - --> $DIR/args-checked.rs:8:1 + --> $DIR/args-checked.rs:14:1 | LL | #[inline(always(x, y, z))] | ^^^^^^^^^---------------^^ @@ -41,7 +59,7 @@ LL + #[inline] | error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:10:1 + --> $DIR/args-checked.rs:16:1 | LL | #[instruction_set(arm::a32 = 5)] | ^^^^^^^^^^^^^^^^^^------------^^ @@ -52,7 +70,7 @@ LL | #[instruction_set(arm::a32 = 5)] = note: for more information, visit error[E0539]: malformed `instruction_set` attribute input - --> $DIR/args-checked.rs:12:1 + --> $DIR/args-checked.rs:18:1 | LL | #[instruction_set(arm::a32(x, y, z))] | ^^^^^^^^^^^^^^^^^^-----------------^^ @@ -63,7 +81,7 @@ LL | #[instruction_set(arm::a32(x, y, z))] = note: for more information, visit error[E0539]: malformed `optimize` attribute input - --> $DIR/args-checked.rs:14:1 + --> $DIR/args-checked.rs:20:1 | LL | #[optimize(size = 5)] | ^^^^^^^^^^^--------^^ @@ -83,7 +101,7 @@ LL + #[optimize(speed)] | error[E0539]: malformed `optimize` attribute input - --> $DIR/args-checked.rs:16:1 + --> $DIR/args-checked.rs:22:1 | LL | #[optimize(size(x, y, z))] | ^^^^^^^^^^^-------------^^ @@ -103,7 +121,7 @@ LL + #[optimize(speed)] | error[E0539]: malformed `coverage` attribute input - --> $DIR/args-checked.rs:18:1 + --> $DIR/args-checked.rs:24:1 | LL | #[coverage(off = 5)] | ^^^^^^^^^^^-------^^ @@ -120,7 +138,7 @@ LL + #[coverage(on)] | error[E0539]: malformed `coverage` attribute input - --> $DIR/args-checked.rs:20:1 + --> $DIR/args-checked.rs:26:1 | LL | #[coverage(off(x, y, z))] | ^^^^^^^^^^^------------^^ @@ -137,7 +155,7 @@ LL + #[coverage(on)] | error[E0539]: malformed `rustc_abi` attribute input - --> $DIR/args-checked.rs:22:1 + --> $DIR/args-checked.rs:28:1 | LL | #[rustc_abi(debug = 5)] | ^^^^^^^^^^^-----------^ @@ -154,7 +172,7 @@ LL + #[rustc_abi(debug)] | error[E0539]: malformed `rustc_abi` attribute input - --> $DIR/args-checked.rs:24:1 + --> $DIR/args-checked.rs:30:1 | LL | #[rustc_abi(debug(x, y, z))] | ^^^^^^^^^^^----------------^ @@ -171,19 +189,19 @@ LL + #[rustc_abi(debug)] | error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:40:33 + --> $DIR/args-checked.rs:46:33 | LL | #[rustc_allow_const_fn_unstable(x = 5)] | ^^^^^ error: `rustc_allow_const_fn_unstable` expects feature names - --> $DIR/args-checked.rs:42:33 + --> $DIR/args-checked.rs:48:33 | LL | #[rustc_allow_const_fn_unstable(x(x, y, z))] | ^^^^^^^^^^ error[E0539]: malformed `used` attribute input - --> $DIR/args-checked.rs:46:1 + --> $DIR/args-checked.rs:52:1 | LL | #[used(always = 5)] | ^^^^^^^----------^^ @@ -203,7 +221,7 @@ LL + #[used] | error[E0539]: malformed `used` attribute input - --> $DIR/args-checked.rs:48:1 + --> $DIR/args-checked.rs:54:1 | LL | #[used(always(x, y, z))] | ^^^^^^^---------------^^ @@ -223,7 +241,7 @@ LL + #[used] | error[E0539]: malformed `rustc_must_implement_one_of` attribute input - --> $DIR/args-checked.rs:52:1 + --> $DIR/args-checked.rs:58:1 | LL | #[rustc_must_implement_one_of(eq = 5, neq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^^^^^^ @@ -232,7 +250,7 @@ LL | #[rustc_must_implement_one_of(eq = 5, neq)] | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` error[E0539]: malformed `rustc_must_implement_one_of` attribute input - --> $DIR/args-checked.rs:54:1 + --> $DIR/args-checked.rs:60:1 | LL | #[rustc_must_implement_one_of(eq(x, y, z), neq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^ @@ -241,7 +259,7 @@ LL | #[rustc_must_implement_one_of(eq(x, y, z), neq)] | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` error[E0565]: malformed `rustc_dump_layout` attribute input - --> $DIR/args-checked.rs:60:1 + --> $DIR/args-checked.rs:66:1 | LL | #[rustc_dump_layout(debug = 5)] | ^^^^^^^^^^^^^^^^^^^^---------^^ @@ -249,7 +267,7 @@ LL | #[rustc_dump_layout(debug = 5)] | didn't expect a literal here error[E0565]: malformed `rustc_dump_layout` attribute input - --> $DIR/args-checked.rs:62:1 + --> $DIR/args-checked.rs:68:1 | LL | #[rustc_dump_layout(debug(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^--------------^^ @@ -257,7 +275,7 @@ LL | #[rustc_dump_layout(debug(x, y, z))] | didn't expect a literal here error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:30:1 + --> $DIR/args-checked.rs:36:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -267,7 +285,7 @@ LL | #[macro_export(local_inner_macros = 5)] = note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:33:1 + --> $DIR/args-checked.rs:39:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -275,13 +293,13 @@ LL | #[macro_export(local_inner_macros(x, y, z))] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 -error: aborting due to 20 previous errors +error: aborting due to 22 previous errors Some errors have detailed explanations: E0539, E0565. For more information about an error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:30:1 + --> $DIR/args-checked.rs:36:1 | LL | #[macro_export(local_inner_macros = 5)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -292,7 +310,7 @@ LL | #[macro_export(local_inner_macros = 5)] Future breakage diagnostic: error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/args-checked.rs:33:1 + --> $DIR/args-checked.rs:39:1 | LL | #[macro_export(local_inner_macros(x, y, z))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^