Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b1d2f2c

Browse files
committed
Auto merge of #140717 - mejrs:diagnostic_lints, r=oli-obk
Split up the `unknown_or_malformed_diagnostic_attributes` lint This splits up the lint into the following lint group: - `unknown_diagnostic_attributes` - triggers if the attribute is unknown to the current compiler - `misplaced_diagnostic_attributes` - triggers if the attribute exists but it is not placed on the item kind it's meant for - `malformed_diagnostic_attributes` - triggers if the attribute's syntax or options are invalid - `malformed_diagnostic_format_literals` - triggers if the format string literal is invalid, for example if it has unpaired curly braces or invalid parameters - this pr doesn't create it, but future lints for things like deprecations can also go here. This PR does not start emitting lints in places that previously did not. ## Motivation I want to have finer control over what `unknown_or_malformed_diagnostic_attributes` does I have a project with fairly low msrv that is/will have a lower msrv than future diagnostic attributes. So lints will be emitted when I or others compile it on a lower msrv. At this time, there are two options to silence these lints: - `#[allow(unknown_or_malformed_diagnostic_attributes)]` - this risks diagnostic regressions if I (or others) mess up using the attribute, or if the attribute's syntax ever changes. - write a build script to detect the compiler version and emit cfgs, and then conditionally enable the attribute: ```rust #[cfg_attr(rust_version_99, diagnostic::new_attr_in_rust_99(thing = ..))]` struct Foo; ``` or conditionally `allow` the lint: ```rust // lib.rs #![cfg_attr(not(current_rust), allow(unknown_or_malformed_diagnostic_attributes))] ``` I like to avoid using build scripts if I can, so the following works much better for me. That is what this PR will let me do in the future: ```rust #[allow(unknown_diagnostic_attribute, reason = "attribute came out in rust 1.99 but msrv is 1.70")] #[diagnostic::new_attr_in_rust_99(thing = ..)]` struct Foo;
2 parents 288e94c + a7bf5c4 commit b1d2f2c

25 files changed

+157
-59
lines changed

‎compiler/rustc_lint/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,14 @@ fn register_builtins(store: &mut LintStore) {
339339

340340
add_lint_group!("deprecated_safe", DEPRECATED_SAFE_2024);
341341

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

‎compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 89 additions & 12 deletions
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_UNSAFE_ON_EXTERN,
6972
MUST_NOT_SUSPEND,
@@ -112,8 +115,8 @@ declare_lint_pass! {
112115
UNFULFILLED_LINT_EXPECTATIONS,
113116
UNINHABITED_STATIC,
114117
UNKNOWN_CRATE_TYPES,
118+
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
115119
UNKNOWN_LINTS,
116-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
117120
UNNAMEABLE_TEST_ITEMS,
118121
UNNAMEABLE_TYPES,
119122
UNREACHABLE_CODE,
@@ -4284,31 +4287,105 @@ declare_lint! {
42844287
}
42854288

42864289
declare_lint! {
4287-
/// The `unknown_or_malformed_diagnostic_attributes` lint detects unrecognized or otherwise malformed
4288-
/// diagnostic attributes.
4290+
/// The `malformed_diagnostic_attributes` lint detects malformed diagnostic attributes.
42894291
///
42904292
/// ### Example
42914293
///
42924294
/// ```rust
4293-
/// #![feature(diagnostic_namespace)]
4294-
/// #[diagnostic::does_not_exist]
4295-
/// struct Foo;
4295+
/// #[diagnostic::do_not_recommend(message = "message")]
4296+
/// trait Trait {}
42964297
/// ```
42974298
///
42984299
/// {{produces}}
42994300
///
4301+
/// ### Explanation
4302+
///
4303+
/// It is usually a mistake to use options or syntax that is not supported. Check the spelling,
4304+
/// and check the diagnostic attribute listing for the correct name and syntax. Also consider if
4305+
/// you are using an old version of the compiler; perhaps the option or syntax is only available
4306+
/// in a newer version. See the [reference] for a list of diagnostic attributes and the syntax
4307+
/// of each.
4308+
///
4309+
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4310+
pub MALFORMED_DIAGNOSTIC_ATTRIBUTES,
4311+
Warn,
4312+
"detects malformed diagnostic attributes",
4313+
}
4314+
4315+
declare_lint! {
4316+
/// The `misplaced_diagnostic_attributes` lint detects wrongly placed diagnostic attributes.
4317+
///
4318+
/// ### Example
4319+
///
4320+
/// ```rust
4321+
/// #[diagnostic::do_not_recommend]
4322+
/// struct NotUserFacing;
4323+
/// ```
4324+
///
4325+
/// {{produces}}
43004326
///
43014327
/// ### Explanation
43024328
///
4303-
/// It is usually a mistake to specify a diagnostic attribute that does not exist. Check
4304-
/// the spelling, and check the diagnostic attribute listing for the correct name. Also
4305-
/// consider if you are using an old version of the compiler, and the attribute
4306-
/// is only available in a newer version.
4307-
pub UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
4329+
/// It is usually a mistake to specify a diagnostic attribute on an item it is not meant for.
4330+
/// For example, `#[diagnostic::do_not_recommend]` can only be placed on trait implementations,
4331+
/// and does nothing if placed elsewhere. See the [reference] for a list of diagnostic
4332+
/// attributes and their correct positions.
4333+
///
4334+
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4335+
pub MISPLACED_DIAGNOSTIC_ATTRIBUTES,
43084336
Warn,
4309-
"unrecognized or malformed diagnostic attribute",
4337+
"detects diagnostic attributes that are placed on the wrong item",
43104338
}
43114339

4340+
declare_lint! {
4341+
/// The `unknown_diagnostic_attributes` lint detects unknown diagnostic attributes.
4342+
///
4343+
/// ### Example
4344+
///
4345+
/// ```rust
4346+
/// #[diagnostic::does_not_exist]
4347+
/// struct Thing;
4348+
/// ```
4349+
///
4350+
/// {{produces}}
4351+
///
4352+
/// ### Explanation
4353+
///
4354+
/// It is usually a mistake to specify a diagnostic attribute that does not exist. Check the
4355+
/// spelling, and check the diagnostic attribute listing for the correct name. Also consider if
4356+
/// you are using an old version of the compiler and the attribute is only available in a newer
4357+
/// version. See the [reference] for the list of diagnostic attributes.
4358+
///
4359+
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4360+
pub UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
4361+
Warn,
4362+
"detects unknown diagnostic attributes",
4363+
}
4364+
4365+
declare_lint! {
4366+
/// The `malformed_diagnostic_format_literals` lint detects malformed diagnostic format
4367+
/// literals.
4368+
///
4369+
/// ### Example
4370+
///
4371+
/// ```rust
4372+
/// #[diagnostic::on_unimplemented(message = "{Self}} does not implement `Trait`")]
4373+
/// trait Trait {}
4374+
/// ```
4375+
///
4376+
/// {{produces}}
4377+
///
4378+
/// ### Explanation
4379+
///
4380+
/// The `#[diagnostic::on_unimplemented]` attribute accepts string literal values that are
4381+
/// similar to `format!`'s string literal. See the [reference] for details on what is permitted
4382+
/// in this string literal.
4383+
///
4384+
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4385+
pub MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
4386+
Warn,
4387+
"detects diagnostic attribute with malformed diagnostic format literals",
4388+
}
43124389
declare_lint! {
43134390
/// The `ambiguous_glob_imports` lint detects glob imports that should report ambiguity
43144391
/// errors, but previously didn't do that due to rustc bugs.

‎compiler/rustc_passes/src/check_attr.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rustc_session::config::CrateType;
3333
use rustc_session::lint;
3434
use rustc_session::lint::builtin::{
3535
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
36-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
36+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
3737
};
3838
use rustc_session::parse::feature_err;
3939
use rustc_span::edition::Edition;
@@ -460,7 +460,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
460460
);
461461
}
462462

463-
/// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl.
463+
/// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl and that it has no
464+
/// arguments.
464465
fn check_do_not_recommend(
465466
&self,
466467
attr_span: Span,
@@ -477,15 +478,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
477478
)
478479
{
479480
self.tcx.emit_node_span_lint(
480-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
481+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
481482
hir_id,
482483
attr_span,
483484
errors::IncorrectDoNotRecommendLocation,
484485
);
485486
}
486487
if !attr.is_word() {
487488
self.tcx.emit_node_span_lint(
488-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
489+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
489490
hir_id,
490491
attr_span,
491492
errors::DoNotRecommendDoesNotExpectArgs,
@@ -497,7 +498,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
497498
fn check_diagnostic_on_unimplemented(&self, attr_span: Span, hir_id: HirId, target: Target) {
498499
if !matches!(target, Target::Trait) {
499500
self.tcx.emit_node_span_lint(
500-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
501+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
501502
hir_id,
502503
attr_span,
503504
DiagnosticOnUnimplementedOnlyForTraits,

‎compiler/rustc_resolve/src/macros.rs

Lines changed: 2 additions & 2 deletions
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;
@@ -689,7 +689,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
689689
);
690690

691691
self.tcx.sess.psess.buffer_lint(
692-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
692+
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
693693
attribute.span(),
694694
node_id,
695695
BuiltinLintDiag::UnknownDiagnosticAttribute { span: attribute.span(), typo_name },

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

Lines changed: 9 additions & 7 deletions
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 },
@@ -533,7 +535,7 @@ impl<'tcx> OnUnimplementedDirective {
533535
if is_diagnostic_namespace_variant {
534536
if let Some(def_id) = item_def_id.as_local() {
535537
tcx.emit_node_span_lint(
536-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
538+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
537539
tcx.local_def_id_to_hir_id(def_id),
538540
vec![item.span()],
539541
MalformedOnUnimplementedAttrLint::new(item.span()),
@@ -689,7 +691,7 @@ impl<'tcx> OnUnimplementedDirective {
689691

690692
if let Some(item_def_id) = item_def_id.as_local() {
691693
tcx.emit_node_span_lint(
692-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
694+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
693695
tcx.local_def_id_to_hir_id(item_def_id),
694696
report_span,
695697
MalformedOnUnimplementedAttrLint::new(report_span),
@@ -702,7 +704,7 @@ impl<'tcx> OnUnimplementedDirective {
702704
Attribute::Unparsed(p) if !matches!(p.args, AttrArgs::Empty) => {
703705
if let Some(item_def_id) = item_def_id.as_local() {
704706
tcx.emit_node_span_lint(
705-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
707+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
706708
tcx.local_def_id_to_hir_id(item_def_id),
707709
attr.span(),
708710
MalformedOnUnimplementedAttrLint::new(attr.span()),
@@ -712,7 +714,7 @@ impl<'tcx> OnUnimplementedDirective {
712714
_ => {
713715
if let Some(item_def_id) = item_def_id.as_local() {
714716
tcx.emit_node_span_lint(
715-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
717+
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
716718
tcx.local_def_id_to_hir_id(item_def_id),
717719
attr.span(),
718720
MissingOptionsForOnUnimplementedAttr,
@@ -859,7 +861,7 @@ impl<'tcx> OnUnimplementedFormatString {
859861
if self.is_diagnostic_namespace_variant {
860862
if let Some(trait_def_id) = trait_def_id.as_local() {
861863
tcx.emit_node_span_lint(
862-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
864+
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
863865
tcx.local_def_id_to_hir_id(trait_def_id),
864866
self.span,
865867
WrappedParserError { description: e.description, label: e.label },

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_middle::ty::{GenericParamDefKind, TyCtxt};
77
use rustc_parse_format::{
88
Argument, FormatSpec, ParseError, ParseMode, Parser, 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::{InnerSpan, 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,

‎src/tools/lint-docs/src/groups.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[
2626
"Lints that detect identifiers which will be come keywords in later editions",
2727
),
2828
("deprecated-safe", "Lints for functions which were erroneously marked as safe in the past"),
29+
(
30+
"unknown-or-malformed-diagnostic-attributes",
31+
"detects unknown or malformed diagnostic attributes",
32+
),
2933
];
3034

3135
type LintGroups = BTreeMap<String, BTreeSet<String>>;

‎tests/ui/attributes/malformed-attrs.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
594594
LL | #[diagnostic::do_not_recommend()]
595595
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
596596
|
597-
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
597+
= note: `#[warn(malformed_diagnostic_attributes)]` on by default
598598

599599
warning: missing options for `on_unimplemented` attribute
600600
--> $DIR/malformed-attrs.rs:138:1

‎tests/ui/diagnostic_namespace/deny_malformed_attribute.stderr

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /