From 5f0ccfba88a3f9423099198441006579b5f21740 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 19 Apr 2026 00:36:20 +0200 Subject: [PATCH] Remove `AttributeLintKind::IllFormedAttributeInput` variant --- .../rustc_attr_parsing/src/attributes/doc.rs | 9 ++-- compiler/rustc_attr_parsing/src/context.rs | 7 ++- compiler/rustc_attr_parsing/src/errors.rs | 45 ++++++++++++++++++- .../rustc_attr_parsing/src/validate_attr.rs | 13 +++--- compiler/rustc_lint/src/early/diagnostics.rs | 12 ----- compiler/rustc_lint/src/lints.rs | 26 ----------- compiler/rustc_lint_defs/src/lib.rs | 5 --- 7 files changed, 59 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index a5b8c0ebe25e..3983f892744b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -666,12 +666,11 @@ fn accept_single_doc_attr( ArgParser::NoArgs => { let suggestions = cx.adcx().suggestions(); let span = cx.attr_span; - cx.emit_lint( + cx.emit_dyn_lint( rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, - AttributeLintKind::IllFormedAttributeInput { - suggestions, - docs: None, - help: None, + move |dcx, level| { + crate::errors::IllFormedAttributeInput::new(&suggestions, None, None) + .into_diag(dcx, level) }, span, ); diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index aa9284e54d36..e51ffa0696e7 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -916,9 +916,12 @@ pub(crate) fn warn_ill_formed_attribute_input_with_help( ) { let suggestions = self.suggestions(); let span = self.attr_span; - self.emit_lint( + self.emit_dyn_lint( lint, - AttributeLintKind::IllFormedAttributeInput { suggestions, docs: None, help }, + move |dcx, level| { + crate::errors::IllFormedAttributeInput::new(&suggestions, None, help.as_deref()) + .into_diag(dcx, level) + }, span, ); } diff --git a/compiler/rustc_attr_parsing/src/errors.rs b/compiler/rustc_attr_parsing/src/errors.rs index 7049ffae89ab..0750ed0e614d 100644 --- a/compiler/rustc_attr_parsing/src/errors.rs +++ b/compiler/rustc_attr_parsing/src/errors.rs @@ -1,4 +1,4 @@ -use rustc_errors::MultiSpan; +use rustc_errors::{DiagArgValue, MultiSpan}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; @@ -66,3 +66,46 @@ pub(crate) struct UnsafeAttrOutsideUnsafeLint { #[subdiagnostic] pub suggestion: Option, } + +#[derive(Diagnostic)] +#[diag( + "{$num_suggestions -> + [1] attribute must be of the form {$suggestions} + *[other] valid forms for the attribute are {$suggestions} + }" +)] +pub(crate) struct IllFormedAttributeInput { + pub num_suggestions: usize, + pub suggestions: DiagArgValue, + #[note("for more information, visit <{$docs}>")] + pub has_docs: bool, + pub docs: &'static str, + #[subdiagnostic] + help: Option, +} + +impl IllFormedAttributeInput { + pub(crate) fn new( + suggestions: &[String], + docs: Option<&'static str>, + help: Option<&str>, + ) -> Self { + Self { + num_suggestions: suggestions.len(), + suggestions: DiagArgValue::StrListSepByAnd( + suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), + ), + has_docs: docs.is_some(), + docs: docs.unwrap_or(""), + help: help.map(|h| IllFormedAttributeInputHelp { lint: h.to_string() }), + } + } +} + +#[derive(Subdiagnostic)] +#[help( + "if you meant to silence a warning, consider using #![allow({$lint})] or #![expect({$lint})]" +)] +struct IllFormedAttributeInputHelp { + pub lint: String, +} diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index 06ff674f2538..d8c4aaa2e11e 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -8,10 +8,9 @@ use rustc_ast::{ self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety, }; -use rustc_errors::{Applicability, PResult}; +use rustc_errors::{Applicability, Diagnostic, PResult}; use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, template}; use rustc_hir::AttrPath; -use rustc_hir::lints::AttributeLintKind; use rustc_parse::parse_in; use rustc_session::errors::report_lit_error; use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; @@ -210,14 +209,14 @@ pub fn emit_malformed_attribute( suggestions.clear(); } if should_warn(name) { - psess.buffer_lint( + let suggestions = suggestions.clone(); + psess.dyn_buffer_lint( ILL_FORMED_ATTRIBUTE_INPUT, span, ast::CRATE_NODE_ID, - AttributeLintKind::IllFormedAttributeInput { - suggestions: suggestions.clone(), - docs: template.docs, - help: None, + move |dcx, level| { + crate::errors::IllFormedAttributeInput::new(&suggestions, template.docs, None) + .into_diag(dcx, level) }, ); } else { diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 7340ba0b2f39..fd7dbefcd0f7 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -35,18 +35,6 @@ pub struct DecorateAttrLint<'a, 'sess, 'tcx> { impl<'a> Diagnostic<'a, ()> for DecorateAttrLint<'_, '_, '_> { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { match self.diagnostic { - AttributeLintKind::IllFormedAttributeInput { suggestions, docs, help } => { - lints::IllFormedAttributeInput { - num_suggestions: suggestions.len(), - suggestions: DiagArgValue::StrListSepByAnd( - suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), - ), - has_docs: docs.is_some(), - docs: docs.unwrap_or(""), - help: help.clone().map(|h| lints::IllFormedAttributeInputHelp { lint: h }), - } - .into_diag(dcx, level) - } AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => { lints::EmptyAttributeList { attr_span: *first_span, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 20d88505f042..22953510e612 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3025,32 +3025,6 @@ pub(crate) enum CargoHelp { } } -// FIXME(jdonszelmann): duplicated in rustc_attr_parsing, should be moved there completely. -#[derive(Diagnostic)] -#[diag( - "{$num_suggestions -> - [1] attribute must be of the form {$suggestions} - *[other] valid forms for the attribute are {$suggestions} - }" -)] -pub(crate) struct IllFormedAttributeInput { - pub num_suggestions: usize, - pub suggestions: DiagArgValue, - #[note("for more information, visit <{$docs}>")] - pub has_docs: bool, - pub docs: &'static str, - #[subdiagnostic] - pub help: Option, -} - -#[derive(Subdiagnostic)] -#[help( - "if you meant to silence a warning, consider using #![allow({$lint})] or #![expect({$lint})]" -)] -pub(crate) struct IllFormedAttributeInputHelp { - pub lint: String, -} - #[derive(Diagnostic)] #[diag("creating a {$shared_label}reference to mutable static")] pub(crate) struct RefOfMutStatic<'a> { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index ea5006c7f03f..534658ba386a 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -654,11 +654,6 @@ pub enum DeprecatedSinceKind { #[derive(Debug)] pub enum AttributeLintKind { - IllFormedAttributeInput { - suggestions: Vec, - docs: Option<&'static str>, - help: Option, - }, EmptyAttribute { first_span: Span, attr_path: String,