Skip to content

compiler: Sort and doc ExternAbi variants #142140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 8, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 63 additions & 36 deletions compiler/rustc_abi/src/extern_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,66 +12,93 @@ use crate::AbiFromStrErr;
#[cfg(test)]
mod tests;

use ExternAbi as Abi;

/// ABI we expect to see within `extern "{abi}"`
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable))]
pub enum ExternAbi {
// 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,
/* universal */
/// presumed C ABI for the platform
C {
unwind: bool,
},
Cdecl {
/// ABI of the "system" interface, e.g. the Win32 API, always "aliasing"
System {
unwind: bool,
},
Stdcall {

/// that's us!
Rust,
/// the mostly-unused `unboxed_closures` ABI, effectively now an impl detail unless someone
/// puts in the work to make it viable again... but would we need a special ABI?
RustCall,
/// For things unlikely to be called, where reducing register pressure in
/// `extern "Rust"` callers is worth paying extra cost in the callee.
/// Stronger than just `#[cold]` because `fn` pointers might be incompatible.
RustCold,

/// 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,

/// UEFI ABI, usually an alias of C, but sometimes an arch-specific alias
/// and only valid on platforms that have a UEFI standard
EfiApi,

/* arm */
/// Arm Architecture Procedure Call Standard, sometimes `ExternAbi::C` is an alias for this
Aapcs {
unwind: bool,
},
Fastcall {
/// extremely constrained barely-C ABI for TrustZone
CCmseNonSecureCall,
/// extremely constrained barely-C ABI for TrustZone
CCmseNonSecureEntry,

/* gpu */
/// An entry-point function called by the GPU's host
// FIXME: should not be callable from Rust on GPU targets, is for host's use only
GpuKernel,
/// An entry-point function called by the GPU's host
// FIXME: why do we have two of these?
PtxKernel,

/* interrupt */
AvrInterrupt,
AvrNonBlockingInterrupt,
Msp430Interrupt,
RiscvInterruptM,
RiscvInterruptS,
X86Interrupt,

/* x86 */
/// `ExternAbi::C` but spelled funny because x86
Cdecl {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't yet treated as an arch-specific ABI by the rest of the compiler but it will be as-of #141435

unwind: bool,
},
Vectorcall {
/// gnu-stdcall on "unix" and win-stdcall on "windows"
Stdcall {
unwind: bool,
},
Thiscall {
/// gnu-fastcall on "unix" and win-fastcall on "windows"
Fastcall {
unwind: bool,
},
Aapcs {
/// windows C++ ABI
Thiscall {
unwind: bool,
},
Win64 {
/// uses AVX and stuff
Vectorcall {
unwind: bool,
},

/* x86_64 */
SysV64 {
unwind: bool,
},
PtxKernel,
Msp430Interrupt,
X86Interrupt,
/// An entry-point function called by the GPU's host
// FIXME: should not be callable from Rust on GPU targets, is for host's use only
GpuKernel,
EfiApi,
AvrInterrupt,
AvrNonBlockingInterrupt,
CCmseNonSecureCall,
CCmseNonSecureEntry,
System {
Win64 {
unwind: bool,
},
RustCall,
/// *Not* a stable ABI, just directly use the Rust types to describe the ABI for LLVM. Even
/// normally ABI-compatible Rust types can become ABI-incompatible with this ABI!
Unadjusted,
/// For things unlikely to be called, where reducing register pressure in
/// `extern "Rust"` callers is worth paying extra cost in the callee.
/// Stronger than just `#[cold]` because `fn` pointers might be incompatible.
RustCold,
RiscvInterruptM,
RiscvInterruptS,
}

macro_rules! abi_impls {
Expand Down Expand Up @@ -224,7 +251,7 @@ pub fn all_names() -> Vec<&'static str> {

impl ExternAbi {
/// Default ABI chosen for `extern fn` declarations without an explicit ABI.
pub const FALLBACK: Abi = Abi::C { unwind: false };
pub const FALLBACK: ExternAbi = ExternAbi::C { unwind: false };

pub fn name(self) -> &'static str {
self.as_str()
Expand Down
Loading