@@ -6,6 +6,8 @@ use std::hash::{Hash, Hasher};
66use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher , StableOrd } ;
77#[ cfg( feature = "nightly" ) ]
88use rustc_macros:: { Decodable , Encodable } ;
9+ #[ cfg( feature = "nightly" ) ]
10+ use rustc_span:: Symbol ;
911
1012use crate :: AbiFromStrErr ;
1113
@@ -226,6 +228,13 @@ impl StableOrd for ExternAbi {
226228#[ cfg( feature = "nightly" ) ]
227229rustc_error_messages:: into_diag_arg_using_display!( ExternAbi ) ;
228230
231+ #[ cfg( feature = "nightly" ) ]
232+ pub enum CVariadicStatus {
233+ NotSupported ,
234+ Stable ,
235+ Unstable { feature : Symbol } ,
236+ }
237+
229238impl ExternAbi {
230239 /// An ABI "like Rust"
231240 ///
@@ -238,23 +247,33 @@ impl ExternAbi {
238247 matches ! ( self , Rust | RustCall | RustCold )
239248 }
240249
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 {
242255 // * C and Cdecl obviously support varargs.
243256 // * C can be based on Aapcs, SysV64 or Win64, so they must support varargs.
244257 // * 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.
245259 //
246260 // * Stdcall does not, because it would be impossible for the callee to clean
247261 // up the arguments. (callee doesn't know how many arguments are there)
248262 // * Same for Fastcall, Vectorcall and Thiscall.
249263 // * 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`.
250266 match self {
251267 Self :: C { .. }
252268 | Self :: Cdecl { .. }
253269 | Self :: Aapcs { .. }
254270 | Self :: Win64 { .. }
255271 | 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 ,
258277 }
259278 }
260279}
0 commit comments