diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs index 8b69bbb90374..ea5e81c3db81 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs @@ -50,6 +50,33 @@ fn as_str(&self) -> &'static str { Self::DiagnosticOnUnknown => "diagnostic::on_unknown", } } + + fn expected_options(&self) -> &'static str { + const DEFAULT: &str = + "at least one of the `message`, `note` and `label` options are expected"; + match self { + Self::RustcOnUnimplemented => { + "see " + } + Self::DiagnosticOnUnimplemented => DEFAULT, + Self::DiagnosticOnConst => DEFAULT, + Self::DiagnosticOnMove => DEFAULT, + Self::DiagnosticOnUnknown => DEFAULT, + } + } + + fn allowed_options(&self) -> &'static str { + const DEFAULT: &str = "only `message`, `note` and `label` are allowed as options"; + match self { + Self::RustcOnUnimplemented => { + "see " + } + Self::DiagnosticOnUnimplemented => DEFAULT, + Self::DiagnosticOnConst => DEFAULT, + Self::DiagnosticOnMove => DEFAULT, + Self::DiagnosticOnUnknown => DEFAULT, + } + } } fn merge_directives( @@ -118,6 +145,7 @@ fn parse_list<'p, S: Stage>( MALFORMED_DIAGNOSTIC_ATTRIBUTES, AttributeLintKind::MissingOptionsForDiagnosticAttribute { attribute: mode.as_str(), + options: mode.expected_options(), }, span, ); @@ -125,7 +153,11 @@ fn parse_list<'p, S: Stage>( ArgParser::NameValue(_) => { cx.emit_lint( MALFORMED_DIAGNOSTIC_ATTRIBUTES, - AttributeLintKind::MalFormedDiagnosticAttribute { attribute: mode.as_str(), span }, + AttributeLintKind::MalFormedDiagnosticAttribute { + attribute: mode.as_str(), + options: mode.allowed_options(), + span, + }, span, ); } @@ -153,7 +185,8 @@ fn parse_directive_items<'p, S: Stage>( cx.emit_lint( MALFORMED_DIAGNOSTIC_ATTRIBUTES, AttributeLintKind::MalFormedDiagnosticAttribute { - attribute: mode.as_str(), + attribute: mode.as_str(), + options: mode.allowed_options(), span, }, span, diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 1e91b7685421..361ba4989dda 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -176,8 +176,9 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { &AttributeLintKind::ExpectedNoArgs => lints::ExpectedNoArgs.into_diag(dcx, level), &AttributeLintKind::ExpectedNameValue => lints::ExpectedNameValue.into_diag(dcx, level), - &AttributeLintKind::MalFormedDiagnosticAttribute { attribute, span } => { - lints::MalFormedDiagnosticAttributeLint { attribute, span }.into_diag(dcx, level) + &AttributeLintKind::MalFormedDiagnosticAttribute { attribute, options, span } => { + lints::MalFormedDiagnosticAttributeLint { attribute, options, span } + .into_diag(dcx, level) } AttributeLintKind::MalformedDiagnosticFormat { warning } => match warning { @@ -198,8 +199,9 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { lints::IgnoredDiagnosticOption { option_name, first_span, later_span } .into_diag(dcx, level) } - &AttributeLintKind::MissingOptionsForDiagnosticAttribute { attribute } => { - lints::MissingOptionsForDiagnosticAttribute { attribute }.into_diag(dcx, level) + &AttributeLintKind::MissingOptionsForDiagnosticAttribute { attribute, options } => { + lints::MissingOptionsForDiagnosticAttribute { attribute, options } + .into_diag(dcx, level) } &AttributeLintKind::NonMetaItemDiagnosticAttribute => { lints::NonMetaItemDiagnosticAttribute.into_diag(dcx, level) diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 8859e4880fd6..099e918f70a4 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3585,9 +3585,10 @@ pub(crate) struct IgnoredDiagnosticOption { #[derive(Diagnostic)] #[diag("missing options for `{$attribute}` attribute")] -#[help("at least one of the `message`, `note` and `label` options are expected")] +#[help("{$options}")] pub(crate) struct MissingOptionsForDiagnosticAttribute { pub attribute: &'static str, + pub options: &'static str, } #[derive(Diagnostic)] @@ -3604,9 +3605,10 @@ pub(crate) struct MissingOptionsForDiagnosticAttribute { #[derive(Diagnostic)] #[diag("malformed `{$attribute}` attribute")] -#[help("only `message`, `note` and `label` are allowed as options")] +#[help("{$options}")] pub(crate) struct MalFormedDiagnosticAttributeLint { pub attribute: &'static str, + pub options: &'static str, #[label("invalid option found here")] pub span: Span, } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index cd307739af52..731d3ca42603 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -735,6 +735,7 @@ pub enum AttributeLintKind { ExpectedNameValue, MalFormedDiagnosticAttribute { attribute: &'static str, + options: &'static str, span: Span, }, MalformedDiagnosticFormat { @@ -752,6 +753,7 @@ pub enum AttributeLintKind { }, MissingOptionsForDiagnosticAttribute { attribute: &'static str, + options: &'static str, }, NonMetaItemDiagnosticAttribute, } diff --git a/tests/ui/on-unimplemented/bad-annotation.stderr b/tests/ui/on-unimplemented/bad-annotation.stderr index 25f30247f580..058014fd4e08 100644 --- a/tests/ui/on-unimplemented/bad-annotation.stderr +++ b/tests/ui/on-unimplemented/bad-annotation.stderr @@ -84,7 +84,7 @@ warning: missing options for `rustc_on_unimplemented` attribute LL | #[rustc_on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: at least one of the `message`, `note` and `label` options are expected + = help: see = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: positional format arguments are not allowed here @@ -101,7 +101,7 @@ warning: malformed `rustc_on_unimplemented` attribute LL | #[rustc_on_unimplemented(lorem = "")] | ^^^^^^^^^^ invalid option found here | - = help: only `message`, `note` and `label` are allowed as options + = help: see warning: malformed `rustc_on_unimplemented` attribute --> $DIR/bad-annotation.rs:34:26 @@ -109,7 +109,7 @@ warning: malformed `rustc_on_unimplemented` attribute LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))] | ^^^^^^^^^^^^^^^^^^^ invalid option found here | - = help: only `message`, `note` and `label` are allowed as options + = help: see warning: `message` is ignored due to previous definition of `message` --> $DIR/bad-annotation.rs:39:41 @@ -125,7 +125,7 @@ warning: malformed `rustc_on_unimplemented` attribute LL | #[rustc_on_unimplemented(on = "x", message = "y")] | ^^^^^^^^ invalid option found here | - = help: only `message`, `note` and `label` are allowed as options + = help: see warning: malformed `rustc_on_unimplemented` attribute --> $DIR/bad-annotation.rs:60:26 @@ -133,7 +133,7 @@ warning: malformed `rustc_on_unimplemented` attribute LL | #[rustc_on_unimplemented(on(Self = "y"), message = "y")] | ^^^^^^^^^^^^^^ invalid option found here | - = help: only `message`, `note` and `label` are allowed as options + = help: see warning: malformed `rustc_on_unimplemented` attribute --> $DIR/bad-annotation.rs:65:46 @@ -141,7 +141,7 @@ warning: malformed `rustc_on_unimplemented` attribute LL | #[rustc_on_unimplemented(on(from_desugaring, on(from_desugaring, message = "x")), message = "y")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here | - = help: only `message`, `note` and `label` are allowed as options + = help: see error: aborting due to 10 previous errors; 11 warnings emitted