Skip to content

Commit 0705b60

Browse files
Rollup merge of rust-lang#155815 - djc:swift-cc, r=jieyouxu
Add Swift function call ABI Adds an unstable `extern "Swift"` ABI behind the `abi_swift` feature gate, mapping to LLVM's `swiftcc` calling convention. This is only allowed (a) for `is_darwin_like` targets, since the [ABI is only stable for those platforms](https://www.swift.org/blog/abi-stability-and-more/) and (b) with the LLVM backend, since the other backends don't support it. Current approaches to interoperability with Swift lower to Objective-C (or require a Swift stub exposing a C ABI), but that is an optional mapping on the Swift side that some newer Apple frameworks omit. It would be great to be able to more directly/natively be able to call into Swift code directly via its stable API (on Apple platforms at least). Reimplements rust-lang#64582 on top of current main. The main objection to the previous PR seemed to be that it needed an RFC, but there was pushback (which seems sensible to me) that an RFC could be deferred until stabilization. I think this needs a tracking issue? Would be happy to write one up if/when there is a consensus that this will be merged.
2 parents eab3d97 + f49e451 commit 0705b60

23 files changed

Lines changed: 233 additions & 3 deletions

File tree

compiler/rustc_abi/src/canon_abi.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ pub enum CanonAbi {
3232
/// An ABI that rustc does not know how to call or define.
3333
Custom,
3434

35+
/// Swift calling convention, exposed via LLVM's `swiftcc`. Cross-platform
36+
/// and not tied to a specific target architecture.
37+
Swift,
38+
3539
/// ABIs relevant to 32-bit Arm targets
3640
Arm(ArmCall),
3741
/// ABI relevant to GPUs: the entry point for a GPU kernel
@@ -58,6 +62,7 @@ impl CanonAbi {
5862
CanonAbi::Rust | CanonAbi::RustCold | CanonAbi::RustPreserveNone => true,
5963
CanonAbi::C
6064
| CanonAbi::Custom
65+
| CanonAbi::Swift
6166
| CanonAbi::Arm(_)
6267
| CanonAbi::GpuKernel
6368
| CanonAbi::Interrupt(_)
@@ -77,6 +82,7 @@ impl fmt::Display for CanonAbi {
7782
CanonAbi::RustCold => ExternAbi::RustCold,
7883
CanonAbi::RustPreserveNone => ExternAbi::RustPreserveNone,
7984
CanonAbi::Custom => ExternAbi::Custom,
85+
CanonAbi::Swift => ExternAbi::Swift,
8086
CanonAbi::Arm(arm_call) => match arm_call {
8187
ArmCall::Aapcs => ExternAbi::Aapcs { unwind: false },
8288
ArmCall::CCmseNonSecureCall => ExternAbi::CmseNonSecureCall,

compiler/rustc_abi/src/extern_abi.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ pub enum ExternAbi {
6262
/// and only valid on platforms that have a UEFI standard
6363
EfiApi,
6464

65+
/// Swift's calling convention, used to interoperate with Swift code without
66+
/// going through C as an intermediary.
67+
Swift,
68+
6569
/* arm */
6670
/// Arm Architecture Procedure Call Standard, sometimes `ExternAbi::C` is an alias for this
6771
Aapcs {
@@ -173,6 +177,7 @@ abi_impls! {
173177
C { unwind: false } =><= "C",
174178
C { unwind: true } =><= "C-unwind",
175179
Rust =><= "Rust",
180+
Swift =><= "Swift",
176181
Aapcs { unwind: false } =><= "aapcs",
177182
Aapcs { unwind: true } =><= "aapcs-unwind",
178183
AvrInterrupt =><= "avr-interrupt",
@@ -348,7 +353,8 @@ impl ExternAbi {
348353
| Self::Vectorcall { .. }
349354
| Self::SysV64 { .. }
350355
| Self::Win64 { .. }
351-
| Self::RustPreserveNone => true,
356+
| Self::RustPreserveNone
357+
| Self::Swift => true,
352358
}
353359
}
354360
}

compiler/rustc_ast_lowering/src/stability.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,5 +144,8 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> {
144144
ExternAbi::Custom => {
145145
Err(UnstableAbi { abi, feature: sym::abi_custom, explain: GateReason::Experimental })
146146
}
147+
ExternAbi::Swift => {
148+
Err(UnstableAbi { abi, feature: sym::abi_swift, explain: GateReason::Experimental })
149+
}
147150
}
148151
}

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ impl<'a> AstValidator<'a> {
424424
| CanonAbi::Rust
425425
| CanonAbi::RustCold
426426
| CanonAbi::RustPreserveNone
427+
| CanonAbi::Swift
427428
| CanonAbi::Arm(_)
428429
| CanonAbi::X86(_) => { /* nothing to check */ }
429430

compiler/rustc_codegen_cranelift/src/abi/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub(crate) fn conv_to_call_conv(
7070
_ => default_call_conv,
7171
},
7272

73-
CanonAbi::Interrupt(_) | CanonAbi::Arm(_) => {
73+
CanonAbi::Interrupt(_) | CanonAbi::Arm(_) | CanonAbi::Swift => {
7474
sess.dcx().fatal("call conv {c:?} is not yet implemented")
7575
}
7676
CanonAbi::GpuKernel => {

compiler/rustc_codegen_gcc/src/abi.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option<FnAttri
245245
// possible to declare an `extern "custom"` block, so the backend still needs a calling
246246
// convention for declaring foreign functions.
247247
CanonAbi::Custom => return None,
248+
// gcc/gccjit does not have anything for Swift's calling convention.
249+
CanonAbi::Swift => panic!("gcc/gccjit backend does not support Swift calling convention"),
248250
CanonAbi::Arm(arm_call) => match arm_call {
249251
ArmCall::CCmseNonSecureCall => FnAttribute::ArmCmseNonsecureCall,
250252
ArmCall::CCmseNonSecureEntry => FnAttribute::ArmCmseNonsecureEntry,

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm:
722722
// possible to declare an `extern "custom"` block, so the backend still needs a calling
723723
// convention for declaring foreign functions.
724724
CanonAbi::Custom => llvm::CCallConv,
725+
CanonAbi::Swift => llvm::SwiftCallConv,
725726
CanonAbi::GpuKernel => match &sess.target.arch {
726727
Arch::AmdGpu => llvm::AmdgpuKernel,
727728
Arch::Nvptx64 => llvm::PtxKernel,

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ pub(crate) enum CallConv {
166166
ColdCallConv = 9,
167167
PreserveMost = 14,
168168
PreserveAll = 15,
169+
SwiftCallConv = 16,
169170
Tail = 18,
170171
PreserveNone = 21,
171172
X86StdcallCallConv = 64,

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,8 @@ declare_features! (
380380
(unstable, abi_ptx, "1.15.0", Some(38788)),
381381
/// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`.
382382
(unstable, abi_riscv_interrupt, "1.73.0", Some(111889)),
383+
/// Allows `extern "Swift" fn()`.
384+
(unstable, abi_swift, "CURRENT_RUSTC_VERSION", Some(156481)),
383385
/// Allows `extern "x86-interrupt" fn()`.
384386
(unstable, abi_x86_interrupt, "1.17.0", Some(40180)),
385387
/// Allows additional const parameter types, such as `[u8; 10]` or user defined types

compiler/rustc_hir_typeck/src/callee.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
202202
| CanonAbi::Rust
203203
| CanonAbi::RustCold
204204
| CanonAbi::RustPreserveNone
205+
| CanonAbi::Swift
205206
| CanonAbi::Arm(_)
206207
| CanonAbi::X86(_) => {}
207208
}

0 commit comments

Comments
 (0)