Move diagnostic::do_not_recommend target checking

This commit is contained in:
mejrs
2026-04-20 23:58:00 +02:00
parent c62be6e992
commit 80fb0aa44e
4 changed files with 23 additions and 31 deletions
@@ -1,11 +1,16 @@
use rustc_errors::Diagnostic;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::Target;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::AttributeLintKind;
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use rustc_session::lint::builtin::{
MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES,
};
use rustc_span::{Symbol, sym};
use crate::attributes::{OnDuplicate, SingleAttributeParser};
use crate::context::{AcceptContext, Stage};
use crate::errors::IncorrectDoNotRecommendLocation;
use crate::parser::ArgParser;
use crate::target_checking::{ALL_TARGETS, AllowedTargets};
@@ -13,7 +18,8 @@
impl<S: Stage> SingleAttributeParser<S> for DoNotRecommendParser {
const PATH: &[Symbol] = &[sym::diagnostic, sym::do_not_recommend];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Checked in check_attr.
// "Allowed" on any target, noop on all but trait impls
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const TEMPLATE: AttributeTemplate = template!(Word /*doesn't matter */);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
@@ -25,6 +31,16 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
attr_span,
);
}
if !matches!(cx.target, Target::Impl { of_trait: true }) {
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| IncorrectDoNotRecommendLocation.into_diag(dcx, level),
attr_span,
);
return None;
}
Some(AttributeKind::DoNotRecommend { attr_span })
}
}
@@ -274,3 +274,7 @@ pub(crate) struct DiagnosticOnUnknownOnlyForImports {
#[label("not an import")]
pub target_span: Span,
}
#[derive(Diagnostic)]
#[diag("`#[diagnostic::do_not_recommend]` can only be placed on trait implementations")]
pub(crate) struct IncorrectDoNotRecommendLocation;
+1 -25
View File
@@ -199,7 +199,6 @@ fn check_attributes(
Attribute::Parsed(AttributeKind::RustcMustImplementOneOf { attr_span, fn_names }) => {
self.check_rustc_must_implement_one_of(*attr_span, fn_names, hir_id,target)
},
Attribute::Parsed(AttributeKind::DoNotRecommend{attr_span}) => {self.check_do_not_recommend(*attr_span, hir_id, target, item)},
Attribute::Parsed(AttributeKind::OnUnimplemented{directive,..}) => {self.check_diagnostic_on_unimplemented(hir_id, directive.as_deref())},
Attribute::Parsed(AttributeKind::OnConst{span, ..}) => {self.check_diagnostic_on_const(*span, hir_id, target, item)}
Attribute::Parsed(AttributeKind::OnMove { directive , .. }) => {
@@ -222,6 +221,7 @@ fn check_attributes(
| AttributeKind::CustomMir(..)
| AttributeKind::DebuggerVisualizer(..)
| AttributeKind::DefaultLibAllocator
| AttributeKind::DoNotRecommend {..}
// `#[doc]` is actually a lot more than just doc comments, so is checked below
| AttributeKind::DocComment {..}
| AttributeKind::EiiDeclaration { .. }
@@ -490,30 +490,6 @@ fn check_eii_impl(&self, impls: &[EiiImpl], target: Target) {
}
}
/// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl
fn check_do_not_recommend(
&self,
attr_span: Span,
hir_id: HirId,
target: Target,
item: Option<ItemLike<'_>>,
) {
if !matches!(target, Target::Impl { .. })
|| matches!(
item,
Some(ItemLike::Item(hir::Item { kind: hir::ItemKind::Impl(_impl),.. }))
if _impl.of_trait.is_none()
)
{
self.tcx.emit_node_span_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
hir_id,
attr_span,
errors::IncorrectDoNotRecommendLocation,
);
}
}
/// Checks use of generic formatting parameters in `#[diagnostic::on_unimplemented]`
fn check_diagnostic_on_unimplemented(&self, hir_id: HirId, directive: Option<&Directive>) {
if let Some(directive) = directive {
-4
View File
@@ -13,10 +13,6 @@
use crate::check_attr::ProcMacroKind;
use crate::lang_items::Duplicate;
#[derive(Diagnostic)]
#[diag("`#[diagnostic::do_not_recommend]` can only be placed on trait implementations")]
pub(crate) struct IncorrectDoNotRecommendLocation;
#[derive(Diagnostic)]
#[diag("`#[loop_match]` should be applied to a loop")]
pub(crate) struct LoopMatchAttr {