Skip to content

Commit 100b92a

Browse files
Split out the extern_system_varargs feature
After the stabilization PR was opened, `extern "system"` functions were added to `extended_varargs_abi_support`. This has a number of questions regarding it that were not discussed and were somewhat surprising. It deserves to be considered as its own feature, separate from `extended_varargs_abi_support`.
1 parent ced8e65 commit 100b92a

File tree

7 files changed

+45
-16
lines changed

7 files changed

+45
-16
lines changed

compiler/rustc_abi/src/extern_abi.rs

-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ impl Abi {
7373
// * C and Cdecl obviously support varargs.
7474
// * C can be based on Aapcs, SysV64 or Win64, so they must support varargs.
7575
// * EfiApi is based on Win64 or C, so it also supports it.
76-
// * System falls back to C for functions with varargs.
7776
//
7877
// * Stdcall does not, because it would be impossible for the callee to clean
7978
// up the arguments. (callee doesn't know how many arguments are there)
@@ -82,7 +81,6 @@ impl Abi {
8281
match self {
8382
Self::C { .. }
8483
| Self::Cdecl { .. }
85-
| Self::System { .. }
8684
| Self::Aapcs { .. }
8785
| Self::Win64 { .. }
8886
| Self::SysV64 { .. }

compiler/rustc_feature/src/unstable.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -487,9 +487,11 @@ declare_features! (
487487
(unstable, exhaustive_patterns, "1.13.0", Some(51085)),
488488
/// Allows explicit tail calls via `become` expression.
489489
(incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
490-
/// Allows using `efiapi`, `sysv64` and `win64` as calling convention
490+
/// Allows using `aapcs`, `efiapi`, `sysv64` and `win64` as calling conventions
491491
/// for functions with varargs.
492492
(unstable, extended_varargs_abi_support, "1.65.0", Some(100189)),
493+
/// Allows using `system` as a calling convention with varargs.
494+
(unstable, extern_system_varargs, "CURRENT_RUSTC_VERSION", Some(136946)),
493495
/// Allows defining `extern type`s.
494496
(unstable, extern_types, "1.23.0", Some(43467)),
495497
/// Allow using 128-bit (quad precision) floating point numbers.

compiler/rustc_hir_analysis/src/lib.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,23 @@ fn require_c_abi_if_c_variadic(
127127
}
128128

129129
let extended_abi_support = tcx.features().extended_varargs_abi_support();
130-
let conventions = match (extended_abi_support, abi.supports_varargs()) {
130+
let extern_system_varargs = tcx.features().extern_system_varargs();
131+
let conventions = if extended_abi_support { CONVENTIONS_UNSTABLE } else { CONVENTIONS_STABLE };
132+
match abi {
131133
// User enabled additional ABI support for varargs and function ABI matches those ones.
132-
(true, true) => return,
134+
ExternAbi::System { .. } if extern_system_varargs => return,
135+
abi if abi.supports_varargs() && extended_abi_support => return,
133136

134137
// Using this ABI would be ok, if the feature for additional ABI support was enabled.
135-
// Return CONVENTIONS_STABLE, because we want the other error to look the same.
136-
(false, true) => {
137-
feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
138-
.emit();
139-
CONVENTIONS_STABLE
138+
ExternAbi::System { .. } => {
139+
feature_err(&tcx.sess, sym::extern_system_varargs, span, UNSTABLE_EXPLAIN).emit();
140+
}
141+
abi => {
142+
if abi.supports_varargs() && !extended_abi_support {
143+
feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
144+
.emit();
145+
};
140146
}
141-
142-
(false, false) => CONVENTIONS_STABLE,
143-
(true, false) => CONVENTIONS_UNSTABLE,
144147
};
145148

146149
tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,7 @@ symbols! {
879879
extern_crate_self,
880880
extern_in_paths,
881881
extern_prelude,
882+
extern_system_varargs,
882883
extern_types,
883884
external,
884885
external_doc,

tests/ui/c-variadic/variadic-ffi-2.rs

-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ fn baz(f: extern "stdcall" fn(usize, ...)) {
88
f(22, 44);
99
}
1010

11-
fn system(f: extern "system" fn(usize, ...)) {
12-
f(22, 44);
13-
}
1411
#[cfg(target_arch = "x86_64")]
1512
fn sysv(f: extern "sysv64" fn(usize, ...)) {
1613
f(22, 44);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn system(f: extern "system" fn(usize, ...)) {
2+
//~^ ERROR using calling conventions other than `C` or `cdecl` for varargs functions is unstable
3+
//~| ERROR C-variadic function must have a compatible calling convention, like `C` or `cdecl`
4+
5+
f(22, 44);
6+
}
7+
8+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
2+
--> $DIR/feature-gate-extern_system_varargs.rs:1:14
3+
|
4+
LL | fn system(f: extern "system" fn(usize, ...)) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #136946 <https://github.com/rust-lang/rust/issues/136946> for more information
8+
= help: add `#![feature(extern_system_varargs)]` to the crate attributes to enable
9+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
10+
11+
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
12+
--> $DIR/feature-gate-extern_system_varargs.rs:1:14
13+
|
14+
LL | fn system(f: extern "system" fn(usize, ...)) {
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
16+
17+
error: aborting due to 2 previous errors
18+
19+
Some errors have detailed explanations: E0045, E0658.
20+
For more information about an error, try `rustc --explain E0045`.

0 commit comments

Comments
 (0)