diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 0684163617fe6..d5c9fc960c86b 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -13,6 +13,7 @@ use crate::util::literal::escape_string_symbol; use rustc_index::bit_set::GrowableBitSet; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; +use smallvec::{smallvec, SmallVec}; use std::iter; use std::sync::atomic::{AtomicU32, Ordering}; use thin_vec::{thin_vec, ThinVec}; @@ -87,10 +88,20 @@ impl Attribute { AttrKind::DocComment(..) => None, } } + pub fn name_or_empty(&self) -> Symbol { self.ident().unwrap_or_else(Ident::empty).name } + pub fn path(&self) -> SmallVec<[Symbol; 1]> { + match &self.kind { + AttrKind::Normal(normal) => { + normal.item.path.segments.iter().map(|s| s.ident.name).collect() + } + AttrKind::DocComment(..) => smallvec![sym::doc], + } + } + #[inline] pub fn has_name(&self, name: Symbol) -> bool { match &self.kind { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index ebaa9f8d95004..0b4a871dd50c2 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -515,12 +515,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::Yes, experimental!(deprecated_safe), ), - // RFC 2397 - gated!( - do_not_recommend, Normal, template!(Word), WarnFollowing, - EncodeCrossCrate::Yes, experimental!(do_not_recommend) - ), - // `#[cfi_encoding = ""]` gated!( cfi_encoding, Normal, template!(NameValueStr: "encoding"), ErrorPreceding, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8bb19bc85acbd..f27409894fa59 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1814,6 +1814,11 @@ impl<'tcx> TyCtxt<'tcx> { self.get_attrs(did, attr).next().is_some() } + /// Determines whether an item is annotated with a multi-segement attribute + pub fn has_attrs_with_path(self, did: impl Into, attrs: &[Symbol]) -> bool { + self.get_attrs_by_path(did.into(), attrs).next().is_some() + } + /// Returns `true` if this is an `auto trait`. pub fn trait_is_auto(self, trait_def_id: DefId) -> bool { self.trait_def(trait_def_id).has_auto_impl diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 3deefcaa06c3d..d850644bb452f 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -341,7 +341,7 @@ passes_implied_feature_not_exist = feature `{$implied_by}` implying `{$feature}` does not exist passes_incorrect_do_not_recommend_location = - `#[do_not_recommend]` can only be placed on trait implementations + `#[diagnostic::do_not_recommend]` can only be placed on trait implementations passes_incorrect_meta_item = expected a quoted string literal passes_incorrect_meta_item_suggestion = consider surrounding this with quotes diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index b1438a542aca4..1924533e28049 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -113,92 +113,96 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut seen = FxHashMap::default(); let attrs = self.tcx.hir().attrs(hir_id); for attr in attrs { - if attr.path_matches(&[sym::diagnostic, sym::on_unimplemented]) { - self.check_diagnostic_on_unimplemented(attr.span, hir_id, target); - } - match attr.name_or_empty() { - sym::do_not_recommend => self.check_do_not_recommend(attr.span, target), - sym::inline => self.check_inline(hir_id, attr, span, target), - sym::coverage => self.check_coverage(hir_id, attr, span, target), - sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target), - sym::marker => self.check_marker(hir_id, attr, span, target), - sym::target_feature => self.check_target_feature(hir_id, attr, span, target, attrs), - sym::thread_local => self.check_thread_local(attr, span, target), - sym::track_caller => { + match attr.path().as_slice() { + [sym::diagnostic, sym::do_not_recommend] => { + self.check_do_not_recommend(attr.span, hir_id, target) + } + [sym::diagnostic, sym::on_unimplemented] => { + self.check_diagnostic_on_unimplemented(attr.span, hir_id, target) + } + [sym::inline] => self.check_inline(hir_id, attr, span, target), + [sym::coverage] => self.check_coverage(hir_id, attr, span, target), + [sym::non_exhaustive] => self.check_non_exhaustive(hir_id, attr, span, target), + [sym::marker] => self.check_marker(hir_id, attr, span, target), + [sym::target_feature] => { + self.check_target_feature(hir_id, attr, span, target, attrs) + } + [sym::thread_local] => self.check_thread_local(attr, span, target), + [sym::track_caller] => { self.check_track_caller(hir_id, attr.span, attrs, span, target) } - sym::doc => self.check_doc_attrs( + [sym::doc] => self.check_doc_attrs( attr, hir_id, target, &mut specified_inline, &mut doc_aliases, ), - sym::no_link => self.check_no_link(hir_id, attr, span, target), - sym::export_name => self.check_export_name(hir_id, attr, span, target), - sym::rustc_layout_scalar_valid_range_start - | sym::rustc_layout_scalar_valid_range_end => { + [sym::no_link] => self.check_no_link(hir_id, attr, span, target), + [sym::export_name] => self.check_export_name(hir_id, attr, span, target), + [sym::rustc_layout_scalar_valid_range_start] + | [sym::rustc_layout_scalar_valid_range_end] => { self.check_rustc_layout_scalar_valid_range(attr, span, target) } - sym::allow_internal_unstable => { + [sym::allow_internal_unstable] => { self.check_allow_internal_unstable(hir_id, attr, span, target, attrs) } - sym::debugger_visualizer => self.check_debugger_visualizer(attr, target), - sym::rustc_allow_const_fn_unstable => { + [sym::debugger_visualizer] => self.check_debugger_visualizer(attr, target), + [sym::rustc_allow_const_fn_unstable] => { self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target) } - sym::rustc_std_internal_symbol => { + [sym::rustc_std_internal_symbol] => { self.check_rustc_std_internal_symbol(attr, span, target) } - sym::naked => self.check_naked(hir_id, attr, span, target), - sym::rustc_never_returns_null_ptr => { + [sym::naked] => self.check_naked(hir_id, attr, span, target), + [sym::rustc_never_returns_null_ptr] => { self.check_applied_to_fn_or_method(hir_id, attr, span, target) } - sym::rustc_legacy_const_generics => { + [sym::rustc_legacy_const_generics] => { self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item) } - sym::rustc_lint_query_instability => { + [sym::rustc_lint_query_instability] => { self.check_rustc_lint_query_instability(hir_id, attr, span, target) } - sym::rustc_lint_diagnostics => { + [sym::rustc_lint_diagnostics] => { self.check_rustc_lint_diagnostics(hir_id, attr, span, target) } - sym::rustc_lint_opt_ty => self.check_rustc_lint_opt_ty(attr, span, target), - sym::rustc_lint_opt_deny_field_access => { + [sym::rustc_lint_opt_ty] => self.check_rustc_lint_opt_ty(attr, span, target), + [sym::rustc_lint_opt_deny_field_access] => { self.check_rustc_lint_opt_deny_field_access(attr, span, target) } - sym::rustc_clean - | sym::rustc_dirty - | sym::rustc_if_this_changed - | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(attr), - sym::rustc_coinductive - | sym::rustc_must_implement_one_of - | sym::rustc_deny_explicit_impl - | sym::const_trait => self.check_must_be_applied_to_trait(attr, span, target), - sym::cmse_nonsecure_entry => { + [sym::rustc_clean] + | [sym::rustc_dirty] + | [sym::rustc_if_this_changed] + | [sym::rustc_then_this_would_need] => self.check_rustc_dirty_clean(attr), + [sym::rustc_coinductive] + | [sym::rustc_must_implement_one_of] + | [sym::rustc_deny_explicit_impl] + | [sym::const_trait] => self.check_must_be_applied_to_trait(attr, span, target), + [sym::cmse_nonsecure_entry] => { self.check_cmse_nonsecure_entry(hir_id, attr, span, target) } - sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target), - sym::must_not_suspend => self.check_must_not_suspend(attr, span, target), - sym::must_use => self.check_must_use(hir_id, attr, target), - sym::rustc_pass_by_value => self.check_pass_by_value(attr, span, target), - sym::rustc_allow_incoherent_impl => { + [sym::collapse_debuginfo] => self.check_collapse_debuginfo(attr, span, target), + [sym::must_not_suspend] => self.check_must_not_suspend(attr, span, target), + [sym::must_use] => self.check_must_use(hir_id, attr, target), + [sym::rustc_pass_by_value] => self.check_pass_by_value(attr, span, target), + [sym::rustc_allow_incoherent_impl] => { self.check_allow_incoherent_impl(attr, span, target) } - sym::rustc_has_incoherent_inherent_impls => { + [sym::rustc_has_incoherent_inherent_impls] => { self.check_has_incoherent_inherent_impls(attr, span, target) } - sym::ffi_pure => self.check_ffi_pure(attr.span, attrs, target), - sym::ffi_const => self.check_ffi_const(attr.span, target), - sym::rustc_const_unstable - | sym::rustc_const_stable - | sym::unstable - | sym::stable - | sym::rustc_allowed_through_unstable_modules - | sym::rustc_promotable => self.check_stability_promotable(attr, target), - sym::link_ordinal => self.check_link_ordinal(attr, span, target), - sym::rustc_confusables => self.check_confusables(attr, target), - sym::rustc_safe_intrinsic => { + [sym::ffi_pure] => self.check_ffi_pure(attr.span, attrs, target), + [sym::ffi_const] => self.check_ffi_const(attr.span, target), + [sym::rustc_const_unstable] + | [sym::rustc_const_stable] + | [sym::unstable] + | [sym::stable] + | [sym::rustc_allowed_through_unstable_modules] + | [sym::rustc_promotable] => self.check_stability_promotable(attr, target), + [sym::link_ordinal] => self.check_link_ordinal(attr, span, target), + [sym::rustc_confusables] => self.check_confusables(attr, target), + [sym::rustc_safe_intrinsic] => { self.check_rustc_safe_intrinsic(hir_id, attr, span, target) } _ => true, @@ -290,18 +294,26 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ); } - /// Checks if `#[do_not_recommend]` is applied on a trait impl. - fn check_do_not_recommend(&self, attr_span: Span, target: Target) -> bool { - if let Target::Impl = target { - true - } else { - self.dcx().emit_err(errors::IncorrectDoNotRecommendLocation { span: attr_span }); - false + /// 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) -> bool { + if !matches!(target, Target::Impl) { + self.tcx.emit_node_span_lint( + UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + hir_id, + attr_span, + errors::IncorrectDoNotRecommendLocation, + ); } + true } /// 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) { + fn check_diagnostic_on_unimplemented( + &self, + attr_span: Span, + hir_id: HirId, + target: Target, + ) -> bool { if !matches!(target, Target::Trait) { self.tcx.emit_node_span_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, @@ -310,6 +322,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { DiagnosticOnUnimplementedOnlyForTraits, ); } + true } /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index b8586e7e974ad..180552785fe75 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -17,12 +17,9 @@ use rustc_span::{Span, Symbol, DUMMY_SP}; use crate::check_attr::ProcMacroKind; use crate::lang_items::Duplicate; -#[derive(Diagnostic)] +#[derive(LintDiagnostic)] #[diag(passes_incorrect_do_not_recommend_location)] -pub struct IncorrectDoNotRecommendLocation { - #[primary_span] - pub span: Span, -} +pub struct IncorrectDoNotRecommendLocation; #[derive(LintDiagnostic)] #[diag(passes_outer_crate_level_attr)] diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 092eb1ce2eed6..268e7f06d0423 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -578,7 +578,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if res == Res::NonMacroAttr(NonMacroAttrKind::Tool) && let [namespace, attribute, ..] = &*path.segments && namespace.ident.name == sym::diagnostic - && attribute.ident.name != sym::on_unimplemented + && !(attribute.ident.name == sym::on_unimplemented + || (attribute.ident.name == sym::do_not_recommend + && self.tcx.features().do_not_recommend)) { let distance = edit_distance(attribute.ident.name.as_str(), sym::on_unimplemented.as_str(), 5); diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 4933080451daa..7291eb00e7271 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -380,7 +380,10 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { source: CandidateSource::Impl(impl_def_id), result: _, } = candidate.kind() - && goal.infcx().tcx.has_attr(impl_def_id, sym::do_not_recommend) + && goal + .infcx() + .tcx + .has_attrs_with_path(impl_def_id, &[sym::diagnostic, sym::do_not_recommend]) { return ControlFlow::Break(self.obligation.clone()); } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 20dfb5e6642df..494fca0336cc0 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1012,7 +1012,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut base_cause = obligation.cause.code().clone(); loop { if let ObligationCauseCode::ImplDerived(ref c) = base_cause { - if self.tcx.has_attr(c.impl_or_alias_def_id, sym::do_not_recommend) { + if self.tcx.has_attrs_with_path( + c.impl_or_alias_def_id, + &[sym::diagnostic, sym::do_not_recommend], + ) { let code = (*c.derived.parent_code).clone(); obligation.cause.map_code(|_| code); obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx); diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs index 9cdc193d386d8..5fd5cc544009f 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs @@ -26,7 +26,7 @@ impl Expression for Bound { type SqlType = T; } -#[do_not_recommend] +#[diagnostic::do_not_recommend] impl AsExpression for T where T: Expression, diff --git a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs similarity index 56% rename from tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs rename to tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs index c9dc1c6e6498b..5a26d28188c25 100644 --- a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs @@ -1,17 +1,13 @@ #![feature(do_not_recommend)] -pub trait Foo { -} +pub trait Foo {} -impl Foo for i32 { -} +impl Foo for i32 {} -pub trait Bar { -} +pub trait Bar {} -#[do_not_recommend] -impl Bar for T { -} +#[diagnostic::do_not_recommend] +impl Bar for T {} fn stuff(_: T) {} diff --git a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.stderr similarity index 79% rename from tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr rename to tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.stderr index e6f199445bf50..3951231fa2e71 100644 --- a/tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `u8: Bar` is not satisfied - --> $DIR/feature-gate-do_not_recommend.rs:19:11 + --> $DIR/feature-gate-do_not_recommend.rs:15:11 | LL | stuff(1u8); | ^^^ the trait `Bar` is not implemented for `u8` | note: required by a bound in `stuff` - --> $DIR/feature-gate-do_not_recommend.rs:16:13 + --> $DIR/feature-gate-do_not_recommend.rs:12:13 | LL | fn stuff(_: T) {} | ^^^ required by this bound in `stuff` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs new file mode 100644 index 0000000000000..400ef83873e13 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs @@ -0,0 +1,39 @@ +//@ check-pass +#![feature(do_not_recommend)] + +#[diagnostic::do_not_recommend] +//~^WARN `#[diagnostic::do_not_recommend]` can only be placed +const CONST: () = (); + +#[diagnostic::do_not_recommend] +//~^WARN `#[diagnostic::do_not_recommend]` can only be placed +static STATIC: () = (); + +#[diagnostic::do_not_recommend] +//~^WARN `#[diagnostic::do_not_recommend]` can only be placed +type Type = (); + +#[diagnostic::do_not_recommend] +//~^WARN `#[diagnostic::do_not_recommend]` can only be placed +enum Enum {} + +#[diagnostic::do_not_recommend] +//~^WARN `#[diagnostic::do_not_recommend]` can only be placed +extern "C" {} + +#[diagnostic::do_not_recommend] +//~^WARN `#[diagnostic::do_not_recommend]` can only be placed +fn fun() {} + +#[diagnostic::do_not_recommend] +//~^WARN `#[diagnostic::do_not_recommend]` can only be placed +struct Struct {} + +#[diagnostic::do_not_recommend] +//~^WARN `#[diagnostic::do_not_recommend]` can only be placed +trait Trait {} + +#[diagnostic::do_not_recommend] +impl Trait for i32 {} + +fn main() {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.stderr new file mode 100644 index 0000000000000..c83fd46db5841 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.stderr @@ -0,0 +1,52 @@ +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:4:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:8:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:12:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:16:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:20:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:24:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:28:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:32:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 8 warnings emitted + diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs b/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs index 6fb15b90138a4..780649b009c63 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs @@ -6,7 +6,7 @@ trait Foo {} -#[do_not_recommend] +#[diagnostic::do_not_recommend] impl Foo for T where T: Send {} fn needs_foo() {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs index 695660d359619..fc355bdc4e204 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs @@ -8,7 +8,7 @@ trait Root {} trait DontRecommend {} trait Other {} -#[do_not_recommend] +#[diagnostic::do_not_recommend] impl Root for T where T: DontRecommend {} impl DontRecommend for T where T: Other {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs new file mode 100644 index 0000000000000..ccc687aa5b362 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs @@ -0,0 +1,8 @@ +#![deny(unknown_or_malformed_diagnostic_attributes)] +trait Foo {} + +#[diagnostic::do_not_recommend] +//~^ ERROR unknown diagnostic attribute [unknown_or_malformed_diagnostic_attributes] +impl Foo for i32 {} + +fn main() {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.stderr new file mode 100644 index 0000000000000..d8332229d4fc4 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.stderr @@ -0,0 +1,14 @@ +error: unknown diagnostic attribute + --> $DIR/unstable-feature.rs:4:15 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unstable-feature.rs:1:9 + | +LL | #![deny(unknown_or_malformed_diagnostic_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rfcs/rfc-2397-do-not-recommend/incorrect-locations.rs b/tests/ui/rfcs/rfc-2397-do-not-recommend/incorrect-locations.rs deleted file mode 100644 index 91863f5e49787..0000000000000 --- a/tests/ui/rfcs/rfc-2397-do-not-recommend/incorrect-locations.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![feature(do_not_recommend)] - -#[do_not_recommend] -//~^ `#[do_not_recommend]` can only be placed -const CONST: () = (); - -#[do_not_recommend] -//~^ `#[do_not_recommend]` can only be placed -static Static: () = (); - -#[do_not_recommend] -//~^ `#[do_not_recommend]` can only be placed -type Type = (); - -#[do_not_recommend] -//~^ `#[do_not_recommend]` can only be placed -enum Enum { -} - -#[do_not_recommend] -//~^ `#[do_not_recommend]` can only be placed -extern { -} - -#[do_not_recommend] -//~^ `#[do_not_recommend]` can only be placed -fn fun() { -} - -#[do_not_recommend] -//~^ `#[do_not_recommend]` can only be placed -struct Struct { -} - -#[do_not_recommend] -//~^ `#[do_not_recommend]` can only be placed -trait Trait { -} - -#[do_not_recommend] -impl Trait for i32 { -} - -fn main() { -} diff --git a/tests/ui/rfcs/rfc-2397-do-not-recommend/incorrect-locations.stderr b/tests/ui/rfcs/rfc-2397-do-not-recommend/incorrect-locations.stderr deleted file mode 100644 index 01ebc23c86e19..0000000000000 --- a/tests/ui/rfcs/rfc-2397-do-not-recommend/incorrect-locations.stderr +++ /dev/null @@ -1,50 +0,0 @@ -error: `#[do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:3:1 - | -LL | #[do_not_recommend] - | ^^^^^^^^^^^^^^^^^^^ - -error: `#[do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:7:1 - | -LL | #[do_not_recommend] - | ^^^^^^^^^^^^^^^^^^^ - -error: `#[do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:11:1 - | -LL | #[do_not_recommend] - | ^^^^^^^^^^^^^^^^^^^ - -error: `#[do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:15:1 - | -LL | #[do_not_recommend] - | ^^^^^^^^^^^^^^^^^^^ - -error: `#[do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:20:1 - | -LL | #[do_not_recommend] - | ^^^^^^^^^^^^^^^^^^^ - -error: `#[do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:25:1 - | -LL | #[do_not_recommend] - | ^^^^^^^^^^^^^^^^^^^ - -error: `#[do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:30:1 - | -LL | #[do_not_recommend] - | ^^^^^^^^^^^^^^^^^^^ - -error: `#[do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:35:1 - | -LL | #[do_not_recommend] - | ^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 8 previous errors - diff --git a/tests/ui/rfcs/rfc-2397-do-not-recommend/unstable-feature.rs b/tests/ui/rfcs/rfc-2397-do-not-recommend/unstable-feature.rs deleted file mode 100644 index f0c5c222e786f..0000000000000 --- a/tests/ui/rfcs/rfc-2397-do-not-recommend/unstable-feature.rs +++ /dev/null @@ -1,10 +0,0 @@ -trait Foo { -} - -#[do_not_recommend] -//~^ ERROR the `#[do_not_recommend]` attribute is an experimental feature -impl Foo for i32 { -} - -fn main() { -} diff --git a/tests/ui/rfcs/rfc-2397-do-not-recommend/unstable-feature.stderr b/tests/ui/rfcs/rfc-2397-do-not-recommend/unstable-feature.stderr deleted file mode 100644 index 02bc51ccd3f58..0000000000000 --- a/tests/ui/rfcs/rfc-2397-do-not-recommend/unstable-feature.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: the `#[do_not_recommend]` attribute is an experimental feature - --> $DIR/unstable-feature.rs:4:1 - | -LL | #[do_not_recommend] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #51992 for more information - = help: add `#![feature(do_not_recommend)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`.