about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSimonas Kazlauskas <git@kazlauskas.me>2021-06-11 14:22:13 +0300
committerSimonas Kazlauskas <git@kazlauskas.me>2021-07-06 13:12:15 +0300
commit8240e7aa101815e2009c7d03b33dd2566d843e73 (patch)
treeacd63da2f2a9ec826d6d5844cdc8a4d3892dbd6c
parent96859dbaf6229f131fbd427a32aaa95d4f9cb132 (diff)
downloadrust-8240e7aa101815e2009c7d03b33dd2566d843e73.tar.gz
rust-8240e7aa101815e2009c7d03b33dd2566d843e73.zip
Replace per-target ABI denylist with an allowlist
It makes very little sense to maintain denylists of ABIs when, as far as
non-generic ABIs are concerned, targets usually only support a small
subset of the available ABIs.

This has historically been a cause of bugs such as us allowing use of
the platform-specific ABIs on x86 targets – these in turn would cause
LLVM errors or assertions to fire.

Fixes #57182

Sponsored by: standard.ai
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs47
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_ios.rs4
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs4
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs1
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_tvos.rs4
-rw-r--r--compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs7
-rw-r--r--compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs7
-rw-r--r--compiler/rustc_target/src/spec/aarch64_fuchsia.rs10
-rw-r--r--compiler/rustc_target/src/spec/aarch64_linux_android.rs15
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs5
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs17
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs7
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs6
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs10
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_none.rs1
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs1
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs8
-rw-r--r--compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs5
-rw-r--r--compiler/rustc_target/src/spec/abi.rs83
-rw-r--r--compiler/rustc_target/src/spec/arm_base.rs15
-rw-r--r--compiler/rustc_target/src/spec/arm_linux_androideabi.rs12
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs7
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs7
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs13
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs13
-rw-r--r--compiler/rustc_target/src/spec/armebv7r_none_eabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs5
-rw-r--r--compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs5
-rw-r--r--compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs6
-rw-r--r--compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs5
-rw-r--r--compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs7
-rw-r--r--compiler/rustc_target/src/spec/armv7_apple_ios.rs4
-rw-r--r--compiler/rustc_target/src/spec/armv7_linux_androideabi.rs9
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs5
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs5
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs5
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs4
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs4
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs5
-rw-r--r--compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs4
-rw-r--r--compiler/rustc_target/src/spec/armv7a_none_eabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7a_none_eabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7r_none_eabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7r_none_eabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7s_apple_ios.rs4
-rw-r--r--compiler/rustc_target/src/spec/bpf_base.rs18
-rw-r--r--compiler/rustc_target/src/spec/mipsel_unknown_none.rs11
-rw-r--r--compiler/rustc_target/src/spec/mod.rs155
-rw-r--r--compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs20
-rw-r--r--compiler/rustc_target/src/spec/riscv32gc_unknown_linux_gnu.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv32gc_unknown_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv_base.rs22
-rw-r--r--compiler/rustc_target/src/spec/thumb_base.rs1
-rw-r--r--compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs10
-rw-r--r--compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs16
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs9
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs5
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs4
-rw-r--r--compiler/rustc_typeck/src/check/check.rs20
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs2
-rw-r--r--src/test/codegen/unwind-abis/stdcall-unwind-abi.rs13
-rw-r--r--src/test/codegen/unwind-abis/thiscall-unwind-abi.rs14
-rw-r--r--src/test/ui/abi/unsupported.aarch64.stderr58
-rw-r--r--src/test/ui/abi/unsupported.i686.stderr39
-rw-r--r--src/test/ui/abi/unsupported.rs48
-rw-r--r--src/test/ui/abi/unsupported.x64.stderr58
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-1.rs9
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-1.stderr26
-rw-r--r--src/test/ui/extern/extern-methods.rs4
-rw-r--r--src/test/ui/extern/extern-thiscall.rs4
-rw-r--r--src/test/ui/extern/extern-vectorcall.rs6
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs50
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr123
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs37
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr60
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-x86-interrupt.rs28
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr66
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi.rs64
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi.stderr495
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi_amdgpu_kernel.rs30
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi_amdgpu_kernel.stderr97
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi_ptx.rs26
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi_ptx.stderr66
-rw-r--r--src/test/ui/feature-gates/feature-gate-vectorcall.rs31
-rw-r--r--src/test/ui/feature-gates/feature-gate-vectorcall.stderr59
-rw-r--r--src/test/ui/feature-gates/feature-gate-wasm_abi.rs27
-rw-r--r--src/test/ui/feature-gates/feature-gate-wasm_abi.stderr60
-rw-r--r--src/test/ui/unwind-abis/feature-gate-stdcall-unwind.rs31
-rw-r--r--src/test/ui/unwind-abis/feature-gate-stdcall-unwind.stderr60
-rw-r--r--src/test/ui/unwind-abis/feature-gate-thiscall-unwind.rs40
-rw-r--r--src/test/ui/unwind-abis/feature-gate-thiscall-unwind.stderr116
-rw-r--r--src/tools/tidy/src/error_codes_check.rs2
101 files changed, 1507 insertions, 1038 deletions
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 9bb1109fc64..9dab4053c8e 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2974,6 +2974,7 @@ declare_lint_pass! {
         LARGE_ASSIGNMENTS,
         FUTURE_PRELUDE_COLLISION,
         RESERVED_PREFIX,
+        UNSUPPORTED_CALLING_CONVENTIONS,
     ]
 }
 
@@ -3303,3 +3304,49 @@ declare_lint! {
     };
     crate_level_only
 }
+
+declare_lint! {
+    /// The `unsupported_calling_conventions` lint is output whenever there is an use of the
+    /// `stdcall`, `fastcall`, `thiscall`, `vectorcall` calling conventions (or their unwind
+    /// variants) on targets that cannot meaningfully be supported for the requested target.
+    ///
+    /// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
+    /// code, because this calling convention was never specified for those targets.
+    ///
+    /// Historically MSVC toolchains have fallen back to the regular C calling convention for
+    /// targets other than x86, but Rust doesn't really see a similar need to introduce a similar
+    /// hack across many more targets.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,ignore (needs specific targets)
+    /// extern "stdcall" fn stdcall() {}
+    /// ```
+    ///
+    /// This will produce:
+    ///
+    /// ```text
+    /// warning: use of calling convention not supported on this target
+    ///   --> $DIR/unsupported.rs:39:1
+    ///    |
+    /// LL | extern "stdcall" fn stdcall() {}
+    ///    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    ///    |
+    ///    = note: `#[warn(unsupported_calling_conventions)]` on by default
+    ///    = warning: this was previously accepted by the compiler but is being phased out;
+    ///               it will become a hard error in a future release!
+    ///    = note: for more information, see issue ...
+    /// ```
+    ///
+    /// ### Explanation
+    ///
+    /// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
+    /// defined at all, but was previously accepted due to a bug in the implementation of the
+    /// compiler.
+    pub UNSUPPORTED_CALLING_CONVENTIONS,
+    Warn,
+    "use of unsupported calling convention",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "issue #00000 <https://github.com/rust-lang/rust/issues/00000>",
+    };
+}
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs
index 9fa8ef69d81..e5805d9e691 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_ios.rs
@@ -2,7 +2,6 @@ use super::apple_sdk_base::{opts, Arch};
 use crate::spec::{FramePointer, Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = opts("ios", Arch::Arm64);
     Target {
         llvm_target: "arm64-apple-ios".to_string(),
         pointer_width: 64,
@@ -11,7 +10,6 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".to_string(),
             max_atomic_width: Some(128),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             forces_embed_bitcode: true,
             frame_pointer: FramePointer::NonLeaf,
             // Taken from a clang build on Xcode 11.4.1.
@@ -25,7 +23,7 @@ pub fn target() -> Target {
                 darwinpcs\0\
                 -Os\0"
                 .to_string(),
-            ..base
+            ..opts("ios", Arch::Arm64)
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs
index a43eb99a1d7..d16328f00f9 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs
@@ -2,7 +2,6 @@ use super::apple_sdk_base::{opts, Arch};
 use crate::spec::{FramePointer, Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = opts("ios", Arch::Arm64_macabi);
     Target {
         llvm_target: "arm64-apple-ios14.0-macabi".to_string(),
         pointer_width: 64,
@@ -11,7 +10,6 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a12".to_string(),
             max_atomic_width: Some(128),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             forces_embed_bitcode: true,
             frame_pointer: FramePointer::NonLeaf,
             // Taken from a clang build on Xcode 11.4.1.
@@ -23,7 +21,7 @@ pub fn target() -> Target {
                 -disable-llvm-passes\0\
                 -Os\0"
                 .to_string(),
-            ..base
+            ..opts("ios", Arch::Arm64_macabi)
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs
index 586e4043d79..07b3453218f 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_sim.rs
@@ -19,7 +19,6 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".to_string(),
             max_atomic_width: Some(128),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             forces_embed_bitcode: true,
             frame_pointer: FramePointer::NonLeaf,
             // Taken from a clang build on Xcode 11.4.1.
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs
index 934f3370369..b4bd72a082b 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_tvos.rs
@@ -2,7 +2,6 @@ use super::apple_sdk_base::{opts, Arch};
 use crate::spec::{FramePointer, Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = opts("tvos", Arch::Arm64);
     Target {
         llvm_target: "arm64-apple-tvos".to_string(),
         pointer_width: 64,
@@ -11,10 +10,9 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".to_string(),
             max_atomic_width: Some(128),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             forces_embed_bitcode: true,
             frame_pointer: FramePointer::NonLeaf,
-            ..base
+            ..opts("tvos", Arch::Arm64)
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs
index 192c4661c7c..71ee6deb07f 100644
--- a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu.rs
@@ -2,19 +2,16 @@ use crate::abi::Endian;
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::linux_gnu_base::opts();
-    base.max_atomic_width = Some(128);
-
     Target {
         llvm_target: "aarch64_be-unknown-linux-gnu".to_string(),
         pointer_width: 64,
         data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
         options: TargetOptions {
-            unsupported_abis: super::arm_base::unsupported_abis(),
+            max_atomic_width: Some(128),
             mcount: "\u{1}_mcount".to_string(),
             endian: Endian::Big,
-            ..base
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
index 5b9e9c9519c..c1adc963425 100644
--- a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
+++ b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
@@ -10,11 +10,6 @@ pub fn target() -> Target {
         pointer_width: 32,
         data_layout: "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions {
-            unsupported_abis: super::arm_base::unsupported_abis(),
-            mcount: "\u{1}_mcount".to_string(),
-            endian: Endian::Big,
-            ..base
-        },
+        options: TargetOptions { mcount: "\u{1}_mcount".to_string(), endian: Endian::Big, ..base },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_fuchsia.rs b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs
index c9cb21f1eb1..56d71df6bda 100644
--- a/compiler/rustc_target/src/spec/aarch64_fuchsia.rs
+++ b/compiler/rustc_target/src/spec/aarch64_fuchsia.rs
@@ -1,15 +1,15 @@
 use crate::spec::{SanitizerSet, Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::fuchsia_base::opts();
-    base.max_atomic_width = Some(128);
-    base.supported_sanitizers = SanitizerSet::ADDRESS;
-
     Target {
         llvm_target: "aarch64-fuchsia".to_string(),
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
+        options: TargetOptions {
+            max_atomic_width: Some(128),
+            supported_sanitizers: SanitizerSet::ADDRESS,
+            ..super::fuchsia_base::opts()
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/aarch64_linux_android.rs
index d00883ae71a..409cab72ec2 100644
--- a/compiler/rustc_target/src/spec/aarch64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/aarch64_linux_android.rs
@@ -4,17 +4,18 @@ use crate::spec::{SanitizerSet, Target, TargetOptions};
 // for target ABI requirements.
 
 pub fn target() -> Target {
-    let mut base = super::android_base::opts();
-    base.max_atomic_width = Some(128);
-    // As documented in https://developer.android.com/ndk/guides/cpu-features.html
-    // the neon (ASIMD) and FP must exist on all android aarch64 targets.
-    base.features = "+neon,+fp-armv8".to_string();
-    base.supported_sanitizers = SanitizerSet::HWADDRESS;
     Target {
         llvm_target: "aarch64-linux-android".to_string(),
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
+        options: TargetOptions {
+            max_atomic_width: Some(128),
+            // As documented in https://developer.android.com/ndk/guides/cpu-features.html
+            // the neon (ASIMD) and FP must exist on all android aarch64 targets.
+            features: "+neon,+fp-armv8".to_string(),
+            supported_sanitizers: SanitizerSet::HWADDRESS,
+            ..super::android_base::opts()
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs
index d48389d4a35..09ea7d33cfd 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_freebsd.rs
@@ -1,14 +1,11 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::freebsd_base::opts();
-    base.max_atomic_width = Some(128);
-
     Target {
         llvm_target: "aarch64-unknown-freebsd".to_string(),
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
+        options: TargetOptions { max_atomic_width: Some(128), ..super::freebsd_base::opts() },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
index a07cd7db889..3e92ecbae05 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu.rs
@@ -1,23 +1,20 @@
 use crate::spec::{SanitizerSet, Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::linux_gnu_base::opts();
-    base.max_atomic_width = Some(128);
-    base.supported_sanitizers = SanitizerSet::ADDRESS
-        | SanitizerSet::LEAK
-        | SanitizerSet::MEMORY
-        | SanitizerSet::THREAD
-        | SanitizerSet::HWADDRESS;
-
     Target {
         llvm_target: "aarch64-unknown-linux-gnu".to_string(),
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
         options: TargetOptions {
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}_mcount".to_string(),
-            ..base
+            max_atomic_width: Some(128),
+            supported_sanitizers: SanitizerSet::ADDRESS
+                | SanitizerSet::LEAK
+                | SanitizerSet::MEMORY
+                | SanitizerSet::THREAD
+                | SanitizerSet::HWADDRESS,
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
index f2d7576280f..e2618447f28 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
@@ -1,18 +1,15 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::linux_gnu_base::opts();
-    base.max_atomic_width = Some(128);
-
     Target {
         llvm_target: "aarch64-unknown-linux-gnu_ilp32".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
         options: TargetOptions {
-            unsupported_abis: super::arm_base::unsupported_abis(),
+            max_atomic_width: Some(128),
             mcount: "\u{1}_mcount".to_string(),
-            ..base
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs
index 7bbfc8ec0f7..6a16b4ce419 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_musl.rs
@@ -9,10 +9,6 @@ pub fn target() -> Target {
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions {
-            unsupported_abis: super::arm_base::unsupported_abis(),
-            mcount: "\u{1}_mcount".to_string(),
-            ..base
-        },
+        options: TargetOptions { mcount: "\u{1}_mcount".to_string(), ..base },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs
index 09efbdbb293..4042028e2dc 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_netbsd.rs
@@ -1,15 +1,15 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::netbsd_base::opts();
-    base.max_atomic_width = Some(128);
-    base.unsupported_abis = super::arm_base::unsupported_abis();
-
     Target {
         llvm_target: "aarch64-unknown-netbsd".to_string(),
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions { mcount: "__mcount".to_string(), ..base },
+        options: TargetOptions {
+            mcount: "__mcount".to_string(),
+            max_atomic_width: Some(128),
+            ..super::netbsd_base::opts()
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs
index de92b167f00..9d365279010 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs
@@ -18,7 +18,6 @@ pub fn target() -> Target {
         disable_redzone: true,
         max_atomic_width: Some(128),
         panic_strategy: PanicStrategy::Abort,
-        unsupported_abis: super::arm_base::unsupported_abis(),
         ..Default::default()
     };
     Target {
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs
index 2566eeae14a..482db0c5342 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs
@@ -18,7 +18,6 @@ pub fn target() -> Target {
         disable_redzone: true,
         max_atomic_width: Some(128),
         panic_strategy: PanicStrategy::Abort,
-        unsupported_abis: super::arm_base::unsupported_abis(),
         ..Default::default()
     };
     Target {
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs
index 83ba1ecd1d3..193f9814210 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_openbsd.rs
@@ -1,15 +1,11 @@
-use crate::spec::Target;
+use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::openbsd_base::opts();
-    base.max_atomic_width = Some(128);
-    base.unsupported_abis = super::arm_base::unsupported_abis();
-
     Target {
         llvm_target: "aarch64-unknown-openbsd".to_string(),
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: base,
+        options: TargetOptions { max_atomic_width: Some(128), ..super::openbsd_base::opts() },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs
index beb8ce30cc9..66140060f8e 100644
--- a/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs
+++ b/compiler/rustc_target/src/spec/aarch64_wrs_vxworks.rs
@@ -1,14 +1,11 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::vxworks_base::opts();
-    base.max_atomic_width = Some(128);
-
     Target {
         llvm_target: "aarch64-unknown-linux-gnu".to_string(),
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
+        options: TargetOptions { max_atomic_width: Some(128), ..super::vxworks_base::opts() },
     }
 }
diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs
index a026a623f78..ee36090c549 100644
--- a/compiler/rustc_target/src/spec/abi.rs
+++ b/compiler/rustc_target/src/spec/abi.rs
@@ -8,16 +8,11 @@ mod tests;
 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)]
 #[derive(HashStable_Generic, Encodable, Decodable)]
 pub enum Abi {
-    // Multiplatform / generic ABIs
-    //
-    // These ABIs come first because every time we add a new ABI, we
-    // have to re-bless all the hashing tests. These are used in many
-    // places, so giving them stable values reduces test churn. The
-    // specific values are meaningless.
+    // Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the
+    // hashing tests. These are used in many places, so giving them stable values reduces test
+    // churn. The specific values are meaningless.
     Rust,
     C { unwind: bool },
-
-    // Single platform ABIs
     Cdecl,
     Stdcall { unwind: bool },
     Fastcall,
@@ -35,8 +30,6 @@ pub enum Abi {
     AvrNonBlockingInterrupt,
     CCmseNonSecureCall,
     Wasm,
-
-    // Multiplatform / generic ABIs
     System { unwind: bool },
     RustIntrinsic,
     RustCall,
@@ -50,48 +43,38 @@ pub struct AbiData {
 
     /// Name of this ABI as we like it called.
     name: &'static str,
-
-    /// A generic ABI is supported on all platforms.
-    generic: bool,
 }
 
 #[allow(non_upper_case_globals)]
 const AbiDatas: &[AbiData] = &[
-    // Cross-platform ABIs
-    AbiData { abi: Abi::Rust, name: "Rust", generic: true },
-    AbiData { abi: Abi::C { unwind: false }, name: "C", generic: true },
-    AbiData { abi: Abi::C { unwind: true }, name: "C-unwind", generic: true },
-    // Platform-specific ABIs
-    AbiData { abi: Abi::Cdecl, name: "cdecl", generic: false },
-    AbiData { abi: Abi::Stdcall { unwind: false }, name: "stdcall", generic: false },
-    AbiData { abi: Abi::Stdcall { unwind: true }, name: "stdcall-unwind", generic: false },
-    AbiData { abi: Abi::Fastcall, name: "fastcall", generic: false },
-    AbiData { abi: Abi::Vectorcall, name: "vectorcall", generic: false },
-    AbiData { abi: Abi::Thiscall { unwind: false }, name: "thiscall", generic: false },
-    AbiData { abi: Abi::Thiscall { unwind: true }, name: "thiscall-unwind", generic: false },
-    AbiData { abi: Abi::Aapcs, name: "aapcs", generic: false },
-    AbiData { abi: Abi::Win64, name: "win64", generic: false },
-    AbiData { abi: Abi::SysV64, name: "sysv64", generic: false },
-    AbiData { abi: Abi::PtxKernel, name: "ptx-kernel", generic: false },
-    AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false },
-    AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false },
-    AbiData { abi: Abi::AmdGpuKernel, name: "amdgpu-kernel", generic: false },
-    AbiData { abi: Abi::EfiApi, name: "efiapi", generic: false },
-    AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt", generic: false },
-    AbiData {
-        abi: Abi::AvrNonBlockingInterrupt,
-        name: "avr-non-blocking-interrupt",
-        generic: false,
-    },
-    AbiData { abi: Abi::CCmseNonSecureCall, name: "C-cmse-nonsecure-call", generic: false },
-    AbiData { abi: Abi::Wasm, name: "wasm", generic: false },
-    // Cross-platform ABIs
-    AbiData { abi: Abi::System { unwind: false }, name: "system", generic: true },
-    AbiData { abi: Abi::System { unwind: true }, name: "system-unwind", generic: true },
-    AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic", generic: true },
-    AbiData { abi: Abi::RustCall, name: "rust-call", generic: true },
-    AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic", generic: true },
-    AbiData { abi: Abi::Unadjusted, name: "unadjusted", generic: true },
+    AbiData { abi: Abi::Rust, name: "Rust" },
+    AbiData { abi: Abi::C { unwind: false }, name: "C" },
+    AbiData { abi: Abi::C { unwind: true }, name: "C-unwind" },
+    AbiData { abi: Abi::Cdecl, name: "cdecl" },
+    AbiData { abi: Abi::Stdcall { unwind: false }, name: "stdcall" },
+    AbiData { abi: Abi::Stdcall { unwind: true }, name: "stdcall-unwind" },
+    AbiData { abi: Abi::Fastcall, name: "fastcall" },
+    AbiData { abi: Abi::Vectorcall, name: "vectorcall" },
+    AbiData { abi: Abi::Thiscall { unwind: false }, name: "thiscall" },
+    AbiData { abi: Abi::Thiscall { unwind: true }, name: "thiscall-unwind" },
+    AbiData { abi: Abi::Aapcs, name: "aapcs" },
+    AbiData { abi: Abi::Win64, name: "win64" },
+    AbiData { abi: Abi::SysV64, name: "sysv64" },
+    AbiData { abi: Abi::PtxKernel, name: "ptx-kernel" },
+    AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt" },
+    AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt" },
+    AbiData { abi: Abi::AmdGpuKernel, name: "amdgpu-kernel" },
+    AbiData { abi: Abi::EfiApi, name: "efiapi" },
+    AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt" },
+    AbiData { abi: Abi::AvrNonBlockingInterrupt, name: "avr-non-blocking-interrupt" },
+    AbiData { abi: Abi::CCmseNonSecureCall, name: "C-cmse-nonsecure-call" },
+    AbiData { abi: Abi::Wasm, name: "wasm" },
+    AbiData { abi: Abi::System { unwind: false }, name: "system" },
+    AbiData { abi: Abi::System { unwind: true }, name: "system-unwind" },
+    AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic" },
+    AbiData { abi: Abi::RustCall, name: "rust-call" },
+    AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" },
+    AbiData { abi: Abi::Unadjusted, name: "unadjusted" },
 ];
 
 /// Returns the ABI with the given name (if any).
@@ -163,10 +146,6 @@ impl Abi {
     pub fn name(self) -> &'static str {
         self.data().name
     }
-
-    pub fn generic(self) -> bool {
-        self.data().generic
-    }
 }
 
 impl fmt::Display for Abi {
diff --git a/compiler/rustc_target/src/spec/arm_base.rs b/compiler/rustc_target/src/spec/arm_base.rs
deleted file mode 100644
index 01f573313c9..00000000000
--- a/compiler/rustc_target/src/spec/arm_base.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-use crate::spec::abi::Abi;
-
-// All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm
-pub fn unsupported_abis() -> Vec<Abi> {
-    vec![
-        Abi::Stdcall { unwind: false },
-        Abi::Stdcall { unwind: true },
-        Abi::Fastcall,
-        Abi::Vectorcall,
-        Abi::Thiscall { unwind: false },
-        Abi::Thiscall { unwind: true },
-        Abi::Win64,
-        Abi::SysV64,
-    ]
-}
diff --git a/compiler/rustc_target/src/spec/arm_linux_androideabi.rs b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs
index 43537569e7d..f2430830afc 100644
--- a/compiler/rustc_target/src/spec/arm_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs
@@ -1,16 +1,16 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::android_base::opts();
-    // https://developer.android.com/ndk/guides/abis.html#armeabi
-    base.features = "+strict-align,+v5te".to_string();
-    base.max_atomic_width = Some(32);
-
     Target {
         llvm_target: "arm-linux-androideabi".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
+        options: TargetOptions {
+            // https://developer.android.com/ndk/guides/abis.html#armeabi
+            features: "+strict-align,+v5te".to_string(),
+            max_atomic_width: Some(32),
+            ..super::android_base::opts()
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs
index c41cf6e521a..225db0032a8 100644
--- a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs
@@ -1,19 +1,16 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::linux_gnu_base::opts();
-    base.max_atomic_width = Some(64);
     Target {
         llvm_target: "arm-unknown-linux-gnueabi".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             features: "+strict-align,+v6".to_string(),
-            unsupported_abis: super::arm_base::unsupported_abis(),
+            max_atomic_width: Some(64),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
-            ..base
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs
index f2143966c1d..33703195ee7 100644
--- a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs
@@ -1,19 +1,16 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::linux_gnu_base::opts();
-    base.max_atomic_width = Some(64);
     Target {
         llvm_target: "arm-unknown-linux-gnueabihf".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             features: "+strict-align,+v6,+vfp2,-d32".to_string(),
-            unsupported_abis: super::arm_base::unsupported_abis(),
+            max_atomic_width: Some(64),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
-            ..base
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs
index 53ff1001c20..850844993f9 100644
--- a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs
@@ -1,12 +1,6 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::linux_musl_base::opts();
-
-    // Most of these settings are copied from the arm_unknown_linux_gnueabi
-    // target.
-    base.features = "+strict-align,+v6".to_string();
-    base.max_atomic_width = Some(64);
     Target {
         // It's important we use "gnueabi" and not "musleabi" here. LLVM uses it
         // to determine the calling convention and float ABI, and it doesn't
@@ -16,9 +10,12 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
-            unsupported_abis: super::arm_base::unsupported_abis(),
+            // Most of these settings are copied from the arm_unknown_linux_gnueabi
+            // target.
+            features: "+strict-align,+v6".to_string(),
+            max_atomic_width: Some(64),
             mcount: "\u{1}mcount".to_string(),
-            ..base
+            ..super::linux_musl_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs
index 6d8a5f9f88b..ff69c462e8e 100644
--- a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs
@@ -1,12 +1,6 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::linux_musl_base::opts();
-
-    // Most of these settings are copied from the arm_unknown_linux_gnueabihf
-    // target.
-    base.features = "+strict-align,+v6,+vfp2,-d32".to_string();
-    base.max_atomic_width = Some(64);
     Target {
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
         // uses it to determine the calling convention and float ABI, and it
@@ -16,9 +10,12 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
-            unsupported_abis: super::arm_base::unsupported_abis(),
+            // Most of these settings are copied from the arm_unknown_linux_gnueabihf
+            // target.
+            features: "+strict-align,+v6,+vfp2,-d32".to_string(),
+            max_atomic_width: Some(64),
             mcount: "\u{1}mcount".to_string(),
-            ..base
+            ..super::linux_musl_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
index 255740cb9c0..547f48c5d3b 100644
--- a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
@@ -10,7 +10,6 @@ pub fn target() -> Target {
         pointer_width: 32,
         data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             endian: Endian::Big,
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
@@ -19,7 +18,6 @@ pub fn target() -> Target {
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
             max_atomic_width: Some(32),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             emit_debug_gdb_scripts: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
index eb82e4d17b0..f4f61e87ab9 100644
--- a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
@@ -10,7 +10,6 @@ pub fn target() -> Target {
         pointer_width: 32,
         data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             endian: Endian::Big,
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
@@ -20,7 +19,6 @@ pub fn target() -> Target {
             panic_strategy: PanicStrategy::Abort,
             features: "+vfp3,-d32,-fp16".to_string(),
             max_atomic_width: Some(32),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             emit_debug_gdb_scripts: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs
index e1ba72bf83b..8a289fee781 100644
--- a/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs
@@ -1,21 +1,18 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = super::linux_gnu_base::opts();
     Target {
         llvm_target: "armv4t-unknown-linux-gnueabi".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
             has_thumb_interworking: true,
-            ..base
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs
index 3ac8d53564d..177ab453b04 100644
--- a/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs
@@ -1,21 +1,18 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = super::linux_gnu_base::opts();
     Target {
         llvm_target: "armv5te-unknown-linux-gnueabi".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
             has_thumb_interworking: true,
-            ..base
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs
index 40d405c30a2..1f084443bd9 100644
--- a/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs
@@ -1,8 +1,8 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = super::linux_musl_base::opts();
     Target {
+        // FIXME: this comment below does not seem applicable?
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
         // uses it to determine the calling convention and float ABI, and LLVM
         // doesn't support the "musleabihf" value.
@@ -10,15 +10,13 @@ pub fn target() -> Target {
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}mcount".to_string(),
             has_thumb_interworking: true,
-            ..base
+            ..super::linux_musl_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs
index 3eb0f4db833..4e5b714bded 100644
--- a/compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs
+++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs
@@ -10,10 +10,8 @@ pub fn target() -> Target {
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
             has_thumb_interworking: true,
-
             ..super::linux_uclibc_base::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs
index a149bd983b7..08fc51e8a8b 100644
--- a/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs
@@ -1,20 +1,17 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = super::freebsd_base::opts();
     Target {
         llvm_target: "armv6-unknown-freebsd-gnueabihf".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             env: "gnueabihf".to_string(),
             features: "+v6,+vfp2,-d32".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
-            ..base
+            ..super::freebsd_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs
index 6c81a458b9b..b109aa1e1ab 100644
--- a/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs
@@ -1,20 +1,17 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::netbsd_base::opts();
-    base.max_atomic_width = Some(64);
     Target {
         llvm_target: "armv6-unknown-netbsdelf-eabihf".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             env: "eabihf".to_string(),
             features: "+v6,+vfp2,-d32".to_string(),
-            unsupported_abis: super::arm_base::unsupported_abis(),
+            max_atomic_width: Some(64),
             mcount: "__mcount".to_string(),
-            ..base
+            ..super::netbsd_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs
index 051a394657c..2f228688f43 100644
--- a/compiler/rustc_target/src/spec/armv7_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/armv7_apple_ios.rs
@@ -2,7 +2,6 @@ use super::apple_sdk_base::{opts, Arch};
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = opts("ios", Arch::Armv7);
     Target {
         llvm_target: "armv7-apple-ios".to_string(),
         pointer_width: 32,
@@ -11,8 +10,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v7,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
-            ..base
+            ..opts("ios", Arch::Armv7)
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
index 02a1191463e..821080ec07d 100644
--- a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
@@ -10,15 +10,16 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::android_base::opts();
-    base.features = "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".to_string();
-    base.max_atomic_width = Some(64);
     base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-march=armv7-a".to_string());
-
     Target {
         llvm_target: "armv7-none-linux-android".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
+        options: TargetOptions {
+            features: "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".to_string(),
+            max_atomic_width: Some(64),
+            ..base
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs
index 6f24c6818fc..190d3bb691a 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs
@@ -1,20 +1,17 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = super::freebsd_base::opts();
     Target {
         llvm_target: "armv7-unknown-freebsd-gnueabihf".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             env: "gnueabihf".to_string(),
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
-            ..base
+            ..super::freebsd_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs
index f6fe88de37c..088a8cf7534 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs
@@ -4,19 +4,16 @@ use crate::spec::{Target, TargetOptions};
 // hardfloat.
 
 pub fn target() -> Target {
-    let base = super::linux_gnu_base::opts();
     Target {
         llvm_target: "armv7-unknown-linux-gnueabi".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             features: "+v7,+thumb2,+soft-float,-neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
-            ..base
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs
index 5f0f47dd397..521053ec2d3 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs
@@ -4,20 +4,17 @@ use crate::spec::{Target, TargetOptions};
 // thumb-mode. See the thumbv7neon variant for enabling both.
 
 pub fn target() -> Target {
-    let base = super::linux_gnu_base::opts();
     Target {
         llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
-            ..base
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs
index c888fc2d4a3..0ee2c3e45e0 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs
@@ -4,7 +4,6 @@ use crate::spec::{Target, TargetOptions};
 // hardfloat.
 
 pub fn target() -> Target {
-    let base = super::linux_musl_base::opts();
     // Most of these settings are copied from the armv7_unknown_linux_gnueabi
     // target.
     Target {
@@ -19,9 +18,8 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v7,+thumb2,+soft-float,-neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}mcount".to_string(),
-            ..base
+            ..super::linux_musl_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs
index 2432ea519a8..a6ce382c7a6 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs
@@ -3,7 +3,6 @@ use crate::spec::{Target, TargetOptions};
 // This target is for musl Linux on ARMv7 without thumb-mode or NEON.
 
 pub fn target() -> Target {
-    let base = super::linux_musl_base::opts();
     Target {
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
         // uses it to determine the calling convention and float ABI, and LLVM
@@ -18,9 +17,8 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}mcount".to_string(),
-            ..base
+            ..super::linux_musl_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs
index 4fae3a8d0bf..e509dcaddaa 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs
@@ -1,20 +1,17 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = super::netbsd_base::opts();
     Target {
         llvm_target: "armv7-unknown-netbsdelf-eabihf".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             env: "eabihf".to_string(),
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "__mcount".to_string(),
-            ..base
+            ..super::netbsd_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs
index 9fe7098a85f..0aabf2fe486 100644
--- a/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs
@@ -1,7 +1,6 @@
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = super::vxworks_base::opts();
     Target {
         llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
         pointer_width: 32,
@@ -11,8 +10,7 @@ pub fn target() -> Target {
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
-            ..base
+            ..super::vxworks_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
index 74deab01916..bd703ee3e45 100644
--- a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
@@ -26,7 +26,6 @@ pub fn target() -> Target {
         disable_redzone: true,
         max_atomic_width: Some(64),
         panic_strategy: PanicStrategy::Abort,
-        unsupported_abis: super::arm_base::unsupported_abis(),
         emit_debug_gdb_scripts: false,
         ..Default::default()
     };
diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
index c5c720f5fbd..ad86ae1cedc 100644
--- a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
@@ -17,7 +17,6 @@ pub fn target() -> Target {
         disable_redzone: true,
         max_atomic_width: Some(64),
         panic_strategy: PanicStrategy::Abort,
-        unsupported_abis: super::arm_base::unsupported_abis(),
         emit_debug_gdb_scripts: false,
         ..Default::default()
     };
diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
index 3f49bd87869..c07d6adc37e 100644
--- a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
@@ -17,7 +17,6 @@ pub fn target() -> Target {
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
             max_atomic_width: Some(32),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             emit_debug_gdb_scripts: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
index 9b2e8a8058f..fbf2f8e9b72 100644
--- a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
@@ -18,7 +18,6 @@ pub fn target() -> Target {
             panic_strategy: PanicStrategy::Abort,
             features: "+vfp3,-d32,-fp16".to_string(),
             max_atomic_width: Some(32),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             emit_debug_gdb_scripts: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
index be74136a2d6..2a48e7b6214 100644
--- a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
@@ -2,7 +2,6 @@ use super::apple_sdk_base::{opts, Arch};
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = opts("ios", Arch::Armv7s);
     Target {
         llvm_target: "armv7s-apple-ios".to_string(),
         pointer_width: 32,
@@ -11,8 +10,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v7,+vfp4,+neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
-            ..base
+            ..opts("ios", Arch::Armv7s)
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/bpf_base.rs b/compiler/rustc_target/src/spec/bpf_base.rs
index 764cc735d75..4fa6e12f5ba 100644
--- a/compiler/rustc_target/src/spec/bpf_base.rs
+++ b/compiler/rustc_target/src/spec/bpf_base.rs
@@ -1,5 +1,5 @@
+use crate::abi::Endian;
 use crate::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, TargetOptions};
-use crate::{abi::Endian, spec::abi::Abi};
 
 pub fn opts(endian: Endian) -> TargetOptions {
     TargetOptions {
@@ -21,22 +21,6 @@ pub fn opts(endian: Endian) -> TargetOptions {
         requires_lto: false,
         singlethread: true,
         max_atomic_width: Some(64),
-        unsupported_abis: vec![
-            Abi::Cdecl,
-            Abi::Stdcall { unwind: false },
-            Abi::Stdcall { unwind: true },
-            Abi::Fastcall,
-            Abi::Vectorcall,
-            Abi::Thiscall { unwind: false },
-            Abi::Thiscall { unwind: true },
-            Abi::Aapcs,
-            Abi::Win64,
-            Abi::SysV64,
-            Abi::PtxKernel,
-            Abi::Msp430Interrupt,
-            Abi::X86Interrupt,
-            Abi::AmdGpuKernel,
-        ],
         ..Default::default()
     }
 }
diff --git a/compiler/rustc_target/src/spec/mipsel_unknown_none.rs b/compiler/rustc_target/src/spec/mipsel_unknown_none.rs
index 110c8dd80ea..5955baa31db 100644
--- a/compiler/rustc_target/src/spec/mipsel_unknown_none.rs
+++ b/compiler/rustc_target/src/spec/mipsel_unknown_none.rs
@@ -2,7 +2,6 @@
 //!
 //! Can be used for MIPS M4K core (e.g. on PIC32MX devices)
 
-use crate::spec::abi::Abi;
 use crate::spec::{LinkerFlavor, LldFlavor, RelocModel};
 use crate::spec::{PanicStrategy, Target, TargetOptions};
 
@@ -22,16 +21,6 @@ pub fn target() -> Target {
             linker: Some("rust-lld".to_owned()),
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
-            unsupported_abis: vec![
-                Abi::Stdcall { unwind: false },
-                Abi::Stdcall { unwind: true },
-                Abi::Fastcall,
-                Abi::Vectorcall,
-                Abi::Thiscall { unwind: false },
-                Abi::Thiscall { unwind: true },
-                Abi::Win64,
-                Abi::SysV64,
-            ],
             emit_debug_gdb_scripts: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index cfdae9623f3..0a5f8c17c63 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -55,7 +55,6 @@ pub mod crt_objects;
 mod android_base;
 mod apple_base;
 mod apple_sdk_base;
-mod arm_base;
 mod avr_gnu_base;
 mod bpf_base;
 mod dragonfly_base;
@@ -75,7 +74,6 @@ mod msvc_base;
 mod netbsd_base;
 mod openbsd_base;
 mod redox_base;
-mod riscv_base;
 mod solaris_base;
 mod thumb_base;
 mod uefi_msvc_base;
@@ -1226,11 +1224,6 @@ pub struct TargetOptions {
     /// Panic strategy: "unwind" or "abort"
     pub panic_strategy: PanicStrategy,
 
-    /// A list of ABIs unsupported by the current target. Note that generic ABIs
-    /// are considered to be supported on all platforms and cannot be marked
-    /// unsupported.
-    pub unsupported_abis: Vec<Abi>,
-
     /// Whether or not linking dylibs to a static CRT is allowed.
     pub crt_static_allows_dylibs: bool,
     /// Whether or not the CRT is statically linked by default.
@@ -1412,7 +1405,6 @@ impl Default for TargetOptions {
             max_atomic_width: None,
             atomic_cas: true,
             panic_strategy: PanicStrategy::Unwind,
-            unsupported_abis: vec![],
             crt_static_allows_dylibs: false,
             crt_static_default: false,
             crt_static_respected: false,
@@ -1465,40 +1457,88 @@ impl Target {
     /// Given a function ABI, turn it into the correct ABI for this target.
     pub fn adjust_abi(&self, abi: Abi) -> Abi {
         match abi {
-            Abi::System { unwind } => {
-                if self.is_like_windows && self.arch == "x86" {
-                    Abi::Stdcall { unwind }
-                } else {
-                    Abi::C { unwind }
-                }
-            }
-            // These ABI kinds are ignored on non-x86 Windows targets.
-            // See https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
-            // and the individual pages for __stdcall et al.
-            Abi::Stdcall { unwind } | Abi::Thiscall { unwind } => {
-                if self.is_like_windows && self.arch != "x86" { Abi::C { unwind } } else { abi }
-            }
-            Abi::Fastcall | Abi::Vectorcall => {
-                if self.is_like_windows && self.arch != "x86" {
-                    Abi::C { unwind: false }
-                } else {
-                    abi
-                }
-            }
-            Abi::EfiApi => {
-                if self.arch == "x86_64" {
-                    Abi::Win64
-                } else {
-                    Abi::C { unwind: false }
-                }
+            Abi::C { .. } => self.default_adjusted_cabi.unwrap_or(abi),
+            Abi::System { unwind } if self.is_like_windows && self.arch == "x86" => {
+                Abi::Stdcall { unwind }
             }
+            Abi::System { unwind } => Abi::C { unwind },
+            Abi::EfiApi if self.arch == "x86_64" => Abi::Win64,
+            Abi::EfiApi => Abi::C { unwind: false },
 
-            Abi::C { unwind } => self.default_adjusted_cabi.unwrap_or(Abi::C { unwind }),
+            // See commentary in `is_abi_supported`.
+            Abi::Stdcall { .. } | Abi::Thiscall { .. } if self.arch == "x86" => abi,
+            Abi::Stdcall { unwind } | Abi::Thiscall { unwind } => Abi::C { unwind },
+            Abi::Fastcall if self.arch == "x86" => abi,
+            Abi::Vectorcall if ["x86", "x86_64"].contains(&&self.arch[..]) => abi,
+            Abi::Fastcall | Abi::Vectorcall => Abi::C { unwind: false },
 
             abi => abi,
         }
     }
 
+    /// Returns a None if the UNSUPPORTED_CALLING_CONVENTIONS lint should be emitted
+    pub fn is_abi_supported(&self, abi: Abi) -> Option<bool> {
+        use Abi::*;
+        Some(match abi {
+            Rust
+            | C { .. }
+            | System { .. }
+            | RustIntrinsic
+            | RustCall
+            | PlatformIntrinsic
+            | Unadjusted
+            | Cdecl
+            | EfiApi => true,
+            X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]),
+            Aapcs | CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]),
+            Win64 | SysV64 => self.arch == "x86_64",
+            PtxKernel => self.arch == "nvptx64",
+            Msp430Interrupt => self.arch == "msp430",
+            AmdGpuKernel => self.arch == "amdgcn",
+            AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr",
+            Wasm => ["wasm32", "wasm64"].contains(&&self.arch[..]),
+            // On windows these fall-back to platform native calling convention (C) when the
+            // architecture is not supported.
+            //
+            // This is I believe a historical accident that has occurred as part of Microsoft
+            // striving to allow most of the code to "just" compile when support for 64-bit x86
+            // was added and then later again, when support for ARM architectures was added.
+            //
+            // This is well documented across MSDN. Support for this in Rust has been added in
+            // #54576. This makes much more sense in context of Microsoft's C++ than it does in
+            // Rust, but there isn't much leeway remaining here to change it back at the time this
+            // comment has been written.
+            //
+            // Following are the relevant excerpts from the MSDN documentation.
+            //
+            // > The __vectorcall calling convention is only supported in native code on x86 and
+            // x64 processors that include Streaming SIMD Extensions 2 (SSE2) and above.
+            // > ...
+            // > On ARM machines, __vectorcall is accepted and ignored by the compiler.
+            //
+            // -- https://docs.microsoft.com/en-us/cpp/cpp/vectorcall?view=msvc-160
+            //
+            // > On ARM and x64 processors, __stdcall is accepted and ignored by the compiler;
+            //
+            // -- https://docs.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-160
+            //
+            // > In most cases, keywords or compiler switches that specify an unsupported
+            // > convention on a particular platform are ignored, and the platform default
+            // > convention is used.
+            //
+            // -- https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
+            Stdcall { .. } | Fastcall | Thiscall { .. } | Vectorcall if self.is_like_windows => {
+                true
+            }
+            // Outside of Windows we want to only support these calling conventions for the
+            // architectures for which these calling conventions are actually well defined.
+            Stdcall { .. } | Fastcall | Thiscall { .. } if self.arch == "x86" => true,
+            Vectorcall if ["x86", "x86_64"].contains(&&self.arch[..]) => true,
+            // Return a `None` for other cases so that we know to emit a future compat lint.
+            Stdcall { .. } | Fastcall | Thiscall { .. } | Vectorcall => return None,
+        })
+    }
+
     /// Minimum integer size in bits that this target can perform atomic
     /// operations on.
     pub fn min_atomic_width(&self) -> u64 {
@@ -1511,10 +1551,6 @@ impl Target {
         self.max_atomic_width.unwrap_or_else(|| self.pointer_width.into())
     }
 
-    pub fn is_abi_supported(&self, abi: Abi) -> bool {
-        abi.generic() || !self.unsupported_abis.contains(&abi)
-    }
-
     /// Loads a target descriptor from a JSON object.
     pub fn from_json(mut obj: Json) -> Result<(Target, TargetWarnings), String> {
         // While ugly, this code must remain this way to retain
@@ -1974,36 +2010,6 @@ impl Target {
         key!(supported_sanitizers, SanitizerSet)?;
         key!(default_adjusted_cabi, Option<Abi>)?;
 
-        // NB: The old name is deprecated, but support for it is retained for
-        // compatibility.
-        for name in ["abi-blacklist", "unsupported-abis"].iter() {
-            if let Some(j) = obj.remove_key(name) {
-                if let Some(array) = Json::as_array(&j) {
-                    for name in array.iter().filter_map(|abi| abi.as_string()) {
-                        match lookup_abi(name) {
-                            Some(abi) => {
-                                if abi.generic() {
-                                    return Err(format!(
-                                        "The ABI \"{}\" is considered to be supported on all \
-                                        targets and cannot be marked unsupported",
-                                        abi
-                                    ));
-                                }
-
-                                base.unsupported_abis.push(abi)
-                            }
-                            None => {
-                                return Err(format!(
-                                    "Unknown ABI \"{}\" in target specification",
-                                    name
-                                ));
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
         // Each field should have been read using `Json::remove_key` so any keys remaining are unused.
         let remaining_keys = obj.as_object().ok_or("Expected JSON object for target")?.keys();
         Ok((
@@ -2241,17 +2247,6 @@ impl ToJson for Target {
             d.insert("default-adjusted-cabi".to_string(), Abi::name(abi).to_json());
         }
 
-        if default.unsupported_abis != self.unsupported_abis {
-            d.insert(
-                "unsupported-abis".to_string(),
-                self.unsupported_abis
-                    .iter()
-                    .map(|&name| Abi::name(name).to_json())
-                    .collect::<Vec<_>>()
-                    .to_json(),
-            );
-        }
-
         Json::Object(d)
     }
 }
diff --git a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs
index 97960a75b09..083262cf351 100644
--- a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs
+++ b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs
@@ -1,4 +1,3 @@
-use crate::spec::abi::Abi;
 use crate::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, Target, TargetOptions};
 
 pub fn target() -> Target {
@@ -45,25 +44,6 @@ pub fn target() -> Target {
             // produce kernel functions that call other kernel functions.
             // This behavior is not supported by PTX ISA.
             merge_functions: MergeFunctions::Disabled,
-
-            // FIXME: enable compilation tests for the target and
-            // create the tests for this.
-            unsupported_abis: vec![
-                Abi::Cdecl,
-                Abi::Stdcall { unwind: false },
-                Abi::Stdcall { unwind: true },
-                Abi::Fastcall,
-                Abi::Vectorcall,
-                Abi::Thiscall { unwind: false },
-                Abi::Thiscall { unwind: true },
-                Abi::Aapcs,
-                Abi::Win64,
-                Abi::SysV64,
-                Abi::Msp430Interrupt,
-                Abi::X86Interrupt,
-                Abi::AmdGpuKernel,
-            ],
-
             ..Default::default()
         },
     }
diff --git a/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_gnu.rs
index cf5e0201d08..a9cdad1a8b1 100644
--- a/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_gnu.rs
@@ -7,7 +7,6 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(),
         arch: "riscv32".to_string(),
         options: TargetOptions {
-            unsupported_abis: super::riscv_base::unsupported_abis(),
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv32".to_string(),
             features: "+m,+a,+f,+d,+c".to_string(),
diff --git a/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_musl.rs
index e5fbd09297f..a64a82d55b9 100644
--- a/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/riscv32gc_unknown_linux_musl.rs
@@ -7,7 +7,6 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-i64:64-n32-S128".to_string(),
         arch: "riscv32".to_string(),
         options: TargetOptions {
-            unsupported_abis: super::riscv_base::unsupported_abis(),
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv32".to_string(),
             features: "+m,+a,+f,+d,+c".to_string(),
diff --git a/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs
index 88a22f25ff4..16d37218f41 100644
--- a/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs
@@ -18,7 +18,6 @@ pub fn target() -> Target {
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
-            unsupported_abis: super::riscv_base::unsupported_abis(),
             eh_frame_header: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs
index b406eec1e75..b53bae6cb56 100644
--- a/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs
@@ -18,7 +18,6 @@ pub fn target() -> Target {
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
-            unsupported_abis: super::riscv_base::unsupported_abis(),
             eh_frame_header: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs
index 89d760e082f..9a23def1996 100644
--- a/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs
@@ -19,7 +19,6 @@ pub fn target() -> Target {
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
-            unsupported_abis: super::riscv_base::unsupported_abis(),
             eh_frame_header: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs
index 84f28413fcb..02d44b5ed7e 100644
--- a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_gnu.rs
@@ -7,7 +7,6 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".to_string(),
         arch: "riscv64".to_string(),
         options: TargetOptions {
-            unsupported_abis: super::riscv_base::unsupported_abis(),
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".to_string(),
             features: "+m,+a,+f,+d,+c".to_string(),
diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs
index 0232b15e8c2..3754750e48d 100644
--- a/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_linux_musl.rs
@@ -7,7 +7,6 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".to_string(),
         arch: "riscv64".to_string(),
         options: TargetOptions {
-            unsupported_abis: super::riscv_base::unsupported_abis(),
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".to_string(),
             features: "+m,+a,+f,+d,+c".to_string(),
diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs
index 481bce05a08..f527a6cd26d 100644
--- a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs
@@ -20,7 +20,6 @@ pub fn target() -> Target {
             relocation_model: RelocModel::Static,
             code_model: Some(CodeModel::Medium),
             emit_debug_gdb_scripts: false,
-            unsupported_abis: super::riscv_base::unsupported_abis(),
             eh_frame_header: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs
index 3e4afd446dd..8b1ba88e67f 100644
--- a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs
@@ -19,7 +19,6 @@ pub fn target() -> Target {
             relocation_model: RelocModel::Static,
             code_model: Some(CodeModel::Medium),
             emit_debug_gdb_scripts: false,
-            unsupported_abis: super::riscv_base::unsupported_abis(),
             eh_frame_header: false,
             ..Default::default()
         },
diff --git a/compiler/rustc_target/src/spec/riscv_base.rs b/compiler/rustc_target/src/spec/riscv_base.rs
deleted file mode 100644
index 5bcbb2e621b..00000000000
--- a/compiler/rustc_target/src/spec/riscv_base.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use crate::spec::abi::Abi;
-
-// All the calling conventions trigger an assertion(Unsupported calling
-// convention) in llvm on RISCV
-pub fn unsupported_abis() -> Vec<Abi> {
-    vec![
-        Abi::Cdecl,
-        Abi::Stdcall { unwind: false },
-        Abi::Stdcall { unwind: true },
-        Abi::Fastcall,
-        Abi::Vectorcall,
-        Abi::Thiscall { unwind: false },
-        Abi::Thiscall { unwind: true },
-        Abi::Aapcs,
-        Abi::Win64,
-        Abi::SysV64,
-        Abi::PtxKernel,
-        Abi::Msp430Interrupt,
-        Abi::X86Interrupt,
-        Abi::AmdGpuKernel,
-    ]
-}
diff --git a/compiler/rustc_target/src/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs
index fbe4dd5b501..bac1203980e 100644
--- a/compiler/rustc_target/src/spec/thumb_base.rs
+++ b/compiler/rustc_target/src/spec/thumb_base.rs
@@ -43,7 +43,6 @@ pub fn opts() -> TargetOptions {
         // Similarly, one almost always never wants to use relocatable code because of the extra
         // costs it involves.
         relocation_model: RelocModel::Static,
-        unsupported_abis: super::arm_base::unsupported_abis(),
         // When this section is added a volatile load to its start address is also generated. This
         // volatile load is a footgun as it can end up loading an invalid memory address, depending
         // on how the user set up their linker scripts. This section adds pretty printer for stuff
diff --git a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs
index 1232daa577f..369e6cd5e93 100644
--- a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs
@@ -2,7 +2,6 @@ use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions}
 
 pub fn target() -> Target {
     let mut base = super::windows_msvc_base::opts();
-
     // Prevent error LNK2013: BRANCH24(T) fixup overflow
     // The LBR optimization tries to eliminate branch islands,
     // but if the displacement is larger than can fit
@@ -17,20 +16,17 @@ pub fn target() -> Target {
         .or_default()
         .push(pre_link_args_msvc);
 
-    // FIXME(jordanrh): use PanicStrategy::Unwind when SEH is
-    // implemented for windows/arm in LLVM
-    base.panic_strategy = PanicStrategy::Abort;
-
     Target {
         llvm_target: "thumbv7a-pc-windows-msvc".to_string(),
         pointer_width: 32,
         data_layout: "e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             features: "+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
+            // FIXME(jordanrh): use PanicStrategy::Unwind when SEH is
+            // implemented for windows/arm in LLVM
+            panic_strategy: PanicStrategy::Abort,
             ..base
         },
     }
diff --git a/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs
index e6a59f015c9..b44c0085005 100644
--- a/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/thumbv7a_uwp_windows_msvc.rs
@@ -1,14 +1,6 @@
 use crate::spec::{PanicStrategy, Target, TargetOptions};
 
 pub fn target() -> Target {
-    let mut base = super::windows_uwp_msvc_base::opts();
-    base.max_atomic_width = Some(64);
-    base.has_elf_tls = true;
-
-    // FIXME(jordanrh): use PanicStrategy::Unwind when SEH is
-    // implemented for windows/arm in LLVM
-    base.panic_strategy = PanicStrategy::Abort;
-
     Target {
         llvm_target: "thumbv7a-pc-windows-msvc".to_string(),
         pointer_width: 32,
@@ -16,8 +8,12 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
         options: TargetOptions {
             features: "+vfp3,+neon".to_string(),
-            unsupported_abis: super::arm_base::unsupported_abis(),
-            ..base
+            max_atomic_width: Some(64),
+            has_elf_tls: true,
+            // FIXME(jordanrh): use PanicStrategy::Unwind when SEH is
+            // implemented for windows/arm in LLVM
+            panic_strategy: PanicStrategy::Abort,
+            ..super::windows_uwp_msvc_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
index 58b0a9d2202..14020b88695 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
@@ -10,15 +10,16 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
 
 pub fn target() -> Target {
     let mut base = super::android_base::opts();
-    base.features = "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string();
-    base.max_atomic_width = Some(64);
     base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-march=armv7-a".to_string());
-
     Target {
         llvm_target: "armv7-none-linux-android".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
+        options: TargetOptions {
+            features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
+            max_atomic_width: Some(64),
+            ..base
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
index 12d816d095b..4042d539416 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
@@ -7,19 +7,16 @@ use crate::spec::{Target, TargetOptions};
 // https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
 
 pub fn target() -> Target {
-    let base = super::linux_gnu_base::opts();
     Target {
         llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
         pointer_width: 32,
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
-
         options: TargetOptions {
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
-            ..base
+            ..super::linux_gnu_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
index 020de87147c..318b864a9cf 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
@@ -7,7 +7,6 @@ use crate::spec::{Target, TargetOptions};
 // https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
 
 pub fn target() -> Target {
-    let base = super::linux_musl_base::opts();
     Target {
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
         // uses it to determine the calling convention and float ABI, and LLVM
@@ -22,9 +21,8 @@ pub fn target() -> Target {
         options: TargetOptions {
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
-            unsupported_abis: super::arm_base::unsupported_abis(),
             mcount: "\u{1}mcount".to_string(),
-            ..base
+            ..super::linux_musl_base::opts()
         },
     }
 }
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 77644ea1c3c..496721e6f76 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -17,7 +17,7 @@ use rustc_middle::ty::layout::MAX_SIMD_LANES;
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::util::{Discr, IntTypeExt};
 use rustc_middle::ty::{self, OpaqueTypeKey, ParamEnv, RegionKind, Ty, TyCtxt};
-use rustc_session::lint::builtin::UNINHABITED_STATIC;
+use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
 use rustc_span::symbol::sym;
 use rustc_span::{self, MultiSpan, Span};
 use rustc_target::spec::abi::Abi;
@@ -34,16 +34,22 @@ pub fn check_wf_new(tcx: TyCtxt<'_>) {
     tcx.hir().krate().par_visit_all_item_likes(&visit);
 }
 
-pub(super) fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: Abi) {
-    if !tcx.sess.target.is_abi_supported(abi) {
-        struct_span_err!(
+pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
+    match tcx.sess.target.is_abi_supported(abi) {
+        Some(true) => (),
+        Some(false) => struct_span_err!(
             tcx.sess,
             span,
             E0570,
-            "The ABI `{}` is not supported for the current target",
+            "`{}` is not a supported ABI for the current target",
             abi
         )
-        .emit()
+        .emit(),
+        None => {
+            tcx.struct_span_lint_hir(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
+                lint.build("use of calling convention not supported on this target").emit()
+            });
+        }
     }
 
     // This ABI is only allowed on function pointers
@@ -828,7 +834,7 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
             check_type_params_are_used(tcx, &generics, pty_ty);
         }
         hir::ItemKind::ForeignMod { abi, items } => {
-            check_abi(tcx, it.span, abi);
+            check_abi(tcx, it.hir_id(), it.span, abi);
 
             if abi == Abi::RustIntrinsic {
                 for item in items {
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index b5dc7b750b1..ff7d291d3c9 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -499,7 +499,7 @@ fn typeck_with_fallback<'tcx>(
                 tcx.fn_sig(def_id)
             };
 
-            check_abi(tcx, span, fn_sig.abi());
+            check_abi(tcx, id, span, fn_sig.abi());
 
             // Compute the fty from point of view of inside the fn.
             let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
diff --git a/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs b/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs
index ed804ca278d..f1dff27ad67 100644
--- a/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/stdcall-unwind-abi.rs
@@ -1,15 +1,14 @@
-// compile-flags: -C opt-level=0
-// ignore-arm stdcall isn't supported
-// ignore-aarch64 stdcall isn't supported
-// ignore-riscv64 stdcall isn't supported
+// needs-llvm-components: x86
+// compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes
+#![no_core]
+#![feature(no_core, lang_items, c_unwind)]
+#[lang="sized"]
+trait Sized { }
 
 // Test that `nounwind` atributes are correctly applied to exported `stdcall` and `stdcall-unwind`
 // extern functions. `stdcall-unwind` functions MUST NOT have this attribute. We disable
 // optimizations above to prevent LLVM from inferring the attribute.
 
-#![crate_type = "lib"]
-#![feature(c_unwind)]
-
 // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 {
 #[no_mangle]
 pub extern "stdcall" fn rust_item_that_cannot_unwind() {
diff --git a/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs b/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs
index aaa63ae55c3..d2cf041b72d 100644
--- a/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs
+++ b/src/test/codegen/unwind-abis/thiscall-unwind-abi.rs
@@ -1,16 +1,14 @@
-// compile-flags: -C opt-level=0
-// ignore-arm thiscall isn't supported
-// ignore-aarch64 thiscall isn't supported
-// ignore-riscv64 thiscall isn't supported
+// needs-llvm-components: x86
+// compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib -Cno-prepopulate-passes
+#![no_core]
+#![feature(no_core, lang_items, c_unwind, abi_thiscall)]
+#[lang="sized"]
+trait Sized { }
 
 // Test that `nounwind` atributes are correctly applied to exported `thiscall` and
 // `thiscall-unwind` extern functions. `thiscall-unwind` functions MUST NOT have this attribute. We
 // disable optimizations above to prevent LLVM from inferring the attribute.
 
-#![crate_type = "lib"]
-#![feature(abi_thiscall)]
-#![feature(c_unwind)]
-
 // CHECK: @rust_item_that_cannot_unwind() unnamed_addr #0 {
 #[no_mangle]
 pub extern "thiscall" fn rust_item_that_cannot_unwind() {
diff --git a/src/test/ui/abi/unsupported.aarch64.stderr b/src/test/ui/abi/unsupported.aarch64.stderr
new file mode 100644
index 00000000000..89017453759
--- /dev/null
+++ b/src/test/ui/abi/unsupported.aarch64.stderr
@@ -0,0 +1,58 @@
+error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:24:1
+   |
+LL | extern "ptx-kernel" fn ptx() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:26:1
+   |
+LL | extern "amdgpu-kernel" fn amdgpu() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"wasm"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:28:1
+   |
+LL | extern "wasm" fn wasm() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:33:1
+   |
+LL | extern "msp430-interrupt" fn msp430() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:35:1
+   |
+LL | extern "avr-interrupt" fn avr() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:37:1
+   |
+LL | extern "x86-interrupt" fn x86() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:39:1
+   |
+LL | extern "stdcall" fn stdcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #00000 <https://github.com/rust-lang/rust/issues/00000>
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:44:1
+   |
+LL | extern "thiscall" fn thiscall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #00000 <https://github.com/rust-lang/rust/issues/00000>
+
+error: aborting due to 6 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0570`.
diff --git a/src/test/ui/abi/unsupported.i686.stderr b/src/test/ui/abi/unsupported.i686.stderr
new file mode 100644
index 00000000000..81b12653d2e
--- /dev/null
+++ b/src/test/ui/abi/unsupported.i686.stderr
@@ -0,0 +1,39 @@
+error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:24:1
+   |
+LL | extern "ptx-kernel" fn ptx() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:26:1
+   |
+LL | extern "amdgpu-kernel" fn amdgpu() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"wasm"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:28:1
+   |
+LL | extern "wasm" fn wasm() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"aapcs"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:30:1
+   |
+LL | extern "aapcs" fn aapcs() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:33:1
+   |
+LL | extern "msp430-interrupt" fn msp430() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:35:1
+   |
+LL | extern "avr-interrupt" fn avr() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0570`.
diff --git a/src/test/ui/abi/unsupported.rs b/src/test/ui/abi/unsupported.rs
new file mode 100644
index 00000000000..f0debdcf621
--- /dev/null
+++ b/src/test/ui/abi/unsupported.rs
@@ -0,0 +1,48 @@
+// revisions: x64 i686 aarch64
+//
+// [x64] needs-llvm-components: x86
+// [x64]compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib
+// [i686] needs-llvm-components: x86
+// [i686]compile-flags: --target=i686-unknown-linux-gnu --crate-type=rlib
+// [aarch64] needs-llvm-components: aarch64
+// [aarch64]compile-flags: --target=aarch64-unknown-linux-gnu --crate-type=rlib
+#![no_core]
+#![feature(
+    no_core,
+    lang_items,
+    abi_ptx,
+    abi_msp430_interrupt,
+    abi_avr_interrupt,
+    abi_thiscall,
+    abi_amdgpu_kernel,
+    wasm_abi,
+    abi_x86_interrupt
+)]
+#[lang="sized"]
+trait Sized { }
+
+extern "ptx-kernel" fn ptx() {}
+//~^ ERROR is not a supported ABI
+extern "amdgpu-kernel" fn amdgpu() {}
+//~^ ERROR is not a supported ABI
+extern "wasm" fn wasm() {}
+//~^ ERROR is not a supported ABI
+extern "aapcs" fn aapcs() {}
+//[x64]~^ ERROR is not a supported ABI
+//[i686]~^^ ERROR is not a supported ABI
+extern "msp430-interrupt" fn msp430() {}
+//~^ ERROR is not a supported ABI
+extern "avr-interrupt" fn avr() {}
+//~^ ERROR is not a supported ABI
+extern "x86-interrupt" fn x86() {}
+//[aarch64]~^ ERROR is not a supported ABI
+extern "stdcall" fn stdcall() {}
+//[x64]~^ WARN use of calling convention not supported
+//[x64]~^^ WARN this was previously accepted
+//[aarch64]~^^^ WARN use of calling convention not supported
+//[aarch64]~^^^^ WARN this was previously accepted
+extern "thiscall" fn thiscall() {}
+//[x64]~^ WARN use of calling convention not supported
+//[x64]~^^ WARN this was previously accepted
+//[aarch64]~^^^ WARN use of calling convention not supported
+//[aarch64]~^^^^ WARN this was previously accepted
diff --git a/src/test/ui/abi/unsupported.x64.stderr b/src/test/ui/abi/unsupported.x64.stderr
new file mode 100644
index 00000000000..5c68461e4fb
--- /dev/null
+++ b/src/test/ui/abi/unsupported.x64.stderr
@@ -0,0 +1,58 @@
+error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:24:1
+   |
+LL | extern "ptx-kernel" fn ptx() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:26:1
+   |
+LL | extern "amdgpu-kernel" fn amdgpu() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"wasm"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:28:1
+   |
+LL | extern "wasm" fn wasm() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"aapcs"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:30:1
+   |
+LL | extern "aapcs" fn aapcs() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:33:1
+   |
+LL | extern "msp430-interrupt" fn msp430() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
+  --> $DIR/unsupported.rs:35:1
+   |
+LL | extern "avr-interrupt" fn avr() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:39:1
+   |
+LL | extern "stdcall" fn stdcall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #00000 <https://github.com/rust-lang/rust/issues/00000>
+
+warning: use of calling convention not supported on this target
+  --> $DIR/unsupported.rs:44:1
+   |
+LL | extern "thiscall" fn thiscall() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #00000 <https://github.com/rust-lang/rust/issues/00000>
+
+error: aborting due to 6 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0570`.
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.rs b/src/test/ui/c-variadic/variadic-ffi-1.rs
index 2c02a0d3081..a76efd9a205 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.rs
+++ b/src/test/ui/c-variadic/variadic-ffi-1.rs
@@ -1,6 +1,9 @@
-// ignore-arm stdcall isn't supported
-// ignore-aarch64 stdcall isn't supported
-// ignore-riscv64 stdcall isn't supported
+// needs-llvm-components: x86
+// compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
 
 extern "stdcall" {
     fn printf(_: *const u8, ...); //~ ERROR: variadic function must have C or cdecl calling
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr
index 6f2a6c359b5..5b4e656d9dc 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr
@@ -1,11 +1,11 @@
 error[E0045]: C-variadic function must have C or cdecl calling convention
-  --> $DIR/variadic-ffi-1.rs:6:5
+  --> $DIR/variadic-ffi-1.rs:9:5
    |
 LL |     fn printf(_: *const u8, ...);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadics require C or cdecl calling convention
 
 error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied
-  --> $DIR/variadic-ffi-1.rs:17:9
+  --> $DIR/variadic-ffi-1.rs:20:9
    |
 LL |         foo();
    |         ^^^-- supplied 0 arguments
@@ -13,13 +13,13 @@ LL |         foo();
    |         expected at least 2 arguments
    |
 note: function defined here
-  --> $DIR/variadic-ffi-1.rs:10:8
+  --> $DIR/variadic-ffi-1.rs:13:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^
 
 error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
-  --> $DIR/variadic-ffi-1.rs:18:9
+  --> $DIR/variadic-ffi-1.rs:21:9
    |
 LL |         foo(1);
    |         ^^^ - supplied 1 argument
@@ -27,13 +27,13 @@ LL |         foo(1);
    |         expected at least 2 arguments
    |
 note: function defined here
-  --> $DIR/variadic-ffi-1.rs:10:8
+  --> $DIR/variadic-ffi-1.rs:13:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^
 
 error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-1.rs:20:56
+  --> $DIR/variadic-ffi-1.rs:23:56
    |
 LL |         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
    |                -------------------------------------   ^^^ expected non-variadic fn, found variadic function
@@ -44,7 +44,7 @@ LL |         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
                  found fn item `unsafe extern "C" fn(_, _, ...) {foo}`
 
 error[E0308]: mismatched types
-  --> $DIR/variadic-ffi-1.rs:21:54
+  --> $DIR/variadic-ffi-1.rs:24:54
    |
 LL |         let y: extern "C" fn(f: isize, x: u8, ...) = bar;
    |                -----------------------------------   ^^^ expected variadic fn, found non-variadic function
@@ -55,37 +55,37 @@ LL |         let y: extern "C" fn(f: isize, x: u8, ...) = bar;
                  found fn item `extern "C" fn(_, _) {bar}`
 
 error[E0617]: can't pass `f32` to variadic function
-  --> $DIR/variadic-ffi-1.rs:23:19
+  --> $DIR/variadic-ffi-1.rs:26:19
    |
 LL |         foo(1, 2, 3f32);
    |                   ^^^^ help: cast the value to `c_double`: `3f32 as c_double`
 
 error[E0617]: can't pass `bool` to variadic function
-  --> $DIR/variadic-ffi-1.rs:24:19
+  --> $DIR/variadic-ffi-1.rs:27:19
    |
 LL |         foo(1, 2, true);
    |                   ^^^^ help: cast the value to `c_int`: `true as c_int`
 
 error[E0617]: can't pass `i8` to variadic function
-  --> $DIR/variadic-ffi-1.rs:25:19
+  --> $DIR/variadic-ffi-1.rs:28:19
    |
 LL |         foo(1, 2, 1i8);
    |                   ^^^ help: cast the value to `c_int`: `1i8 as c_int`
 
 error[E0617]: can't pass `u8` to variadic function
-  --> $DIR/variadic-ffi-1.rs:26:19
+  --> $DIR/variadic-ffi-1.rs:29:19
    |
 LL |         foo(1, 2, 1u8);
    |                   ^^^ help: cast the value to `c_uint`: `1u8 as c_uint`
 
 error[E0617]: can't pass `i16` to variadic function
-  --> $DIR/variadic-ffi-1.rs:27:19
+  --> $DIR/variadic-ffi-1.rs:30:19
    |
 LL |         foo(1, 2, 1i16);
    |                   ^^^^ help: cast the value to `c_int`: `1i16 as c_int`
 
 error[E0617]: can't pass `u16` to variadic function
-  --> $DIR/variadic-ffi-1.rs:28:19
+  --> $DIR/variadic-ffi-1.rs:31:19
    |
 LL |         foo(1, 2, 1u16);
    |                   ^^^^ help: cast the value to `c_uint`: `1u16 as c_uint`
diff --git a/src/test/ui/extern/extern-methods.rs b/src/test/ui/extern/extern-methods.rs
index 97559a68442..3909b5301ad 100644
--- a/src/test/ui/extern/extern-methods.rs
+++ b/src/test/ui/extern/extern-methods.rs
@@ -1,7 +1,5 @@
 // run-pass
-// ignore-arm
-// ignore-aarch64
-// ignore-riscv64 fastcall isn't supported
+// only-i686
 
 trait A {
     extern "fastcall" fn test1(i: i32);
diff --git a/src/test/ui/extern/extern-thiscall.rs b/src/test/ui/extern/extern-thiscall.rs
index c6ff8a43204..8ce94aa71aa 100644
--- a/src/test/ui/extern/extern-thiscall.rs
+++ b/src/test/ui/extern/extern-thiscall.rs
@@ -1,7 +1,5 @@
 // run-pass
-// ignore-arm
-// ignore-aarch64
-// ignore-riscv64 thiscall isn't supported
+// only-i686
 
 #![feature(abi_thiscall)]
 
diff --git a/src/test/ui/extern/extern-vectorcall.rs b/src/test/ui/extern/extern-vectorcall.rs
index da50c3fb927..f625eb0890f 100644
--- a/src/test/ui/extern/extern-vectorcall.rs
+++ b/src/test/ui/extern/extern-vectorcall.rs
@@ -1,7 +1,7 @@
 // run-pass
-// ignore-arm
-// ignore-aarch64
-// ignore-riscv64 vectorcall isn't supported
+// revisions: x64 x32
+// [x64]only-x86_64
+// [x32]only-i686
 
 #![feature(abi_vectorcall)]
 
diff --git a/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs
index 0d7df8182c4..05461297afd 100644
--- a/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs
+++ b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.rs
@@ -1,9 +1,51 @@
+// needs-llvm-components: avr
+// compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
+
 // Test that the AVR interrupt ABI cannot be used when avr_interrupt
 // feature gate is not used.
 
-extern "avr-interrupt" fn foo() {}
-//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+extern "avr-non-blocking-interrupt" fn fu() {}
+//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+extern "avr-interrupt" fn f() {}
+//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+
+trait T {
+    extern "avr-interrupt" fn m();
+    //~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+    extern "avr-non-blocking-interrupt" fn mu();
+    //~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+
+    extern "avr-interrupt" fn dm() {}
+    //~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+    extern "avr-non-blocking-interrupt" fn dmu() {}
+    //~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+}
+
+struct S;
+impl T for S {
+    extern "avr-interrupt" fn m() {}
+    //~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+    extern "avr-non-blocking-interrupt" fn mu() {}
+    //~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+}
 
-fn main() {
-    foo();
+impl S {
+    extern "avr-interrupt" fn im() {}
+    //~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+    extern "avr-non-blocking-interrupt" fn imu() {}
+    //~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
 }
+
+type TA = extern "avr-interrupt" fn();
+//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+type TAU = extern "avr-non-blocking-interrupt" fn();
+//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+
+extern "avr-interrupt" {}
+//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
+extern "avr-non-blocking-interrupt" {}
+//~^ ERROR avr-interrupt and avr-non-blocking-interrupt ABIs are experimental
diff --git a/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr
index be7040e1491..d017d03a385 100644
--- a/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi-avr-interrupt.stderr
@@ -1,12 +1,129 @@
 error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi-avr-interrupt.rs:4:8
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:11:8
    |
-LL | extern "avr-interrupt" fn foo() {}
+LL | extern "avr-non-blocking-interrupt" fn fu() {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:13:8
+   |
+LL | extern "avr-interrupt" fn f() {}
    |        ^^^^^^^^^^^^^^^
    |
    = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
    = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:17:12
+   |
+LL |     extern "avr-interrupt" fn m();
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:19:12
+   |
+LL |     extern "avr-non-blocking-interrupt" fn mu();
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:22:12
+   |
+LL |     extern "avr-interrupt" fn dm() {}
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:24:12
+   |
+LL |     extern "avr-non-blocking-interrupt" fn dmu() {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:30:12
+   |
+LL |     extern "avr-interrupt" fn m() {}
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:32:12
+   |
+LL |     extern "avr-non-blocking-interrupt" fn mu() {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:37:12
+   |
+LL |     extern "avr-interrupt" fn im() {}
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:39:12
+   |
+LL |     extern "avr-non-blocking-interrupt" fn imu() {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:43:18
+   |
+LL | type TA = extern "avr-interrupt" fn();
+   |                  ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:45:19
+   |
+LL | type TAU = extern "avr-non-blocking-interrupt" fn();
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:48:8
+   |
+LL | extern "avr-interrupt" {}
+   |        ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error[E0658]: avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi-avr-interrupt.rs:50:8
+   |
+LL | extern "avr-non-blocking-interrupt" {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #69664 <https://github.com/rust-lang/rust/issues/69664> for more information
+   = help: add `#![feature(abi_avr_interrupt)]` to the crate attributes to enable
+
+error: aborting due to 14 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs
index 440570c5494..8b7d8066aa6 100644
--- a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs
+++ b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs
@@ -1,11 +1,34 @@
-// Test that the MSP430 interrupt ABI cannot be used when msp430_interrupt
-// feature gate is not used.
+// needs-llvm-components: msp430
+// compile-flags: --target=msp430-none-elf --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
 
-// ignore-riscv64 msp430 is not supported
+extern "msp430-interrupt" fn f() {}
+//~^ ERROR msp430-interrupt ABI is experimental
 
-extern "msp430-interrupt" fn foo() {}
-//~^ ERROR msp430-interrupt ABI is experimental and subject to change
+trait T {
+    extern "msp430-interrupt" fn m();
+    //~^ ERROR msp430-interrupt ABI is experimental
 
-fn main() {
-    foo();
+    extern "msp430-interrupt" fn dm() {}
+    //~^ ERROR msp430-interrupt ABI is experimental
 }
+
+struct S;
+impl T for S {
+    extern "msp430-interrupt" fn m() {}
+    //~^ ERROR msp430-interrupt ABI is experimental
+}
+
+impl S {
+    extern "msp430-interrupt" fn im() {}
+    //~^ ERROR msp430-interrupt ABI is experimental
+}
+
+type TA = extern "msp430-interrupt" fn();
+//~^ ERROR msp430-interrupt ABI is experimental
+
+extern "msp430-interrupt" {}
+//~^ ERROR msp430-interrupt ABI is experimental
diff --git a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr
index 554226bd2b9..c19ec97896b 100644
--- a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr
@@ -1,12 +1,66 @@
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi-msp430-interrupt.rs:6:8
+  --> $DIR/feature-gate-abi-msp430-interrupt.rs:8:8
    |
-LL | extern "msp430-interrupt" fn foo() {}
+LL | extern "msp430-interrupt" fn f() {}
    |        ^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: msp430-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-msp430-interrupt.rs:12:12
+   |
+LL |     extern "msp430-interrupt" fn m();
+   |            ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
+   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
+
+error[E0658]: msp430-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-msp430-interrupt.rs:15:12
+   |
+LL |     extern "msp430-interrupt" fn dm() {}
+   |            ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
+   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
+
+error[E0658]: msp430-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-msp430-interrupt.rs:21:12
+   |
+LL |     extern "msp430-interrupt" fn m() {}
+   |            ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
+   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
+
+error[E0658]: msp430-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-msp430-interrupt.rs:26:12
+   |
+LL |     extern "msp430-interrupt" fn im() {}
+   |            ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
+   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
+
+error[E0658]: msp430-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-msp430-interrupt.rs:30:18
+   |
+LL | type TA = extern "msp430-interrupt" fn();
+   |                  ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
+   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
+
+error[E0658]: msp430-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-msp430-interrupt.rs:33:8
+   |
+LL | extern "msp430-interrupt" {}
+   |        ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
+   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-abi-x86-interrupt.rs b/src/test/ui/feature-gates/feature-gate-abi-x86-interrupt.rs
new file mode 100644
index 00000000000..7c3e4d10d99
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-abi-x86-interrupt.rs
@@ -0,0 +1,28 @@
+// needs-llvm-components: x86
+// compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
+
+extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental
+trait Tr {
+    extern "x86-interrupt" fn m7(); //~ ERROR x86-interrupt ABI is experimental
+    extern "x86-interrupt" fn dm7() {} //~ ERROR x86-interrupt ABI is experimental
+}
+
+struct S;
+
+// Methods in trait impl
+impl Tr for S {
+    extern "x86-interrupt" fn m7() {} //~ ERROR x86-interrupt ABI is experimental
+}
+
+// Methods in inherent impl
+impl S {
+    extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
+}
+
+type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental
+
+extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental
diff --git a/src/test/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr b/src/test/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr
new file mode 100644
index 00000000000..3b727a745e8
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-abi-x86-interrupt.stderr
@@ -0,0 +1,66 @@
+error[E0658]: x86-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-x86-interrupt.rs:8:8
+   |
+LL | extern "x86-interrupt" fn f7() {}
+   |        ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
+   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
+
+error[E0658]: x86-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-x86-interrupt.rs:10:12
+   |
+LL |     extern "x86-interrupt" fn m7();
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
+   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
+
+error[E0658]: x86-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-x86-interrupt.rs:11:12
+   |
+LL |     extern "x86-interrupt" fn dm7() {}
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
+   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
+
+error[E0658]: x86-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-x86-interrupt.rs:18:12
+   |
+LL |     extern "x86-interrupt" fn m7() {}
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
+   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
+
+error[E0658]: x86-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-x86-interrupt.rs:23:12
+   |
+LL |     extern "x86-interrupt" fn im7() {}
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
+   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
+
+error[E0658]: x86-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-x86-interrupt.rs:26:18
+   |
+LL | type A7 = extern "x86-interrupt" fn();
+   |                  ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
+   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
+
+error[E0658]: x86-interrupt ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi-x86-interrupt.rs:28:8
+   |
+LL | extern "x86-interrupt" {}
+   |        ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
+   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-abi.rs b/src/test/ui/feature-gates/feature-gate-abi.rs
index 49cf2e158ed..855263595d0 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.rs
+++ b/src/test/ui/feature-gates/feature-gate-abi.rs
@@ -1,27 +1,21 @@
-// only-x86_64
 // gate-test-intrinsics
 // gate-test-platform_intrinsics
-// gate-test-abi_vectorcall
-// gate-test-abi_thiscall
-// gate-test-abi_ptx
-// gate-test-abi_x86_interrupt
-// gate-test-abi_amdgpu_kernel
 // gate-test-abi_efiapi
+// compile-flags: --crate-type=rlib
+
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized { }
 
 // Functions
 extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
                                    //~^ ERROR intrinsic must be in
 extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental
                                        //~^ ERROR intrinsic must be in
-extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject to change
 extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change
-extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental
-extern "ptx-kernel" fn f6() {} //~ ERROR PTX ABIs are experimental and subject to change
-extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental
-extern "thiscall" fn f8() {} //~ ERROR thiscall is experimental and subject to change
-extern "amdgpu-kernel" fn f9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
 extern "efiapi" fn f10() {} //~ ERROR efiapi ABI is experimental and subject to change
-extern "wasm" fn f11() {} //~ ERROR wasm ABI is experimental and subject to change
 
 // Methods in trait definition
 trait Tr {
@@ -29,25 +23,11 @@ trait Tr {
                                      //~^ ERROR intrinsic must be in
     extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental
                                          //~^ ERROR intrinsic must be in
-    extern "vectorcall" fn m3(); //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn m4(_: ()); //~ ERROR rust-call ABI is subject to change
-    extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental
-    extern "ptx-kernel" fn m6(); //~ ERROR PTX ABIs are experimental and subject to change
-    extern "x86-interrupt" fn m7(); //~ ERROR x86-interrupt ABI is experimental
-    extern "thiscall" fn m8(); //~ ERROR thiscall is experimental and subject to change
-    extern "amdgpu-kernel" fn m9(); //~ ERROR amdgpu-kernel ABI is experimental and subject to change
     extern "efiapi" fn m10(); //~ ERROR efiapi ABI is experimental and subject to change
-    extern "wasm" fn m11() {} //~ ERROR wasm ABI is experimental and subject to change
 
-    extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn dm4(_: ()) {} //~ ERROR rust-call ABI is subject to change
-    extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental
-    extern "ptx-kernel" fn dm6() {} //~ ERROR PTX ABIs are experimental and subject to change
-    extern "x86-interrupt" fn dm7() {} //~ ERROR x86-interrupt ABI is experimental
-    extern "thiscall" fn dm8() {} //~ ERROR thiscall is experimental and subject to change
-    extern "amdgpu-kernel" fn dm9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
     extern "efiapi" fn dm10() {} //~ ERROR efiapi ABI is experimental and subject to change
-    extern "wasm" fn dm11() {} //~ ERROR wasm ABI is experimental and subject to change
 }
 
 struct S;
@@ -58,15 +38,8 @@ impl Tr for S {
                                        //~^ ERROR intrinsic must be in
     extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental
                                            //~^ ERROR intrinsic must be in
-    extern "vectorcall" fn m3() {} //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn m4(_: ()) {} //~ ERROR rust-call ABI is subject to change
-    extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental
-    extern "ptx-kernel" fn m6() {} //~ ERROR PTX ABIs are experimental and subject to change
-    extern "x86-interrupt" fn m7() {} //~ ERROR x86-interrupt ABI is experimental
-    extern "thiscall" fn m8() {} //~ ERROR thiscall is experimental and subject to change
-    extern "amdgpu-kernel" fn m9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
     extern "efiapi" fn m10() {} //~ ERROR efiapi ABI is experimental and subject to change
-    extern "wasm" fn m11() {} //~ ERROR wasm ABI is experimental and subject to change
 }
 
 // Methods in inherent impl
@@ -75,41 +48,18 @@ impl S {
                                         //~^ ERROR intrinsic must be in
     extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental
                                             //~^ ERROR intrinsic must be in
-    extern "vectorcall" fn im3() {} //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn im4(_: ()) {} //~ ERROR rust-call ABI is subject to change
-    extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental
-    extern "ptx-kernel" fn im6() {} //~ ERROR PTX ABIs are experimental and subject to change
-    extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental
-    extern "thiscall" fn im8() {} //~ ERROR thiscall is experimental and subject to change
-    extern "amdgpu-kernel" fn im9() {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
     extern "efiapi" fn im10() {} //~ ERROR efiapi ABI is experimental and subject to change
-    extern "wasm" fn im11() {} //~ ERROR wasm ABI is experimental and subject to change
 }
 
 // Function pointer types
 type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change
 type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are experimental
-type A3 = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental and subject to change
 type A4 = extern "rust-call" fn(_: ()); //~ ERROR rust-call ABI is subject to change
-type A5 = extern "msp430-interrupt" fn(); //~ ERROR msp430-interrupt ABI is experimental
-type A6 = extern "ptx-kernel" fn(); //~ ERROR PTX ABIs are experimental and subject to change
-type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental
-type A8 = extern "thiscall" fn(); //~ ERROR thiscall is experimental and subject to change
-type A9 = extern "amdgpu-kernel" fn(); //~ ERROR amdgpu-kernel ABI is experimental and subject to change
 type A10 = extern "efiapi" fn(); //~ ERROR efiapi ABI is experimental and subject to change
-type A11 = extern "wasm" fn(); //~ ERROR wasm ABI is experimental and subject to change
 
 // Foreign modules
 extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
 extern "platform-intrinsic" {} //~ ERROR platform intrinsics are experimental
-extern "vectorcall" {} //~ ERROR vectorcall is experimental and subject to change
 extern "rust-call" {} //~ ERROR rust-call ABI is subject to change
-extern "msp430-interrupt" {} //~ ERROR msp430-interrupt ABI is experimental
-extern "ptx-kernel" {} //~ ERROR PTX ABIs are experimental and subject to change
-extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental
-extern "thiscall" {} //~ ERROR thiscall is experimental and subject to change
-extern "amdgpu-kernel" {} //~ ERROR amdgpu-kernel ABI is experimental and subject to change
 extern "efiapi" {} //~ ERROR efiapi ABI is experimental and subject to change
-extern "wasm" {} //~ ERROR wasm ABI is experimental and subject to change
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr
index 078d21ad36f..bcca39c8fb8 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi.stderr
@@ -1,5 +1,5 @@
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:12:8
+  --> $DIR/feature-gate-abi.rs:13:8
    |
 LL | extern "rust-intrinsic" fn f1() {}
    |        ^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | extern "rust-intrinsic" fn f1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:14:8
+  --> $DIR/feature-gate-abi.rs:15:8
    |
 LL | extern "platform-intrinsic" fn f2() {}
    |        ^^^^^^^^^^^^^^^^^^^^
@@ -15,14 +15,6 @@ LL | extern "platform-intrinsic" fn f2() {}
    = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
-error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:16:8
-   |
-LL | extern "vectorcall" fn f3() {}
-   |        ^^^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
-
 error[E0658]: rust-call ABI is subject to change
   --> $DIR/feature-gate-abi.rs:17:8
    |
@@ -32,52 +24,8 @@ LL | extern "rust-call" fn f4(_: ()) {}
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:18:8
-   |
-LL | extern "msp430-interrupt" fn f5() {}
-   |        ^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
-   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
-
-error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:19:8
-   |
-LL | extern "ptx-kernel" fn f6() {}
-   |        ^^^^^^^^^^^^
-   |
-   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
-   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
-
-error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:20:8
-   |
-LL | extern "x86-interrupt" fn f7() {}
-   |        ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
-   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
-
-error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:21:8
-   |
-LL | extern "thiscall" fn f8() {}
-   |        ^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
-
-error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:22:8
-   |
-LL | extern "amdgpu-kernel" fn f9() {}
-   |        ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
-   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
-
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:23:8
+  --> $DIR/feature-gate-abi.rs:18:8
    |
 LL | extern "efiapi" fn f10() {}
    |        ^^^^^^^^
@@ -85,17 +33,8 @@ LL | extern "efiapi" fn f10() {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:24:8
-   |
-LL | extern "wasm" fn f11() {}
-   |        ^^^^^^
-   |
-   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
-   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
-
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:28:12
+  --> $DIR/feature-gate-abi.rs:22:12
    |
 LL |     extern "rust-intrinsic" fn m1();
    |            ^^^^^^^^^^^^^^^^
@@ -103,7 +42,7 @@ LL |     extern "rust-intrinsic" fn m1();
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:30:12
+  --> $DIR/feature-gate-abi.rs:24:12
    |
 LL |     extern "platform-intrinsic" fn m2();
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -111,16 +50,8 @@ LL |     extern "platform-intrinsic" fn m2();
    = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
-error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:32:12
-   |
-LL |     extern "vectorcall" fn m3();
-   |            ^^^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
-
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:33:12
+  --> $DIR/feature-gate-abi.rs:26:12
    |
 LL |     extern "rust-call" fn m4(_: ());
    |            ^^^^^^^^^^^
@@ -128,52 +59,8 @@ LL |     extern "rust-call" fn m4(_: ());
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:34:12
-   |
-LL |     extern "msp430-interrupt" fn m5();
-   |            ^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
-   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
-
-error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:35:12
-   |
-LL |     extern "ptx-kernel" fn m6();
-   |            ^^^^^^^^^^^^
-   |
-   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
-   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
-
-error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:36:12
-   |
-LL |     extern "x86-interrupt" fn m7();
-   |            ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
-   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
-
-error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:37:12
-   |
-LL |     extern "thiscall" fn m8();
-   |            ^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
-
-error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:38:12
-   |
-LL |     extern "amdgpu-kernel" fn m9();
-   |            ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
-   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
-
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:39:12
+  --> $DIR/feature-gate-abi.rs:27:12
    |
 LL |     extern "efiapi" fn m10();
    |            ^^^^^^^^
@@ -181,25 +68,8 @@ LL |     extern "efiapi" fn m10();
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:40:12
-   |
-LL |     extern "wasm" fn m11() {}
-   |            ^^^^^^
-   |
-   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
-   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
-
-error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:42:12
-   |
-LL |     extern "vectorcall" fn dm3() {}
-   |            ^^^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
-
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:43:12
+  --> $DIR/feature-gate-abi.rs:29:12
    |
 LL |     extern "rust-call" fn dm4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -207,52 +77,8 @@ LL |     extern "rust-call" fn dm4(_: ()) {}
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:44:12
-   |
-LL |     extern "msp430-interrupt" fn dm5() {}
-   |            ^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
-   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
-
-error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:45:12
-   |
-LL |     extern "ptx-kernel" fn dm6() {}
-   |            ^^^^^^^^^^^^
-   |
-   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
-   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
-
-error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:46:12
-   |
-LL |     extern "x86-interrupt" fn dm7() {}
-   |            ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
-   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
-
-error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:47:12
-   |
-LL |     extern "thiscall" fn dm8() {}
-   |            ^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
-
-error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:48:12
-   |
-LL |     extern "amdgpu-kernel" fn dm9() {}
-   |            ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
-   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
-
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:49:12
+  --> $DIR/feature-gate-abi.rs:30:12
    |
 LL |     extern "efiapi" fn dm10() {}
    |            ^^^^^^^^
@@ -260,17 +86,8 @@ LL |     extern "efiapi" fn dm10() {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:50:12
-   |
-LL |     extern "wasm" fn dm11() {}
-   |            ^^^^^^
-   |
-   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
-   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
-
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:57:12
+  --> $DIR/feature-gate-abi.rs:37:12
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -278,7 +95,7 @@ LL |     extern "rust-intrinsic" fn m1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:59:12
+  --> $DIR/feature-gate-abi.rs:39:12
    |
 LL |     extern "platform-intrinsic" fn m2() {}
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -286,16 +103,8 @@ LL |     extern "platform-intrinsic" fn m2() {}
    = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
-error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:61:12
-   |
-LL |     extern "vectorcall" fn m3() {}
-   |            ^^^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
-
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:62:12
+  --> $DIR/feature-gate-abi.rs:41:12
    |
 LL |     extern "rust-call" fn m4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -303,52 +112,8 @@ LL |     extern "rust-call" fn m4(_: ()) {}
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:63:12
-   |
-LL |     extern "msp430-interrupt" fn m5() {}
-   |            ^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
-   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
-
-error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:64:12
-   |
-LL |     extern "ptx-kernel" fn m6() {}
-   |            ^^^^^^^^^^^^
-   |
-   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
-   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
-
-error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:65:12
-   |
-LL |     extern "x86-interrupt" fn m7() {}
-   |            ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
-   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
-
-error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:66:12
-   |
-LL |     extern "thiscall" fn m8() {}
-   |            ^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
-
-error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:67:12
-   |
-LL |     extern "amdgpu-kernel" fn m9() {}
-   |            ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
-   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
-
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:68:12
+  --> $DIR/feature-gate-abi.rs:42:12
    |
 LL |     extern "efiapi" fn m10() {}
    |            ^^^^^^^^
@@ -356,17 +121,8 @@ LL |     extern "efiapi" fn m10() {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:69:12
-   |
-LL |     extern "wasm" fn m11() {}
-   |            ^^^^^^
-   |
-   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
-   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
-
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:74:12
+  --> $DIR/feature-gate-abi.rs:47:12
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -374,7 +130,7 @@ LL |     extern "rust-intrinsic" fn im1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:76:12
+  --> $DIR/feature-gate-abi.rs:49:12
    |
 LL |     extern "platform-intrinsic" fn im2() {}
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -382,16 +138,8 @@ LL |     extern "platform-intrinsic" fn im2() {}
    = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
-error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:78:12
-   |
-LL |     extern "vectorcall" fn im3() {}
-   |            ^^^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
-
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:79:12
+  --> $DIR/feature-gate-abi.rs:51:12
    |
 LL |     extern "rust-call" fn im4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -399,52 +147,8 @@ LL |     extern "rust-call" fn im4(_: ()) {}
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:80:12
-   |
-LL |     extern "msp430-interrupt" fn im5() {}
-   |            ^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
-   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
-
-error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:81:12
-   |
-LL |     extern "ptx-kernel" fn im6() {}
-   |            ^^^^^^^^^^^^
-   |
-   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
-   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
-
-error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:82:12
-   |
-LL |     extern "x86-interrupt" fn im7() {}
-   |            ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
-   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
-
-error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:83:12
-   |
-LL |     extern "thiscall" fn im8() {}
-   |            ^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
-
-error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:84:12
-   |
-LL |     extern "amdgpu-kernel" fn im9() {}
-   |            ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
-   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
-
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:85:12
+  --> $DIR/feature-gate-abi.rs:52:12
    |
 LL |     extern "efiapi" fn im10() {}
    |            ^^^^^^^^
@@ -452,17 +156,8 @@ LL |     extern "efiapi" fn im10() {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:86:12
-   |
-LL |     extern "wasm" fn im11() {}
-   |            ^^^^^^
-   |
-   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
-   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
-
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:90:18
+  --> $DIR/feature-gate-abi.rs:56:18
    |
 LL | type A1 = extern "rust-intrinsic" fn();
    |                  ^^^^^^^^^^^^^^^^
@@ -470,7 +165,7 @@ LL | type A1 = extern "rust-intrinsic" fn();
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:91:18
+  --> $DIR/feature-gate-abi.rs:57:18
    |
 LL | type A2 = extern "platform-intrinsic" fn();
    |                  ^^^^^^^^^^^^^^^^^^^^
@@ -478,16 +173,8 @@ LL | type A2 = extern "platform-intrinsic" fn();
    = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
-error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:92:18
-   |
-LL | type A3 = extern "vectorcall" fn();
-   |                  ^^^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
-
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:93:18
+  --> $DIR/feature-gate-abi.rs:58:18
    |
 LL | type A4 = extern "rust-call" fn(_: ());
    |                  ^^^^^^^^^^^
@@ -495,52 +182,8 @@ LL | type A4 = extern "rust-call" fn(_: ());
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:94:18
-   |
-LL | type A5 = extern "msp430-interrupt" fn();
-   |                  ^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
-   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
-
-error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:95:18
-   |
-LL | type A6 = extern "ptx-kernel" fn();
-   |                  ^^^^^^^^^^^^
-   |
-   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
-   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
-
-error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:96:18
-   |
-LL | type A7 = extern "x86-interrupt" fn();
-   |                  ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
-   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
-
-error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:97:18
-   |
-LL | type A8 = extern "thiscall" fn();
-   |                  ^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
-
-error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:98:18
-   |
-LL | type A9 = extern "amdgpu-kernel" fn();
-   |                  ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
-   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
-
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:99:19
+  --> $DIR/feature-gate-abi.rs:59:19
    |
 LL | type A10 = extern "efiapi" fn();
    |                   ^^^^^^^^
@@ -548,17 +191,8 @@ LL | type A10 = extern "efiapi" fn();
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:100:19
-   |
-LL | type A11 = extern "wasm" fn();
-   |                   ^^^^^^
-   |
-   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
-   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
-
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:103:8
+  --> $DIR/feature-gate-abi.rs:62:8
    |
 LL | extern "rust-intrinsic" {}
    |        ^^^^^^^^^^^^^^^^
@@ -566,7 +200,7 @@ LL | extern "rust-intrinsic" {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:104:8
+  --> $DIR/feature-gate-abi.rs:63:8
    |
 LL | extern "platform-intrinsic" {}
    |        ^^^^^^^^^^^^^^^^^^^^
@@ -574,16 +208,8 @@ LL | extern "platform-intrinsic" {}
    = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
-error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:105:8
-   |
-LL | extern "vectorcall" {}
-   |        ^^^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
-
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:106:8
+  --> $DIR/feature-gate-abi.rs:64:8
    |
 LL | extern "rust-call" {}
    |        ^^^^^^^^^^^
@@ -591,52 +217,8 @@ LL | extern "rust-call" {}
    = note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:107:8
-   |
-LL | extern "msp430-interrupt" {}
-   |        ^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #38487 <https://github.com/rust-lang/rust/issues/38487> for more information
-   = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
-
-error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:108:8
-   |
-LL | extern "ptx-kernel" {}
-   |        ^^^^^^^^^^^^
-   |
-   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
-   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
-
-error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:109:8
-   |
-LL | extern "x86-interrupt" {}
-   |        ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #40180 <https://github.com/rust-lang/rust/issues/40180> for more information
-   = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
-
-error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:110:8
-   |
-LL | extern "thiscall" {}
-   |        ^^^^^^^^^^
-   |
-   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
-
-error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:111:8
-   |
-LL | extern "amdgpu-kernel" {}
-   |        ^^^^^^^^^^^^^^^
-   |
-   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
-   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
-
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:112:8
+  --> $DIR/feature-gate-abi.rs:65:8
    |
 LL | extern "efiapi" {}
    |        ^^^^^^^^
@@ -644,63 +226,54 @@ LL | extern "efiapi" {}
    = note: see issue #65815 <https://github.com/rust-lang/rust/issues/65815> for more information
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
-error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:113:8
-   |
-LL | extern "wasm" {}
-   |        ^^^^^^
-   |
-   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
-   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
-
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:28:32
+  --> $DIR/feature-gate-abi.rs:22:32
    |
 LL |     extern "rust-intrinsic" fn m1();
    |                                ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:30:36
+  --> $DIR/feature-gate-abi.rs:24:36
    |
 LL |     extern "platform-intrinsic" fn m2();
    |                                    ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:12:33
+  --> $DIR/feature-gate-abi.rs:13:33
    |
 LL | extern "rust-intrinsic" fn f1() {}
    |                                 ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:14:37
+  --> $DIR/feature-gate-abi.rs:15:37
    |
 LL | extern "platform-intrinsic" fn f2() {}
    |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:57:37
+  --> $DIR/feature-gate-abi.rs:37:37
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:59:41
+  --> $DIR/feature-gate-abi.rs:39:41
    |
 LL |     extern "platform-intrinsic" fn m2() {}
    |                                         ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:74:38
+  --> $DIR/feature-gate-abi.rs:47:38
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |                                      ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:76:42
+  --> $DIR/feature-gate-abi.rs:49:42
    |
 LL |     extern "platform-intrinsic" fn im2() {}
    |                                          ^^
 
-error: aborting due to 83 previous errors
+error: aborting due to 34 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-abi_amdgpu_kernel.rs b/src/test/ui/feature-gates/feature-gate-abi_amdgpu_kernel.rs
new file mode 100644
index 00000000000..465b81d7fe3
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-abi_amdgpu_kernel.rs
@@ -0,0 +1,30 @@
+// compile-flags: --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
+
+extern "amdgpu-kernel" fn fu() {} //~ ERROR amdgpu-kernel ABI is experimental
+//~^ ERROR is not a supported ABI
+
+trait T {
+    extern "amdgpu-kernel" fn mu(); //~ ERROR amdgpu-kernel ABI is experimental
+    extern "amdgpu-kernel" fn dmu() {} //~ ERROR amdgpu-kernel ABI is experimental
+    //~^ ERROR is not a supported ABI
+}
+
+struct S;
+impl T for S {
+    extern "amdgpu-kernel" fn mu() {} //~ ERROR amdgpu-kernel ABI is experimental
+    //~^ ERROR is not a supported ABI
+}
+
+impl S {
+    extern "amdgpu-kernel" fn imu() {} //~ ERROR amdgpu-kernel ABI is experimental
+    //~^ ERROR is not a supported ABI
+}
+
+type TAU = extern "amdgpu-kernel" fn(); //~ ERROR amdgpu-kernel ABI is experimental
+
+extern "amdgpu-kernel" {} //~ ERROR amdgpu-kernel ABI is experimental
+//~^ ERROR is not a supported ABI
diff --git a/src/test/ui/feature-gates/feature-gate-abi_amdgpu_kernel.stderr b/src/test/ui/feature-gates/feature-gate-abi_amdgpu_kernel.stderr
new file mode 100644
index 00000000000..c89ab7bae11
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-abi_amdgpu_kernel.stderr
@@ -0,0 +1,97 @@
+error[E0658]: amdgpu-kernel ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:7:8
+   |
+LL | extern "amdgpu-kernel" fn fu() {}
+   |        ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
+   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
+
+error[E0658]: amdgpu-kernel ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:11:12
+   |
+LL |     extern "amdgpu-kernel" fn mu();
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
+   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
+
+error[E0658]: amdgpu-kernel ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:12:12
+   |
+LL |     extern "amdgpu-kernel" fn dmu() {}
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
+   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
+
+error[E0658]: amdgpu-kernel ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:18:12
+   |
+LL |     extern "amdgpu-kernel" fn mu() {}
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
+   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
+
+error[E0658]: amdgpu-kernel ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:23:12
+   |
+LL |     extern "amdgpu-kernel" fn imu() {}
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
+   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
+
+error[E0658]: amdgpu-kernel ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:27:19
+   |
+LL | type TAU = extern "amdgpu-kernel" fn();
+   |                   ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
+   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
+
+error[E0658]: amdgpu-kernel ABI is experimental and subject to change
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:29:8
+   |
+LL | extern "amdgpu-kernel" {}
+   |        ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #51575 <https://github.com/rust-lang/rust/issues/51575> for more information
+   = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:29:1
+   |
+LL | extern "amdgpu-kernel" {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:7:1
+   |
+LL | extern "amdgpu-kernel" fn fu() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:12:5
+   |
+LL |     extern "amdgpu-kernel" fn dmu() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:18:5
+   |
+LL |     extern "amdgpu-kernel" fn mu() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target
+  --> $DIR/feature-gate-abi_amdgpu_kernel.rs:23:5
+   |
+LL |     extern "amdgpu-kernel" fn imu() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
+Some errors have detailed explanations: E0570, E0658.
+For more information about an error, try `rustc --explain E0570`.
diff --git a/src/test/ui/feature-gates/feature-gate-abi_ptx.rs b/src/test/ui/feature-gates/feature-gate-abi_ptx.rs
new file mode 100644
index 00000000000..e3405641ecd
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-abi_ptx.rs
@@ -0,0 +1,26 @@
+// needs-llvm-components: nvptx
+// compile-flags: --target=nvptx64-nvidia-cuda --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
+
+extern "ptx-kernel" fn fu() {} //~ ERROR PTX ABIs are experimental
+
+trait T {
+    extern "ptx-kernel" fn mu(); //~ ERROR PTX ABIs are experimental
+    extern "ptx-kernel" fn dmu() {} //~ ERROR PTX ABIs are experimental
+}
+
+struct S;
+impl T for S {
+    extern "ptx-kernel" fn mu() {} //~ ERROR PTX ABIs are experimental
+}
+
+impl S {
+    extern "ptx-kernel" fn imu() {} //~ ERROR PTX ABIs are experimental
+}
+
+type TAU = extern "ptx-kernel" fn(); //~ ERROR PTX ABIs are experimental
+
+extern "ptx-kernel" {} //~ ERROR PTX ABIs are experimental
diff --git a/src/test/ui/feature-gates/feature-gate-abi_ptx.stderr b/src/test/ui/feature-gates/feature-gate-abi_ptx.stderr
new file mode 100644
index 00000000000..40782d361ee
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-abi_ptx.stderr
@@ -0,0 +1,66 @@
+error[E0658]: PTX ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi_ptx.rs:8:8
+   |
+LL | extern "ptx-kernel" fn fu() {}
+   |        ^^^^^^^^^^^^
+   |
+   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
+   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
+
+error[E0658]: PTX ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi_ptx.rs:11:12
+   |
+LL |     extern "ptx-kernel" fn mu();
+   |            ^^^^^^^^^^^^
+   |
+   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
+   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
+
+error[E0658]: PTX ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi_ptx.rs:12:12
+   |
+LL |     extern "ptx-kernel" fn dmu() {}
+   |            ^^^^^^^^^^^^
+   |
+   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
+   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
+
+error[E0658]: PTX ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi_ptx.rs:17:12
+   |
+LL |     extern "ptx-kernel" fn mu() {}
+   |            ^^^^^^^^^^^^
+   |
+   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
+   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
+
+error[E0658]: PTX ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi_ptx.rs:21:12
+   |
+LL |     extern "ptx-kernel" fn imu() {}
+   |            ^^^^^^^^^^^^
+   |
+   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
+   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
+
+error[E0658]: PTX ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi_ptx.rs:24:19
+   |
+LL | type TAU = extern "ptx-kernel" fn();
+   |                   ^^^^^^^^^^^^
+   |
+   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
+   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
+
+error[E0658]: PTX ABIs are experimental and subject to change
+  --> $DIR/feature-gate-abi_ptx.rs:26:8
+   |
+LL | extern "ptx-kernel" {}
+   |        ^^^^^^^^^^^^
+   |
+   = note: see issue #38788 <https://github.com/rust-lang/rust/issues/38788> for more information
+   = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-vectorcall.rs b/src/test/ui/feature-gates/feature-gate-vectorcall.rs
new file mode 100644
index 00000000000..5a6c6d28804
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-vectorcall.rs
@@ -0,0 +1,31 @@
+// gate-test-abi_vectorcall
+// needs-llvm-components: x86
+// compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
+
+// Test that the "vectorcall-unwind" ABI is feature-gated, and cannot be used when
+// the `c_unwind` feature gate is not used.
+
+extern "vectorcall" fn f() {} //~ ERROR vectorcall is experimental
+
+trait T {
+    extern "vectorcall" fn m(); //~ ERROR vectorcall is experimental
+
+    extern "vectorcall" fn dm() {} //~ ERROR vectorcall is experimental
+}
+
+struct S;
+impl T for S {
+    extern "vectorcall" fn m() {} //~ ERROR vectorcall is experimental
+}
+
+impl S {
+    extern "vectorcall" fn im() {} //~ ERROR vectorcall is experimental
+}
+
+type TA = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental
+
+extern "vectorcall" {} //~ ERROR vectorcall is experimental
diff --git a/src/test/ui/feature-gates/feature-gate-vectorcall.stderr b/src/test/ui/feature-gates/feature-gate-vectorcall.stderr
new file mode 100644
index 00000000000..55ee76ec3f1
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-vectorcall.stderr
@@ -0,0 +1,59 @@
+error[E0658]: vectorcall is experimental and subject to change
+  --> $DIR/feature-gate-vectorcall.rs:12:8
+   |
+LL | extern "vectorcall" fn f() {}
+   |        ^^^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
+
+error[E0658]: vectorcall is experimental and subject to change
+  --> $DIR/feature-gate-vectorcall.rs:15:12
+   |
+LL |     extern "vectorcall" fn m();
+   |            ^^^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
+
+error[E0658]: vectorcall is experimental and subject to change
+  --> $DIR/feature-gate-vectorcall.rs:17:12
+   |
+LL |     extern "vectorcall" fn dm() {}
+   |            ^^^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
+
+error[E0658]: vectorcall is experimental and subject to change
+  --> $DIR/feature-gate-vectorcall.rs:22:12
+   |
+LL |     extern "vectorcall" fn m() {}
+   |            ^^^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
+
+error[E0658]: vectorcall is experimental and subject to change
+  --> $DIR/feature-gate-vectorcall.rs:26:12
+   |
+LL |     extern "vectorcall" fn im() {}
+   |            ^^^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
+
+error[E0658]: vectorcall is experimental and subject to change
+  --> $DIR/feature-gate-vectorcall.rs:29:18
+   |
+LL | type TA = extern "vectorcall" fn();
+   |                  ^^^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
+
+error[E0658]: vectorcall is experimental and subject to change
+  --> $DIR/feature-gate-vectorcall.rs:31:8
+   |
+LL | extern "vectorcall" {}
+   |        ^^^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-wasm_abi.rs b/src/test/ui/feature-gates/feature-gate-wasm_abi.rs
index 8c8de076365..222c88daf94 100644
--- a/src/test/ui/feature-gates/feature-gate-wasm_abi.rs
+++ b/src/test/ui/feature-gates/feature-gate-wasm_abi.rs
@@ -1,7 +1,26 @@
-extern "wasm" fn foo() {
-    //~^ ERROR: wasm ABI is experimental and subject to change
+// needs-llvm-components: webassembly
+// compile-flags: --target=wasm32-unknown-unknown --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
+
+extern "wasm" fn fu() {} //~ ERROR wasm ABI is experimental
+
+trait T {
+    extern "wasm" fn mu(); //~ ERROR wasm ABI is experimental
+    extern "wasm" fn dmu() {} //~ ERROR wasm ABI is experimental
+}
+
+struct S;
+impl T for S {
+    extern "wasm" fn mu() {} //~ ERROR wasm ABI is experimental
 }
 
-fn main() {
-    foo();
+impl S {
+    extern "wasm" fn imu() {} //~ ERROR wasm ABI is experimental
 }
+
+type TAU = extern "wasm" fn(); //~ ERROR wasm ABI is experimental
+
+extern "wasm" {} //~ ERROR wasm ABI is experimental
diff --git a/src/test/ui/feature-gates/feature-gate-wasm_abi.stderr b/src/test/ui/feature-gates/feature-gate-wasm_abi.stderr
index c4113fd6af9..0140002e350 100644
--- a/src/test/ui/feature-gates/feature-gate-wasm_abi.stderr
+++ b/src/test/ui/feature-gates/feature-gate-wasm_abi.stderr
@@ -1,12 +1,66 @@
 error[E0658]: wasm ABI is experimental and subject to change
-  --> $DIR/feature-gate-wasm_abi.rs:1:8
+  --> $DIR/feature-gate-wasm_abi.rs:8:8
    |
-LL | extern "wasm" fn foo() {
+LL | extern "wasm" fn fu() {}
    |        ^^^^^^
    |
    = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
    = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-wasm_abi.rs:11:12
+   |
+LL |     extern "wasm" fn mu();
+   |            ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-wasm_abi.rs:12:12
+   |
+LL |     extern "wasm" fn dmu() {}
+   |            ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-wasm_abi.rs:17:12
+   |
+LL |     extern "wasm" fn mu() {}
+   |            ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-wasm_abi.rs:21:12
+   |
+LL |     extern "wasm" fn imu() {}
+   |            ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-wasm_abi.rs:24:19
+   |
+LL | type TAU = extern "wasm" fn();
+   |                   ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
+error[E0658]: wasm ABI is experimental and subject to change
+  --> $DIR/feature-gate-wasm_abi.rs:26:8
+   |
+LL | extern "wasm" {}
+   |        ^^^^^^
+   |
+   = note: see issue #83788 <https://github.com/rust-lang/rust/issues/83788> for more information
+   = help: add `#![feature(wasm_abi)]` to the crate attributes to enable
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/unwind-abis/feature-gate-stdcall-unwind.rs b/src/test/ui/unwind-abis/feature-gate-stdcall-unwind.rs
index 7d4dc8c9343..cfa8eb3cad0 100644
--- a/src/test/ui/unwind-abis/feature-gate-stdcall-unwind.rs
+++ b/src/test/ui/unwind-abis/feature-gate-stdcall-unwind.rs
@@ -1,13 +1,30 @@
-// ignore-arm stdcall isn't supported
-// ignore-aarch64 stdcall isn't supported
-// ignore-riscv64 stdcall isn't supported
+// gate-test-c_unwind
+// needs-llvm-components: x86
+// compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
 
 // Test that the "stdcall-unwind" ABI is feature-gated, and cannot be used when
 // the `c_unwind` feature gate is not used.
 
-extern "stdcall-unwind" fn f() {}
-//~^ ERROR stdcall-unwind ABI is experimental and subject to change [E0658]
+extern "stdcall-unwind" fn fu() {} //~ ERROR stdcall-unwind ABI is experimental
 
-fn main() {
-    f();
+trait T {
+    extern "stdcall-unwind" fn mu(); //~ ERROR stdcall-unwind ABI is experimental
+    extern "stdcall-unwind" fn dmu() {} //~ ERROR stdcall-unwind ABI is experimental
 }
+
+struct S;
+impl T for S {
+    extern "stdcall-unwind" fn mu() {} //~ ERROR stdcall-unwind ABI is experimental
+}
+
+impl S {
+    extern "stdcall-unwind" fn imu() {} //~ ERROR stdcall-unwind ABI is experimental
+}
+
+type TAU = extern "stdcall-unwind" fn(); //~ ERROR stdcall-unwind ABI is experimental
+
+extern "stdcall-unwind" {} //~ ERROR stdcall-unwind ABI is experimental
diff --git a/src/test/ui/unwind-abis/feature-gate-stdcall-unwind.stderr b/src/test/ui/unwind-abis/feature-gate-stdcall-unwind.stderr
index e3d569f464f..c2cce0e1193 100644
--- a/src/test/ui/unwind-abis/feature-gate-stdcall-unwind.stderr
+++ b/src/test/ui/unwind-abis/feature-gate-stdcall-unwind.stderr
@@ -1,12 +1,66 @@
 error[E0658]: stdcall-unwind ABI is experimental and subject to change
-  --> $DIR/feature-gate-stdcall-unwind.rs:8:8
+  --> $DIR/feature-gate-stdcall-unwind.rs:12:8
    |
-LL | extern "stdcall-unwind" fn f() {}
+LL | extern "stdcall-unwind" fn fu() {}
    |        ^^^^^^^^^^^^^^^^
    |
    = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
    = help: add `#![feature(c_unwind)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: stdcall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-stdcall-unwind.rs:15:12
+   |
+LL |     extern "stdcall-unwind" fn mu();
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: stdcall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-stdcall-unwind.rs:16:12
+   |
+LL |     extern "stdcall-unwind" fn dmu() {}
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: stdcall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-stdcall-unwind.rs:21:12
+   |
+LL |     extern "stdcall-unwind" fn mu() {}
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: stdcall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-stdcall-unwind.rs:25:12
+   |
+LL |     extern "stdcall-unwind" fn imu() {}
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: stdcall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-stdcall-unwind.rs:28:19
+   |
+LL | type TAU = extern "stdcall-unwind" fn();
+   |                   ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: stdcall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-stdcall-unwind.rs:30:8
+   |
+LL | extern "stdcall-unwind" {}
+   |        ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/unwind-abis/feature-gate-thiscall-unwind.rs b/src/test/ui/unwind-abis/feature-gate-thiscall-unwind.rs
index 2f4cefccc19..0a323e50fcf 100644
--- a/src/test/ui/unwind-abis/feature-gate-thiscall-unwind.rs
+++ b/src/test/ui/unwind-abis/feature-gate-thiscall-unwind.rs
@@ -1,13 +1,39 @@
-// ignore-arm thiscall isn't supported
-// ignore-aarch64 thiscall isn't supported
-// ignore-riscv64 thiscall isn't supported
+// gate-test-abi_thiscall
+// gate-test-c_unwind
+// needs-llvm-components: x86
+// compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib
+#![no_core]
+#![feature(no_core, lang_items)]
+#[lang="sized"]
+trait Sized { }
 
 // Test that the "thiscall-unwind" ABI is feature-gated, and cannot be used when
 // the `c_unwind` feature gate is not used.
 
-extern "thiscall-unwind" fn f() {}
-//~^ ERROR thiscall-unwind ABI is experimental and subject to change [E0658]
+extern "thiscall-unwind" fn fu() {} //~ ERROR thiscall-unwind ABI is experimental
+extern "thiscall" fn f() {} //~ ERROR thiscall is experimental
 
-fn main() {
-    f();
+trait T {
+    extern "thiscall" fn m(); //~ ERROR thiscall is experimental
+    extern "thiscall-unwind" fn mu(); //~ ERROR thiscall-unwind ABI is experimental
+
+    extern "thiscall" fn dm() {} //~ ERROR thiscall is experimental
+    extern "thiscall-unwind" fn dmu() {} //~ ERROR thiscall-unwind ABI is experimental
+}
+
+struct S;
+impl T for S {
+    extern "thiscall" fn m() {} //~ ERROR thiscall is experimental
+    extern "thiscall-unwind" fn mu() {} //~ ERROR thiscall-unwind ABI is experimental
 }
+
+impl S {
+    extern "thiscall" fn im() {} //~ ERROR thiscall is experimental
+    extern "thiscall-unwind" fn imu() {} //~ ERROR thiscall-unwind ABI is experimental
+}
+
+type TA = extern "thiscall" fn(); //~ ERROR thiscall is experimental
+type TAU = extern "thiscall-unwind" fn(); //~ ERROR thiscall-unwind ABI is experimental
+
+extern "thiscall" {} //~ ERROR thiscall is experimental
+extern "thiscall-unwind" {} //~ ERROR thiscall-unwind ABI is experimental
diff --git a/src/test/ui/unwind-abis/feature-gate-thiscall-unwind.stderr b/src/test/ui/unwind-abis/feature-gate-thiscall-unwind.stderr
index b103bb8d565..9ca00a55cd8 100644
--- a/src/test/ui/unwind-abis/feature-gate-thiscall-unwind.stderr
+++ b/src/test/ui/unwind-abis/feature-gate-thiscall-unwind.stderr
@@ -1,12 +1,122 @@
 error[E0658]: thiscall-unwind ABI is experimental and subject to change
-  --> $DIR/feature-gate-thiscall-unwind.rs:8:8
+  --> $DIR/feature-gate-thiscall-unwind.rs:13:8
    |
-LL | extern "thiscall-unwind" fn f() {}
+LL | extern "thiscall-unwind" fn fu() {}
    |        ^^^^^^^^^^^^^^^^^
    |
    = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
    = help: add `#![feature(c_unwind)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: thiscall is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:14:8
+   |
+LL | extern "thiscall" fn f() {}
+   |        ^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
+
+error[E0658]: thiscall is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:17:12
+   |
+LL |     extern "thiscall" fn m();
+   |            ^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
+
+error[E0658]: thiscall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:18:12
+   |
+LL |     extern "thiscall-unwind" fn mu();
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: thiscall is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:20:12
+   |
+LL |     extern "thiscall" fn dm() {}
+   |            ^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
+
+error[E0658]: thiscall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:21:12
+   |
+LL |     extern "thiscall-unwind" fn dmu() {}
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: thiscall is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:26:12
+   |
+LL |     extern "thiscall" fn m() {}
+   |            ^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
+
+error[E0658]: thiscall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:27:12
+   |
+LL |     extern "thiscall-unwind" fn mu() {}
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: thiscall is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:31:12
+   |
+LL |     extern "thiscall" fn im() {}
+   |            ^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
+
+error[E0658]: thiscall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:32:12
+   |
+LL |     extern "thiscall-unwind" fn imu() {}
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: thiscall is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:35:18
+   |
+LL | type TA = extern "thiscall" fn();
+   |                  ^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
+
+error[E0658]: thiscall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:36:19
+   |
+LL | type TAU = extern "thiscall-unwind" fn();
+   |                   ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error[E0658]: thiscall is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:38:8
+   |
+LL | extern "thiscall" {}
+   |        ^^^^^^^^^^
+   |
+   = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
+
+error[E0658]: thiscall-unwind ABI is experimental and subject to change
+  --> $DIR/feature-gate-thiscall-unwind.rs:39:8
+   |
+LL | extern "thiscall-unwind" {}
+   |        ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information
+   = help: add `#![feature(c_unwind)]` to the crate attributes to enable
+
+error: aborting due to 14 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs
index 63fbee34bd6..53c75a46339 100644
--- a/src/tools/tidy/src/error_codes_check.rs
+++ b/src/tools/tidy/src/error_codes_check.rs
@@ -11,7 +11,7 @@ use regex::Regex;
 // A few of those error codes can't be tested but all the others can and *should* be tested!
 const EXEMPTED_FROM_TEST: &[&str] = &[
     "E0227", "E0279", "E0280", "E0313", "E0377", "E0461", "E0462", "E0464", "E0465", "E0476",
-    "E0482", "E0514", "E0519", "E0523", "E0554", "E0570", "E0640", "E0717", "E0729",
+    "E0482", "E0514", "E0519", "E0523", "E0554", "E0640", "E0717", "E0729",
 ];
 
 // Some error codes don't have any tests apparently...