diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs index 41d744e1946ad..e3b2b1eff72d4 100644 --- a/compiler/rustc_abi/src/extern_abi.rs +++ b/compiler/rustc_abi/src/extern_abi.rs @@ -6,6 +6,8 @@ use std::hash::{Hash, Hasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable}; +#[cfg(feature = "nightly")] +use rustc_span::Symbol; use crate::AbiFromStrErr; @@ -226,6 +228,13 @@ impl StableOrd for ExternAbi { #[cfg(feature = "nightly")] rustc_error_messages::into_diag_arg_using_display!(ExternAbi); +#[cfg(feature = "nightly")] +pub enum CVariadicStatus { + NotSupported, + Stable, + Unstable { feature: Symbol }, +} + impl ExternAbi { /// An ABI "like Rust" /// @@ -238,23 +247,33 @@ impl ExternAbi { matches!(self, Rust | RustCall | RustCold) } - pub fn supports_varargs(self) -> bool { + /// Returns whether the ABI supports C variadics. This only controls whether we allow *imports* + /// of such functions via `extern` blocks; there's a separate check during AST construction + /// guarding *definitions* of variadic functions. + #[cfg(feature = "nightly")] + pub fn supports_c_variadic(self) -> CVariadicStatus { // * C and Cdecl obviously support varargs. // * C can be based on Aapcs, SysV64 or Win64, so they must support varargs. // * EfiApi is based on Win64 or C, so it also supports it. + // * System automatically falls back to C when used with variadics, therefore supports it. // // * Stdcall does not, because it would be impossible for the callee to clean // up the arguments. (callee doesn't know how many arguments are there) // * Same for Fastcall, Vectorcall and Thiscall. // * Other calling conventions are related to hardware or the compiler itself. + // + // All of the supported ones must have a test in `tests/codegen/cffi/c-variadic-ffi.rs`. match self { Self::C { .. } | Self::Cdecl { .. } | Self::Aapcs { .. } | Self::Win64 { .. } | Self::SysV64 { .. } - | Self::EfiApi => true, - _ => false, + | Self::EfiApi => CVariadicStatus::Stable, + Self::System { .. } => { + CVariadicStatus::Unstable { feature: rustc_span::sym::extern_system_varargs } + } + _ => CVariadicStatus::NotSupported, } } } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 14e256b8045df..22aba1fac0f8b 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -63,6 +63,8 @@ mod tests; pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind}; pub use canon_abi::{ArmCall, CanonAbi, InterruptKind, X86Call}; +#[cfg(feature = "nightly")] +pub use extern_abi::CVariadicStatus; pub use extern_abi::{ExternAbi, all_names}; #[cfg(feature = "nightly")] pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx}; diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index a95f144396844..e5f1fcdc4b40d 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -57,7 +57,7 @@ ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetim .label = {ast_passes_auto_super_lifetime} .suggestion = remove the super traits or lifetime bounds -ast_passes_bad_c_variadic = only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +ast_passes_bad_c_variadic = defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block .cannot_have = cannot have a body diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 9fe55216f9395..6af4cfb0e562e 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -203,6 +203,9 @@ declare_features! ( (accepted, expr_fragment_specifier_2024, "1.83.0", Some(123742)), /// Allows arbitrary expressions in key-value attributes at parse time. (accepted, extended_key_value_attributes, "1.54.0", Some(78835)), + /// Allows using `aapcs`, `efiapi`, `sysv64` and `win64` as calling conventions + /// for functions with varargs. + (accepted, extended_varargs_abi_support, "CURRENT_RUSTC_VERSION", Some(100189)), /// Allows resolving absolute paths as paths from other crates. (accepted, extern_absolute_paths, "1.30.0", Some(44660)), /// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 92b435b4b0178..573e9aab0554a 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -492,9 +492,6 @@ declare_features! ( (incomplete, explicit_tail_calls, "1.72.0", Some(112788)), /// Allows using `#[export_stable]` which indicates that an item is exportable. (incomplete, export_stable, "1.88.0", Some(139939)), - /// Allows using `aapcs`, `efiapi`, `sysv64` and `win64` as calling conventions - /// for functions with varargs. - (unstable, extended_varargs_abi_support, "1.65.0", Some(100189)), /// Allows using `system` as a calling convention with varargs. (unstable, extern_system_varargs, "1.86.0", Some(136946)), /// Allows defining `extern type`s. diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index eccb88a938fba..08b344638dd59 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -978,7 +978,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().fn_sig(def_id); let item = tcx.hir_foreign_item(item); let hir::ForeignItemKind::Fn(sig, ..) = item.kind else { bug!() }; - require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span); + check_c_variadic_abi(tcx, sig.decl, abi, item.span); } DefKind::Static { .. } => { tcx.ensure_ok().codegen_fn_attrs(def_id); diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 2e4b151d4dc8c..b5c0ca4727cda 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -98,7 +98,7 @@ use tracing::debug; use self::compare_impl_item::collect_return_position_impl_trait_in_trait_tys; use self::region::region_scope_tree; -use crate::{errors, require_c_abi_if_c_variadic}; +use crate::{check_c_variadic_abi, errors}; /// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`] pub(super) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index c7b984d9b259c..c5e079fe89ac4 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -52,11 +52,11 @@ use rustc_trait_selection::traits::{self, FulfillmentError}; use tracing::{debug, instrument}; use crate::check::check_abi; +use crate::check_c_variadic_abi; use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation}; use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint}; use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args}; use crate::middle::resolve_bound_vars as rbv; -use crate::require_c_abi_if_c_variadic; /// A path segment that is semantically allowed to have generic arguments. #[derive(Debug)] @@ -2412,7 +2412,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t))) } hir::TyKind::FnPtr(bf) => { - require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, hir_ty.span); + check_c_variadic_abi(tcx, bf.decl, bf.abi, hir_ty.span); Ty::new_fn_ptr( tcx, diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 44a5ceed46961..2562ab7542a6a 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -90,7 +90,7 @@ mod outlives; mod variance; pub use errors::NoVariantNamed; -use rustc_abi::ExternAbi; +use rustc_abi::{CVariadicStatus, ExternAbi}; use rustc_hir::def::DefKind; use rustc_hir::lints::DelayedLint; use rustc_hir::{self as hir}; @@ -99,7 +99,6 @@ use rustc_middle::mir::interpret::GlobalId; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; use rustc_session::parse::feature_err; -use rustc_span::symbol::sym; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits; @@ -108,46 +107,34 @@ use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer}; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } -fn require_c_abi_if_c_variadic( - tcx: TyCtxt<'_>, - decl: &hir::FnDecl<'_>, - abi: ExternAbi, - span: Span, -) { - // ABIs which can stably use varargs - if !decl.c_variadic || matches!(abi, ExternAbi::C { .. } | ExternAbi::Cdecl { .. }) { +fn check_c_variadic_abi(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: ExternAbi, span: Span) { + if !decl.c_variadic { + // Not even a variadic function. return; } - // ABIs with feature-gated stability - let extended_abi_support = tcx.features().extended_varargs_abi_support(); - let extern_system_varargs = tcx.features().extern_system_varargs(); - - // If the feature gate has been enabled, we can stop here - if extern_system_varargs && let ExternAbi::System { .. } = abi { - return; - }; - if extended_abi_support && abi.supports_varargs() { - return; - }; - - // Looks like we need to pick an error to emit. - // Is there any feature which we could have enabled to make this work? - let unstable_explain = - format!("C-variadic functions with the {abi} calling convention are unstable"); - match abi { - ExternAbi::System { .. } => { - feature_err(&tcx.sess, sym::extern_system_varargs, span, unstable_explain) + match abi.supports_c_variadic() { + CVariadicStatus::Stable => {} + CVariadicStatus::NotSupported => { + tcx.dcx() + .create_err(errors::VariadicFunctionCompatibleConvention { + span, + convention: &format!("{abi}"), + }) + .emit(); } - abi if abi.supports_varargs() => { - feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, unstable_explain) + CVariadicStatus::Unstable { feature } => { + if !tcx.features().enabled(feature) { + feature_err( + &tcx.sess, + feature, + span, + format!("C-variadic functions with the {abi} calling convention are unstable"), + ) + .emit(); + } } - _ => tcx.dcx().create_err(errors::VariadicFunctionCompatibleConvention { - span, - convention: &format!("{abi}"), - }), } - .emit(); } /// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index f0de03c9a2806..da8fda42cd143 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -291,7 +291,6 @@ #![feature(doc_masked)] #![feature(doc_notable_trait)] #![feature(dropck_eyepatch)] -#![feature(extended_varargs_abi_support)] #![feature(f16)] #![feature(f128)] #![feature(ffi_const)] diff --git a/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md deleted file mode 100644 index b20c30ec8f1c8..0000000000000 --- a/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md +++ /dev/null @@ -1,10 +0,0 @@ -# `extended_varargs_abi_support` - -The tracking issue for this feature is: [#100189] - -[#100189]: https://github.com/rust-lang/rust/issues/100189 - ------------------------- - -This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling -conventions on functions with varargs. diff --git a/tests/codegen-llvm/cffi/c-variadic-ffi.rs b/tests/codegen-llvm/cffi/c-variadic-ffi.rs index 3e99c9fb84e42..1dee477e9ed7c 100644 --- a/tests/codegen-llvm/cffi/c-variadic-ffi.rs +++ b/tests/codegen-llvm/cffi/c-variadic-ffi.rs @@ -14,7 +14,7 @@ //@[arm32] needs-llvm-components: arm #![crate_type = "lib"] #![feature(no_core)] -#![feature(extended_varargs_abi_support, extern_system_varargs)] +#![feature(extern_system_varargs)] #![no_core] extern crate minicore; diff --git a/tests/ui/abi/unsupported-varargs-fnptr.rs b/tests/ui/abi/unsupported-varargs-fnptr.rs index 1d23916d03902..ac3913b3ef88f 100644 --- a/tests/ui/abi/unsupported-varargs-fnptr.rs +++ b/tests/ui/abi/unsupported-varargs-fnptr.rs @@ -6,8 +6,6 @@ // We have to use this flag to force ABI computation of an invalid ABI //@ compile-flags: -Clink-dead-code -#![feature(extended_varargs_abi_support)] - // sometimes fn ptrs with varargs make layout and ABI computation ICE // as found in https://github.com/rust-lang/rust/issues/142107 diff --git a/tests/ui/abi/unsupported-varargs-fnptr.stderr b/tests/ui/abi/unsupported-varargs-fnptr.stderr index 238f2b3133044..c05c55df82e75 100644 --- a/tests/ui/abi/unsupported-varargs-fnptr.stderr +++ b/tests/ui/abi/unsupported-varargs-fnptr.stderr @@ -1,5 +1,5 @@ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported-varargs-fnptr.rs:14:20 + --> $DIR/unsupported-varargs-fnptr.rs:12:20 | LL | fn aapcs(f: extern "aapcs" fn(usize, ...)) { | ^^^^^^^ diff --git a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs deleted file mode 100644 index 1e0576b21866b..0000000000000 --- a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ only-x86_64 - -fn efiapi(f: extern "efiapi" fn(usize, ...)) { - //~^ ERROR: unstable - f(22, 44); -} -fn sysv(f: extern "sysv64" fn(usize, ...)) { - //~^ ERROR: unstable - f(22, 44); -} -fn win(f: extern "win64" fn(usize, ...)) { - //~^ ERROR: unstable - f(22, 44); -} - -fn main() {} diff --git a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr deleted file mode 100644 index 7ef54b639ad2b..0000000000000 --- a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0658]: C-variadic functions with the "efiapi" calling convention are unstable - --> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14 - | -LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #100189 for more information - = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: C-variadic functions with the "sysv64" calling convention are unstable - --> $DIR/feature-gate-extended_varargs_abi_support.rs:7:12 - | -LL | fn sysv(f: extern "sysv64" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #100189 for more information - = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: C-variadic functions with the "win64" calling convention are unstable - --> $DIR/feature-gate-extended_varargs_abi_support.rs:11:11 - | -LL | fn win(f: extern "win64" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #100189 for more information - = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs index 8eeb99a4cc19c..537d0263adf78 100644 --- a/tests/ui/c-variadic/issue-86053-1.rs +++ b/tests/ui/c-variadic/issue-86053-1.rs @@ -13,6 +13,6 @@ fn ordering4 < 'a , 'b > ( a : , self , self , self , //~| ERROR unexpected `self` parameter in function //~| ERROR unexpected `self` parameter in function //~| ERROR `...` must be the last argument of a C-variadic function - //~| ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~| ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR cannot find type `F` in this scope } diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr index dc323f9a234d6..472295c92b972 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -46,7 +46,7 @@ error: `...` must be the last argument of a C-variadic function LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/issue-86053-1.rs:11:12 | LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { diff --git a/tests/ui/c-variadic/same-program-multiple-abis-arm.rs b/tests/ui/c-variadic/same-program-multiple-abis-arm.rs index 1b0bdecabfbc8..1445bbb47bbd3 100644 --- a/tests/ui/c-variadic/same-program-multiple-abis-arm.rs +++ b/tests/ui/c-variadic/same-program-multiple-abis-arm.rs @@ -1,4 +1,3 @@ -#![feature(extended_varargs_abi_support)] //@ run-pass //@ only-arm //@ ignore-thumb (this test uses arm assembly) diff --git a/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs b/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs index b21accb999e9b..aff8ab613c431 100644 --- a/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs +++ b/tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs @@ -1,4 +1,3 @@ -#![feature(extended_varargs_abi_support)] //@ run-pass //@ only-x86_64 diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index 800dd580af290..ad4fca8252d24 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -71,6 +71,6 @@ extern "cmse-nonsecure-entry" fn wrapped_trait_object( } extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR requires `va_list` lang_item } diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr index f0190671b5a17..7aeb6969feb9f 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -1,4 +1,4 @@ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/generics.rs:73:53 | LL | extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { diff --git a/tests/ui/feature-gates/feature-gate-c_variadic.rs b/tests/ui/feature-gates/feature-gate-c_variadic.rs index f189f02a26ddf..45c688420931d 100644 --- a/tests/ui/feature-gates/feature-gate-c_variadic.rs +++ b/tests/ui/feature-gates/feature-gate-c_variadic.rs @@ -2,3 +2,9 @@ pub unsafe extern "C" fn test(_: i32, ap: ...) { } //~^ ERROR C-variadic functions are unstable + +trait Trait { + unsafe extern "C" fn trait_test(_: i32, ap: ...) { } + //~^ ERROR C-variadic functions are unstable + //~| ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention +} diff --git a/tests/ui/feature-gates/feature-gate-c_variadic.stderr b/tests/ui/feature-gates/feature-gate-c_variadic.stderr index 1b6a8c92af5ed..e30a2f1ede367 100644 --- a/tests/ui/feature-gates/feature-gate-c_variadic.stderr +++ b/tests/ui/feature-gates/feature-gate-c_variadic.stderr @@ -1,3 +1,9 @@ +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention + --> $DIR/feature-gate-c_variadic.rs:7:45 + | +LL | unsafe extern "C" fn trait_test(_: i32, ap: ...) { } + | ^^^^^^^ + error[E0658]: C-variadic functions are unstable --> $DIR/feature-gate-c_variadic.rs:3:1 | @@ -8,6 +14,16 @@ LL | pub unsafe extern "C" fn test(_: i32, ap: ...) { } = help: add `#![feature(c_variadic)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error +error[E0658]: C-variadic functions are unstable + --> $DIR/feature-gate-c_variadic.rs:7:5 + | +LL | unsafe extern "C" fn trait_test(_: i32, ap: ...) { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #44930 for more information + = help: add `#![feature(c_variadic)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs index 78e5c96180285..9277994d9b30f 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.rs +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.rs @@ -5,6 +5,6 @@ fn main() {} fn foo(_: Bar, ...) -> impl {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR cannot find type `Bar` in this scope //~| ERROR at least one trait must be specified diff --git a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr index 80a8a94aea400..4a1aa49eb6e6f 100644 --- a/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr +++ b/tests/ui/mir/issue-83499-input-output-iteration-ice.stderr @@ -1,4 +1,4 @@ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/issue-83499-input-output-iteration-ice.rs:7:16 | LL | fn foo(_: Bar, ...) -> impl {} diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index 1cd6d13d56b6b..e7a0248cffab9 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -4,29 +4,29 @@ fn main() {} fn f1_1(x: isize, ...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention fn f1_2(...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention extern "C" fn f2_1(x: isize, ...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention extern "C" fn f2_2(...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention extern "C" fn f2_3(..., x: isize) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function extern "C" fn f3_1(x: isize, ...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention extern "C" fn f3_2(...) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention extern "C" fn f3_3(..., x: isize) {} -//~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function const unsafe extern "C" fn f4_1(x: isize, ...) {} @@ -35,12 +35,12 @@ const unsafe extern "C" fn f4_1(x: isize, ...) {} const extern "C" fn f4_2(x: isize, ...) {} //~^ ERROR functions cannot be both `const` and C-variadic -//~| ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~| ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time const extern "C" fn f4_3(..., x: isize, ...) {} //~^ ERROR functions cannot be both `const` and C-variadic -//~| ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +//~| ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function extern "C" { @@ -52,34 +52,34 @@ struct X; impl X { fn i_f1(x: isize, ...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention fn i_f2(...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention fn i_f3(..., x: isize, ...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function fn i_f4(..., x: isize, ...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function const fn i_f5(x: isize, ...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR functions cannot be both `const` and C-variadic //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time } trait T { fn t_f1(x: isize, ...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention fn t_f2(x: isize, ...); - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention fn t_f3(...) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention fn t_f4(...); - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention fn t_f5(..., x: isize) {} - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function fn t_f6(..., x: isize); - //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~^ ERROR defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention //~| ERROR `...` must be the last argument of a C-variadic function } diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index b740cef020055..5379045967aa0 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -1,22 +1,22 @@ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:6:19 | LL | fn f1_1(x: isize, ...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9 | LL | fn f1_2(...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:12:30 | LL | extern "C" fn f2_1(x: isize, ...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:15:20 | LL | extern "C" fn f2_2(...) {} @@ -28,19 +28,19 @@ error: `...` must be the last argument of a C-variadic function LL | extern "C" fn f2_3(..., x: isize) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20 | LL | extern "C" fn f2_3(..., x: isize) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:22:30 | LL | extern "C" fn f3_1(x: isize, ...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:25:20 | LL | extern "C" fn f3_2(...) {} @@ -52,7 +52,7 @@ error: `...` must be the last argument of a C-variadic function LL | extern "C" fn f3_3(..., x: isize) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:28:20 | LL | extern "C" fn f3_3(..., x: isize) {} @@ -70,7 +70,7 @@ error: functions cannot be both `const` and C-variadic LL | const extern "C" fn f4_2(x: isize, ...) {} | ^^^^^ `const` because of this ^^^ C-variadic because of this -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:36:36 | LL | const extern "C" fn f4_2(x: isize, ...) {} @@ -91,7 +91,7 @@ LL | const extern "C" fn f4_3(..., x: isize, ...) {} | | C-variadic because of this | `const` because of this -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:41:26 | LL | const extern "C" fn f4_3(..., x: isize, ...) {} @@ -103,13 +103,13 @@ error: `...` must be the last argument of a C-variadic function LL | fn e_f2(..., x: isize); | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:54:23 | LL | fn i_f1(x: isize, ...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:56:13 | LL | fn i_f2(...) {} @@ -121,7 +121,7 @@ error: `...` must be the last argument of a C-variadic function LL | fn i_f3(..., x: isize, ...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13 | LL | fn i_f3(..., x: isize, ...) {} @@ -133,7 +133,7 @@ error: `...` must be the last argument of a C-variadic function LL | fn i_f4(..., x: isize, ...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13 | LL | fn i_f4(..., x: isize, ...) {} @@ -147,31 +147,31 @@ LL | const fn i_f5(x: isize, ...) {} | | | `const` because of this -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:64:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:71:23 | LL | fn t_f1(x: isize, ...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:73:23 | LL | fn t_f2(x: isize, ...); | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:75:13 | LL | fn t_f3(...) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:77:13 | LL | fn t_f4(...); @@ -183,7 +183,7 @@ error: `...` must be the last argument of a C-variadic function LL | fn t_f5(..., x: isize) {} | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13 | LL | fn t_f5(..., x: isize) {} @@ -195,7 +195,7 @@ error: `...` must be the last argument of a C-variadic function LL | fn t_f6(..., x: isize); | ^^^ -error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg +error: defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13 | LL | fn t_f6(..., x: isize);