diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 8102208ec519d..d244e6c59e5f9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -306,7 +306,8 @@ pub fn parse_cfg_attr( features: Option<&Features>, lint_node_id: ast::NodeId, ) -> Option<(CfgEntry, Vec<(WithTokens, Span)>)> { - match &cfg_attr.get_normal_item().args { + let item = cfg_attr.get_normal_item(); + match &item.args { ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, tokens }) if !tokens.is_empty() => { check_cfg_attr_bad_delim(&sess.psess, *dspan, *delim); match parse_in(&sess.psess, tokens.clone(), "`cfg_attr` input", |p| { @@ -316,11 +317,11 @@ pub fn parse_cfg_attr( Err(e) => { let suggestions = CFG_ATTR_TEMPLATE.suggestions( ParsedDescription::Attribute, - cfg_attr.get_normal_item().unsafety, + item.unsafety, sym::cfg_attr, ); e.with_span_suggestions( - cfg_attr.get_normal_item().span, + item.span, "must be of the form", suggestions, Applicability::HasPlaceholders, @@ -334,25 +335,24 @@ pub fn parse_cfg_attr( } } _ => { - let (span, reason) = if let ast::AttrArgs::Delimited(ast::DelimArgs { dspan, .. }) = - cfg_attr.get_normal_item().args - { - (dspan.entire(), AttributeParseErrorReason::ExpectedAtLeastOneArgument) - } else { - (cfg_attr.get_normal_item().span, AttributeParseErrorReason::ExpectedList) - }; + let (span, reason) = + if let ast::AttrArgs::Delimited(ast::DelimArgs { dspan, .. }) = item.args { + (dspan.entire(), AttributeParseErrorReason::ExpectedAtLeastOneArgument) + } else { + (item.span, AttributeParseErrorReason::ExpectedList) + }; sess.dcx().emit_err(AttributeParseError { span, - inner_span: cfg_attr.get_normal_item().span, + inner_span: item.span, template: CFG_ATTR_TEMPLATE, - path: AttrPath::from_ast(&cfg_attr.get_normal_item().path, identity), + path: AttrPath::from_ast(&item.path, identity), description: ParsedDescription::Attribute, reason, suggestions: diagnostics::AttributeParseErrorSuggestions::CreatedByTemplate( CFG_ATTR_TEMPLATE.suggestions( ParsedDescription::Attribute, - cfg_attr.get_normal_item().unsafety, + item.unsafety, sym::cfg_attr, ), ), @@ -389,13 +389,14 @@ fn parse_cfg_attr_internal<'a>( )?; let pred_span = pred_start.with_hi(parser.token.span.hi()); + let item = attribute.get_normal_item(); let cfg_predicate = AttributeParser::parse_single_args( sess, attribute.span, - attribute.get_normal_item().span, + item.span, attribute.style, AttrPath { segments: attribute.path().into_boxed_slice(), span: attribute.span }, - Some(attribute.get_normal_item().unsafety), + Some(item.unsafety), AttributeSafety::Normal, ParsedDescription::Attribute, pred_span, diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index fb4a32d864fbe..a43cd918c8f35 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -1235,7 +1235,7 @@ pub(crate) struct UnknownVersionLiteral { #[diag("multiple `{$name}` attributes")] pub(crate) struct UnusedMultiple { #[primary_span] - #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] + #[suggestion("remove this attribute", code = "", applicability = "unspecified")] pub this: Span, #[note("attribute also specified here")] pub other: Span, @@ -2061,7 +2061,7 @@ pub(crate) struct AdditionalCommaSuggestion { #[derive(Diagnostic)] #[diag("unused attribute")] pub(crate) struct UnusedDuplicate { - #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] + #[suggestion("remove this attribute", code = "", applicability = "unspecified")] pub this: Span, #[note("attribute also specified here")] pub other: Span, diff --git a/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.rs b/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.rs new file mode 100644 index 0000000000000..30434569dbe73 --- /dev/null +++ b/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.rs @@ -0,0 +1,34 @@ +// Test for handling of duplicated attributes within `cfg_attr`, in particular the suggestions of +// what to remove. + +#[inline] +#[inline] +//~^ WARN unused attribute +//~| WARN this was previously accepted +fn f1() {} + +#[deprecated] +#[deprecated] +//~^ ERROR multiple `deprecated` attributes +fn f2() {} + +#[inline] +#[cfg_attr(true, inline)] +//~^ WARN unused attribute +//~| WARN this was previously accepted +fn f3() {} + +#[deprecated] +#[cfg_attr(true, deprecated)] +//~^ ERROR multiple `deprecated` attributes +fn f4() {} + +#[inline] +#[deprecated] +#[cfg_attr(true, inline, deprecated)] +//~^ WARN unused attribute +//~| WARN this was previously accepted +//~| ERROR multiple `deprecated` attributes +fn f5() {} + +fn main() {} diff --git a/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.stderr b/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.stderr new file mode 100644 index 0000000000000..c30bc26b22ce7 --- /dev/null +++ b/tests/ui/conditional-compilation/cfg-attr-duplicate-attrs.stderr @@ -0,0 +1,78 @@ +error: multiple `deprecated` attributes + --> $DIR/cfg-attr-duplicate-attrs.rs:11:1 + | +LL | #[deprecated] + | ^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:10:1 + | +LL | #[deprecated] + | ^^^^^^^^^^^^^ + +error: multiple `deprecated` attributes + --> $DIR/cfg-attr-duplicate-attrs.rs:22:18 + | +LL | #[cfg_attr(true, deprecated)] + | ^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:21:1 + | +LL | #[deprecated] + | ^^^^^^^^^^^^^ + +error: multiple `deprecated` attributes + --> $DIR/cfg-attr-duplicate-attrs.rs:28:26 + | +LL | #[cfg_attr(true, inline, deprecated)] + | ^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:27:1 + | +LL | #[deprecated] + | ^^^^^^^^^^^^^ + +warning: unused attribute + --> $DIR/cfg-attr-duplicate-attrs.rs:5:1 + | +LL | #[inline] + | ^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:4:1 + | +LL | #[inline] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: requested on the command line with `-W unused-attributes` + +warning: unused attribute + --> $DIR/cfg-attr-duplicate-attrs.rs:16:18 + | +LL | #[cfg_attr(true, inline)] + | ^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:15:1 + | +LL | #[inline] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +warning: unused attribute + --> $DIR/cfg-attr-duplicate-attrs.rs:28:18 + | +LL | #[cfg_attr(true, inline, deprecated)] + | ^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/cfg-attr-duplicate-attrs.rs:26:1 + | +LL | #[inline] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: aborting due to 3 previous errors; 3 warnings emitted + diff --git a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs index 907e1b966766f..508b449358964 100644 --- a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs +++ b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs @@ -46,6 +46,9 @@ struct S12; //~| WARN previously accepted struct S13; +#[cfg_attr(true, cfg_attr(true, 3))] //~ ERROR expected identifier, found `3` +struct S14; + #[cfg_attr(true, inline())] //~ ERROR malformed `inline` attribute input fn f1() {} 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 e901460a4eb88..048affd1c4191 100644 --- a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr +++ b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr @@ -120,6 +120,19 @@ LL - #[cfg_attr(true)] LL + #[cfg_attr(predicate, attr1, attr2, ...)] | +error: expected identifier, found `3` + --> $DIR/cfg_attr-attr-syntax-validation.rs:49:33 + | +LL | #[cfg_attr(true, cfg_attr(true, 3))] + | ^ expected identifier + | + = note: for more information, visit +help: must be of the form + | +LL - #[cfg_attr(true, cfg_attr(true, 3))] +LL + #[cfg_attr(true, cfg_attr(predicate, attr1, attr2, ...))] + | + error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable --> $DIR/cfg_attr-attr-syntax-validation.rs:30:30 | @@ -157,7 +170,7 @@ LL | #[cfg_attr(true, link_section = "name")] | ++++++++ error[E0805]: malformed `inline` attribute input - --> $DIR/cfg_attr-attr-syntax-validation.rs:49:18 + --> $DIR/cfg_attr-attr-syntax-validation.rs:52:18 | LL | #[cfg_attr(true, inline())] | ^^^^^^-- @@ -185,7 +198,7 @@ LL | #[cfg_attr(true, link_section)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: requested on the command line with `-W unused-attributes` -error: aborting due to 13 previous errors; 1 warning emitted +error: aborting due to 14 previous errors; 1 warning emitted Some errors have detailed explanations: E0539, E0565, E0805. For more information about an error, try `rustc --explain E0539`.