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..8cf6be088a7a 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,19 @@ fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option, @@ -21,6 +23,21 @@ impl AttributeParser 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 AttributeParser 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 { diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs index 2b62ab7f3d11..feb48fa868d4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs @@ -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 AttributeParser 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 { diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs index dce3226670a1..069cda28582e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs @@ -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; } diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs index a5364f968b21..d30ccfb73fe8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs @@ -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 AttributeParser 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 { diff --git a/compiler/rustc_attr_parsing/src/errors.rs b/compiler/rustc_attr_parsing/src/errors.rs index ca57c25f25a0..8e4dfb40ad86 100644 --- a/compiler/rustc_attr_parsing/src/errors.rs +++ b/compiler/rustc_attr_parsing/src/errors.rs @@ -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, +} diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 10a805a159b0..06dd8cbc089b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -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>, - ) { - 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>, ) { + // 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 { 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 { diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr index d2ad65b3c791..b43a67a65612 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr @@ -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 diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr index d2ad65b3c791..b43a67a65612 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr @@ -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 diff --git a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs index 48654ed47ec4..a580f540a847 100644 --- a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs +++ b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs @@ -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 { None } diff --git a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr index f92ea501696e..0efead672030 100644 --- a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr +++ b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr @@ -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 { - | ---------------------------------------------------------------- not a trait impl +LL | / fn partial_cmp(&self, other: &Foo) -> Option { +LL | | None +LL | | } + | |_____- not a trait implementation error: aborting due to 4 previous errors diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr index 65d92e4592d0..9ed72d334b27 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr @@ -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 | diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr index 14d3c0db1ec9..d5c7f25efbc2 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr @@ -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 | diff --git a/tests/ui/diagnostic_namespace/on_unknown/incorrect-locations.stderr b/tests/ui/diagnostic_namespace/on_unknown/incorrect-locations.stderr index 33636e1fcfc3..c7636217af3e 100644 --- a/tests/ui/diagnostic_namespace/on_unknown/incorrect-locations.stderr +++ b/tests/ui/diagnostic_namespace/on_unknown/incorrect-locations.stderr @@ -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