From e245570def155191b61f73647eb543dd45685b2f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 24 Jun 2025 22:29:54 +0000 Subject: [PATCH] Add rust-invalid ABI --- compiler/rustc_abi/src/extern_abi.rs | 5 +++++ compiler/rustc_ast_lowering/src/stability.rs | 3 +++ compiler/rustc_middle/src/ty/layout.rs | 3 ++- compiler/rustc_smir/src/rustc_internal/internal.rs | 1 + compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 1 + compiler/rustc_smir/src/stable_mir/ty.rs | 1 + compiler/rustc_target/src/spec/abi_map.rs | 3 ++- tests/ui/abi/invalid-call-abi.rs | 12 ++++++++++++ tests/ui/abi/invalid-call-abi.stderr | 9 +++++++++ tests/ui/print-calling-conventions.stdout | 1 + 10 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 tests/ui/abi/invalid-call-abi.rs create mode 100644 tests/ui/abi/invalid-call-abi.stderr diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 7457ae1f0334..1b8c2de15880 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -36,6 +36,10 @@ pub enum ExternAbi { /// Stronger than just `#[cold]` because `fn` pointers might be incompatible. RustCold, + /// An always-invalid ABI that's used to test "this ABI is not supported by this platform" + /// in a platform-agnostic way. + RustInvalid, + /// Unstable impl detail that directly uses Rust types to describe the ABI to LLVM. /// Even normally-compatible Rust types can become ABI-incompatible with this ABI! Unadjusted, @@ -157,6 +161,7 @@ fn from_str(s: &str) -> Result<$e_name, Self::Err> { RiscvInterruptS =><= "riscv-interrupt-s", RustCall =><= "rust-call", RustCold =><= "rust-cold", + RustInvalid =><= "rust-invalid", Stdcall { unwind: false } =><= "stdcall", Stdcall { unwind: true } =><= "stdcall-unwind", System { unwind: false } =><= "system", diff --git a/compiler/rustc_ast_lowering/src/stability.rs b/compiler/rustc_ast_lowering/src/stability.rs index b8fa2dd3dd62..9b60807e6508 100644 --- a/compiler/rustc_ast_lowering/src/stability.rs +++ b/compiler/rustc_ast_lowering/src/stability.rs @@ -96,6 +96,9 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> { ExternAbi::RustCold => { Err(UnstableAbi { abi, feature: sym::rust_cold_cc, explain: GateReason::Experimental }) } + ExternAbi::RustInvalid => { + Err(UnstableAbi { abi, feature: sym::rustc_attrs, explain: GateReason::ImplDetail }) + } ExternAbi::GpuKernel => Err(UnstableAbi { abi, feature: sym::abi_gpu_kernel, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 13c281a61827..5cb943b0d8c6 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1253,7 +1253,8 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option, abi: ExternAbi) | CCmseNonSecureCall | CCmseNonSecureEntry | Custom - | Unadjusted => false, + | Unadjusted + | RustInvalid => false, Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind, } } diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index a4c6f1862221..c0d9937e34de 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -494,6 +494,7 @@ fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self:: Abi::RustCall => rustc_abi::ExternAbi::RustCall, Abi::Unadjusted => rustc_abi::ExternAbi::Unadjusted, Abi::RustCold => rustc_abi::ExternAbi::RustCold, + Abi::RustInvalid => rustc_abi::ExternAbi::RustInvalid, Abi::RiscvInterruptM => rustc_abi::ExternAbi::RiscvInterruptM, Abi::RiscvInterruptS => rustc_abi::ExternAbi::RiscvInterruptS, Abi::Custom => rustc_abi::ExternAbi::Custom, diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index b4239ddd896e..2c652c7546e9 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -877,6 +877,7 @@ fn stable(&self, _: &mut Tables<'_>) -> Self::T { ExternAbi::RustCall => Abi::RustCall, ExternAbi::Unadjusted => Abi::Unadjusted, ExternAbi::RustCold => Abi::RustCold, + ExternAbi::RustInvalid => Abi::RustInvalid, ExternAbi::RiscvInterruptM => Abi::RiscvInterruptM, ExternAbi::RiscvInterruptS => Abi::RiscvInterruptS, ExternAbi::Custom => Abi::Custom, diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 4415cd6e2e3b..1ae79491642d 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1126,6 +1126,7 @@ pub enum Abi { RustCold, RiscvInterruptM, RiscvInterruptS, + RustInvalid, Custom, } diff --git a/compiler/rustc_target/src/spec/abi_map.rs b/compiler/rustc_target/src/spec/abi_map.rs index 42ec10a8e157..ce1bdcbb8acc 100644 --- a/compiler/rustc_target/src/spec/abi_map.rs +++ b/compiler/rustc_target/src/spec/abi_map.rs @@ -156,7 +156,8 @@ pub fn canonize_abi(&self, extern_abi: ExternAbi, has_c_varargs: bool) -> AbiMap | ExternAbi::Msp430Interrupt | ExternAbi::RiscvInterruptM | ExternAbi::RiscvInterruptS - | ExternAbi::X86Interrupt, + | ExternAbi::X86Interrupt + | ExternAbi::RustInvalid, _, ) => return AbiMapping::Invalid, }; diff --git a/tests/ui/abi/invalid-call-abi.rs b/tests/ui/abi/invalid-call-abi.rs new file mode 100644 index 000000000000..076ddd91ab0f --- /dev/null +++ b/tests/ui/abi/invalid-call-abi.rs @@ -0,0 +1,12 @@ +// Tests the `"rustc-invalid"` ABI, which is never canonizable. + +#![feature(rustc_attrs)] + +const extern "rust-invalid" fn foo() { + //~^ ERROR "rust-invalid" is not a supported ABI for the current target + panic!() +} + +fn main() { + foo(); +} diff --git a/tests/ui/abi/invalid-call-abi.stderr b/tests/ui/abi/invalid-call-abi.stderr new file mode 100644 index 000000000000..c4a90158dcfe --- /dev/null +++ b/tests/ui/abi/invalid-call-abi.stderr @@ -0,0 +1,9 @@ +error[E0570]: "rust-invalid" is not a supported ABI for the current target + --> $DIR/invalid-call-abi.rs:5:14 + | +LL | const extern "rust-invalid" fn foo() { + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/print-calling-conventions.stdout b/tests/ui/print-calling-conventions.stdout index 7b5ae4956606..4df6bd27f457 100644 --- a/tests/ui/print-calling-conventions.stdout +++ b/tests/ui/print-calling-conventions.stdout @@ -20,6 +20,7 @@ riscv-interrupt-m riscv-interrupt-s rust-call rust-cold +rust-invalid stdcall stdcall-unwind system