Rollup merge of #155572 - mejrs:move_target_checks, r=JonathanBrouwer,GuillaumeGomez

Move diagnostic attribute target checks from check_attr

Move diagnostic attribute target checks into their targets. Part of https://github.com/rust-lang/rust/issues/131229#issuecomment-3959910413

This is much easier with `emit_dyn_lint` :) (thanks @GuillaumeGomez !)

I think there might be some opportunity to simplify all these `check_diagnostic_*` methods in `check_attr`. However there are some diagnostic attribute prs in flight and I'd like to wait for those to land first and then think about it. So that PR is not for today.

r? @JonathanBrouwer (or @GuillaumeGomez if you want)
This commit is contained in:
Jacob Pratt
2026-04-21 08:22:17 -04:00
committed by GitHub
15 changed files with 238 additions and 172 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,19 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<Attrib
attr_span,
);
}
if !matches!(cx.target, Target::Impl { of_trait: true }) {
let target_span = cx.target_span;
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| {
IncorrectDoNotRecommendLocation { target_span }.into_diag(dcx, level)
},
attr_span,
);
return None;
}
Some(AttributeKind::DoNotRecommend { attr_span })
}
}
@@ -1,8 +1,10 @@
use rustc_errors::Diagnostic;
use rustc_hir::attrs::diagnostic::Directive;
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
use crate::errors::DiagnosticOnConstOnlyForTraitImpls;
#[derive(Default)]
pub(crate) struct OnConstParser {
span: Option<Span>,
@@ -21,6 +23,21 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {
let span = cx.attr_span;
this.span = Some(span);
// FIXME(mejrs) no constness field on `Target`,
// so non-constness is still checked in check_attr.rs
if !matches!(cx.target, Target::Impl { of_trait: true }) {
let target_span = cx.target_span;
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| {
DiagnosticOnConstOnlyForTraitImpls { target_span }.into_diag(dcx, level)
},
span,
);
return;
}
let mode = Mode::DiagnosticOnConst;
let Some(items) = parse_list(cx, args, mode) else { return };
@@ -32,7 +49,8 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {
},
)];
//FIXME Still checked in `check_attr.rs`
// "Allowed" on all targets; noop on anything but non-const trait impls;
// this linted on in parser.
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
@@ -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> {
@@ -1,7 +1,10 @@
use rustc_errors::Diagnostic;
use rustc_hir::attrs::diagnostic::Directive;
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
use crate::errors::DiagnosticOnUnimplementedOnlyForTraits;
#[derive(Default)]
pub(crate) struct OnUnimplementedParser {
@@ -19,11 +22,12 @@ fn parse<'sess, S: Stage>(
let span = cx.attr_span;
self.span = Some(span);
// If target is not a trait, returning early will make `finalize` emit a
// `AttributeKind::OnUnimplemented {span, directive: None }`, to prevent it being
// accidentally used on non-trait items like trait aliases.
if !matches!(cx.target, Target::Trait) {
// Lint later emitted in check_attr
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| DiagnosticOnUnimplementedOnlyForTraits.into_diag(dcx, level),
span,
);
return;
}
@@ -1,7 +1,11 @@
use rustc_errors::Diagnostic;
use rustc_hir::attrs::diagnostic::Directive;
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
use crate::ShouldEmit;
use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
use crate::errors::DiagnosticOnUnknownOnlyForImports;
#[derive(Default)]
pub(crate) struct OnUnknownParser {
@@ -25,6 +29,22 @@ fn parse<'sess, S: Stage>(
let span = cx.attr_span;
self.span = Some(span);
// At early parsing we get passed `Target::Crate` regardless of the item we're on.
// Only do target checking if we're late.
let early = matches!(cx.stage.should_emit(), ShouldEmit::Nothing);
if !early && !matches!(cx.target, Target::Use) {
let target_span = cx.target_span;
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| {
DiagnosticOnUnknownOnlyForImports { target_span }.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) {
@@ -41,7 +61,7 @@ impl<S: Stage> AttributeParser<S> for OnUnknownParser {
this.parse(cx, args, Mode::DiagnosticOnUnknown);
},
)];
//FIXME attribute is not parsed for non-use statements but diagnostics are issued in `check_attr.rs`
// "Allowed" for all targets, but noop for all but use statements.
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
+29
View File
@@ -252,3 +252,32 @@ pub(crate) struct DocUnknownAny {
#[derive(Diagnostic)]
#[diag("expected boolean for `#[doc(auto_cfg = ...)]`")]
pub(crate) struct DocAutoCfgWrongLiteral;
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_const]` can only be applied to non-const trait implementations")]
pub(crate) struct DiagnosticOnConstOnlyForTraitImpls {
#[label("not a trait implementation")]
pub target_span: Span,
}
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_move]` can only be applied to enums, structs or unions")]
pub(crate) struct DiagnosticOnMoveOnlyForAdt;
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_unimplemented]` can only be applied to trait definitions")]
pub(crate) struct DiagnosticOnUnimplementedOnlyForTraits;
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_unknown]` can only be applied to `use` statements")]
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 {
#[label("not a trait implementation")]
pub target_span: Span,
}
+17 -111
View File
@@ -51,31 +51,9 @@
use crate::errors;
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_unimplemented]` can only be applied to trait definitions")]
struct DiagnosticOnUnimplementedOnlyForTraits;
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_const]` can only be applied to trait impls")]
struct DiagnosticOnConstOnlyForTraitImpls {
#[label("not a trait impl")]
item_span: Span,
}
#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_const]` can only be applied to non-const trait impls")]
#[diag("`#[diagnostic::on_const]` can only be applied to non-const trait implementations")]
struct DiagnosticOnConstOnlyForNonConstTraitImpls {
#[label("this is a const trait impl")]
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 {
#[label("not an import")]
#[label("this is a const trait implementation")]
item_span: Span,
}
@@ -221,12 +199,10 @@ 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{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::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 { 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
@@ -245,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 { .. }
@@ -275,6 +252,7 @@ fn check_attributes(
| AttributeKind::NoMain
| AttributeKind::NoMangle(..)
| AttributeKind::NoStd { .. }
| AttributeKind::OnUnknown { .. }
| AttributeKind::Optimize(..)
| AttributeKind::PanicRuntime
| AttributeKind::PatchableFunctionEntry { .. }
@@ -512,47 +490,8 @@ 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 if `#[diagnostic::on_unimplemented]` is applied to a trait definition
fn check_diagnostic_on_unimplemented(
&self,
attr_span: Span,
hir_id: HirId,
target: Target,
directive: Option<&Directive>,
) {
if !matches!(target, Target::Trait) {
self.tcx.emit_node_span_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
hir_id,
attr_span,
DiagnosticOnUnimplementedOnlyForTraits,
);
}
/// 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 {
if let Node::Item(Item {
kind: ItemKind::Trait(_, _, _, _, trait_name, generics, _, _),
@@ -587,7 +526,7 @@ fn check_diagnostic_on_unimplemented(
}
}
/// Checks if `#[diagnostic::on_const]` is applied to a trait impl
/// Checks if `#[diagnostic::on_const]` is applied to a on-const trait impl
fn check_diagnostic_on_const(
&self,
attr_span: Span,
@@ -595,6 +534,8 @@ fn check_diagnostic_on_const(
target: Target,
item: Option<ItemLike<'_>>,
) {
// We only check the non-constness here. A diagnostic for use
// on not-trait impl items is issued during attribute parsing.
if target == (Target::Impl { of_trait: true }) {
match item.unwrap() {
ItemLike::Item(it) => match it.expect_impl().constness {
@@ -613,35 +554,13 @@ fn check_diagnostic_on_const(
ItemLike::ForeignItem => {}
}
}
let item_span = self.tcx.hir_span(hir_id);
self.tcx.emit_node_span_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
hir_id,
attr_span,
DiagnosticOnConstOnlyForTraitImpls { item_span },
);
// We don't check the validity of generic args here...whose generics would that be, anyway?
// The traits' or the impls'?
// FIXME(#155570) Can we do something with generic args here?
// regardless, we don't check the validity of generic args here
// ...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:
@@ -675,19 +594,6 @@ fn check_diagnostic_on_move(
}
}
/// Checks if `#[diagnostic::on_unknown]` is applied to a trait impl
fn check_diagnostic_on_unknown(&self, attr_span: Span, hir_id: HirId, target: Target) {
if !matches!(target, Target::Use) {
let item_span = self.tcx.hir_span(hir_id);
self.tcx.emit_node_span_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
hir_id,
attr_span,
DiagnosticOnUnknownOnlyForImports { item_span },
);
}
}
/// Checks if an `#[inline]` is applied to a function or a closure.
fn check_inline(&self, hir_id: HirId, attr_span: Span, kind: &InlineAttr, target: Target) {
match target {
-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 {
@@ -3,6 +3,9 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | const CONST: () = ();
| --------------------- not a trait implementation
|
= note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
@@ -11,48 +14,72 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | static STATIC: () = ();
| ----------------------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:15:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | type Type = ();
| --------------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:19:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | enum Enum {}
| ------------ not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:23:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | impl Enum {}
| ------------ not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:27:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | extern "C" {}
| ------------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:31:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | fn fun() {}
| ----------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:35:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | struct Struct {}
| ---------------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:39:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | trait Trait {}
| -------------- not a trait implementation
warning: 9 warnings emitted
@@ -3,6 +3,9 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | const CONST: () = ();
| --------------------- not a trait implementation
|
= note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
@@ -11,48 +14,72 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | static STATIC: () = ();
| ----------------------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:15:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | type Type = ();
| --------------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:19:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | enum Enum {}
| ------------ not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:23:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | impl Enum {}
| ------------ not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:27:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | extern "C" {}
| ------------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:31:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | fn fun() {}
| ----------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:35:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | struct Struct {}
| ---------------- not a trait implementation
warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/incorrect-locations.rs:39:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | trait Trait {}
| -------------- not a trait implementation
warning: 9 warnings emitted
@@ -2,11 +2,11 @@
#![deny(misplaced_diagnostic_attributes)]
#[diagnostic::on_const(message = "tadaa", note = "boing")]
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to trait impls
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to non-const trait implementations
pub struct Foo;
#[diagnostic::on_const(message = "tadaa", note = "boing")]
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to non-const trait impls
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to non-const trait implementations
impl const PartialEq for Foo {
fn eq(&self, _other: &Foo) -> bool {
true
@@ -14,7 +14,7 @@ fn eq(&self, _other: &Foo) -> bool {
}
#[diagnostic::on_const(message = "tadaa", note = "boing")]
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to trait impls
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to non-const trait implementations
impl Foo {
fn eq(&self, _other: &Foo) -> bool {
true
@@ -23,7 +23,7 @@ fn eq(&self, _other: &Foo) -> bool {
impl PartialOrd for Foo {
#[diagnostic::on_const(message = "tadaa", note = "boing")]
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to trait impls
//~^ ERROR: `#[diagnostic::on_const]` can only be applied to non-const trait implementations
fn partial_cmp(&self, other: &Foo) -> Option<std::cmp::Ordering> {
None
}
@@ -1,11 +1,11 @@
error: `#[diagnostic::on_const]` can only be applied to trait impls
--> $DIR/misplaced_attr.rs:4:1
error: `#[diagnostic::on_const]` can only be applied to non-const trait implementations
--> $DIR/misplaced_attr.rs:8:1
|
LL | #[diagnostic::on_const(message = "tadaa", note = "boing")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | pub struct Foo;
| -------------- not a trait impl
LL | impl const PartialEq for Foo {
| ---------------------------- this is a const trait implementation
|
note: the lint level is defined here
--> $DIR/misplaced_attr.rs:2:9
@@ -13,32 +13,38 @@ note: the lint level is defined here
LL | #![deny(misplaced_diagnostic_attributes)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `#[diagnostic::on_const]` can only be applied to non-const trait impls
--> $DIR/misplaced_attr.rs:8:1
error: `#[diagnostic::on_const]` can only be applied to non-const trait implementations
--> $DIR/misplaced_attr.rs:4:1
|
LL | #[diagnostic::on_const(message = "tadaa", note = "boing")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | impl const PartialEq for Foo {
| ---------------------------- this is a const trait impl
LL | pub struct Foo;
| --------------- not a trait implementation
error: `#[diagnostic::on_const]` can only be applied to trait impls
error: `#[diagnostic::on_const]` can only be applied to non-const trait implementations
--> $DIR/misplaced_attr.rs:16:1
|
LL | #[diagnostic::on_const(message = "tadaa", note = "boing")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #[diagnostic::on_const(message = "tadaa", note = "boing")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | impl Foo {
| -------- not a trait impl
LL | / impl Foo {
LL | | fn eq(&self, _other: &Foo) -> bool {
LL | | true
LL | | }
LL | | }
| |_- not a trait implementation
error: `#[diagnostic::on_const]` can only be applied to trait impls
error: `#[diagnostic::on_const]` can only be applied to non-const trait implementations
--> $DIR/misplaced_attr.rs:25:5
|
LL | #[diagnostic::on_const(message = "tadaa", note = "boing")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #[diagnostic::on_const(message = "tadaa", note = "boing")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | fn partial_cmp(&self, other: &Foo) -> Option<std::cmp::Ordering> {
| ---------------------------------------------------------------- not a trait impl
LL | / fn partial_cmp(&self, other: &Foo) -> Option<std::cmp::Ordering> {
LL | | None
LL | | }
| |_____- not a trait implementation
error: aborting due to 4 previous errors
@@ -1,11 +1,3 @@
warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:22:1
|
LL | #[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
warning: there is no parameter `from_desugaring` on trait `Baz`
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:17
|
@@ -152,6 +144,14 @@ LL | #[diagnostic::on_unimplemented = "Message"]
|
= help: only `message`, `note` and `label` are allowed as options
warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:22:1
|
LL | #[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
error[E0277]: trait has `()` and `i32` as params
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:53:15
|
@@ -1,11 +1,3 @@
warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:7:1
|
LL | #[diagnostic::on_unimplemented(message = "Baz")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
warning: there is no parameter `DoesNotExist` on trait `Test`
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:44
|
@@ -24,6 +16,14 @@ LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
= help: only `message`, `note` and `label` are allowed as options
= note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:7:1
|
LL | #[diagnostic::on_unimplemented(message = "Baz")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
warning: malformed `diagnostic::on_unimplemented` attribute
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:11:50
|
@@ -5,7 +5,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | extern crate std as other_std;
| ----------------------------- not an import
| ------------------------------ not an import
|
= note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
@@ -16,7 +16,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | const CONST: () = ();
| --------------- not an import
| --------------------- not an import
warning: `#[diagnostic::on_unknown]` can only be applied to `use` statements
--> $DIR/incorrect-locations.rs:13:1
@@ -25,7 +25,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | static STATIC: () = ();
| ----------------- not an import
| ----------------------- not an import
warning: `#[diagnostic::on_unknown]` can only be applied to `use` statements
--> $DIR/incorrect-locations.rs:17:1
@@ -34,7 +34,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | type Type = ();
| --------- not an import
| --------------- not an import
warning: `#[diagnostic::on_unknown]` can only be applied to `use` statements
--> $DIR/incorrect-locations.rs:21:1
@@ -43,7 +43,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | enum Enum {}
| --------- not an import
| ------------ not an import
warning: `#[diagnostic::on_unknown]` can only be applied to `use` statements
--> $DIR/incorrect-locations.rs:25:1
@@ -52,7 +52,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | impl Enum {}
| --------- not an import
| ------------ not an import
warning: `#[diagnostic::on_unknown]` can only be applied to `use` statements
--> $DIR/incorrect-locations.rs:29:1
@@ -70,7 +70,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | fn fun() {}
| -------- not an import
| ----------- not an import
warning: `#[diagnostic::on_unknown]` can only be applied to `use` statements
--> $DIR/incorrect-locations.rs:37:1
@@ -79,7 +79,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | struct Struct {}
| ------------- not an import
| ---------------- not an import
warning: `#[diagnostic::on_unknown]` can only be applied to `use` statements
--> $DIR/incorrect-locations.rs:41:1
@@ -88,7 +88,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | trait Trait {}
| ----------- not an import
| -------------- not an import
warning: `#[diagnostic::on_unknown]` can only be applied to `use` statements
--> $DIR/incorrect-locations.rs:45:1
@@ -97,7 +97,7 @@ LL | #[diagnostic::on_unknown(message = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL |
LL | impl Trait for i32 {}
| ------------------ not an import
| --------------------- not an import
warning: 11 warnings emitted