diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 8005dd76b2a3d..be4e2210c5ee4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -117,6 +117,21 @@ impl SingleAttributeParser for RustcLegacyConstGenericsParser { } } +pub(crate) struct RustcLintDiagnosticsParser; + +impl NoArgsAttributeParser for RustcLintDiagnosticsParser { + const PATH: &[Symbol] = &[sym::rustc_lint_diagnostics]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintDiagnostics; +} + pub(crate) struct RustcLintOptDenyFieldAccessParser; impl SingleAttributeParser for RustcLintOptDenyFieldAccessParser { @@ -165,6 +180,22 @@ impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintQueryInstability; } +pub(crate) struct RustcLintUntrackedQueryInformationParser; + +impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationParser { + const PATH: &[Symbol] = &[sym::rustc_lint_untracked_query_information]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintUntrackedQueryInformation; +} + pub(crate) struct RustcObjectLifetimeDefaultParser; impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index e5448e7792a88..a752869c2eb27 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -61,8 +61,9 @@ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, - RustcLegacyConstGenericsParser, RustcLintOptDenyFieldAccessParser, RustcLintOptTyParser, - RustcLintQueryInstabilityParser, RustcMainParser, RustcNeverReturnsNullPointerParser, + RustcLegacyConstGenericsParser, RustcLintDiagnosticsParser, RustcLintOptDenyFieldAccessParser, + RustcLintOptTyParser, RustcLintQueryInstabilityParser, + RustcLintUntrackedQueryInformationParser, RustcMainParser, RustcNeverReturnsNullPointerParser, RustcNoImplicitAutorefsParser, RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; @@ -257,8 +258,10 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 5991fb5ab24e6..1a382d8f124b6 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -931,6 +931,9 @@ pub enum AttributeKind { /// Represents `#[rustc_legacy_const_generics]` RustcLegacyConstGenerics { fn_indexes: ThinVec<(usize, Span)>, attr_span: Span }, + /// Represents `#[rustc_lint_diagnostics]` + RustcLintDiagnostics, + /// Represents `#[rustc_lint_opt_deny_field_access]` RustcLintOptDenyFieldAccess { lint_message: Symbol }, @@ -940,6 +943,9 @@ pub enum AttributeKind { /// Represents `#[rustc_lint_query_instability]` RustcLintQueryInstability, + /// Represents `#[rustc_lint_untracked_query_information]` + RustcLintUntrackedQueryInformation, + /// Represents `#[rustc_main]`. RustcMain, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 64aa9c2a45bc3..7c1e71f258bee 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -94,9 +94,11 @@ impl AttributeKind { RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcLegacyConstGenerics { .. } => Yes, + RustcLintDiagnostics => Yes, RustcLintOptDenyFieldAccess { .. } => Yes, RustcLintOptTy => Yes, RustcLintQueryInstability => Yes, + RustcLintUntrackedQueryInformation => Yes, RustcMain => No, RustcNeverReturnsNullPointer => Yes, RustcNoImplicitAutorefs => Yes, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index d6f20a4c85a4f..68885e14f40d2 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -106,7 +106,10 @@ impl<'tcx> LateLintPass<'tcx> for QueryStability { ); } - if cx.tcx.has_attr(def_id, sym::rustc_lint_untracked_query_information) { + if find_attr!( + cx.tcx.get_all_attrs(def_id), + AttributeKind::RustcLintUntrackedQueryInformation + ) { cx.emit_span_lint( UNTRACKED_QUERY_INFORMATION, span, @@ -606,14 +609,14 @@ impl Diagnostics { else { return; }; - let has_attr = cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics); - if !has_attr { + + if !find_attr!(cx.tcx.get_all_attrs(inst.def_id()), AttributeKind::RustcLintDiagnostics) { return; }; for (hir_id, _parent) in cx.tcx.hir_parent_iter(current_id) { if let Some(owner_did) = hir_id.as_owner() - && cx.tcx.has_attr(owner_did, sym::rustc_lint_diagnostics) + && find_attr!(cx.tcx.get_all_attrs(owner_did), AttributeKind::RustcLintDiagnostics) { // The parent method is marked with `#[rustc_lint_diagnostics]` return; diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 7ebfca91d499d..c0106ea0c6276 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -484,13 +484,6 @@ passes_sanitize_attribute_not_allowed = .no_body = function has no body .help = sanitize attribute can be applied to a function (with body), impl block, or module -passes_should_be_applied_to_fn = - attribute should be applied to a function definition - .label = {$on_crate -> - [true] cannot be applied to crates - *[false] not a function definition - } - passes_should_be_applied_to_static = attribute should be applied to a static .label = not a static diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 33a3477bcf691..945dcec798e3a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -258,9 +258,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) + | AttributeKind::RustcLintDiagnostics | AttributeKind::RustcLintOptDenyFieldAccess { .. } | AttributeKind::RustcLintOptTy | AttributeKind::RustcLintQueryInstability + | AttributeKind::RustcLintUntrackedQueryInformation | AttributeKind::RustcNeverReturnsNullPointer | AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) @@ -309,12 +311,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::rustc_lint_untracked_query_information, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) - } - [sym::rustc_lint_diagnostics, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) - } [sym::rustc_clean, ..] | [sym::rustc_dirty, ..] | [sym::rustc_if_this_changed, ..] @@ -1230,25 +1226,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Helper function for checking that the provided attribute is only applied to a function or - /// method. - fn check_applied_to_fn_or_method( - &self, - hir_id: HirId, - attr_span: Span, - defn_span: Span, - target: Target, - ) { - let is_function = matches!(target, Target::Fn | Target::Method(..)); - if !is_function { - self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { - attr_span, - defn_span, - on_crate: hir_id == CRATE_HIR_ID, - }); - } - } - /// Checks that the dep-graph debugging attributes are only present when the query-dep-graph /// option is passed to the compiler. fn check_rustc_dirty_clean(&self, attr: &Attribute) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 895cefe672baa..4f97f74c78047 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -80,16 +80,6 @@ pub(crate) struct OuterCrateLevelAttrSuggestion { #[diag(passes_inner_crate_level_attr)] pub(crate) struct InnerCrateLevelAttr; -#[derive(Diagnostic)] -#[diag(passes_should_be_applied_to_fn)] -pub(crate) struct AttrShouldBeAppliedToFn { - #[primary_span] - pub attr_span: Span, - #[label] - pub defn_span: Span, - pub on_crate: bool, -} - #[derive(Diagnostic)] #[diag(passes_non_exhaustive_with_default_field_values)] pub(crate) struct NonExhaustiveWithDefaultFieldValues { diff --git a/tests/ui/internal-lints/diagnostics_incorrect.rs b/tests/ui/internal-lints/diagnostics_incorrect.rs index c1532aa9d57e5..787acdad38842 100644 --- a/tests/ui/internal-lints/diagnostics_incorrect.rs +++ b/tests/ui/internal-lints/diagnostics_incorrect.rs @@ -3,7 +3,7 @@ #![feature(rustc_attrs)] #[rustc_lint_diagnostics] -//~^ ERROR attribute should be applied to a function +//~^ ERROR `#[rustc_lint_diagnostics]` attribute cannot be used on structs struct Foo; impl Foo { diff --git a/tests/ui/internal-lints/diagnostics_incorrect.stderr b/tests/ui/internal-lints/diagnostics_incorrect.stderr index e849ca2829e43..4d509acec7900 100644 --- a/tests/ui/internal-lints/diagnostics_incorrect.stderr +++ b/tests/ui/internal-lints/diagnostics_incorrect.stderr @@ -1,17 +1,20 @@ -error: malformed `rustc_lint_diagnostics` attribute input - --> $DIR/diagnostics_incorrect.rs:10:5 - | -LL | #[rustc_lint_diagnostics(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_diagnostics]` - -error: attribute should be applied to a function definition +error: `#[rustc_lint_diagnostics]` attribute cannot be used on structs --> $DIR/diagnostics_incorrect.rs:5:1 | LL | #[rustc_lint_diagnostics] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | struct Foo; - | ----------- not a function definition + | + = help: `#[rustc_lint_diagnostics]` can only be applied to functions + +error[E0565]: malformed `rustc_lint_diagnostics` attribute input + --> $DIR/diagnostics_incorrect.rs:10:5 + | +LL | #[rustc_lint_diagnostics(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[rustc_lint_diagnostics]` error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0565`.