diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs index 9f3d1e29b4de..70e673ed6dfa 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs @@ -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 SingleAttributeParser for DoNotRecommendParser { const PATH: &[Symbol] = &[sym::diagnostic, sym::do_not_recommend]; const ON_DUPLICATE: OnDuplicate = 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 { @@ -25,6 +31,16 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { 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>, - ) { - 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 { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index cb56a28b8628..a916b4670fde 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -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 {