Skip to content

Commit fd8016c

Browse files
committed
Split up the unknown_or_malformed_diagnostic_attributes lint
1 parent 0eb0b8c commit fd8016c

20 files changed

+132
-76
lines changed

compiler/rustc_lint/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,14 @@ fn register_builtins(store: &mut LintStore) {
337337

338338
add_lint_group!("deprecated_safe", DEPRECATED_SAFE_2024);
339339

340+
add_lint_group!(
341+
"unknown_or_malformed_diagnostic_attributes",
342+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
343+
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
344+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
345+
UNKNOWN_DIAGNOSTIC_ATTRIBUTES
346+
);
347+
340348
// Register renamed and removed lints.
341349
store.register_renamed("single_use_lifetime", "single_use_lifetimes");
342350
store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths");

compiler/rustc_lint_defs/src/builtin.rs

+85-9
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ declare_lint_pass! {
6363
LOSSY_PROVENANCE_CASTS,
6464
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
6565
MACRO_USE_EXTERN_CRATE,
66+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
67+
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
6668
META_VARIABLE_MISUSE,
69+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
6770
MISSING_ABI,
6871
MISSING_FRAGMENT_SPECIFIER,
6972
MISSING_UNSAFE_ON_EXTERN,
@@ -113,8 +116,8 @@ declare_lint_pass! {
113116
UNFULFILLED_LINT_EXPECTATIONS,
114117
UNINHABITED_STATIC,
115118
UNKNOWN_CRATE_TYPES,
119+
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
116120
UNKNOWN_LINTS,
117-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
118121
UNNAMEABLE_TEST_ITEMS,
119122
UNNAMEABLE_TYPES,
120123
UNNECESSARY_TRANSMUTES,
@@ -4297,31 +4300,104 @@ declare_lint! {
42974300
}
42984301

42994302
declare_lint! {
4300-
/// The `unknown_or_malformed_diagnostic_attributes` lint detects unrecognized or otherwise malformed
4301-
/// diagnostic attributes.
4303+
/// The `malformed_diagnostic_attributes` lint detects malformed diagnostic attributes.
43024304
///
43034305
/// ### Example
43044306
///
43054307
/// ```rust
4306-
/// #![feature(diagnostic_namespace)]
4307-
/// #[diagnostic::does_not_exist]
4308-
/// struct Foo;
4308+
/// #[diagnostic::do_not_recommend(message = "message")]
4309+
/// trait Trait {}
4310+
/// ```
4311+
///
4312+
/// {{produces}}
4313+
///
4314+
/// ### Explanation
4315+
///
4316+
/// It is usually a mistake to use options or syntax that is not supported. Check the spelling,
4317+
/// and check the diagnostic attribute listing for the correct name and syntax. Also
4318+
/// consider if you are using an old version of the compiler; perhaps the option or syntax
4319+
/// is only available in a newer version. See the [reference] for a list of diagnostic attributes
4320+
/// and their syntax.
4321+
///
4322+
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4323+
pub MALFORMED_DIAGNOSTIC_ATTRIBUTES,
4324+
Warn,
4325+
"detects malformed diagnostic attributes",
4326+
}
4327+
4328+
declare_lint! {
4329+
/// The `misplaced_diagnostic_attributes` lint detects wrongly placed diagnostic attributes.
4330+
///
4331+
/// ### Example
4332+
///
4333+
/// ```rust
4334+
/// #[diagnostic::do_not_recommend]
4335+
/// struct NotUserFacing;
43094336
/// ```
43104337
///
43114338
/// {{produces}}
43124339
///
4340+
/// ### Explanation
4341+
///
4342+
/// It is usually a mistake to specify a diagnostic attribute on an item it is not meant for. For example,
4343+
/// `#[diagnostic::do_not_recommend]` can only be placed on trait implementations, and does nothing if placed
4344+
/// elsewhere. See the [reference] for a list of diagnostic attributes and their correct positions.
4345+
///
4346+
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4347+
pub MISPLACED_DIAGNOSTIC_ATTRIBUTES,
4348+
Warn,
4349+
"detects diagnostic attributes that are placed on the wrong item",
4350+
}
4351+
4352+
declare_lint! {
4353+
/// The `unknown_diagnostic_attributes` lint detects unknown diagnostic attributes.
4354+
///
4355+
/// ### Example
4356+
///
4357+
/// ```rust
4358+
/// #[diagnostic::does_not_exist]
4359+
/// struct Thing;
4360+
/// ```
4361+
///
4362+
/// {{produces}}
43134363
///
43144364
/// ### Explanation
43154365
///
43164366
/// It is usually a mistake to specify a diagnostic attribute that does not exist. Check
43174367
/// the spelling, and check the diagnostic attribute listing for the correct name. Also
43184368
/// consider if you are using an old version of the compiler, and the attribute
4319-
/// is only available in a newer version.
4320-
pub UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
4369+
/// is only available in a newer version. See the [reference] for the list of diagnostic attributes.
4370+
///
4371+
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4372+
pub UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
43214373
Warn,
4322-
"unrecognized or malformed diagnostic attribute",
4374+
"detects unknown diagnostic attributes",
43234375
}
43244376

4377+
declare_lint! {
4378+
/// The `malformed_diagnostic_format_literals` lint detects malformed
4379+
/// diagnostic format literals.
4380+
///
4381+
/// ### Example
4382+
///
4383+
/// ```rust
4384+
/// #[diagnostic::on_unimplemented(message = "{Self}} does not implement `Trait`")]
4385+
/// trait Trait {}
4386+
/// ```
4387+
///
4388+
/// {{produces}}
4389+
///
4390+
/// ### Explanation
4391+
///
4392+
/// The `#[diagnostic::on_unimplemented]` attribute accepts string literal values that
4393+
/// are similar to `format!`'s string literal. See the [reference] for details on
4394+
/// what is permitted in this string literal.
4395+
///
4396+
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4397+
pub MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
4398+
Warn,
4399+
"detects diagnostic attribute with malformed diagnostic format literals",
4400+
}
43254401
declare_lint! {
43264402
/// The `ambiguous_glob_imports` lint detects glob imports that should report ambiguity
43274403
/// errors, but previously didn't do that due to rustc bugs.

compiler/rustc_passes/src/check_attr.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rustc_middle::{bug, span_bug};
3232
use rustc_session::config::CrateType;
3333
use rustc_session::lint::builtin::{
3434
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
35-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
35+
MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
3636
};
3737
use rustc_session::parse::feature_err;
3838
use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, kw, sym};
@@ -375,7 +375,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
375375
);
376376
}
377377

378-
/// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl.
378+
/// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl and that it is a word.
379379
fn check_do_not_recommend(
380380
&self,
381381
attr_span: Span,
@@ -392,15 +392,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
392392
)
393393
{
394394
self.tcx.emit_node_span_lint(
395-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
395+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
396396
hir_id,
397397
attr_span,
398398
errors::IncorrectDoNotRecommendLocation,
399399
);
400400
}
401401
if !attr.is_word() {
402402
self.tcx.emit_node_span_lint(
403-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
403+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
404404
hir_id,
405405
attr_span,
406406
errors::DoNotRecommendDoesNotExpectArgs,
@@ -412,7 +412,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
412412
fn check_diagnostic_on_unimplemented(&self, attr_span: Span, hir_id: HirId, target: Target) {
413413
if !matches!(target, Target::Trait) {
414414
self.tcx.emit_node_span_lint(
415-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
415+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
416416
hir_id,
417417
attr_span,
418418
DiagnosticOnUnimplementedOnlyForTraits,

compiler/rustc_resolve/src/macros.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_middle::middle::stability;
2424
use rustc_middle::ty::{RegisteredTools, TyCtxt, Visibility};
2525
use rustc_session::lint::BuiltinLintDiag;
2626
use rustc_session::lint::builtin::{
27-
LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
27+
LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
2828
UNUSED_MACRO_RULES, UNUSED_MACROS,
2929
};
3030
use rustc_session::parse::feature_err;
@@ -663,7 +663,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
663663
);
664664

665665
self.tcx.sess.psess.buffer_lint(
666-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
666+
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
667667
attribute.span(),
668668
node_id,
669669
BuiltinLintDiag::UnknownDiagnosticAttribute { span: attribute.span(), typo_name },

compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use rustc_macros::LintDiagnostic;
1111
use rustc_middle::bug;
1212
use rustc_middle::ty::print::PrintTraitRefExt;
1313
use rustc_middle::ty::{self, GenericArgsRef, GenericParamDef, GenericParamDefKind, TyCtxt};
14-
use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
14+
use rustc_session::lint::builtin::{
15+
MALFORMED_DIAGNOSTIC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
16+
};
1517
use rustc_span::{Span, Symbol, sym};
1618
use tracing::{debug, info};
1719

@@ -382,7 +384,7 @@ impl IgnoredDiagnosticOption {
382384
if let (Some(new_item), Some(old_item)) = (new, old) {
383385
if let Some(item_def_id) = item_def_id.as_local() {
384386
tcx.emit_node_span_lint(
385-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
387+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
386388
tcx.local_def_id_to_hir_id(item_def_id),
387389
new_item,
388390
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
@@ -521,7 +523,7 @@ impl<'tcx> OnUnimplementedDirective {
521523
if is_diagnostic_namespace_variant {
522524
if let Some(def_id) = item_def_id.as_local() {
523525
tcx.emit_node_span_lint(
524-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
526+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
525527
tcx.local_def_id_to_hir_id(def_id),
526528
vec![item.span()],
527529
MalformedOnUnimplementedAttrLint::new(item.span()),
@@ -677,7 +679,7 @@ impl<'tcx> OnUnimplementedDirective {
677679

678680
if let Some(item_def_id) = item_def_id.as_local() {
679681
tcx.emit_node_span_lint(
680-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
682+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
681683
tcx.local_def_id_to_hir_id(item_def_id),
682684
report_span,
683685
MalformedOnUnimplementedAttrLint::new(report_span),
@@ -690,7 +692,7 @@ impl<'tcx> OnUnimplementedDirective {
690692
Attribute::Unparsed(p) if !matches!(p.args, AttrArgs::Empty) => {
691693
if let Some(item_def_id) = item_def_id.as_local() {
692694
tcx.emit_node_span_lint(
693-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
695+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
694696
tcx.local_def_id_to_hir_id(item_def_id),
695697
attr.span(),
696698
MalformedOnUnimplementedAttrLint::new(attr.span()),
@@ -700,7 +702,7 @@ impl<'tcx> OnUnimplementedDirective {
700702
_ => {
701703
if let Some(item_def_id) = item_def_id.as_local() {
702704
tcx.emit_node_span_lint(
703-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
705+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
704706
tcx.local_def_id_to_hir_id(item_def_id),
705707
attr.span(),
706708
MissingOptionsForOnUnimplementedAttr,
@@ -847,7 +849,7 @@ impl<'tcx> OnUnimplementedFormatString {
847849
if self.is_diagnostic_namespace_variant {
848850
if let Some(trait_def_id) = trait_def_id.as_local() {
849851
tcx.emit_node_span_lint(
850-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
852+
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
851853
tcx.local_def_id_to_hir_id(trait_def_id),
852854
self.span,
853855
WrappedParserError { description: e.description, label: e.label },

compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs

+4-39
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_parse_format::{
77
Alignment, Argument, Count, FormatSpec, InnerSpan, ParseError, ParseMode, Parser,
88
Piece as RpfPiece, Position,
99
};
10-
use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
10+
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_FORMAT_LITERALS;
1111
use rustc_span::def_id::DefId;
1212
use rustc_span::{BytePos, Pos, Span, Symbol, kw, sym};
1313

@@ -69,7 +69,7 @@ impl FormatWarning {
6969
let this = tcx.item_ident(item_def_id);
7070
if let Some(item_def_id) = item_def_id.as_local() {
7171
tcx.emit_node_span_lint(
72-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
72+
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
7373
tcx.local_def_id_to_hir_id(item_def_id),
7474
span,
7575
UnknownFormatParameterForOnUnimplementedAttr {
@@ -82,7 +82,7 @@ impl FormatWarning {
8282
FormatWarning::PositionalArgument { span, .. } => {
8383
if let Some(item_def_id) = item_def_id.as_local() {
8484
tcx.emit_node_span_lint(
85-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
85+
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
8686
tcx.local_def_id_to_hir_id(item_def_id),
8787
span,
8888
DisallowedPositionalArgument,
@@ -92,7 +92,7 @@ impl FormatWarning {
9292
FormatWarning::InvalidSpecifier { span, .. } => {
9393
if let Some(item_def_id) = item_def_id.as_local() {
9494
tcx.emit_node_span_lint(
95-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
95+
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
9696
tcx.local_def_id_to_hir_id(item_def_id),
9797
span,
9898
InvalidFormatSpecifier,
@@ -376,39 +376,4 @@ pub mod errors {
376376
#[diag(trait_selection_missing_options_for_on_unimplemented_attr)]
377377
#[help]
378378
pub struct MissingOptionsForOnUnimplementedAttr;
379-
380-
#[derive(LintDiagnostic)]
381-
#[diag(trait_selection_ignored_diagnostic_option)]
382-
pub struct IgnoredDiagnosticOption {
383-
pub option_name: &'static str,
384-
#[label]
385-
pub span: Span,
386-
#[label(trait_selection_other_label)]
387-
pub prev_span: Span,
388-
}
389-
390-
impl IgnoredDiagnosticOption {
391-
pub fn maybe_emit_warning<'tcx>(
392-
tcx: TyCtxt<'tcx>,
393-
item_def_id: DefId,
394-
new: Option<Span>,
395-
old: Option<Span>,
396-
option_name: &'static str,
397-
) {
398-
if let (Some(new_item), Some(old_item)) = (new, old) {
399-
if let Some(item_def_id) = item_def_id.as_local() {
400-
tcx.emit_node_span_lint(
401-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
402-
tcx.local_def_id_to_hir_id(item_def_id),
403-
new_item,
404-
IgnoredDiagnosticOption {
405-
span: new_item,
406-
prev_span: old_item,
407-
option_name,
408-
},
409-
);
410-
}
411-
}
412-
}
413-
}
414379
}

tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ note: the lint level is defined here
99
|
1010
LL | #![deny(unknown_or_malformed_diagnostic_attributes)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
= note: `#[deny(unknown_diagnostic_attributes)]` implied by `#[deny(unknown_or_malformed_diagnostic_attributes)]`
1213

1314
error: aborting due to 1 previous error
1415

tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
44
LL | #[diagnostic::do_not_recommend(not_accepted)]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
7+
= note: `#[warn(malformed_diagnostic_attributes)]` on by default
88

99
warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
1010
--> $DIR/does_not_acccept_args.rs:15:1

tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
44
LL | #[diagnostic::do_not_recommend(not_accepted)]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
7+
= note: `#[warn(malformed_diagnostic_attributes)]` on by default
88

99
warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
1010
--> $DIR/does_not_acccept_args.rs:15:1

tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement
44
LL | #[diagnostic::do_not_recommend]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
7+
= note: `#[warn(misplaced_diagnostic_attributes)]` on by default
88

99
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
1010
--> $DIR/incorrect-locations.rs:11:1

tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement
44
LL | #[diagnostic::do_not_recommend]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
7+
= note: `#[warn(misplaced_diagnostic_attributes)]` on by default
88

99
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
1010
--> $DIR/incorrect-locations.rs:11:1

0 commit comments

Comments
 (0)