Skip to content

Commit a1f6e7b

Browse files
committed
add extern "custom" functions
1 parent 3ef8e64 commit a1f6e7b

File tree

29 files changed

+658
-0
lines changed

29 files changed

+658
-0
lines changed

compiler/rustc_abi/src/extern_abi.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ pub enum ExternAbi {
2525
Cdecl {
2626
unwind: bool,
2727
},
28+
/// An ABI that rustc does not know how to call or define. Functions with this ABI can
29+
/// only be created using `#[naked]` functions or `extern "custom"` blocks, and can only
30+
/// be called from inline assembly.
31+
Custom,
2832
Stdcall {
2933
unwind: bool,
3034
},
@@ -141,6 +145,7 @@ abi_impls! {
141145
Win64 { unwind: false } =><= "win64",
142146
Win64 { unwind: true } =><= "win64-unwind",
143147
X86Interrupt =><= "x86-interrupt",
148+
Custom =><= "custom",
144149
}
145150
}
146151

compiler/rustc_ast_lowering/src/stability.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,5 +134,8 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> {
134134
feature: sym::cmse_nonsecure_entry,
135135
explain: GateReason::Experimental,
136136
}),
137+
ExternAbi::Custom => {
138+
Err(UnstableAbi { abi, feature: sym::abi_custom, explain: GateReason::Experimental })
139+
}
137140
}
138141
}

compiler/rustc_codegen_cranelift/src/abi/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ pub(crate) fn conv_to_call_conv(sess: &Session, c: Conv, default_call_conv: Call
6868
Conv::Msp430Intr | Conv::GpuKernel | Conv::AvrInterrupt | Conv::AvrNonBlockingInterrupt => {
6969
unreachable!("tried to use {c:?} call conv which only exists on an unsupported target");
7070
}
71+
72+
// Functions with this calling convention can only be called from assembly, but it is
73+
// possible to declare an `extern "custom"` block, so the backend still needs a calling
74+
// convention for declaring foreign functions.
75+
Conv::Custom => default_call_conv,
7176
}
7277
}
7378

compiler/rustc_codegen_gcc/src/abi.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ pub fn conv_to_fn_attribute<'gcc>(conv: Conv, arch: &str) -> Option<FnAttribute<
272272
Conv::X86VectorCall => return None,
273273
Conv::X86_64SysV => FnAttribute::SysvAbi,
274274
Conv::X86_64Win64 => FnAttribute::MsAbi,
275+
276+
// Functions with this calling convention can only be called from assembly, but it is
277+
// possible to declare an `extern "custom"` block, so the backend still needs a calling
278+
// convention for declaring foreign functions.
279+
Conv::Custom => return None,
275280
};
276281
Some(attribute)
277282
}

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,11 @@ impl llvm::CallConv {
676676
Conv::X86VectorCall => llvm::X86_VectorCall,
677677
Conv::X86_64SysV => llvm::X86_64_SysV,
678678
Conv::X86_64Win64 => llvm::X86_64_Win64,
679+
680+
// Functions with this calling convention can only be called from assembly, but it is
681+
// possible to declare an `extern "custom"` block, so the backend still needs a calling
682+
// convention for declaring foreign functions.
683+
Conv::Custom => llvm::CCallConv,
679684
}
680685
}
681686
}

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,8 @@ declare_features! (
354354
(unstable, abi_avr_interrupt, "1.45.0", Some(69664)),
355355
/// Allows `extern "C-cmse-nonsecure-call" fn()`.
356356
(unstable, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391)),
357+
/// Allows `extern "custom" fn()`.
358+
(unstable, abi_custom, "CURRENT_RUSTC_VERSION", Some(140566)),
357359
/// Allows `extern "gpu-kernel" fn()`.
358360
(unstable, abi_gpu_kernel, "1.86.0", Some(135467)),
359361
/// Allows `extern "msp430-interrupt" fn()`.

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
960960
tcx.ensure_ok().check_mod_loops(module);
961961
tcx.ensure_ok().check_mod_attrs(module);
962962
tcx.ensure_ok().check_mod_naked_functions(module);
963+
tcx.ensure_ok().check_mod_custom_abi(module);
963964
tcx.ensure_ok().check_mod_unstable_api_usage(module);
964965
});
965966
},

compiler/rustc_middle/src/query/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,10 @@ rustc_queries! {
11171117
desc { |tcx| "checking naked functions in {}", describe_as_module(key, tcx) }
11181118
}
11191119

1120+
query check_mod_custom_abi(key: LocalModDefId) {
1121+
desc { |tcx| "checking use of `extern \"custom\"` in {}", describe_as_module(key, tcx) }
1122+
}
1123+
11201124
query check_mod_privacy(key: LocalModDefId) {
11211125
desc { |tcx| "checking privacy in {}", describe_as_module(key.to_local_def_id(), tcx) }
11221126
}

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
12641264
| RiscvInterruptS
12651265
| CCmseNonSecureCall
12661266
| CCmseNonSecureEntry
1267+
| Custom
12671268
| Unadjusted => false,
12681269
Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
12691270
}

compiler/rustc_passes/messages.ftl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@
44
-passes_see_issue =
55
see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
66
7+
passes_abi_custom_call =
8+
functions with the `"custom"` ABI cannot be called
9+
.note = an `extern "custom"` function can only be called from within inline assembly
10+
11+
passes_abi_custom_clothed_function =
12+
functions with the `"custom"` ABI must be naked
13+
.suggestion = add the `#[unsafe(naked)]` attribute to this function
14+
15+
passes_abi_custom_safe_foreign_function =
16+
foreign functions with the `"custom"` ABI cannot be safe
17+
.suggestion = remove the `safe` keyword from this definition
18+
19+
passes_abi_custom_safe_function =
20+
functions with the `"custom"` ABI must be unsafe
21+
.suggestion = add the `unsafe` keyword this function definition
22+
723
passes_abi_invalid_attribute =
824
`#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
925
passes_abi_ne =

0 commit comments

Comments
 (0)