@@ -6,6 +6,8 @@ use std::hash::{Hash, Hasher};
6
6
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher , StableOrd } ;
7
7
#[ cfg( feature = "nightly" ) ]
8
8
use rustc_macros:: { Decodable , Encodable } ;
9
+ #[ cfg( feature = "nightly" ) ]
10
+ use rustc_span:: Symbol ;
9
11
10
12
use crate :: AbiFromStrErr ;
11
13
@@ -226,6 +228,13 @@ impl StableOrd for ExternAbi {
226
228
#[ cfg( feature = "nightly" ) ]
227
229
rustc_error_messages:: into_diag_arg_using_display!( ExternAbi ) ;
228
230
231
+ #[ cfg( feature = "nightly" ) ]
232
+ pub enum CVariadicStatus {
233
+ NotSupported ,
234
+ Stable ,
235
+ Unstable { feature : Symbol } ,
236
+ }
237
+
229
238
impl ExternAbi {
230
239
/// An ABI "like Rust"
231
240
///
@@ -238,23 +247,33 @@ impl ExternAbi {
238
247
matches ! ( self , Rust | RustCall | RustCold )
239
248
}
240
249
241
- pub fn supports_varargs ( self ) -> bool {
250
+ /// Returns whether the ABI supports C variadics. This only controls whether we allow *imports*
251
+ /// of such functions via `extern` blocks; there's a separate check during AST construction
252
+ /// guarding *definitions* of variadic functions.
253
+ #[ cfg( feature = "nightly" ) ]
254
+ pub fn supports_c_variadic ( self ) -> CVariadicStatus {
242
255
// * C and Cdecl obviously support varargs.
243
256
// * C can be based on Aapcs, SysV64 or Win64, so they must support varargs.
244
257
// * EfiApi is based on Win64 or C, so it also supports it.
258
+ // * System automatically falls back to C when used with variadics, therefore supports it.
245
259
//
246
260
// * Stdcall does not, because it would be impossible for the callee to clean
247
261
// up the arguments. (callee doesn't know how many arguments are there)
248
262
// * Same for Fastcall, Vectorcall and Thiscall.
249
263
// * Other calling conventions are related to hardware or the compiler itself.
264
+ //
265
+ // All of the supported ones must have a test in `tests/codegen/cffi/c-variadic-ffi.rs`.
250
266
match self {
251
267
Self :: C { .. }
252
268
| Self :: Cdecl { .. }
253
269
| Self :: Aapcs { .. }
254
270
| Self :: Win64 { .. }
255
271
| Self :: SysV64 { .. }
256
- | Self :: EfiApi => true ,
257
- _ => false ,
272
+ | Self :: EfiApi => CVariadicStatus :: Stable ,
273
+ Self :: System { .. } => {
274
+ CVariadicStatus :: Unstable { feature : rustc_span:: sym:: extern_system_varargs }
275
+ }
276
+ _ => CVariadicStatus :: NotSupported ,
258
277
}
259
278
}
260
279
}
0 commit comments