diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index af94e8acaf68e..dab9e7666c23a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -326,7 +326,8 @@ pub fn parse_cfg_attr( }) { Ok(r) => return Some(r), Err(e) => { - let suggestions = CFG_ATTR_TEMPLATE.suggestions(cfg_attr.style, sym::cfg_attr); + let suggestions = + CFG_ATTR_TEMPLATE.suggestions(Some(cfg_attr.style), sym::cfg_attr); e.with_span_suggestions( cfg_attr.span, "must be of the form", @@ -356,7 +357,7 @@ pub fn parse_cfg_attr( template: CFG_ATTR_TEMPLATE, attribute: AttrPath::from_ast(&cfg_attr.get_normal_item().path), reason, - attr_style: cfg_attr.style, + suggestions: CFG_ATTR_TEMPLATE.suggestions(Some(cfg_attr.style), sym::cfg_attr), }); } } @@ -388,6 +389,7 @@ fn parse_cfg_attr_internal<'a>( let cfg_predicate = AttributeParser::parse_single_args( sess, attribute.span, + attribute.get_normal_item().span(), attribute.style, AttrPath { segments: attribute diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index a10ad27fcc68b..eda272fb7f2b7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -56,8 +56,7 @@ impl SingleAttributeParser for InlineParser { } } ArgParser::NameValue(_) => { - let suggestions = >::TEMPLATE - .suggestions(cx.attr_style, "inline"); + let suggestions = cx.suggestions(); let span = cx.attr_span; cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 40ecd91e5cfc1..797d04b914dd5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -71,8 +71,7 @@ impl CombineAttributeParser for LinkParser { // Specifically `#[link = "dl"]` is accepted with a FCW // For more information, see https://github.com/rust-lang/rust/pull/143193 ArgParser::NameValue(nv) if nv.value_as_str().is_some_and(|v| v == sym::dl) => { - let suggestions = >::TEMPLATE - .suggestions(cx.attr_style, "link"); + let suggestions = cx.suggestions(); let span = cx.attr_span; cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); return None; diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 849141c34f7d9..787003519e78b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -1,4 +1,3 @@ -use rustc_ast::AttrStyle; use rustc_errors::DiagArgValue; use rustc_hir::attrs::MacroUseArgs; @@ -102,7 +101,7 @@ impl AttributeParser for MacroUseParser { } } ArgParser::NameValue(_) => { - let suggestions = MACRO_USE_TEMPLATE.suggestions(cx.attr_style, sym::macro_use); + let suggestions = cx.suggestions(); cx.emit_err(IllFormedAttributeInputLint { num_suggestions: suggestions.len(), suggestions: DiagArgValue::StrListSepByAnd( @@ -149,19 +148,14 @@ impl SingleAttributeParser for MacroExportParser { ]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { - let suggestions = || { - >::TEMPLATE - .suggestions(AttrStyle::Inner, "macro_export") - }; let local_inner_macros = match args { ArgParser::NoArgs => false, ArgParser::List(list) => { let Some(l) = list.single() else { let span = cx.attr_span; + let suggestions = cx.suggestions(); cx.emit_lint( - AttributeLintKind::InvalidMacroExportArguments { - suggestions: suggestions(), - }, + AttributeLintKind::InvalidMacroExportArguments { suggestions }, span, ); return None; @@ -170,10 +164,9 @@ impl SingleAttributeParser for MacroExportParser { Some(sym::local_inner_macros) => true, _ => { let span = cx.attr_span; + let suggestions = cx.suggestions(); cx.emit_lint( - AttributeLintKind::InvalidMacroExportArguments { - suggestions: suggestions(), - }, + AttributeLintKind::InvalidMacroExportArguments { suggestions }, span, ); return None; @@ -182,7 +175,7 @@ impl SingleAttributeParser for MacroExportParser { } ArgParser::NameValue(_) => { let span = cx.attr_span; - let suggestions = suggestions(); + let suggestions = cx.suggestions(); cx.emit_err(IllFormedAttributeInputLint { num_suggestions: suggestions.len(), suggestions: DiagArgValue::StrListSepByAnd( diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index e6a5141d78307..51b43e96adf99 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs @@ -45,8 +45,7 @@ impl SingleAttributeParser for MustUseParser { Some(value_str) } ArgParser::List(_) => { - let suggestions = >::TEMPLATE - .suggestions(cx.attr_style, "must_use"); + let suggestions = cx.suggestions(); cx.emit_err(IllFormedAttributeInputLint { num_suggestions: suggestions.len(), suggestions: DiagArgValue::StrListSepByAnd( diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index 510ff1ded4904..23ecc0bf7d29f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -20,8 +20,7 @@ impl SingleAttributeParser for IgnoreParser { ArgParser::NoArgs => None, ArgParser::NameValue(name_value) => { let Some(str_value) = name_value.value_as_str() else { - let suggestions = >::TEMPLATE - .suggestions(cx.attr_style, "ignore"); + let suggestions = cx.suggestions(); let span = cx.attr_span; cx.emit_lint( AttributeLintKind::IllFormedAttributeInput { suggestions }, @@ -32,8 +31,7 @@ impl SingleAttributeParser for IgnoreParser { Some(str_value) } ArgParser::List(_) => { - let suggestions = >::TEMPLATE - .suggestions(cx.attr_style, "ignore"); + let suggestions = cx.suggestions(); let span = cx.attr_span; cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); return None; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 6749bdfb1a672..6694dac8bb25a 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -337,8 +337,16 @@ pub struct Late; /// Gives [`AttributeParser`]s enough information to create errors, for example. pub struct AcceptContext<'f, 'sess, S: Stage> { pub(crate) shared: SharedContext<'f, 'sess, S>, - /// The span of the attribute currently being parsed + + /// The outer span of the attribute currently being parsed + /// #[attribute(...)] + /// ^^^^^^^^^^^^^^^^^ outer span + /// For attributes in `cfg_attr`, the outer span and inner spans are equal. pub(crate) attr_span: Span, + /// The inner span of the attribute currently being parsed + /// #[attribute(...)] + /// ^^^^^^^^^^^^^^ inner span + pub(crate) inner_span: Span, /// Whether it is an inner or outer attribute pub(crate) attr_style: AttrStyle, @@ -427,7 +435,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span)) }), }, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -438,7 +446,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { template: self.template.clone(), attribute: self.attr_path.clone(), reason: AttributeParseErrorReason::ExpectedIntegerLiteral, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -449,7 +457,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { template: self.template.clone(), attribute: self.attr_path.clone(), reason: AttributeParseErrorReason::ExpectedList, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -460,7 +468,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { template: self.template.clone(), attribute: self.attr_path.clone(), reason: AttributeParseErrorReason::ExpectedNoArgs, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -472,7 +480,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { template: self.template.clone(), attribute: self.attr_path.clone(), reason: AttributeParseErrorReason::ExpectedIdentifier, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -485,7 +493,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { template: self.template.clone(), attribute: self.attr_path.clone(), reason: AttributeParseErrorReason::ExpectedNameValue(name), - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -497,7 +505,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { template: self.template.clone(), attribute: self.attr_path.clone(), reason: AttributeParseErrorReason::DuplicateKey(key), - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -510,7 +518,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { template: self.template.clone(), attribute: self.attr_path.clone(), reason: AttributeParseErrorReason::UnexpectedLiteral, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -521,7 +529,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { template: self.template.clone(), attribute: self.attr_path.clone(), reason: AttributeParseErrorReason::ExpectedSingleArgument, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -532,7 +540,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { template: self.template.clone(), attribute: self.attr_path.clone(), reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -552,7 +560,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { strings: false, list: false, }, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -573,7 +581,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { strings: false, list: true, }, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -593,7 +601,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { strings: true, list: false, }, - attr_style: self.attr_style, + suggestions: self.suggestions(), }) } @@ -605,6 +613,13 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { span, ); } + + pub(crate) fn suggestions(&self) -> Vec { + // If the outer and inner spans are equal, we are parsing an attribute from `cfg_attr`, + // So don't display an attribute style in the suggestions + let style = (self.attr_span != self.inner_span).then_some(self.attr_style); + self.template.suggestions(style, &self.attr_path) + } } impl<'f, 'sess, S: Stage> Deref for AcceptContext<'f, 'sess, S> { diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index b8ef11c26d80e..953b0ebfaf04f 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -142,6 +142,7 @@ impl<'sess> AttributeParser<'sess, Early> { Self::parse_single_args( sess, attr.span, + normal_attr.item.span(), attr.style, path.get_attribute_path(), target_span, @@ -159,6 +160,7 @@ impl<'sess> AttributeParser<'sess, Early> { pub fn parse_single_args( sess: &'sess Session, attr_span: Span, + inner_span: Span, attr_style: AttrStyle, attr_path: AttrPath, target_span: Span, @@ -186,6 +188,7 @@ impl<'sess> AttributeParser<'sess, Early> { }, }, attr_span, + inner_span, attr_style, template, attr_path, @@ -305,6 +308,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { emit_lint: &mut emit_lint, }, attr_span: lower_span(attr.span), + inner_span: lower_span(attr.get_normal_item().span()), attr_style: attr.style, template: &accept.template, attr_path: path.get_attribute_path(), diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 7b82f3baec093..82bd29218313e 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -1,6 +1,6 @@ use std::num::IntErrorKind; -use rustc_ast::{self as ast, AttrStyle, Path}; +use rustc_ast::{self as ast, Path}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, @@ -613,10 +613,10 @@ pub(crate) enum AttributeParseErrorReason<'a> { pub(crate) struct AttributeParseError<'a> { pub(crate) span: Span, pub(crate) attr_span: Span, - pub(crate) attr_style: AttrStyle, pub(crate) template: AttributeTemplate, pub(crate) attribute: AttrPath, pub(crate) reason: AttributeParseErrorReason<'a>, + pub(crate) suggestions: Vec, } impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { @@ -752,16 +752,15 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> { if let Some(link) = self.template.docs { diag.note(format!("for more information, visit <{link}>")); } - let suggestions = self.template.suggestions(self.attr_style, &name); diag.span_suggestions( self.attr_span, - if suggestions.len() == 1 { + if self.suggestions.len() == 1 { "must be of the form" } else { "try changing it to one of the following valid forms of the attribute" }, - suggestions, + self.suggestions, Applicability::HasPlaceholders, ); diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 220388ffe4353..a2acac8b3045d 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -133,24 +133,29 @@ pub struct AttributeTemplate { } impl AttributeTemplate { - pub fn suggestions(&self, style: AttrStyle, name: impl std::fmt::Display) -> Vec { + pub fn suggestions( + &self, + style: Option, + name: impl std::fmt::Display, + ) -> Vec { let mut suggestions = vec![]; - let inner = match style { - AttrStyle::Outer => "", - AttrStyle::Inner => "!", + let (start, end) = match style { + Some(AttrStyle::Outer) => ("#[", "]"), + Some(AttrStyle::Inner) => ("#![", "]"), + None => ("", ""), }; if self.word { - suggestions.push(format!("#{inner}[{name}]")); + suggestions.push(format!("{start}{name}{end}")); } if let Some(descr) = self.list { for descr in descr { - suggestions.push(format!("#{inner}[{name}({descr})]")); + suggestions.push(format!("{start}{name}({descr}){end}")); } } - suggestions.extend(self.one_of.iter().map(|&word| format!("#{inner}[{name}({word})]"))); + suggestions.extend(self.one_of.iter().map(|&word| format!("{start}{name}({word}){end}"))); if let Some(descr) = self.name_value_str { for descr in descr { - suggestions.push(format!("#{inner}[{name} = \"{descr}\"]")); + suggestions.push(format!("{start}{name} = \"{descr}\"{end}")); } } suggestions.sort(); diff --git a/tests/ui/attributes/invalid_macro_export_argument.allow.stderr b/tests/ui/attributes/invalid_macro_export_argument.allow.stderr index 162b315b072a4..2db60a6897282 100644 --- a/tests/ui/attributes/invalid_macro_export_argument.allow.stderr +++ b/tests/ui/attributes/invalid_macro_export_argument.allow.stderr @@ -1,5 +1,5 @@ Future incompatibility report: Future breakage diagnostic: -warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +warning: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:7:1 | LL | #[macro_export(hello, world)] @@ -9,7 +9,7 @@ LL | #[macro_export(hello, world)] = note: for more information, see issue #57571 Future breakage diagnostic: -warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +warning: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:14:1 | LL | #[macro_export(not_local_inner_macros)] @@ -19,7 +19,7 @@ LL | #[macro_export(not_local_inner_macros)] = note: for more information, see issue #57571 Future breakage diagnostic: -warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +warning: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:31:1 | LL | #[macro_export()] @@ -29,7 +29,7 @@ LL | #[macro_export()] = note: for more information, see issue #57571 Future breakage diagnostic: -warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +warning: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:38:1 | LL | #[macro_export("blah")] diff --git a/tests/ui/attributes/invalid_macro_export_argument.deny.stderr b/tests/ui/attributes/invalid_macro_export_argument.deny.stderr index ad225ae187b11..fd50b824d0a26 100644 --- a/tests/ui/attributes/invalid_macro_export_argument.deny.stderr +++ b/tests/ui/attributes/invalid_macro_export_argument.deny.stderr @@ -1,4 +1,4 @@ -error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:7:1 | LL | #[macro_export(hello, world)] @@ -12,7 +12,7 @@ note: the lint level is defined here LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:14:1 | LL | #[macro_export(not_local_inner_macros)] @@ -21,7 +21,7 @@ LL | #[macro_export(not_local_inner_macros)] = 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: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:31:1 | LL | #[macro_export()] @@ -30,7 +30,7 @@ LL | #[macro_export()] = 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: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:38:1 | LL | #[macro_export("blah")] @@ -42,7 +42,7 @@ LL | #[macro_export("blah")] error: aborting due to 4 previous errors Future incompatibility report: Future breakage diagnostic: -error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:7:1 | LL | #[macro_export(hello, world)] @@ -57,7 +57,7 @@ LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: -error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:14:1 | LL | #[macro_export(not_local_inner_macros)] @@ -72,7 +72,7 @@ LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: -error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:31:1 | LL | #[macro_export()] @@ -87,7 +87,7 @@ LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: -error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/invalid_macro_export_argument.rs:38:1 | LL | #[macro_export("blah")] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index c29bd0245bf04..5627cb452a815 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -701,7 +701,7 @@ error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and ` LL | #[macro_use = 1] | ^^^^^^^^^^^^^^^^ -error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` --> $DIR/malformed-attrs.rs:221:1 | LL | #[macro_export = 18] diff --git a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr index 2b7a7da3e33da..fd03fa62864af 100644 --- a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr +++ b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr @@ -113,7 +113,7 @@ error[E0539]: malformed `link_section` attribute input --> $DIR/cfg_attr-attr-syntax-validation.rs:44:18 | LL | #[cfg_attr(true, link_section)] - | ^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` + | ^^^^^^^^^^^^ help: must be of the form: `link_section = "name"` | = note: for more information, visit @@ -129,14 +129,12 @@ LL | #[cfg_attr(true, inline())] help: try changing it to one of the following valid forms of the attribute | LL - #[cfg_attr(true, inline())] -LL + #[cfg_attr(true, #[inline(always)])] - | -LL - #[cfg_attr(true, inline())] -LL + #[cfg_attr(true, #[inline(never)])] - | -LL - #[cfg_attr(true, inline())] -LL + #[cfg_attr(true, #[inline])] +LL + #[cfg_attr(true, inline)] | +LL | #[cfg_attr(true, inline(always))] + | ++++++ +LL | #[cfg_attr(true, inline(never))] + | +++++ warning: `#[link_section]` attribute cannot be used on structs --> $DIR/cfg_attr-attr-syntax-validation.rs:44:18