- match (decl.c_variadic, abi) {
- // The function has the correct calling convention, or isn't a "C-variadic" function.
- (false, _) | (true, Abi::C { .. }) | (true, Abi::Cdecl { .. }) => {}
- // The function is a "C-variadic" function with an incorrect calling convention.
- (true, _) => {
- let mut err = struct_span_err!(
- tcx.sess,
+ const ERROR_HEAD: &str = "C-variadic function must have a compatible calling convention";
+ const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `win64`, `sysv64` or `efiapi`";
+ const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
+ const UNSTABLE_EXPLAIN: &str =
+ "using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
+
+ if !decl.c_variadic || matches!(abi, Abi::C { .. } | Abi::Cdecl { .. }) {
+ return;
+ }
+
+ let extended_abi_support = tcx.features().extended_varargs_abi_support;
+ let conventions = match (extended_abi_support, abi.supports_varargs()) {
+ // User enabled additional ABI support for varargs and function ABI matches those ones.
+ (true, true) => return,
+
+ // Using this ABI would be ok, if the feature for additional ABI support was enabled.
+ // Return CONVENTIONS_STABLE, because we want the other error to look the same.
+ (false, true) => {
+ feature_err(
+ &tcx.sess.parse_sess,
+ sym::extended_varargs_abi_support,