Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions compiler/rustc_attr_parsing/src/attributes/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use thin_vec::ThinVec;

use crate::attributes::{AcceptMapping, AttributeParser, AttributeStability};
use crate::context::{AcceptContext, ExpectStringLiteral, FinalizeContext};
use crate::diagnostics::{MalformedLintAttributeInput, MalformedLintAttributeInputHelp};
use crate::parser::{ArgParser, MetaItemOrLitParser};
use crate::target_checking::AllowedTargets;
use crate::target_checking::Policy::{Allow, Warn};
Expand Down Expand Up @@ -36,9 +37,11 @@ impl LintParser {
let p = parsers.last()?.meta_item()?;
let nv = p.args().as_name_value()?;
if !p.path().word_is(sym::reason) {
cx.emit_err(diagnostics::MalformedAttribute {
// FIXME: We should recommend `reason` here
cx.emit_err(MalformedLintAttributeInput {
span: p.span(),
kind: diagnostics::MalformedAttributeKind::BadAttributeArgument(p.span()),
help: MalformedLintAttributeInputHelp::Other { kind: kind.sym() },
kind: kind.sym(),
});
} else {
parsers = &parsers[..(parsers.len() - 1)];
Expand Down Expand Up @@ -90,26 +93,28 @@ impl LintParser {
nv.expect_string_literal(cx);
}
ArgParser::NameValue(_) | ArgParser::List(_) => {
cx.emit_err(diagnostics::MalformedAttribute {
cx.emit_err(MalformedLintAttributeInput {
span: p.span(),
kind: diagnostics::MalformedAttributeKind::BadAttributeArgument(
item.span(),
),
help: MalformedLintAttributeInputHelp::Other {
kind: kind.sym(),
},
kind: kind.sym(),
});
}
}
}
MetaItemOrLitParser::Lit(lit) => {
cx.emit_err(diagnostics::BadAttributeLit {
cx.emit_err(MalformedLintAttributeInput {
span: item.span(),
help: if lit.kind.is_str() {
diagnostics::BadAttributeLitHelp::StrLit {
MalformedLintAttributeInputHelp::StrLit {
sym: lit.symbol,
kind: kind.sym(),
}
} else {
diagnostics::BadAttributeLitHelp::Other { kind: kind.sym() }
MalformedLintAttributeInputHelp::Other { kind: kind.sym() }
},
kind: kind.sym(),
});
}
}
Expand Down
11 changes: 5 additions & 6 deletions compiler/rustc_attr_parsing/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2146,24 +2146,23 @@ pub(crate) struct MalformedAttribute {

#[derive(Subdiagnostic)]
pub(crate) enum MalformedAttributeKind {
#[label("bad attribute argument")]
BadAttributeArgument(#[primary_span] Span),
#[label("reason in lint attribute must come last")]
ReasonMustComeLast(#[primary_span] Span),
}

#[derive(Diagnostic)]
#[diag("expected a lint, found literal")]
pub(crate) struct BadAttributeLit {
#[diag("malformed `{$kind}` attribute input")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly, this new phrasing is very close again to the phrasing used on stable & beta where it's malformed lint attribute input.

Ah, looking at the blame, this was changed by PR #164486 about 2 weeks ago under your review :D

@JonathanBrouwer JonathanBrouwer Nov 3, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I realized after merging that, that tho the PR is a big improvement, I didn't really like the new diagnostic titles :p
The ones this PR changes them to are consistent with other attributes

pub(crate) struct MalformedLintAttributeInput {
#[primary_span]
#[label("not the name of a lint")]
pub span: Span,
pub kind: Symbol,
#[subdiagnostic]
pub help: BadAttributeLitHelp,
pub help: MalformedLintAttributeInputHelp,
}

#[derive(Subdiagnostic)]
pub(crate) enum BadAttributeLitHelp {
pub(crate) enum MalformedLintAttributeInputHelp {
#[help("try using `#[{$kind}({$sym})]`")]
StrLit { sym: Symbol, kind: Symbol },
#[help("for example, write `#[{$kind}(dead_code)]` for `dead_code`")]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0452.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ An invalid lint attribute has been given.
Erroneous code example:

```compile_fail,E0452
#![allow(foo = "")] // error: malformed lint attribute
#![allow(reason = "", foo)] // error: malformed lint attribute
```

Lint attributes only accept a list of identifiers (where each identifier is a
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/attributes/unsafe/proc-unsafe-attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ pub fn e() {}
//~| ERROR: expected identifier, found keyword `unsafe`
//~| ERROR: expected identifier, found keyword `unsafe`
//~| ERROR: expected identifier, found keyword `unsafe`
//~| ERROR: malformed lint attribute input
//~| ERROR: malformed lint attribute input
//~| ERROR: malformed lint attribute input
//~| ERROR: malformed
//~| ERROR: malformed
//~| ERROR: malformed
pub fn f() {}

fn main() {}
19 changes: 11 additions & 8 deletions tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ help: escape `unsafe` to use it as an identifier
LL | #[unsafe(allow(r#unsafe(dead_code)))]
| ++

error[E0452]: malformed lint attribute input
error: malformed `allow` attribute input
--> $DIR/proc-unsafe-attributes.rs:29:16
|
LL | #[unsafe(allow(unsafe(dead_code)))]
| ^^^^^^^^^^^^^^^^^ bad attribute argument
| ^^^^^^^^^^^^^^^^^ not the name of a lint
|
= help: for example, write `#[allow(dead_code)]` for `dead_code`

error: the `proc_macro` attribute is only usable with crates of the `proc-macro` crate type
--> $DIR/proc-unsafe-attributes.rs:1:10
Expand Down Expand Up @@ -85,12 +87,13 @@ help: escape `unsafe` to use it as an identifier
LL | #[unsafe(allow(r#unsafe(dead_code)))]
| ++

error[E0452]: malformed lint attribute input
error: malformed `allow` attribute input
--> $DIR/proc-unsafe-attributes.rs:29:16
|
LL | #[unsafe(allow(unsafe(dead_code)))]
| ^^^^^^^^^^^^^^^^^ bad attribute argument
| ^^^^^^^^^^^^^^^^^ not the name of a lint
|
= help: for example, write `#[allow(dead_code)]` for `dead_code`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: `proc_macro` is not an unsafe attribute
Expand Down Expand Up @@ -176,15 +179,15 @@ help: escape `unsafe` to use it as an identifier
LL | #[unsafe(allow(r#unsafe(dead_code)))]
| ++

error[E0452]: malformed lint attribute input
error: malformed `allow` attribute input
--> $DIR/proc-unsafe-attributes.rs:29:16
|
LL | #[unsafe(allow(unsafe(dead_code)))]
| ^^^^^^^^^^^^^^^^^ bad attribute argument
| ^^^^^^^^^^^^^^^^^ not the name of a lint
|
= help: for example, write `#[allow(dead_code)]` for `dead_code`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 21 previous errors

Some errors have detailed explanations: E0452, E0565.
For more information about an error, try `rustc --explain E0452`.
For more information about this error, try `rustc --explain E0565`.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: expected a lint, found literal
error: malformed `deny` attribute input
--> $DIR/deduplicate-diagnostics.rs:10:8
|
LL | #[deny("literal")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: expected a lint, found literal
error: malformed `deny` attribute input
--> $DIR/deduplicate-diagnostics.rs:10:8
|
LL | #[deny("literal")]
Expand All @@ -20,7 +20,7 @@ LL | #[derive(Unresolved)]
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: expected a lint, found literal
error: malformed `deny` attribute input
--> $DIR/deduplicate-diagnostics.rs:10:8
|
LL | #[deny("literal")]
Expand All @@ -29,7 +29,7 @@ LL | #[deny("literal")]
= help: try using `#[deny(literal)]`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: expected a lint, found literal
error: malformed `deny` attribute input
--> $DIR/deduplicate-diagnostics.rs:10:8
|
LL | #[deny("literal")]
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/diagnostic-flags/deduplicate-diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//[duplicate]~| ERROR cannot find derive macro `Unresolved` in this scope
struct S;

#[deny("literal")] //~ ERROR expected a lint, found literal
//[duplicate]~| ERROR expected a lint, found literal
//[duplicate]~| ERROR expected a lint, found literal
#[deny("literal")] //~ ERROR malformed
//[duplicate]~| ERROR malformed
//[duplicate]~| ERROR malformed
fn main() {}
12 changes: 6 additions & 6 deletions tests/ui/error-codes/E0452.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![allow(foo = "")] //~ ERROR E0452
//~| ERROR E0452
//~| ERROR E0452
//~| ERROR E0452
//~| ERROR E0452
//~| ERROR E0452
#![allow(foo = "")] //~ ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
fn main() {
}
32 changes: 19 additions & 13 deletions tests/ui/error-codes/E0452.stderr
Original file line number Diff line number Diff line change
@@ -1,49 +1,55 @@
error[E0452]: malformed lint attribute input
error: malformed `allow` attribute input
--> $DIR/E0452.rs:1:10
|
LL | #![allow(foo = "")]
| ^^^^^^^^ bad attribute argument
| ^^^^^^^^ not the name of a lint
|
= help: for example, write `#[allow(dead_code)]` for `dead_code`

error[E0452]: malformed lint attribute input
error: malformed `allow` attribute input
--> $DIR/E0452.rs:1:10
|
LL | #![allow(foo = "")]
| ^^^^^^^^ bad attribute argument
| ^^^^^^^^ not the name of a lint
|
= help: for example, write `#[allow(dead_code)]` for `dead_code`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0452]: malformed lint attribute input
error: malformed `allow` attribute input
--> $DIR/E0452.rs:1:10
|
LL | #![allow(foo = "")]
| ^^^^^^^^ bad attribute argument
| ^^^^^^^^ not the name of a lint
|
= help: for example, write `#[allow(dead_code)]` for `dead_code`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0452]: malformed lint attribute input
error: malformed `allow` attribute input
--> $DIR/E0452.rs:1:10
|
LL | #![allow(foo = "")]
| ^^^^^^^^ bad attribute argument
| ^^^^^^^^ not the name of a lint
|
= help: for example, write `#[allow(dead_code)]` for `dead_code`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0452]: malformed lint attribute input
error: malformed `allow` attribute input
--> $DIR/E0452.rs:1:10
|
LL | #![allow(foo = "")]
| ^^^^^^^^ bad attribute argument
| ^^^^^^^^ not the name of a lint
|
= help: for example, write `#[allow(dead_code)]` for `dead_code`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error[E0452]: malformed lint attribute input
error: malformed `allow` attribute input
--> $DIR/E0452.rs:1:10
|
LL | #![allow(foo = "")]
| ^^^^^^^^ bad attribute argument
| ^^^^^^^^ not the name of a lint
|
= help: for example, write `#[allow(dead_code)]` for `dead_code`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 6 previous errors

For more information about this error, try `rustc --explain E0452`.
12 changes: 6 additions & 6 deletions tests/ui/lint/lint-attribute-literals.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Checks that lint attributes with literals have an explanatory error

#[allow("literal")]
//~^ ERROR expected a lint, found literal
//~| ERROR expected a lint, found literal
//~| ERROR expected a lint, found literal
//~^ ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
#[deny(1.0)]
//~^ ERROR expected a lint, found literal
//~| ERROR expected a lint, found literal
//~| ERROR expected a lint, found literal
//~^ ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
fn main() {}
12 changes: 6 additions & 6 deletions tests/ui/lint/lint-attribute-literals.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
error: expected a lint, found literal
error: malformed `allow` attribute input
--> $DIR/lint-attribute-literals.rs:3:9
|
LL | #[allow("literal")]
| ^^^^^^^^^ not the name of a lint
|
= help: try using `#[allow(literal)]`

error: expected a lint, found literal
error: malformed `deny` attribute input
--> $DIR/lint-attribute-literals.rs:7:8
|
LL | #[deny(1.0)]
| ^^^ not the name of a lint
|
= help: for example, write `#[deny(dead_code)]` for `dead_code`

error: expected a lint, found literal
error: malformed `allow` attribute input
--> $DIR/lint-attribute-literals.rs:3:9
|
LL | #[allow("literal")]
Expand All @@ -23,7 +23,7 @@ LL | #[allow("literal")]
= help: try using `#[allow(literal)]`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: expected a lint, found literal
error: malformed `deny` attribute input
--> $DIR/lint-attribute-literals.rs:7:8
|
LL | #[deny(1.0)]
Expand All @@ -32,7 +32,7 @@ LL | #[deny(1.0)]
= help: for example, write `#[deny(dead_code)]` for `dead_code`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: expected a lint, found literal
error: malformed `allow` attribute input
--> $DIR/lint-attribute-literals.rs:3:9
|
LL | #[allow("literal")]
Expand All @@ -41,7 +41,7 @@ LL | #[allow("literal")]
= help: try using `#[allow(literal)]`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: expected a lint, found literal
error: malformed `deny` attribute input
--> $DIR/lint-attribute-literals.rs:7:8
|
LL | #[deny(1.0)]
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/lint/lint-malformed.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![deny = "foo"] //~ ERROR malformed `deny` attribute input
#![allow(bar = "baz")] //~ ERROR malformed lint attribute
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
//~| ERROR malformed lint attribute
#![allow(bar = "baz")] //~ ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
//~| ERROR malformed
fn main() { }
Loading
Loading