Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions compiler/rustc_abi/src/canon_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ pub enum CanonAbi {
/// An ABI that rustc does not know how to call or define.
Custom,

/// Swift calling convention, exposed via LLVM's `swiftcc`. Cross-platform
/// and not tied to a specific target architecture.
Swift,
Comment thread
djc marked this conversation as resolved.

/// ABIs relevant to 32-bit Arm targets
Arm(ArmCall),
/// ABI relevant to GPUs: the entry point for a GPU kernel
Expand All @@ -58,6 +62,7 @@ impl CanonAbi {
CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::RustPreserveNone => true,
CanonAbi::C
| CanonAbi::Custom
| CanonAbi::Swift
| CanonAbi::Arm(_)
| CanonAbi::GpuKernel
| CanonAbi::Interrupt(_)
Expand All @@ -77,6 +82,7 @@ impl fmt::Display for CanonAbi {
CanonAbi::RustCold => ExternAbi::RustCold,
CanonAbi::RustPreserveNone => ExternAbi::RustPreserveNone,
CanonAbi::Custom => ExternAbi::Custom,
CanonAbi::Swift => ExternAbi::Swift,
CanonAbi::Arm(arm_call) => match arm_call {
ArmCall::Aapcs => ExternAbi::Aapcs { unwind: false },
ArmCall::CCmseNonSecureCall => ExternAbi::CmseNonSecureCall,
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_abi/src/extern_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ pub enum ExternAbi {
/// and only valid on platforms that have a UEFI standard
EfiApi,

/// Swift's calling convention, used to interoperate with Swift code without
/// going through C as an intermediary.
Swift,

/* arm */
/// Arm Architecture Procedure Call Standard, sometimes `ExternAbi::C` is an alias for this
Aapcs {
Expand Down Expand Up @@ -173,6 +177,7 @@ abi_impls! {
C { unwind: false } =><= "C",
C { unwind: true } =><= "C-unwind",
Rust =><= "Rust",
Swift =><= "Swift",
Aapcs { unwind: false } =><= "aapcs",
Aapcs { unwind: true } =><= "aapcs-unwind",
AvrInterrupt =><= "avr-interrupt",
Expand Down Expand Up @@ -348,7 +353,8 @@ impl ExternAbi {
| Self::Vectorcall { .. }
| Self::SysV64 { .. }
| Self::Win64 { .. }
| Self::RustPreserveNone => true,
| Self::RustPreserveNone
| Self::Swift => true,
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ast_lowering/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,8 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> {
ExternAbi::Custom => {
Err(UnstableAbi { abi, feature: sym::abi_custom, explain: GateReason::Experimental })
}
ExternAbi::Swift => {
Err(UnstableAbi { abi, feature: sym::abi_swift, explain: GateReason::Experimental })
}
}
}
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ impl<'a> AstValidator<'a> {
| CanonAbi::Rust
| CanonAbi::RustCold
| CanonAbi::RustPreserveNone
| CanonAbi::Swift
| CanonAbi::Arm(_)
| CanonAbi::X86(_) => { /* nothing to check */ }

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub(crate) fn conv_to_call_conv(
_ => default_call_conv,
},

CanonAbi::Interrupt(_) | CanonAbi::Arm(_) => {
CanonAbi::Interrupt(_) | CanonAbi::Arm(_) | CanonAbi::Swift => {
sess.dcx().fatal("call conv {c:?} is not yet implemented")
}
CanonAbi::GpuKernel => {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_gcc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option<FnAttri
// possible to declare an `extern "custom"` block, so the backend still needs a calling
// convention for declaring foreign functions.
CanonAbi::Custom => return None,
// gcc/gccjit does not have anything for Swift's calling convention.
CanonAbi::Swift => panic!("gcc/gccjit backend does not support Swift calling convention"),
CanonAbi::Arm(arm_call) => match arm_call {
ArmCall::CCmseNonSecureCall => FnAttribute::ArmCmseNonsecureCall,
ArmCall::CCmseNonSecureEntry => FnAttribute::ArmCmseNonsecureEntry,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm:
// possible to declare an `extern "custom"` block, so the backend still needs a calling
// convention for declaring foreign functions.
CanonAbi::Custom => llvm::CCallConv,
CanonAbi::Swift => llvm::SwiftCallConv,
CanonAbi::GpuKernel => match &sess.target.arch {
Arch::AmdGpu => llvm::AmdgpuKernel,
Arch::Nvptx64 => llvm::PtxKernel,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ pub(crate) enum CallConv {
ColdCallConv = 9,
PreserveMost = 14,
PreserveAll = 15,
SwiftCallConv = 16,
Tail = 18,
PreserveNone = 21,
X86StdcallCallConv = 64,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ declare_features! (
(unstable, abi_ptx, "1.15.0", Some(38788)),
/// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`.
(unstable, abi_riscv_interrupt, "1.73.0", Some(111889)),
/// Allows `extern "Swift" fn()`.
(unstable, abi_swift, "CURRENT_RUSTC_VERSION", Some(156481)),
/// Allows `extern "x86-interrupt" fn()`.
(unstable, abi_x86_interrupt, "1.17.0", Some(40180)),
/// Allows additional const parameter types, such as `[u8; 10]` or user defined types
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| CanonAbi::Rust
| CanonAbi::RustCold
| CanonAbi::RustPreserveNone
| CanonAbi::Swift
| CanonAbi::Arm(_)
| CanonAbi::X86(_) => {}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
| RiscvInterruptM
| RiscvInterruptS
| RustInvalid
| Swift
| Unadjusted => false,
Rust | RustCall | RustCold | RustPreserveNone => tcx.sess.panic_strategy().unwinds(),
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_public/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ pub enum CallConvention {

Custom,

Swift,

// Target-specific calling conventions.
ArmAapcs,
CCmseNonSecureCall,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_public/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,7 @@ pub enum Abi {
RustPreserveNone,
RustInvalid,
Custom,
Swift,
}

/// A binder represents a possibly generic type and its bound vars.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_public/src/unstable/convert/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ impl RustcInternal for Abi {
Abi::RiscvInterruptS => rustc_abi::ExternAbi::RiscvInterruptS,
Abi::RustPreserveNone => rustc_abi::ExternAbi::RustPreserveNone,
Abi::Custom => rustc_abi::ExternAbi::Custom,
Abi::Swift => rustc_abi::ExternAbi::Swift,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_public/src/unstable/convert/stable/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ impl<'tcx> Stable<'tcx> for CanonAbi {
CanonAbi::RustCold => CallConvention::Cold,
CanonAbi::RustPreserveNone => CallConvention::PreserveNone,
CanonAbi::Custom => CallConvention::Custom,
CanonAbi::Swift => CallConvention::Swift,
CanonAbi::Arm(arm_call) => match arm_call {
ArmCall::Aapcs => CallConvention::ArmAapcs,
ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_public/src/unstable/convert/stable/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi {
ExternAbi::RiscvInterruptM => Abi::RiscvInterruptM,
ExternAbi::RiscvInterruptS => Abi::RiscvInterruptS,
ExternAbi::Custom => Abi::Custom,
ExternAbi::Swift => Abi::Swift,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ symbols! {
abi_msp430_interrupt,
abi_ptx,
abi_riscv_interrupt,
abi_swift,
abi_sysv64,
abi_thiscall,
abi_unadjusted,
Expand Down
16 changes: 15 additions & 1 deletion compiler/rustc_target/src/spec/abi_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ impl AbiMap {
_ => ArchKind::Other,
};

let os = if target.is_like_windows {
let os = if target.is_like_darwin {
OsKind::Apple
} else if target.is_like_windows {
OsKind::Windows
} else if target.is_like_vexos {
OsKind::VEXos
Expand All @@ -80,6 +82,15 @@ impl AbiMap {
pub fn canonize_abi(&self, extern_abi: ExternAbi, has_c_varargs: bool) -> AbiMapping {
let AbiMap { os, arch } = *self;

if extern_abi == ExternAbi::Swift {
// Per https://www.swift.org/blog/abi-stability-and-more/, Swift's ABI
// is only stable on Apple platforms, so we reject it elsewhere.
match os {
OsKind::Apple => {}
_ => return AbiMapping::Invalid,
}
}

let canon_abi = match (extern_abi, arch) {
// infallible lowerings
(ExternAbi::C { .. }, _) => CanonAbi::C,
Expand All @@ -92,6 +103,8 @@ impl AbiMap {

(ExternAbi::Custom, _) => CanonAbi::Custom,

(ExternAbi::Swift, _) => CanonAbi::Swift,

(ExternAbi::System { .. }, ArchKind::X86)
if os == OsKind::Windows && !has_c_varargs =>
{
Expand Down Expand Up @@ -213,6 +226,7 @@ enum ArchKind {

#[derive(Debug, PartialEq, Copy, Clone)]
enum OsKind {
Apple,
Windows,
VEXos,
Other,
Expand Down
33 changes: 33 additions & 0 deletions tests/ui/abi/swift-abi-non-apple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//@ add-minicore
//@ needs-llvm-components: x86
//@ compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib
//@ ignore-backends: gcc
#![no_core]
#![feature(no_core, lang_items, abi_swift)]

extern crate minicore;
use minicore::*;

// The Swift ABI is only stable on Apple platforms, so it must be rejected
// on other targets even when the `abi_swift` feature gate is enabled.

extern "Swift" fn f() {} //~ ERROR is not a supported ABI

trait T {
extern "Swift" fn m(); //~ ERROR is not a supported ABI

extern "Swift" fn dm() {} //~ ERROR is not a supported ABI
}

struct S;
impl T for S {
extern "Swift" fn m() {} //~ ERROR is not a supported ABI
}

impl S {
extern "Swift" fn im() {} //~ ERROR is not a supported ABI
}

type TA = extern "Swift" fn(); //~ ERROR is not a supported ABI

extern "Swift" {} //~ ERROR is not a supported ABI
45 changes: 45 additions & 0 deletions tests/ui/abi/swift-abi-non-apple.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
error[E0570]: "Swift" is not a supported ABI for the current target
--> $DIR/swift-abi-non-apple.rs:14:8
|
LL | extern "Swift" fn f() {}
| ^^^^^^^

error[E0570]: "Swift" is not a supported ABI for the current target
--> $DIR/swift-abi-non-apple.rs:17:12
|
LL | extern "Swift" fn m();
| ^^^^^^^

error[E0570]: "Swift" is not a supported ABI for the current target
--> $DIR/swift-abi-non-apple.rs:19:12
|
LL | extern "Swift" fn dm() {}
| ^^^^^^^

error[E0570]: "Swift" is not a supported ABI for the current target
--> $DIR/swift-abi-non-apple.rs:24:12
|
LL | extern "Swift" fn m() {}
| ^^^^^^^

error[E0570]: "Swift" is not a supported ABI for the current target
--> $DIR/swift-abi-non-apple.rs:28:12
|
LL | extern "Swift" fn im() {}
| ^^^^^^^

error[E0570]: "Swift" is not a supported ABI for the current target
--> $DIR/swift-abi-non-apple.rs:31:18
|
LL | type TA = extern "Swift" fn();
| ^^^^^^^

error[E0570]: "Swift" is not a supported ABI for the current target
--> $DIR/swift-abi-non-apple.rs:33:8
|
LL | extern "Swift" {}
| ^^^^^^^

error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0570`.
33 changes: 33 additions & 0 deletions tests/ui/feature-gates/feature-gate-abi_swift.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//@ add-minicore
//@ needs-llvm-components: aarch64
//@ compile-flags: --target=aarch64-apple-darwin --crate-type=rlib
//@ ignore-backends: gcc
#![no_core]
#![feature(no_core, lang_items)]

extern crate minicore;
use minicore::*;

// Test that the "Swift" ABI is feature-gated, and cannot be used when
// the `abi_swift` feature gate is not used.

extern "Swift" fn f() {} //~ ERROR "Swift" ABI is experimental

trait T {
extern "Swift" fn m(); //~ ERROR "Swift" ABI is experimental

extern "Swift" fn dm() {} //~ ERROR "Swift" ABI is experimental
}

struct S;
impl T for S {
extern "Swift" fn m() {} //~ ERROR "Swift" ABI is experimental
}

impl S {
extern "Swift" fn im() {} //~ ERROR "Swift" ABI is experimental
}

type TA = extern "Swift" fn(); //~ ERROR "Swift" ABI is experimental

extern "Swift" {} //~ ERROR "Swift" ABI is experimental
Loading
Loading