Skip to content

Split up the unknown_or_malformed_diagnostic_attributes lint #140717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
8 changes: 8 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ fn register_builtins(store: &mut LintStore) {

add_lint_group!("deprecated_safe", DEPRECATED_SAFE_2024);

add_lint_group!(
"unknown_or_malformed_diagnostic_attributes",
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
UNKNOWN_DIAGNOSTIC_ATTRIBUTES
);

// Register renamed and removed lints.
store.register_renamed("single_use_lifetime", "single_use_lifetimes");
store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths");
Expand Down
94 changes: 85 additions & 9 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ declare_lint_pass! {
LOSSY_PROVENANCE_CASTS,
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
MACRO_USE_EXTERN_CRATE,
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
META_VARIABLE_MISUSE,
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
MISSING_ABI,
MISSING_FRAGMENT_SPECIFIER,
MISSING_UNSAFE_ON_EXTERN,
Expand Down Expand Up @@ -113,8 +116,8 @@ declare_lint_pass! {
UNFULFILLED_LINT_EXPECTATIONS,
UNINHABITED_STATIC,
UNKNOWN_CRATE_TYPES,
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
UNKNOWN_LINTS,
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
UNNAMEABLE_TEST_ITEMS,
UNNAMEABLE_TYPES,
UNNECESSARY_TRANSMUTES,
Expand Down Expand Up @@ -4297,31 +4300,104 @@ declare_lint! {
}

declare_lint! {
/// The `unknown_or_malformed_diagnostic_attributes` lint detects unrecognized or otherwise malformed
/// diagnostic attributes.
/// The `malformed_diagnostic_attributes` lint detects malformed diagnostic attributes.
///
/// ### Example
///
/// ```rust
/// #![feature(diagnostic_namespace)]
/// #[diagnostic::does_not_exist]
/// struct Foo;
/// #[diagnostic::do_not_recommend(message = "message")]
/// trait Trait {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// It is usually a mistake to use options or syntax that is not supported. Check the spelling,
/// and check the diagnostic attribute listing for the correct name and syntax. Also
/// consider if you are using an old version of the compiler; perhaps the option or syntax
/// is only available in a newer version. See the [reference] for a list of diagnostic attributes
/// and their syntax.
///
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
pub MALFORMED_DIAGNOSTIC_ATTRIBUTES,
Warn,
"detects malformed diagnostic attributes",
}

declare_lint! {
/// The `misplaced_diagnostic_attributes` lint detects wrongly placed diagnostic attributes.
///
/// ### Example
///
/// ```rust
/// #[diagnostic::do_not_recommend]
/// struct NotUserFacing;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// It is usually a mistake to specify a diagnostic attribute on an item it is not meant for. For example,
/// `#[diagnostic::do_not_recommend]` can only be placed on trait implementations, and does nothing if placed
/// elsewhere. See the [reference] for a list of diagnostic attributes and their correct positions.
///
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
pub MISPLACED_DIAGNOSTIC_ATTRIBUTES,
Warn,
"detects diagnostic attributes that are placed on the wrong item",
}

declare_lint! {
/// The `unknown_diagnostic_attributes` lint detects unknown diagnostic attributes.
///
/// ### Example
///
/// ```rust
/// #[diagnostic::does_not_exist]
/// struct Thing;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// It is usually a mistake to specify a diagnostic attribute that does not exist. Check
/// the spelling, and check the diagnostic attribute listing for the correct name. Also
/// consider if you are using an old version of the compiler, and the attribute
/// is only available in a newer version.
pub UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
/// is only available in a newer version. See the [reference] for the list of diagnostic attributes.
///
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
pub UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
Warn,
"unrecognized or malformed diagnostic attribute",
"detects unknown diagnostic attributes",
}

declare_lint! {
/// The `malformed_diagnostic_format_literals` lint detects malformed
/// diagnostic format literals.
///
/// ### Example
///
/// ```rust
/// #[diagnostic::on_unimplemented(message = "{Self}} does not implement `Trait`")]
/// trait Trait {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The `#[diagnostic::on_unimplemented]` attribute accepts string literal values that
/// are similar to `format!`'s string literal. See the [reference] for details on
/// what is permitted in this string literal.
///
/// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
pub MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
Warn,
"detects diagnostic attribute with malformed diagnostic format literals",
}
declare_lint! {
/// The `ambiguous_glob_imports` lint detects glob imports that should report ambiguity
/// errors, but previously didn't do that due to rustc bugs.
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use rustc_middle::{bug, span_bug};
use rustc_session::config::CrateType;
use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
};
use rustc_session::parse::feature_err;
use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, kw, sym};
Expand Down Expand Up @@ -375,7 +375,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
);
}

/// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl.
/// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl and that it is a word.
fn check_do_not_recommend(
&self,
attr_span: Span,
Expand All @@ -392,15 +392,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
)
{
self.tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
hir_id,
attr_span,
errors::IncorrectDoNotRecommendLocation,
);
}
if !attr.is_word() {
self.tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
hir_id,
attr_span,
errors::DoNotRecommendDoesNotExpectArgs,
Expand All @@ -412,7 +412,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
fn check_diagnostic_on_unimplemented(&self, attr_span: Span, hir_id: HirId, target: Target) {
if !matches!(target, Target::Trait) {
self.tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
hir_id,
attr_span,
DiagnosticOnUnimplementedOnlyForTraits,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use rustc_middle::middle::stability;
use rustc_middle::ty::{RegisteredTools, TyCtxt, Visibility};
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::{
LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
UNUSED_MACRO_RULES, UNUSED_MACROS,
};
use rustc_session::parse::feature_err;
Expand Down Expand Up @@ -663,7 +663,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
);

self.tcx.sess.psess.buffer_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
attribute.span(),
node_id,
BuiltinLintDiag::UnknownDiagnosticAttribute { span: attribute.span(), typo_name },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use rustc_macros::LintDiagnostic;
use rustc_middle::bug;
use rustc_middle::ty::print::PrintTraitRefExt;
use rustc_middle::ty::{self, GenericArgsRef, GenericParamDef, GenericParamDefKind, TyCtxt};
use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use rustc_session::lint::builtin::{
MALFORMED_DIAGNOSTIC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
};
use rustc_span::{Span, Symbol, sym};
use tracing::{debug, info};

Expand Down Expand Up @@ -382,7 +384,7 @@ impl IgnoredDiagnosticOption {
if let (Some(new_item), Some(old_item)) = (new, old) {
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
new_item,
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
Expand Down Expand Up @@ -521,7 +523,7 @@ impl<'tcx> OnUnimplementedDirective {
if is_diagnostic_namespace_variant {
if let Some(def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(def_id),
vec![item.span()],
MalformedOnUnimplementedAttrLint::new(item.span()),
Expand Down Expand Up @@ -677,7 +679,7 @@ impl<'tcx> OnUnimplementedDirective {

if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
report_span,
MalformedOnUnimplementedAttrLint::new(report_span),
Expand All @@ -690,7 +692,7 @@ impl<'tcx> OnUnimplementedDirective {
Attribute::Unparsed(p) if !matches!(p.args, AttrArgs::Empty) => {
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
attr.span(),
MalformedOnUnimplementedAttrLint::new(attr.span()),
Expand All @@ -700,7 +702,7 @@ impl<'tcx> OnUnimplementedDirective {
_ => {
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
attr.span(),
MissingOptionsForOnUnimplementedAttr,
Expand Down Expand Up @@ -847,7 +849,7 @@ impl<'tcx> OnUnimplementedFormatString {
if self.is_diagnostic_namespace_variant {
if let Some(trait_def_id) = trait_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
tcx.local_def_id_to_hir_id(trait_def_id),
self.span,
WrappedParserError { description: e.description, label: e.label },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_parse_format::{
Alignment, Argument, Count, FormatSpec, InnerSpan, ParseError, ParseMode, Parser,
Piece as RpfPiece, Position,
};
use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_FORMAT_LITERALS;
use rustc_span::def_id::DefId;
use rustc_span::{BytePos, Pos, Span, Symbol, kw, sym};

Expand Down Expand Up @@ -69,7 +69,7 @@ impl FormatWarning {
let this = tcx.item_ident(item_def_id);
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
tcx.local_def_id_to_hir_id(item_def_id),
span,
UnknownFormatParameterForOnUnimplementedAttr {
Expand All @@ -82,7 +82,7 @@ impl FormatWarning {
FormatWarning::PositionalArgument { span, .. } => {
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
tcx.local_def_id_to_hir_id(item_def_id),
span,
DisallowedPositionalArgument,
Expand All @@ -92,7 +92,7 @@ impl FormatWarning {
FormatWarning::InvalidSpecifier { span, .. } => {
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
tcx.local_def_id_to_hir_id(item_def_id),
span,
InvalidFormatSpecifier,
Expand Down Expand Up @@ -376,39 +376,4 @@ pub mod errors {
#[diag(trait_selection_missing_options_for_on_unimplemented_attr)]
#[help]
pub struct MissingOptionsForOnUnimplementedAttr;

#[derive(LintDiagnostic)]
#[diag(trait_selection_ignored_diagnostic_option)]
pub struct IgnoredDiagnosticOption {
pub option_name: &'static str,
#[label]
pub span: Span,
#[label(trait_selection_other_label)]
pub prev_span: Span,
}
Comment on lines -380 to -388
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a duplicate of the one in ../on_unimplemented.rs, I think I accidentally copy pasted it in the past 😞


impl IgnoredDiagnosticOption {
pub fn maybe_emit_warning<'tcx>(
tcx: TyCtxt<'tcx>,
item_def_id: DefId,
new: Option<Span>,
old: Option<Span>,
option_name: &'static str,
) {
if let (Some(new_item), Some(old_item)) = (new, old) {
if let Some(item_def_id) = item_def_id.as_local() {
tcx.emit_node_span_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.local_def_id_to_hir_id(item_def_id),
new_item,
IgnoredDiagnosticOption {
span: new_item,
prev_span: old_item,
option_name,
},
);
}
}
}
}
}
4 changes: 4 additions & 0 deletions src/tools/lint-docs/src/groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ static GROUP_DESCRIPTIONS: &[(&str, &str)] = &[
"Lints that detect identifiers which will be come keywords in later editions",
),
("deprecated-safe", "Lints for functions which were erroneously marked as safe in the past"),
(
"unknown-or-malformed-diagnostic-attributes",
"detects unknown or malformed diagnostic attributes",
),
];

type LintGroups = BTreeMap<String, BTreeSet<String>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ note: the lint level is defined here
|
LL | #![deny(unknown_or_malformed_diagnostic_attributes)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `#[deny(unknown_diagnostic_attributes)]` implied by `#[deny(unknown_or_malformed_diagnostic_attributes)]`

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
LL | #[diagnostic::do_not_recommend(not_accepted)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
= note: `#[warn(malformed_diagnostic_attributes)]` on by default

warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
--> $DIR/does_not_acccept_args.rs:15:1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
LL | #[diagnostic::do_not_recommend(not_accepted)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
= note: `#[warn(malformed_diagnostic_attributes)]` on by default

warning: `#[diagnostic::do_not_recommend]` does not expect any arguments
--> $DIR/does_not_acccept_args.rs:15:1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
= note: `#[warn(misplaced_diagnostic_attributes)]` on by default

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