Move diagnostic::on_move target check

This commit is contained in:
mejrs
2026-04-20 21:00:45 +02:00
parent 5ba06cccd0
commit 26d2c30682
3 changed files with 22 additions and 23 deletions
@@ -1,10 +1,13 @@
use rustc_errors::Diagnostic;
use rustc_feature::template;
use rustc_hir::attrs::AttributeKind;
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
use rustc_span::sym;
use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
use crate::context::{AcceptContext, Stage};
use crate::errors::DiagnosticOnMoveOnlyForAdt;
use crate::parser::ArgParser;
use crate::target_checking::{ALL_TARGETS, AllowedTargets};
@@ -29,6 +32,15 @@ fn parse<'sess, S: Stage>(
let span = cx.attr_span;
self.span = Some(span);
if !matches!(cx.target, Target::Enum | Target::Struct | Target::Union) {
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| DiagnosticOnMoveOnlyForAdt.into_diag(dcx, level),
span,
);
return;
}
let Some(items) = parse_list(cx, args, mode) else { return };
if let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) {
@@ -44,6 +56,8 @@ impl<S: Stage> AttributeParser<S> for OnMoveParser {
this.parse(cx, args, Mode::DiagnosticOnMove);
},
)];
// "Allowed" for all targets but noop if used on not-adt.
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
@@ -259,3 +259,7 @@ pub(crate) struct DiagnosticOnConstOnlyForTraitImpls {
#[label("not a trait impl")]
pub target_span: Span,
}
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_move]` can only be applied to enums, structs or unions")]
pub(crate) struct DiagnosticOnMoveOnlyForAdt;
+4 -23
View File
@@ -61,10 +61,6 @@ struct DiagnosticOnConstOnlyForNonConstTraitImpls {
item_span: Span,
}
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_move]` can only be applied to enums, structs or unions")]
struct DiagnosticOnMoveOnlyForAdt;
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_unknown]` can only be applied to `use` statements")]
struct DiagnosticOnUnknownOnlyForImports {
@@ -218,8 +214,8 @@ fn check_attributes(
Attribute::Parsed(AttributeKind::OnUnimplemented{span, directive}) => {self.check_diagnostic_on_unimplemented(*span, hir_id, target,directive.as_deref())},
Attribute::Parsed(AttributeKind::OnUnknown { span, .. }) => { self.check_diagnostic_on_unknown(*span, hir_id, target) },
Attribute::Parsed(AttributeKind::OnConst{span, ..}) => {self.check_diagnostic_on_const(*span, hir_id, target, item)}
Attribute::Parsed(AttributeKind::OnMove { span, directive }) => {
self.check_diagnostic_on_move(*span, hir_id, target, directive.as_deref())
Attribute::Parsed(AttributeKind::OnMove { directive , .. }) => {
self.check_diagnostic_on_move(hir_id, directive.as_deref())
},
Attribute::Parsed(
// tidy-alphabetical-start
@@ -613,23 +609,8 @@ fn check_diagnostic_on_const(
// ...whose generics would that be, anyway? The traits' or the impls'?
}
/// Checks if `#[diagnostic::on_move]` is applied to an ADT definition
fn check_diagnostic_on_move(
&self,
attr_span: Span,
hir_id: HirId,
target: Target,
directive: Option<&Directive>,
) {
if !matches!(target, Target::Enum | Target::Struct | Target::Union) {
self.tcx.emit_node_span_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
hir_id,
attr_span,
DiagnosticOnMoveOnlyForAdt,
);
}
/// Checks use of generic formatting parameters in `#[diagnostic::on_move]`
fn check_diagnostic_on_move(&self, hir_id: HirId, directive: Option<&Directive>) {
if let Some(directive) = directive {
if let Node::Item(Item {
kind: