mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Move diagnostic::do_not_recommend target checking
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user