about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonathan Brouwer <jonathantbrouwer@gmail.com>2025-08-09 20:40:47 +0200
committerJonathan Brouwer <jonathantbrouwer@gmail.com>2025-08-14 18:18:42 +0200
commit5245c399720cf4f2414c2a4d9b4a5007ad942956 (patch)
treed8b6e6028519343324206b6308fb5fd5c691c1cd
parent35e04b67a6eeb1603d67f4220b05da9c1b77eed7 (diff)
downloadrust-5245c399720cf4f2414c2a4d9b4a5007ad942956.tar.gz
rust-5245c399720cf4f2414c2a4d9b4a5007ad942956.zip
Remove the old target checking logic
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl2
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs7
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0518.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0701.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0739.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0755.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0756.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0788.md4
-rw-r--r--compiler/rustc_hir/src/hir.rs14
-rw-r--r--compiler/rustc_passes/messages.ftl152
-rw-r--r--compiler/rustc_passes/src/check_attr.rs943
-rw-r--r--compiler/rustc_passes/src/errors.rs298
13 files changed, 138 insertions, 1310 deletions
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index ae186d744c4..eb3c40cc593 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -259,8 +259,6 @@ builtin_macros_only_one_argument = {$name} takes 1 argument
 
 builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
 
-builtin_macros_proc_macro_attribute_only_be_used_on_bare_functions = the `#[{$path}]` attribute may only be used on bare functions
-
 builtin_macros_proc_macro_attribute_only_usable_with_crate_type = the `#[{$path}]` attribute is only usable with crates of the `proc-macro` crate type
 
 builtin_macros_requires_cfg_pattern =
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index 6bcf4d3e0a2..bb520db75b9 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -906,14 +906,6 @@ pub(crate) struct TakesNoArguments<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(builtin_macros_proc_macro_attribute_only_be_used_on_bare_functions)]
-pub(crate) struct AttributeOnlyBeUsedOnBareFunctions<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub path: &'a str,
-}
-
-#[derive(Diagnostic)]
 #[diag(builtin_macros_proc_macro_attribute_only_usable_with_crate_type)]
 pub(crate) struct AttributeOnlyUsableWithCrateType<'a> {
     #[primary_span]
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index f440adf6cf0..6ac3e17503d 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -231,12 +231,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         let fn_ident = if let ast::ItemKind::Fn(fn_) = &item.kind {
             fn_.ident
         } else {
-            self.dcx
-                .create_err(errors::AttributeOnlyBeUsedOnBareFunctions {
-                    span: attr.span,
-                    path: &pprust::path_to_string(&attr.get_normal_item().path),
-                })
-                .emit();
+            // Error handled by general target checking logic
             return;
         };
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0518.md b/compiler/rustc_error_codes/src/error_codes/E0518.md
index f04329bc4e6..87dc231578a 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0518.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0518.md
@@ -1,9 +1,11 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 An `#[inline(..)]` attribute was incorrectly placed on something other than a
 function or method.
 
 Example of erroneous code:
 
-```compile_fail,E0518
+```ignore (no longer emitted)
 #[inline(always)]
 struct Foo;
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0701.md b/compiler/rustc_error_codes/src/error_codes/E0701.md
index 4965e643105..e1be0e915f4 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0701.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0701.md
@@ -1,9 +1,11 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 This error indicates that a `#[non_exhaustive]` attribute was incorrectly placed
 on something other than a struct or enum.
 
 Erroneous code example:
 
-```compile_fail,E0701
+```ignore (no longer emitted)
 #[non_exhaustive]
 trait Foo { }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0739.md b/compiler/rustc_error_codes/src/error_codes/E0739.md
index 406d3d52779..5403405ca9d 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0739.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0739.md
@@ -1,8 +1,10 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 `#[track_caller]` must  be applied to a function
 
 Erroneous code example:
 
-```compile_fail,E0739
+```ignore (no longer emitted)
 #[track_caller]
 struct Bar {
     a: u8,
diff --git a/compiler/rustc_error_codes/src/error_codes/E0755.md b/compiler/rustc_error_codes/src/error_codes/E0755.md
index b67f078c78e..bd93626a8db 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0755.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0755.md
@@ -1,8 +1,10 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 The `ffi_pure` attribute was used on a non-foreign function.
 
 Erroneous code example:
 
-```compile_fail,E0755
+```ignore (no longer emitted)
 #![feature(ffi_pure)]
 
 #[unsafe(ffi_pure)] // error!
diff --git a/compiler/rustc_error_codes/src/error_codes/E0756.md b/compiler/rustc_error_codes/src/error_codes/E0756.md
index aadde038d12..daafc2a5ac0 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0756.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0756.md
@@ -1,9 +1,11 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 The `ffi_const` attribute was used on something other than a foreign function
 declaration.
 
 Erroneous code example:
 
-```compile_fail,E0756
+```ignore (no longer emitted)
 #![feature(ffi_const)]
 
 #[unsafe(ffi_const)] // error!
diff --git a/compiler/rustc_error_codes/src/error_codes/E0788.md b/compiler/rustc_error_codes/src/error_codes/E0788.md
index ba138aed2d1..1afa961f9b7 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0788.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0788.md
@@ -1,3 +1,5 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 A `#[coverage(off|on)]` attribute was found in a position where it is not
 allowed.
 
@@ -10,7 +12,7 @@ Coverage attributes can be applied to:
 
 Example of erroneous code:
 
-```compile_fail,E0788
+```ignore (no longer emitted)
 unsafe extern "C" {
     #[coverage(off)]
     fn foreign_fn();
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 0cc03ef7b5b..2c8986b7c7d 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1232,6 +1232,13 @@ impl Attribute {
             _ => None,
         }
     }
+
+    pub fn is_parsed_attr(&self) -> bool {
+        match self {
+            Attribute::Parsed(_) => true,
+            Attribute::Unparsed(_) => false,
+        }
+    }
 }
 
 impl AttributeExt for Attribute {
@@ -1302,13 +1309,8 @@ impl AttributeExt for Attribute {
         match &self {
             Attribute::Unparsed(u) => u.span,
             // FIXME: should not be needed anymore when all attrs are parsed
-            Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
             Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
-            Attribute::Parsed(AttributeKind::MacroUse { span, .. }) => *span,
-            Attribute::Parsed(AttributeKind::MayDangle(span)) => *span,
-            Attribute::Parsed(AttributeKind::Ignore { span, .. }) => *span,
-            Attribute::Parsed(AttributeKind::ShouldPanic { span, .. }) => *span,
-            Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) => *span,
+            Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
             Attribute::Parsed(AttributeKind::AllowInternalUnsafe(span)) => *span,
             Attribute::Parsed(AttributeKind::Linkage(_, span)) => *span,
             a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index eb03235de0c..7481b0ea960 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -13,22 +13,6 @@ passes_abi_ne =
 passes_abi_of =
     fn_abi_of({$fn_name}) = {$fn_abi}
 
-passes_align_attr_application =
-    `#[rustc_align(...)]` should be applied to a function item
-    .label = not a function item
-
-passes_align_on_fields =
-    attribute should be applied to a function or method
-    .warn = {-passes_previously_accepted}
-
-passes_align_should_be_repr_align =
-    `#[rustc_align(...)]` is not supported on {$item} items
-    .suggestion = use `#[repr(align(...))]` instead
-
-passes_allow_incoherent_impl =
-    `rustc_allow_incoherent_impl` attribute should be applied to impl items
-    .label = the only currently supported targets are inherent methods
-
 passes_macro_only_attribute =
     attribute should be applied to a macro
     .label = not a macro
@@ -78,18 +62,10 @@ passes_change_fields_to_be_of_unit_type =
      *[other] fields
     }
 
-passes_cold =
-    {passes_should_be_applied_to_fn}
-    .warn = {-passes_previously_accepted}
-    .label = {passes_should_be_applied_to_fn.label}
-
 passes_collapse_debuginfo =
     `collapse_debuginfo` attribute should be applied to macro definitions
     .label = not a macro definition
 
-passes_confusables = attribute should be applied to an inherent method
-    .label = not an inherent method
-
 passes_const_continue_attr =
     `#[const_continue]` should be applied to a break expression
     .label = not a break expression
@@ -98,16 +74,6 @@ passes_const_stable_not_stable =
     attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]`
     .label = attribute specified here
 
-passes_coroutine_on_non_closure =
-    attribute should be applied to closures
-    .label = not a closure
-
-passes_coverage_attribute_not_allowed =
-    coverage attribute not allowed here
-    .not_fn_impl_mod = not a function, impl block, or module
-    .no_body = function has no body
-    .help = coverage attribute can be applied to a function (with body), impl block, or module
-
 passes_dead_codes =
     { $multiple ->
       *[true] multiple {$descr}s are
@@ -129,9 +95,6 @@ passes_debug_visualizer_placement =
 passes_debug_visualizer_unreadable =
     couldn't read {$file}: {$error}
 
-passes_deprecated =
-    attribute is ignored here
-
 passes_deprecated_annotation_has_no_effect =
     this `#[deprecated]` annotation has no effect
     .suggestion = remove the unnecessary deprecation attribute
@@ -304,10 +267,6 @@ passes_duplicate_lang_item_crate_depends =
 passes_enum_variant_same_name =
     it is impossible to refer to the {$dead_descr} `{$dead_name}` because it is shadowed by this enum variant with the same name
 
-passes_export_name =
-    attribute should be applied to a free function, impl method or static
-    .label = not a free function, impl method or static
-
 passes_extern_main =
     the `main` function cannot be declared in an `extern` block
 
@@ -317,21 +276,10 @@ passes_feature_previously_declared =
 passes_feature_stable_twice =
     feature `{$feature}` is declared stable since {$since}, but was previously declared stable since {$prev_since}
 
-passes_ffi_const_invalid_target =
-    `#[ffi_const]` may only be used on foreign functions
-
-passes_ffi_pure_invalid_target =
-    `#[ffi_pure]` may only be used on foreign functions
-
 passes_has_incoherent_inherent_impl =
     `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits
     .label = only adts, extern types and traits are supported
 
-passes_ignored_attr =
-    `#[{$sym}]` is ignored on struct fields and match arms
-    .warn = {-passes_previously_accepted}
-    .note = {-passes_see_issue(issue: "80564")}
-
 passes_ignored_attr_with_macro =
     `#[{$sym}]` is ignored on struct fields, match arms and macro defs
     .warn = {-passes_previously_accepted}
@@ -373,22 +321,10 @@ passes_incorrect_target =
 passes_ineffective_unstable_impl = an `#[unstable]` annotation here has no effect
     .note = see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information
 
-passes_inline_ignored_constants =
-    `#[inline]` is ignored on constants
-    .warn = {-passes_previously_accepted}
-    .note = {-passes_see_issue(issue: "65833")}
-
 passes_inline_ignored_for_exported =
     `#[inline]` is ignored on externally exported functions
     .help = externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`
 
-passes_inline_ignored_function_prototype =
-    `#[inline]` is ignored on function prototypes
-
-passes_inline_not_fn_or_closure =
-    attribute should be applied to function or closure
-    .label = not a function or closure
-
 passes_inner_crate_level_attr =
     crate-level attribute should be in the root module
 
@@ -438,25 +374,6 @@ passes_link =
     .warn = {-passes_previously_accepted}
     .label = not an `extern` block
 
-passes_link_name =
-    attribute should be applied to a foreign function or static
-    .warn = {-passes_previously_accepted}
-    .label = not a foreign function or static
-    .help = try `#[link(name = "{$value}")]` instead
-
-passes_link_ordinal =
-    attribute should be applied to a foreign function or static
-    .label = not a foreign function or static
-
-passes_link_section =
-    attribute should be applied to a function or static
-    .warn = {-passes_previously_accepted}
-    .label = not a function or static
-
-passes_linkage =
-    attribute should be applied to a function or static
-    .label = not a function definition or static
-
 passes_loop_match_attr =
     `#[loop_match]` should be applied to a loop
     .label = not a loop
@@ -468,9 +385,6 @@ passes_macro_export_on_decl_macro =
     `#[macro_export]` has no effect on declarative macro definitions
     .note = declarative macros follow the same exporting rules as regular items
 
-passes_macro_use =
-    `#[{$name}]` only has an effect on `extern crate` and modules
-
 passes_may_dangle =
     `#[may_dangle]` must be applied to a lifetime or type generic parameter in `Drop` impl
 
@@ -509,7 +423,7 @@ passes_must_not_suspend =
     .label = is not a struct, enum, union, or trait
 
 passes_must_use_no_effect =
-    `#[must_use]` has no effect when applied to {$article} {$target}
+    `#[must_use]` has no effect when applied to {$target}
     .suggestion = remove the attribute
 
 passes_no_link =
@@ -530,18 +444,6 @@ passes_no_main_function =
     .teach_note = If you don't know the basics of Rust, you can go look to the Rust Book to get started: https://doc.rust-lang.org/book/
     .non_function_main = non-function item at `crate::main` is found
 
-passes_no_mangle =
-    attribute should be applied to a free function, impl method or static
-    .warn = {-passes_previously_accepted}
-    .label = not a free function, impl method or static
-
-passes_no_mangle_foreign =
-    `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
-    .warn = {-passes_previously_accepted}
-    .label = foreign {$foreign_item_kind}
-    .note = symbol names in extern blocks are not mangled
-    .suggestion = remove this attribute
-
 passes_no_sanitize =
     `#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind}
     .label = not {$accepted_kind}
@@ -557,19 +459,6 @@ passes_non_exported_macro_invalid_attrs =
 passes_object_lifetime_err =
     {$repr}
 
-passes_only_has_effect_on =
-    `#[{$attr_name}]` only has an effect on {$target_name ->
-        [function] functions
-        [module] modules
-        [trait_implementation_block] trait implementation blocks
-        [inherent_implementation_block] inherent implementation blocks
-        *[unspecified] (unspecified--this is a compiler bug)
-    }
-
-passes_optimize_invalid_target =
-    attribute applied to an invalid target
-    .label = invalid target
-
 passes_outer_crate_level_attr =
     crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
 
@@ -585,10 +474,6 @@ passes_parent_info =
      *[other] {$descr}s
     } in this {$parent_descr}
 
-passes_pass_by_value =
-    `pass_by_value` attribute should be applied to a struct, enum or type alias
-    .label = is not a struct, enum or type alias
-
 passes_proc_macro_bad_sig = {$kind} has incorrect signature
 
 passes_remove_fields =
@@ -605,7 +490,7 @@ passes_repr_align_greater_than_target_max =
     .note = `isize::MAX` is {$size} for the current target
 
 passes_repr_align_should_be_align =
-    `#[repr(align(...))]` is not supported on {$item} items
+    `#[repr(align(...))]` is not supported on {$item}
     .help = use `#[rustc_align(...)]` instead
 
 passes_repr_conflicting =
@@ -620,18 +505,10 @@ passes_rustc_const_stable_indirect_pairing =
 passes_rustc_dirty_clean =
     attribute requires -Z query-dep-graph to be enabled
 
-passes_rustc_force_inline =
-    attribute should be applied to a function
-    .label = not a function definition
-
 passes_rustc_force_inline_coro =
     attribute cannot be applied to a `async`, `gen` or `async gen` function
     .label = `async`, `gen` or `async gen` function
 
-passes_rustc_layout_scalar_valid_range_not_struct =
-    attribute should be applied to a struct
-    .label = not a struct
-
 passes_rustc_legacy_const_generics_index =
     #[rustc_legacy_const_generics] must have one index for each generic parameter
     .label = generic parameters
@@ -665,14 +542,6 @@ passes_rustc_pub_transparent =
     attribute should be applied to `#[repr(transparent)]` types
     .label = not a `#[repr(transparent)]` type
 
-passes_rustc_std_internal_symbol =
-    attribute should be applied to functions or statics
-    .label = not a function or static
-
-passes_rustc_unstable_feature_bound =
-    attribute should be applied to `impl`, trait or free function
-    .label = not an `impl`, trait or free function
-
 passes_should_be_applied_to_fn =
     attribute should be applied to a function definition
     .label = {$on_crate ->
@@ -684,24 +553,12 @@ passes_should_be_applied_to_static =
     attribute should be applied to a static
     .label = not a static
 
-passes_should_be_applied_to_struct_enum =
-    attribute should be applied to a struct or enum
-    .label = not a struct or enum
-
 passes_should_be_applied_to_trait =
     attribute should be applied to a trait
     .label = not a trait
 
-passes_stability_promotable =
-    attribute cannot be applied to an expression
-
 passes_string_interpolation_only_works = string interpolation only works in `format!` invocations
 
-passes_target_feature_on_statement =
-    {passes_should_be_applied_to_fn}
-    .warn = {-passes_previously_accepted}
-    .label = {passes_should_be_applied_to_fn.label}
-
 passes_trait_impl_const_stability_mismatch = const stability on the impl does not match the const stability on the trait
 passes_trait_impl_const_stability_mismatch_impl_stable = this impl is (implicitly) stable...
 passes_trait_impl_const_stability_mismatch_impl_unstable = this impl is unstable...
@@ -826,11 +683,6 @@ passes_unused_variable_try_prefix = unused variable: `{$name}`
     .label = unused variable
     .suggestion = if this is intentional, prefix it with an underscore
 
-
-passes_used_static =
-    attribute must be applied to a `static` variable
-    .label = but this is a {$target}
-
 passes_useless_assignment =
     useless assignment of {$is_field_assign ->
         [true] field
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index df1db65c06e..0e28c51e981 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -10,7 +10,7 @@ use std::collections::hash_map::Entry;
 use std::slice;
 
 use rustc_abi::{Align, ExternAbi, Size};
-use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, ast, join_path_syms};
+use rustc_ast::{AttrStyle, LitKind, MetaItemInner, MetaItemKind, ast};
 use rustc_attr_parsing::{AttributeParser, Late};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey};
@@ -40,7 +40,6 @@ use rustc_session::lint;
 use rustc_session::lint::builtin::{
     CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
     MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
-    USELESS_DEPRECATED,
 };
 use rustc_session::parse::feature_err;
 use rustc_span::edition::Edition;
@@ -50,7 +49,6 @@ use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
 use rustc_trait_selection::traits::ObligationCtxt;
 use tracing::debug;
 
-use crate::errors::AlignOnFields;
 use crate::{errors, fluent_generated as fluent};
 
 #[derive(LintDiagnostic)]
@@ -134,56 +132,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 Attribute::Parsed(AttributeKind::ProcMacroAttribute(_)) => {
                     self.check_proc_macro(hir_id, target, ProcMacroKind::Attribute);
                 }
-                Attribute::Parsed(AttributeKind::ProcMacroDerive { span: attr_span, .. }) => {
-                    self.check_generic_attr(
-                        hir_id,
-                        sym::proc_macro_derive,
-                        *attr_span,
-                        target,
-                        Target::Fn,
-                    );
+                Attribute::Parsed(AttributeKind::ProcMacroDerive { .. }) => {
                     self.check_proc_macro(hir_id, target, ProcMacroKind::Derive)
                 }
-                Attribute::Parsed(
-                    AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. }
-                    | AttributeKind::Coinductive(attr_span)
-                    | AttributeKind::ConstTrait(attr_span)
-                    | AttributeKind::DenyExplicitImpl(attr_span)
-                    | AttributeKind::DoNotImplementViaObject(attr_span),
-                ) => {
-                    self.check_must_be_applied_to_trait(*attr_span, span, target);
-                }
-                &Attribute::Parsed(
-                    AttributeKind::SpecializationTrait(attr_span)
-                    | AttributeKind::UnsafeSpecializationMarker(attr_span)
-                    | AttributeKind::ParenSugar(attr_span),
-                ) => {
-                    // FIXME: more validation is needed
-                    self.check_must_be_applied_to_trait(attr_span, span, target);
-                }
                 &Attribute::Parsed(AttributeKind::TypeConst(attr_span)) => {
                     self.check_type_const(hir_id, attr_span, target)
                 }
-                &Attribute::Parsed(AttributeKind::Marker(attr_span)) => {
-                    self.check_marker(hir_id, attr_span, span, target)
-                }
-                Attribute::Parsed(AttributeKind::Fundamental | AttributeKind::CoherenceIsCore) => {
-                    // FIXME: add validation
-                }
-                &Attribute::Parsed(AttributeKind::AllowIncoherentImpl(attr_span)) => {
-                    self.check_allow_incoherent_impl(attr_span, span, target)
-                }
-                Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => {
-                    self.check_confusables(*first_span, target);
-                }
-                Attribute::Parsed(AttributeKind::AutomaticallyDerived(attr_span)) => self
-                    .check_generic_attr(
-                        hir_id,
-                        sym::automatically_derived,
-                        *attr_span,
-                        target,
-                        Target::Impl { of_trait: true },
-                    ),
                 Attribute::Parsed(
                     AttributeKind::Stability {
                         span: attr_span,
@@ -193,13 +147,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         span: attr_span,
                         stability: PartialConstStability { level, feature, .. },
                     },
-                ) => self.check_stability(*attr_span, span, level, *feature, target),
+                ) => self.check_stability(*attr_span, span, level, *feature),
                 Attribute::Parsed(AttributeKind::Inline(InlineAttr::Force { .. }, ..)) => {} // handled separately below
                 Attribute::Parsed(AttributeKind::Inline(kind, attr_span)) => {
-                    self.check_inline(hir_id, *attr_span, span, kind, target)
-                }
-                Attribute::Parsed(AttributeKind::Optimize(_, attr_span)) => {
-                    self.check_optimize(hir_id, *attr_span, span, target)
+                    self.check_inline(hir_id, *attr_span, kind, target)
                 }
                 Attribute::Parsed(AttributeKind::LoopMatch(attr_span)) => {
                     self.check_loop_match(hir_id, *attr_span, target)
@@ -207,11 +158,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 Attribute::Parsed(AttributeKind::ConstContinue(attr_span)) => {
                     self.check_const_continue(hir_id, *attr_span, target)
                 }
-                Attribute::Parsed(AttributeKind::AllowInternalUnsafe(attr_span)) => {
-                    self.check_allow_internal_unsafe(hir_id, *attr_span, span, target, attrs)
-                }
-                Attribute::Parsed(AttributeKind::AllowInternalUnstable(_, first_span)) => {
-                    self.check_allow_internal_unstable(hir_id, *first_span, span, target, attrs)
+                Attribute::Parsed(AttributeKind::AllowInternalUnsafe(attr_span) | AttributeKind::AllowInternalUnstable(.., attr_span)) => {
+                    self.check_macro_only_attr(*attr_span, span, target, attrs)
                 }
                 Attribute::Parsed(AttributeKind::AllowConstFnUnstable(_, first_span)) => {
                     self.check_rustc_allow_const_fn_unstable(hir_id, *first_span, span, target)
@@ -220,11 +168,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     self.check_deprecated(hir_id, attr, span, target)
                 }
                 Attribute::Parsed(AttributeKind::TargetFeature(_, attr_span)) => {
-                    self.check_target_feature(hir_id, *attr_span, span, target, attrs)
-                }
-                Attribute::Parsed(AttributeKind::DocComment { .. }) => { /* `#[doc]` is actually a lot more than just doc comments, so is checked below*/
-                }
-                Attribute::Parsed(AttributeKind::Repr { .. }) => { /* handled below this loop and elsewhere */
+                    self.check_target_feature(hir_id, *attr_span, target, attrs)
                 }
                 Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault) => {
                     self.check_object_lifetime_default(hir_id);
@@ -232,59 +176,26 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 &Attribute::Parsed(AttributeKind::PubTransparent(attr_span)) => {
                     self.check_rustc_pub_transparent(attr_span, span, attrs)
                 }
-                Attribute::Parsed(AttributeKind::Cold(attr_span)) => {
-                    self.check_cold(hir_id, *attr_span, span, target)
-                }
-                Attribute::Parsed(AttributeKind::ExportName { span: attr_span, .. }) => {
-                    self.check_export_name(hir_id, *attr_span, span, target)
-                }
                 Attribute::Parsed(AttributeKind::Align { align, span: attr_span }) => {
-                    self.check_align(span, hir_id, target, *align, *attr_span)
-                }
-                Attribute::Parsed(AttributeKind::LinkSection { span: attr_span, .. }) => {
-                    self.check_link_section(hir_id, *attr_span, span, target)
-                }
-                Attribute::Parsed(AttributeKind::MacroUse { span, .. }) => {
-                    self.check_macro_use(hir_id, sym::macro_use, *span, target)
+                    self.check_align(*align, *attr_span)
                 }
-                Attribute::Parsed(AttributeKind::MacroEscape(span)) => {
-                    self.check_macro_use(hir_id, sym::macro_escape, *span, target)
-                }
-                Attribute::Parsed(AttributeKind::Naked(attr_span)) => {
-                    self.check_naked(hir_id, *attr_span, span, target)
-                }
-                Attribute::Parsed(AttributeKind::NoImplicitPrelude(attr_span)) => self
-                    .check_generic_attr(
-                        hir_id,
-                        sym::no_implicit_prelude,
-                        *attr_span,
-                        target,
-                        Target::Mod,
-                    ),
-                Attribute::Parsed(AttributeKind::Path(_, attr_span)) => {
-                    self.check_generic_attr(hir_id, sym::path, *attr_span, target, Target::Mod)
+                Attribute::Parsed(AttributeKind::Naked(..)) => {
+                    self.check_naked(hir_id, target)
                 }
                 Attribute::Parsed(AttributeKind::TrackCaller(attr_span)) => {
-                    self.check_track_caller(hir_id, *attr_span, attrs, span, target)
+                    self.check_track_caller(hir_id, *attr_span, attrs, target)
                 }
                 Attribute::Parsed(AttributeKind::NonExhaustive(attr_span)) => {
-                    self.check_non_exhaustive(hir_id, *attr_span, span, target, item)
-                }
-                Attribute::Parsed(
-                    AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span)
-                    | AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span),
-                ) => self.check_rustc_layout_scalar_valid_range(*attr_span, span, target),
-                Attribute::Parsed(AttributeKind::ExportStable) => {
-                    // handled in `check_export`
-                }
-                &Attribute::Parsed(AttributeKind::FfiConst(attr_span)) => {
-                    self.check_ffi_const(attr_span, target)
+                    self.check_non_exhaustive(*attr_span, span, target, item)
                 }
                 &Attribute::Parsed(AttributeKind::FfiPure(attr_span)) => {
-                    self.check_ffi_pure(attr_span, attrs, target)
+                    self.check_ffi_pure(attr_span, attrs)
                 }
-                Attribute::Parsed(AttributeKind::UnstableFeatureBound(syms)) => {
-                    self.check_unstable_feature_bound(syms.first().unwrap().1, span, target)
+                Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
+                    self.check_may_dangle(hir_id, *attr_span)
+                }
+                Attribute::Parsed(AttributeKind::MustUse { span, .. }) => {
+                    self.check_must_use(hir_id, *span, target)
                 }
                 Attribute::Parsed(
                     AttributeKind::BodyStability { .. }
@@ -292,49 +203,52 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     | AttributeKind::MacroTransparency(_)
                     | AttributeKind::Pointee(..)
                     | AttributeKind::Dummy
-                    | AttributeKind::RustcBuiltinMacro { .. },
+                    | AttributeKind::RustcBuiltinMacro { .. }
+                    | AttributeKind::Ignore { .. }
+                    | AttributeKind::Path(..)
+                    | AttributeKind::NoImplicitPrelude(..)
+                    | AttributeKind::AutomaticallyDerived(..)
+                    | AttributeKind::Marker(..)
+                    | AttributeKind::SkipDuringMethodDispatch { .. }
+                    | AttributeKind::Coinductive(..)
+                    | AttributeKind::ConstTrait(..)
+                    | AttributeKind::DenyExplicitImpl(..)
+                    | AttributeKind::DoNotImplementViaObject(..)
+                    | AttributeKind::SpecializationTrait(..)
+                    | AttributeKind::UnsafeSpecializationMarker(..)
+                    | AttributeKind::ParenSugar(..)
+                    | AttributeKind::AllowIncoherentImpl(..)
+                    | AttributeKind::Confusables { .. }
+                    // `#[doc]` is actually a lot more than just doc comments, so is checked below
+                    | AttributeKind::DocComment {..}
+                    // handled below this loop and elsewhere
+                    | AttributeKind::Repr { .. }
+                    | AttributeKind::Cold(..)
+                    | AttributeKind::ExportName { .. }
+                    | AttributeKind::CoherenceIsCore
+                    | AttributeKind::Fundamental
+                    | AttributeKind::Optimize(..)
+                    | AttributeKind::LinkSection { .. }
+                    | AttributeKind::MacroUse { .. }
+                    | AttributeKind::MacroEscape( .. )
+                    | AttributeKind::RustcLayoutScalarValidRangeStart(..)
+                    | AttributeKind::RustcLayoutScalarValidRangeEnd(..)
+                    | AttributeKind::ExportStable
+                    | AttributeKind::FfiConst(..)
+                    | AttributeKind::UnstableFeatureBound(..)
+                    | AttributeKind::AsPtr(..)
+                    | AttributeKind::LinkName { .. }
+                    | AttributeKind::LinkOrdinal { .. }
+                    | AttributeKind::NoMangle(..)
+                    | AttributeKind::Used { .. }
+                    | AttributeKind::PassByValue (..)
+                    | AttributeKind::StdInternalSymbol (..)
+                    | AttributeKind::Coverage (..)
+                    | AttributeKind::ShouldPanic { .. }
+                    | AttributeKind::Coroutine(..)
+                    | AttributeKind::Linkage(..),
                 ) => { /* do nothing  */ }
-                Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
-                    self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
-                }
-                Attribute::Parsed(AttributeKind::LinkName { span: attr_span, name }) => {
-                    self.check_link_name(hir_id, *attr_span, *name, span, target)
-                }
-                Attribute::Parsed(AttributeKind::LinkOrdinal { span: attr_span, .. }) => {
-                    self.check_link_ordinal(*attr_span, span, target)
-                }
-                Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
-                    self.check_may_dangle(hir_id, *attr_span)
-                }
-                Attribute::Parsed(AttributeKind::Ignore { span, .. }) => {
-                    self.check_generic_attr(hir_id, sym::ignore, *span, target, Target::Fn)
-                }
-                Attribute::Parsed(AttributeKind::MustUse { span, .. }) => {
-                    self.check_must_use(hir_id, *span, target)
-                }
-                Attribute::Parsed(AttributeKind::NoMangle(attr_span)) => {
-                    self.check_no_mangle(hir_id, *attr_span, span, target)
-                }
-                Attribute::Parsed(AttributeKind::Used { span: attr_span, .. }) => {
-                    self.check_used(*attr_span, target, span);
-                }
-                Attribute::Parsed(AttributeKind::ShouldPanic { span: attr_span, .. }) => self
-                    .check_generic_attr(hir_id, sym::should_panic, *attr_span, target, Target::Fn),
-                &Attribute::Parsed(AttributeKind::PassByValue(attr_span)) => {
-                    self.check_pass_by_value(attr_span, span, target)
-                }
-                &Attribute::Parsed(AttributeKind::StdInternalSymbol(attr_span)) => {
-                    self.check_rustc_std_internal_symbol(attr_span, span, target)
-                }
-                &Attribute::Parsed(AttributeKind::Coverage(attr_span, _)) => {
-                    self.check_coverage(attr_span, span, target)
-                }
-                &Attribute::Parsed(AttributeKind::Coroutine(attr_span)) => {
-                    self.check_coroutine(attr_span, target)
-                }
-                &Attribute::Parsed(AttributeKind::Linkage(_, attr_span)) => {
-                    self.check_linkage(attr_span, span, target);
-                }
+
                 Attribute::Unparsed(attr_item) => {
                     style = Some(attr_item.style);
                     match attr.path().as_slice() {
@@ -390,10 +304,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         [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::link, ..] => self.check_link(hir_id, attr, span, target),
-                        [sym::path, ..] => self.check_generic_attr_unparsed(hir_id, attr, target, Target::Mod),
                         [sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target),
                         [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => {
                             self.check_autodiff(hir_id, attr, span, target)
@@ -485,7 +396,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
 
         self.check_repr(attrs, span, target, item, hir_id);
-        self.check_rustc_force_inline(hir_id, attrs, span, target);
+        self.check_rustc_force_inline(hir_id, attrs, target);
         self.check_mix_no_mangle_export(hir_id, attrs);
     }
 
@@ -498,15 +409,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         );
     }
 
-    fn inline_attr_str_error_without_macro_def(&self, hir_id: HirId, attr_span: Span, sym: &str) {
-        self.tcx.emit_node_span_lint(
-            UNUSED_ATTRIBUTES,
-            hir_id,
-            attr_span,
-            errors::IgnoredAttr { sym },
-        );
-    }
-
     /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl and that it has no
     /// arguments.
     fn check_do_not_recommend(
@@ -554,14 +456,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     }
 
     /// Checks if an `#[inline]` is applied to a function or a closure.
-    fn check_inline(
-        &self,
-        hir_id: HirId,
-        attr_span: Span,
-        defn_span: Span,
-        kind: &InlineAttr,
-        target: Target,
-    ) {
+    fn check_inline(&self, hir_id: HirId, attr_span: Span, kind: &InlineAttr, target: Target) {
         match target {
             Target::Fn
             | Target::Closure
@@ -583,81 +478,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     }
                 }
             }
-            Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    errors::IgnoredInlineAttrFnProto,
-                )
-            }
-            // FIXME(#65833): We permit associated consts to have an `#[inline]` attribute with
-            // just a lint, because we previously erroneously allowed it and some crates used it
-            // accidentally, to be compatible with crates depending on them, we can't throw an
-            // error here.
-            Target::AssocConst => self.tcx.emit_node_span_lint(
-                UNUSED_ATTRIBUTES,
-                hir_id,
-                attr_span,
-                errors::IgnoredInlineAttrConstants,
-            ),
-            // FIXME(#80564): Same for fields, arms, and macro defs
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "inline")
-            }
-            _ => {
-                self.dcx().emit_err(errors::InlineNotFnOrClosure { attr_span, defn_span });
-            }
-        }
-    }
-
-    /// Checks that `#[coverage(..)]` is applied to a function/closure/method,
-    /// or to an impl block or module.
-    fn check_coverage(&self, attr_span: Span, target_span: Span, target: Target) {
-        let mut not_fn_impl_mod = None;
-        let mut no_body = None;
-
-        match target {
-            Target::Fn
-            | Target::Closure
-            | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
-            | Target::Impl { .. }
-            | Target::Mod => return,
-
-            // These are "functions", but they aren't allowed because they don't
-            // have a body, so the usual explanation would be confusing.
-            Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
-                no_body = Some(target_span);
-            }
-
-            _ => {
-                not_fn_impl_mod = Some(target_span);
-            }
-        }
-
-        self.dcx().emit_err(errors::CoverageAttributeNotAllowed {
-            attr_span,
-            not_fn_impl_mod,
-            no_body,
-            help: (),
-        });
-    }
-
-    /// Checks that `#[optimize(..)]` is applied to a function/closure/method,
-    /// or to an impl block or module.
-    fn check_optimize(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
-        let is_valid = matches!(
-            target,
-            Target::Fn
-                | Target::Closure
-                | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
-        );
-        if !is_valid {
-            self.dcx().emit_err(errors::OptimizeInvalidTarget {
-                attr_span,
-                defn_span: span,
-                on_crate: hir_id == CRATE_HIR_ID,
-            });
+            _ => {}
         }
     }
 
@@ -697,51 +518,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    /// FIXME: Remove when all attributes are ported to the new parser
-    fn check_generic_attr_unparsed(
-        &self,
-        hir_id: HirId,
-        attr: &Attribute,
-        target: Target,
-        allowed_target: Target,
-    ) {
-        if target != allowed_target {
-            let attr_name = join_path_syms(attr.path());
-            self.tcx.emit_node_span_lint(
-                UNUSED_ATTRIBUTES,
-                hir_id,
-                attr.span(),
-                errors::OnlyHasEffectOn {
-                    attr_name,
-                    target_name: allowed_target.name().replace(' ', "_"),
-                },
-            );
-        }
-    }
-
-    fn check_generic_attr(
-        &self,
-        hir_id: HirId,
-        attr_name: Symbol,
-        attr_span: Span,
-        target: Target,
-        allowed_target: Target,
-    ) {
-        if target != allowed_target {
-            self.tcx.emit_node_span_lint(
-                UNUSED_ATTRIBUTES,
-                hir_id,
-                attr_span,
-                errors::OnlyHasEffectOn {
-                    attr_name: attr_name.to_string(),
-                    target_name: allowed_target.name().replace(' ', "_"),
-                },
-            );
-        }
-    }
-
     /// Checks if `#[naked]` is applied to a function definition.
-    fn check_naked(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
+    fn check_naked(&self, hir_id: HirId, target: Target) {
         match target {
             Target::Fn
             | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
@@ -760,13 +538,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     .emit();
                 }
             }
-            _ => {
-                self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
-                    attr_span,
-                    defn_span: span,
-                    on_crate: hir_id == CRATE_HIR_ID,
-                });
-            }
+            _ => {}
         }
     }
 
@@ -809,7 +581,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         hir_id: HirId,
         attr_span: Span,
         attrs: &[Attribute],
-        span: Span,
         target: Target,
     ) {
         match target {
@@ -829,28 +600,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     });
                 }
             }
-            Target::Method(..) | Target::ForeignFn | Target::Closure => {}
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[track_caller]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "track_caller");
-            }
-            _ => {
-                self.dcx().emit_err(errors::TrackedCallerWrongLocation {
-                    attr_span,
-                    defn_span: span,
-                    on_crate: hir_id == CRATE_HIR_ID,
-                });
-            }
+            _ => {}
         }
     }
 
     /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid.
     fn check_non_exhaustive(
         &self,
-        hir_id: HirId,
         attr_span: Span,
         span: Span,
         target: Target,
@@ -871,36 +627,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     });
                 }
             }
-            Target::Enum | Target::Variant => {}
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[non_exhaustive]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "non_exhaustive");
-            }
-            _ => {
-                self.dcx()
-                    .emit_err(errors::NonExhaustiveWrongLocation { attr_span, defn_span: span });
-            }
-        }
-    }
-
-    /// Checks if the `#[marker]` attribute on an `item` is valid.
-    fn check_marker(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
-        match target {
-            Target::Trait => {}
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[marker]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "marker");
-            }
-            _ => {
-                self.dcx()
-                    .emit_err(errors::AttrShouldBeAppliedToTrait { attr_span, defn_span: span });
-            }
+            _ => {}
         }
     }
 
@@ -909,7 +636,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         &self,
         hir_id: HirId,
         attr_span: Span,
-        span: Span,
         target: Target,
         attrs: &[Attribute],
     ) {
@@ -932,30 +658,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     });
                 }
             }
-            // FIXME: #[target_feature] was previously erroneously allowed on statements and some
-            // crates used this, so only emit a warning.
-            Target::Statement => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    errors::TargetFeatureOnStatement,
-                );
-            }
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[target_feature]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "target_feature");
-            }
-            _ => {
-                self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
-                    attr_span,
-                    defn_span: span,
-                    on_crate: hir_id == CRATE_HIR_ID,
-                });
-            }
+            _ => {}
         }
     }
 
@@ -1059,7 +762,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             | Target::GenericParam { .. }
             | Target::MacroDef
             | Target::PatField
-            | Target::ExprField => None,
+            | Target::ExprField
+            | Target::Crate
+            | Target::MacroCall
+            | Target::Delegation { .. } => None,
         } {
             tcx.dcx().emit_err(errors::DocAliasBadLocation { span, attr_str, location });
             return;
@@ -1535,25 +1241,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    /// Warns against some misuses of `#[pass_by_value]`
-    fn check_pass_by_value(&self, attr_span: Span, span: Span, target: Target) {
-        match target {
-            Target::Struct | Target::Enum | Target::TyAlias => {}
-            _ => {
-                self.dcx().emit_err(errors::PassByValue { attr_span, span });
-            }
-        }
-    }
-
-    fn check_allow_incoherent_impl(&self, attr_span: Span, span: Span, target: Target) {
-        match target {
-            Target::Method(MethodKind::Inherent) => {}
-            _ => {
-                self.dcx().emit_err(errors::AllowIncoherentImpl { attr_span, span });
-            }
-        }
-    }
-
     fn check_has_incoherent_inherent_impls(&self, attr: &Attribute, span: Span, target: Target) {
         match target {
             Target::Trait | Target::Struct | Target::Enum | Target::Union | Target::ForeignTy => {}
@@ -1565,23 +1252,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_ffi_pure(&self, attr_span: Span, attrs: &[Attribute], target: Target) {
-        if target != Target::ForeignFn {
-            self.dcx().emit_err(errors::FfiPureInvalidTarget { attr_span });
-            return;
-        }
+    fn check_ffi_pure(&self, attr_span: Span, attrs: &[Attribute]) {
         if find_attr!(attrs, AttributeKind::FfiConst(_)) {
             // `#[ffi_const]` functions cannot be `#[ffi_pure]`
             self.dcx().emit_err(errors::BothFfiConstAndPure { attr_span });
         }
     }
 
-    fn check_ffi_const(&self, attr_span: Span, target: Target) {
-        if target != Target::ForeignFn {
-            self.dcx().emit_err(errors::FfiConstInvalidTarget { attr_span });
-        }
-    }
-
     /// Warns against some misuses of `#[must_use]`
     fn check_must_use(&self, hir_id: HirId, attr_span: Span, target: Target) {
         if matches!(
@@ -1609,22 +1286,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             return;
         }
 
-        let article = match target {
-            Target::ExternCrate
-            | Target::Enum
-            | Target::Impl { .. }
-            | Target::Expression
-            | Target::Arm
-            | Target::AssocConst
-            | Target::AssocTy => "an",
-            _ => "a",
-        };
-
         self.tcx.emit_node_span_lint(
             UNUSED_ATTRIBUTES,
             hir_id,
             attr_span,
-            errors::MustUseNoEffect { article, target, attr_span },
+            errors::MustUseNoEffect { target: target.plural_name(), attr_span },
         );
     }
 
@@ -1659,30 +1325,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         self.dcx().emit_err(errors::InvalidMayDangle { attr_span });
     }
 
-    /// Checks if `#[cold]` is applied to a non-function.
-    fn check_cold(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
-        match target {
-            Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => {}
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[cold]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "cold");
-            }
-            _ => {
-                // FIXME: #[cold] was previously allowed on non-functions and some crates used
-                // this, so only emit a warning.
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    errors::Cold { span, on_crate: hir_id == CRATE_HIR_ID },
-                );
-            }
-        }
-    }
-
     /// Checks if `#[link]` is applied to an item other than a foreign module.
     fn check_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
         if target == Target::ForeignMod
@@ -1701,38 +1343,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         );
     }
 
-    /// Checks if `#[link_name]` is applied to an item other than a foreign function or static.
-    fn check_link_name(
-        &self,
-        hir_id: HirId,
-        attr_span: Span,
-        name: Symbol,
-        span: Span,
-        target: Target,
-    ) {
-        match target {
-            Target::ForeignFn | Target::ForeignStatic => {}
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[link_name]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "link_name");
-            }
-            _ => {
-                // FIXME: #[link_name] was previously allowed on non-functions/statics and some crates
-                // used this, so only emit a warning.
-                let help_span = matches!(target, Target::ForeignMod).then_some(attr_span);
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    errors::LinkName { span, help_span, value: name.as_str() },
-                );
-            }
-        }
-    }
-
     /// Checks if `#[no_link]` is applied to an `extern crate`.
     fn check_no_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
         match target {
@@ -1750,35 +1360,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn is_impl_item(&self, hir_id: HirId) -> bool {
-        matches!(self.tcx.hir_node(hir_id), hir::Node::ImplItem(..))
-    }
-
-    /// Checks if `#[export_name]` is applied to a function or static.
-    fn check_export_name(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
-        match target {
-            Target::Static | Target::Fn => {}
-            Target::Method(..) if self.is_impl_item(hir_id) => {}
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[export_name]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "export_name");
-            }
-            _ => {
-                self.dcx().emit_err(errors::ExportName { attr_span, span });
-            }
-        }
-    }
-
-    fn check_rustc_layout_scalar_valid_range(&self, attr_span: Span, span: Span, target: Target) {
-        if target != Target::Struct {
-            self.dcx().emit_err(errors::RustcLayoutScalarValidRangeNotStruct { attr_span, span });
-            return;
-        }
-    }
-
     /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument.
     fn check_rustc_legacy_const_generics(
         &self,
@@ -1913,106 +1494,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    /// Checks if `#[link_section]` is applied to a function or static.
-    fn check_link_section(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
-        match target {
-            Target::Static | Target::Fn | Target::Method(..) => {}
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[link_section]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "link_section");
-            }
-            _ => {
-                // FIXME: #[link_section] was previously allowed on non-functions/statics and some
-                // crates used this, so only emit a warning.
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    errors::LinkSection { span },
-                );
-            }
-        }
-    }
-
-    /// Checks if `#[no_mangle]` is applied to a function or static.
-    fn check_no_mangle(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) {
-        match target {
-            Target::Static | Target::Fn => {}
-            Target::Method(..) if self.is_impl_item(hir_id) => {}
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[no_mangle]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "no_mangle");
-            }
-            // FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
-            // The error should specify that the item that is wrong is specifically a *foreign* fn/static
-            // otherwise the error seems odd
-            Target::ForeignFn | Target::ForeignStatic => {
-                let foreign_item_kind = match target {
-                    Target::ForeignFn => "function",
-                    Target::ForeignStatic => "static",
-                    _ => unreachable!(),
-                };
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    errors::NoMangleForeign { span, attr_span, foreign_item_kind },
-                );
-            }
-            _ => {
-                // FIXME: #[no_mangle] was previously allowed on non-functions/statics and some
-                // crates used this, so only emit a warning.
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    errors::NoMangle { span },
-                );
-            }
-        }
-    }
-
-    /// Checks if the `#[align]` attributes on `item` are valid.
-    // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
-    fn check_align(
-        &self,
-        span: Span,
-        hir_id: HirId,
-        target: Target,
-        align: Align,
-        attr_span: Span,
-    ) {
-        match target {
-            Target::Fn | Target::Method(_) | Target::ForeignFn => {}
-            Target::Field => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    AlignOnFields { span },
-                );
-            }
-            Target::Struct | Target::Union | Target::Enum => {
-                self.dcx().emit_err(errors::AlignShouldBeReprAlign {
-                    span: attr_span,
-                    item: target.name(),
-                    align_bytes: align.bytes(),
-                });
-            }
-            _ => {
-                self.dcx().emit_err(errors::AlignAttrApplication { hint_span: attr_span, span });
-            }
-        }
-
-        self.check_align_value(align, attr_span);
-    }
-
     /// Checks if the `#[repr]` attributes on `item` are valid.
     fn check_repr(
         &self,
@@ -2067,7 +1548,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         Target::Fn | Target::Method(_) => {
                             self.dcx().emit_err(errors::ReprAlignShouldBeAlign {
                                 span: *repr_span,
-                                item: target.name(),
+                                item: target.plural_name(),
                             });
                         }
                         _ => {
@@ -2078,7 +1559,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         }
                     }
 
-                    self.check_align_value(*align, *repr_span);
+                    self.check_align(*align, *repr_span);
                 }
                 ReprAttr::ReprPacked(_) => {
                     if target != Target::Struct && target != Target::Union {
@@ -2137,7 +1618,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 Target::Fn | Target::Method(_) => {
                     self.dcx().emit_err(errors::ReprAlignShouldBeAlign {
                         span: first_attr_span,
-                        item: target.name(),
+                        item: target.plural_name(),
                     });
                 }
                 _ => {
@@ -2184,7 +1665,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_align_value(&self, align: Align, span: Span) {
+    fn check_align(&self, align: Align, span: Span) {
         if align.bytes() > 2_u64.pow(29) {
             // for values greater than 2^29, a different error will be emitted, make sure that happens
             self.dcx().span_delayed_bug(
@@ -2203,61 +1684,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_used(&self, attr_span: Span, target: Target, target_span: Span) {
-        if target != Target::Static {
-            self.dcx().emit_err(errors::UsedStatic {
-                attr_span,
-                span: target_span,
-                target: target.name(),
-            });
-        }
-    }
-
-    /// Outputs an error for `#[allow_internal_unstable]` which can only be applied to macros.
-    /// (Allows proc_macro functions)
-    fn check_allow_internal_unstable(
-        &self,
-        hir_id: HirId,
-        attr_span: Span,
-        span: Span,
-        target: Target,
-        attrs: &[Attribute],
-    ) {
-        self.check_macro_only_attr(
-            hir_id,
-            attr_span,
-            span,
-            target,
-            attrs,
-            "allow_internal_unstable",
-        )
-    }
-
-    /// Outputs an error for `#[allow_internal_unsafe]` which can only be applied to macros.
-    /// (Allows proc_macro functions)
-    fn check_allow_internal_unsafe(
-        &self,
-        hir_id: HirId,
-        attr_span: Span,
-        span: Span,
-        target: Target,
-        attrs: &[Attribute],
-    ) {
-        self.check_macro_only_attr(hir_id, attr_span, span, target, attrs, "allow_internal_unsafe")
-    }
-
     /// Outputs an error for attributes that can only be applied to macros, such as
     /// `#[allow_internal_unsafe]` and `#[allow_internal_unstable]`.
     /// (Allows proc_macro functions)
     // FIXME(jdonszelmann): if possible, move to attr parsing
     fn check_macro_only_attr(
         &self,
-        hir_id: HirId,
         attr_span: Span,
         span: Span,
         target: Target,
         attrs: &[Attribute],
-        attr_name: &str,
     ) {
         match target {
             Target::Fn => {
@@ -2267,23 +1703,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         return;
                     }
                 }
-                // continue out of the match
-            }
-            // return on decl macros
-            Target::MacroDef => return,
-            // FIXME(#80564): We permit struct fields and match arms to have an
-            // `#[allow_internal_unstable]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm => {
-                self.inline_attr_str_error_without_macro_def(hir_id, attr_span, attr_name);
-                return;
+                self.tcx.dcx().emit_err(errors::MacroOnlyAttribute { attr_span, span });
             }
-            // otherwise continue out of the match
             _ => {}
         }
-
-        self.tcx.dcx().emit_err(errors::MacroOnlyAttribute { attr_span, span });
     }
 
     /// Checks if the items on the `#[debugger_visualizer]` attribute are valid.
@@ -2310,66 +1733,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         target: Target,
     ) {
         match target {
-            Target::Fn | Target::Method(_)
-                if self.tcx.is_const_fn(hir_id.expect_owner().to_def_id()) => {}
-            // FIXME(#80564): We permit struct fields and match arms to have an
-            // `#[allow_internal_unstable]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => self
-                .inline_attr_str_error_with_macro_def(hir_id, attr_span, "allow_internal_unstable"),
-            _ => {
-                self.tcx.dcx().emit_err(errors::RustcAllowConstFnUnstable { attr_span, span });
-            }
-        }
-    }
-
-    fn check_unstable_feature_bound(&self, attr_span: Span, span: Span, target: Target) {
-        match target {
-            // FIXME(staged_api): There's no reason we can't support more targets here. We're just
-            // being conservative to begin with.
-            Target::Fn | Target::Impl { .. } | Target::Trait => {}
-            Target::ExternCrate
-            | Target::Use
-            | Target::Static
-            | Target::Const
-            | Target::Closure
-            | Target::Mod
-            | Target::ForeignMod
-            | Target::GlobalAsm
-            | Target::TyAlias
-            | Target::Enum
-            | Target::Variant
-            | Target::Struct
-            | Target::Field
-            | Target::Union
-            | Target::TraitAlias
-            | Target::Expression
-            | Target::Statement
-            | Target::Arm
-            | Target::AssocConst
-            | Target::Method(_)
-            | Target::AssocTy
-            | Target::ForeignFn
-            | Target::ForeignStatic
-            | Target::ForeignTy
-            | Target::GenericParam { .. }
-            | Target::MacroDef
-            | Target::Param
-            | Target::PatField
-            | Target::ExprField
-            | Target::WherePredicate => {
-                self.tcx.dcx().emit_err(errors::RustcUnstableFeatureBound { attr_span, span });
-            }
-        }
-    }
-
-    fn check_rustc_std_internal_symbol(&self, attr_span: Span, span: Span, target: Target) {
-        match target {
-            Target::Fn | Target::Static | Target::ForeignFn | Target::ForeignStatic => {}
-            _ => {
-                self.tcx.dcx().emit_err(errors::RustcStdInternalSymbol { attr_span, span });
+            Target::Fn | Target::Method(_) => {
+                if !self.tcx.is_const_fn(hir_id.expect_owner().to_def_id()) {
+                    self.tcx.dcx().emit_err(errors::RustcAllowConstFnUnstable { attr_span, span });
+                }
             }
+            _ => {}
         }
     }
 
@@ -2379,15 +1748,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         item_span: Span,
         level: &StabilityLevel,
         feature: Symbol,
-        target: Target,
     ) {
-        match target {
-            Target::Expression => {
-                self.dcx().emit_err(errors::StabilityPromotable { attr_span });
-            }
-            _ => {}
-        }
-
         // Stable *language* features shouldn't be used as unstable library features.
         // (Not doing this for stable library features is checked by tidy.)
         if level.is_unstable()
@@ -2399,40 +1760,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_link_ordinal(&self, attr_span: Span, _span: Span, target: Target) {
-        match target {
-            Target::ForeignFn | Target::ForeignStatic => {}
-            _ => {
-                self.dcx().emit_err(errors::LinkOrdinal { attr_span });
-            }
-        }
-    }
-
-    fn check_confusables(&self, span: Span, target: Target) {
-        if !matches!(target, Target::Method(MethodKind::Inherent)) {
-            self.dcx().emit_err(errors::Confusables { attr_span: span });
-        }
-    }
-
     fn check_deprecated(&self, hir_id: HirId, attr: &Attribute, _span: Span, target: Target) {
         match target {
-            Target::Closure | Target::Expression | Target::Statement | Target::Arm => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr.span(),
-                    errors::Deprecated,
-                );
-            }
-            Target::Impl { of_trait: true }
-            | Target::GenericParam { has_default: false, kind: _ } => {
-                self.tcx.emit_node_span_lint(
-                    USELESS_DEPRECATED,
-                    hir_id,
-                    attr.span(),
-                    errors::DeprecatedAnnotationHasNoEffect { span: attr.span() },
-                );
-            }
             Target::AssocConst | Target::Method(..) | Target::AssocTy
                 if matches!(
                     self.tcx.def_kind(self.tcx.local_parent(hir_id.owner.def_id)),
@@ -2440,7 +1769,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 ) =>
             {
                 self.tcx.emit_node_span_lint(
-                    USELESS_DEPRECATED,
+                    UNUSED_ATTRIBUTES,
                     hir_id,
                     attr.span(),
                     errors::DeprecatedAnnotationHasNoEffect { span: attr.span() },
@@ -2450,20 +1779,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_macro_use(&self, hir_id: HirId, name: Symbol, attr_span: Span, target: Target) {
-        match target {
-            Target::ExternCrate | Target::Mod => {}
-            _ => {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    errors::MacroUse { name },
-                );
-            }
-        }
-    }
-
     fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
         if target != Target::MacroDef {
             self.tcx.emit_node_span_lint(
@@ -2683,15 +1998,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_coroutine(&self, attr_span: Span, target: Target) {
-        match target {
-            Target::Closure => return,
-            _ => {
-                self.dcx().emit_err(errors::CoroutineOnNonClosure { span: attr_span });
-            }
-        }
-    }
-
     fn check_type_const(&self, hir_id: HirId, attr_span: Span, target: Target) {
         let tcx = self.tcx;
         if target == Target::AssocConst
@@ -2709,19 +2015,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_linkage(&self, attr_span: Span, span: Span, target: Target) {
-        match target {
-            Target::Fn
-            | Target::Method(..)
-            | Target::Static
-            | Target::ForeignStatic
-            | Target::ForeignFn => {}
-            _ => {
-                self.dcx().emit_err(errors::Linkage { attr_span, span });
-            }
-        }
-    }
-
     fn check_rustc_pub_transparent(&self, attr_span: Span, span: Span, attrs: &[Attribute]) {
         if !find_attr!(attrs, AttributeKind::Repr { reprs, .. } => reprs.iter().any(|(r, _)| r == &ReprAttr::ReprTransparent))
             .unwrap_or(false)
@@ -2730,43 +2023,28 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_rustc_force_inline(
-        &self,
-        hir_id: HirId,
-        attrs: &[Attribute],
-        span: Span,
-        target: Target,
-    ) {
-        match (
+    fn check_rustc_force_inline(&self, hir_id: HirId, attrs: &[Attribute], target: Target) {
+        if let (Target::Closure, None) = (
             target,
             find_attr!(attrs, AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span),
         ) {
-            (Target::Closure, None) => {
-                let is_coro = matches!(
-                    self.tcx.hir_expect_expr(hir_id).kind,
-                    hir::ExprKind::Closure(hir::Closure {
-                        kind: hir::ClosureKind::Coroutine(..)
-                            | hir::ClosureKind::CoroutineClosure(..),
-                        ..
-                    })
-                );
-                let parent_did = self.tcx.hir_get_parent_item(hir_id).to_def_id();
-                let parent_span = self.tcx.def_span(parent_did);
+            let is_coro = matches!(
+                self.tcx.hir_expect_expr(hir_id).kind,
+                hir::ExprKind::Closure(hir::Closure {
+                    kind: hir::ClosureKind::Coroutine(..) | hir::ClosureKind::CoroutineClosure(..),
+                    ..
+                })
+            );
+            let parent_did = self.tcx.hir_get_parent_item(hir_id).to_def_id();
+            let parent_span = self.tcx.def_span(parent_did);
 
-                if let Some(attr_span) = find_attr!(
-                    self.tcx.get_all_attrs(parent_did),
-                    AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span
-                ) && is_coro
-                {
-                    self.dcx()
-                        .emit_err(errors::RustcForceInlineCoro { attr_span, span: parent_span });
-                }
-            }
-            (Target::Fn, _) => (),
-            (_, Some(attr_span)) => {
-                self.dcx().emit_err(errors::RustcForceInline { attr_span, span });
+            if let Some(attr_span) = find_attr!(
+                self.tcx.get_all_attrs(parent_did),
+                AttributeKind::Inline(InlineAttr::Force { attr_span, .. }, _) => *attr_span
+            ) && is_coro
+            {
+                self.dcx().emit_err(errors::RustcForceInlineCoro { attr_span, span: parent_span });
             }
-            (_, None) => (),
         }
     }
 
@@ -2816,8 +2094,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         let node_span = self.tcx.hir_span(hir_id);
 
         if !matches!(target, Target::Expression) {
-            self.dcx().emit_err(errors::LoopMatchAttr { attr_span, node_span });
-            return;
+            return; // Handled in target checking during attr parse
         }
 
         if !matches!(self.tcx.hir_expect_expr(hir_id).kind, hir::ExprKind::Loop(..)) {
@@ -2829,8 +2106,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         let node_span = self.tcx.hir_span(hir_id);
 
         if !matches!(target, Target::Expression) {
-            self.dcx().emit_err(errors::ConstContinueAttr { attr_span, node_span });
-            return;
+            return; // Handled in target checking during attr parse
         }
 
         if !matches!(self.tcx.hir_expect_expr(hir_id).kind, hir::ExprKind::Break(..)) {
@@ -2873,6 +2149,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
             .hir_attrs(where_predicate.hir_id)
             .iter()
             .filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym)))
+            .filter(|attr| !attr.is_parsed_attr())
             .map(|attr| attr.span())
             .collect::<Vec<_>>();
         if !spans.is_empty() {
@@ -3003,10 +2280,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
         }) = attr
         {
             (*first_attr_span, sym::repr)
-        } else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr {
-            (*span, sym::path)
-        } else if let Attribute::Parsed(AttributeKind::AutomaticallyDerived(span)) = attr {
-            (*span, sym::automatically_derived)
         } else {
             continue;
         };
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 37216656e57..c5d5155d0e5 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -75,58 +75,6 @@ pub(crate) struct IgnoredAttrWithMacro<'a> {
     pub sym: &'a str,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_ignored_attr)]
-pub(crate) struct IgnoredAttr<'a> {
-    pub sym: &'a str,
-}
-
-#[derive(LintDiagnostic)]
-#[diag(passes_inline_ignored_function_prototype)]
-pub(crate) struct IgnoredInlineAttrFnProto;
-
-#[derive(LintDiagnostic)]
-#[diag(passes_inline_ignored_constants)]
-#[warning]
-#[note]
-pub(crate) struct IgnoredInlineAttrConstants;
-
-#[derive(Diagnostic)]
-#[diag(passes_inline_not_fn_or_closure, code = E0518)]
-pub(crate) struct InlineNotFnOrClosure {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub defn_span: Span,
-}
-
-/// "coverage attribute not allowed here"
-#[derive(Diagnostic)]
-#[diag(passes_coverage_attribute_not_allowed, code = E0788)]
-pub(crate) struct CoverageAttributeNotAllowed {
-    #[primary_span]
-    pub attr_span: Span,
-    /// "not a function, impl block, or module"
-    #[label(passes_not_fn_impl_mod)]
-    pub not_fn_impl_mod: Option<Span>,
-    /// "function has no body"
-    #[label(passes_no_body)]
-    pub no_body: Option<Span>,
-    /// "coverage attribute can be applied to a function (with body), impl block, or module"
-    #[help]
-    pub help: (),
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_optimize_invalid_target)]
-pub(crate) struct OptimizeInvalidTarget {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub defn_span: Span,
-    pub on_crate: bool,
-}
-
 #[derive(Diagnostic)]
 #[diag(passes_should_be_applied_to_fn)]
 pub(crate) struct AttrShouldBeAppliedToFn {
@@ -138,25 +86,6 @@ pub(crate) struct AttrShouldBeAppliedToFn {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_should_be_applied_to_fn, code = E0739)]
-pub(crate) struct TrackedCallerWrongLocation {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub defn_span: Span,
-    pub on_crate: bool,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_should_be_applied_to_struct_enum, code = E0701)]
-pub(crate) struct NonExhaustiveWrongLocation {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub defn_span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_non_exhaustive_with_default_field_values)]
 pub(crate) struct NonExhaustiveWithDefaultFieldValues {
     #[primary_span]
@@ -174,10 +103,6 @@ pub(crate) struct AttrShouldBeAppliedToTrait {
     pub defn_span: Span,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_target_feature_on_statement)]
-pub(crate) struct TargetFeatureOnStatement;
-
 #[derive(Diagnostic)]
 #[diag(passes_should_be_applied_to_static)]
 pub(crate) struct AttrShouldBeAppliedToStatic {
@@ -417,24 +342,6 @@ pub(crate) struct DocTestUnknownInclude {
 pub(crate) struct DocInvalid;
 
 #[derive(Diagnostic)]
-#[diag(passes_pass_by_value)]
-pub(crate) struct PassByValue {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_allow_incoherent_impl)]
-pub(crate) struct AllowIncoherentImpl {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_has_incoherent_inherent_impl)]
 pub(crate) struct HasIncoherentInherentImpl {
     #[primary_span]
@@ -450,25 +357,10 @@ pub(crate) struct BothFfiConstAndPure {
     pub attr_span: Span,
 }
 
-#[derive(Diagnostic)]
-#[diag(passes_ffi_pure_invalid_target, code = E0755)]
-pub(crate) struct FfiPureInvalidTarget {
-    #[primary_span]
-    pub attr_span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_ffi_const_invalid_target, code = E0756)]
-pub(crate) struct FfiConstInvalidTarget {
-    #[primary_span]
-    pub attr_span: Span,
-}
-
 #[derive(LintDiagnostic)]
 #[diag(passes_must_use_no_effect)]
 pub(crate) struct MustUseNoEffect {
-    pub article: &'static str,
-    pub target: rustc_hir::Target,
+    pub target: &'static str,
     #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
     pub attr_span: Span,
 }
@@ -483,15 +375,6 @@ pub(crate) struct MustNotSuspend {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(passes_cold)]
-#[warning]
-pub(crate) struct Cold {
-    #[label]
-    pub span: Span,
-    pub on_crate: bool,
-}
-
-#[derive(LintDiagnostic)]
 #[diag(passes_link)]
 #[warning]
 pub(crate) struct Link {
@@ -499,17 +382,6 @@ pub(crate) struct Link {
     pub span: Option<Span>,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_link_name)]
-#[warning]
-pub(crate) struct LinkName<'a> {
-    #[help]
-    pub help_span: Option<Span>,
-    #[label]
-    pub span: Span,
-    pub value: &'a str,
-}
-
 #[derive(Diagnostic)]
 #[diag(passes_no_link)]
 pub(crate) struct NoLink {
@@ -520,24 +392,6 @@ pub(crate) struct NoLink {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_export_name)]
-pub(crate) struct ExportName {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_rustc_layout_scalar_valid_range_not_struct)]
-pub(crate) struct RustcLayoutScalarValidRangeNotStruct {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_rustc_legacy_const_generics_only)]
 pub(crate) struct RustcLegacyConstGenericsOnly {
     #[primary_span]
@@ -578,42 +432,6 @@ pub(crate) struct RustcDirtyClean {
     pub span: Span,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_link_section)]
-#[warning]
-pub(crate) struct LinkSection {
-    #[label]
-    pub span: Span,
-}
-
-#[derive(LintDiagnostic)]
-#[diag(passes_no_mangle_foreign)]
-#[warning]
-#[note]
-pub(crate) struct NoMangleForeign {
-    #[label]
-    pub span: Span,
-    #[suggestion(code = "", applicability = "machine-applicable")]
-    pub attr_span: Span,
-    pub foreign_item_kind: &'static str,
-}
-
-#[derive(LintDiagnostic)]
-#[diag(passes_no_mangle)]
-#[warning]
-pub(crate) struct NoMangle {
-    #[label]
-    pub span: Span,
-}
-
-#[derive(LintDiagnostic)]
-#[diag(passes_align_on_fields)]
-#[warning]
-pub(crate) struct AlignOnFields {
-    #[label]
-    pub span: Span,
-}
-
 #[derive(Diagnostic)]
 #[diag(passes_repr_conflicting, code = E0566)]
 pub(crate) struct ReprConflicting {
@@ -635,16 +453,6 @@ pub(crate) struct InvalidReprAlignForTarget {
 pub(crate) struct ReprConflictingLint;
 
 #[derive(Diagnostic)]
-#[diag(passes_used_static)]
-pub(crate) struct UsedStatic {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-    pub target: &'static str,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_macro_only_attribute)]
 pub(crate) struct MacroOnlyAttribute {
     #[primary_span]
@@ -689,24 +497,6 @@ pub(crate) struct RustcAllowConstFnUnstable {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_rustc_unstable_feature_bound)]
-pub(crate) struct RustcUnstableFeatureBound {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_rustc_std_internal_symbol)]
-pub(crate) struct RustcStdInternalSymbol {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_rustc_pub_transparent)]
 pub(crate) struct RustcPubTransparent {
     #[primary_span]
@@ -716,15 +506,6 @@ pub(crate) struct RustcPubTransparent {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_rustc_force_inline)]
-pub(crate) struct RustcForceInline {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_rustc_force_inline_coro)]
 pub(crate) struct RustcForceInlineCoro {
     #[primary_span]
@@ -733,53 +514,6 @@ pub(crate) struct RustcForceInlineCoro {
     pub span: Span,
 }
 
-#[derive(Diagnostic)]
-#[diag(passes_link_ordinal)]
-pub(crate) struct LinkOrdinal {
-    #[primary_span]
-    pub attr_span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_confusables)]
-pub(crate) struct Confusables {
-    #[primary_span]
-    pub attr_span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_coroutine_on_non_closure)]
-pub(crate) struct CoroutineOnNonClosure {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_linkage)]
-pub(crate) struct Linkage {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_stability_promotable)]
-pub(crate) struct StabilityPromotable {
-    #[primary_span]
-    pub attr_span: Span,
-}
-
-#[derive(LintDiagnostic)]
-#[diag(passes_deprecated)]
-pub(crate) struct Deprecated;
-
-#[derive(LintDiagnostic)]
-#[diag(passes_macro_use)]
-pub(crate) struct MacroUse {
-    pub name: Symbol,
-}
-
 #[derive(LintDiagnostic)]
 pub(crate) enum MacroExport {
     #[diag(passes_macro_export)]
@@ -1283,13 +1017,6 @@ pub(crate) struct UselessAssignment<'a> {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(passes_only_has_effect_on)]
-pub(crate) struct OnlyHasEffectOn {
-    pub attr_name: String,
-    pub target_name: String,
-}
-
-#[derive(LintDiagnostic)]
 #[diag(passes_inline_ignored_for_exported)]
 #[help]
 pub(crate) struct InlineIgnoredForExported {}
@@ -1843,26 +1570,3 @@ pub(crate) struct ReprAlignShouldBeAlign {
     pub span: Span,
     pub item: &'static str,
 }
-
-#[derive(Diagnostic)]
-#[diag(passes_align_should_be_repr_align)]
-pub(crate) struct AlignShouldBeReprAlign {
-    #[primary_span]
-    #[suggestion(
-        style = "verbose",
-        applicability = "machine-applicable",
-        code = "#[repr(align({align_bytes}))]"
-    )]
-    pub span: Span,
-    pub item: &'static str,
-    pub align_bytes: u64,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_align_attr_application)]
-pub(crate) struct AlignAttrApplication {
-    #[primary_span]
-    pub hint_span: Span,
-    #[label]
-    pub span: Span,
-}