diff options
| -rw-r--r-- | compiler/rustc_ast_passes/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/ast_validation.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/errors.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/mod.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs | 3 | ||||
| -rw-r--r-- | tests/ui/c-variadic/inherent-method.rs | 45 | ||||
| -rw-r--r-- | tests/ui/c-variadic/not-async.rs | 10 | ||||
| -rw-r--r-- | tests/ui/c-variadic/not-async.stderr | 30 | ||||
| -rw-r--r-- | tests/ui/c-variadic/not-dyn-compatible.rs | 35 | ||||
| -rw-r--r-- | tests/ui/c-variadic/not-dyn-compatible.stderr | 21 | ||||
| -rw-r--r-- | tests/ui/c-variadic/trait-method.rs | 73 | ||||
| -rw-r--r-- | tests/ui/c-variadic/unsupported-abi.rs | 123 | ||||
| -rw-r--r-- | tests/ui/c-variadic/unsupported-abi.stderr | 345 | ||||
| -rw-r--r-- | tests/ui/feature-gates/feature-gate-c_variadic.rs | 1 | ||||
| -rw-r--r-- | tests/ui/feature-gates/feature-gate-c_variadic.stderr | 8 | ||||
| -rw-r--r-- | tests/ui/parser/variadic-ffi-semantic-restrictions.rs | 18 | ||||
| -rw-r--r-- | tests/ui/parser/variadic-ffi-semantic-restrictions.stderr | 36 |
17 files changed, 721 insertions, 49 deletions
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index e5405a7ad91..5e10c5a77d9 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -64,8 +64,6 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect -ast_passes_c_variadic_associated_function = associated functions cannot have a C variable argument list - ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions .label = `extern "{$abi}"` because of this .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index dc221c2fb1a..f773b02058e 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -696,7 +696,7 @@ impl<'a> AstValidator<'a> { match fn_ctxt { FnCtxt::Foreign => return, - FnCtxt::Free => match sig.header.ext { + FnCtxt::Free | FnCtxt::Assoc(_) => match sig.header.ext { Extern::Implicit(_) => { if !matches!(sig.header.safety, Safety::Unsafe(_)) { self.dcx().emit_err(errors::CVariadicMustBeUnsafe { @@ -726,11 +726,6 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(err); } }, - FnCtxt::Assoc(_) => { - // For now, C variable argument lists are unsupported in associated functions. - let err = errors::CVariadicAssociatedFunction { span: variadic_param.span }; - self.dcx().emit_err(err); - } } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index e09ca5b81c8..fd75e999d13 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -319,13 +319,6 @@ pub(crate) struct ExternItemAscii { } #[derive(Diagnostic)] -#[diag(ast_passes_c_variadic_associated_function)] -pub(crate) struct CVariadicAssociatedFunction { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] #[diag(ast_passes_c_variadic_no_extern)] #[help] pub(crate) struct CVariadicNoExtern { diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index ab8a3142953..0c7bddf60d9 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -823,6 +823,9 @@ impl DynCompatibilityViolation { DynCompatibilityViolation::Method(name, MethodViolationCode::AsyncFn, _) => { format!("method `{name}` is `async`").into() } + DynCompatibilityViolation::Method(name, MethodViolationCode::CVariadic, _) => { + format!("method `{name}` is C-variadic").into() + } DynCompatibilityViolation::Method( name, MethodViolationCode::WhereClauseReferencesSelf, @@ -977,6 +980,9 @@ pub enum MethodViolationCode { /// e.g., `fn foo<A>()` Generic, + /// e.g., `fn (mut ap: ...)` + CVariadic, + /// the method's receiver (`self` argument) can't be dispatched on UndispatchableReceiver(Option<Span>), } diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index bcd11d6918d..3260dd712b9 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -426,6 +426,9 @@ fn virtual_call_violations_for_method<'tcx>( if let Some(code) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) { errors.push(code); } + if sig.skip_binder().c_variadic { + errors.push(MethodViolationCode::CVariadic); + } // We can't monomorphize things like `fn foo<A>(...)`. let own_counts = tcx.generics_of(method.def_id).own_counts(); diff --git a/tests/ui/c-variadic/inherent-method.rs b/tests/ui/c-variadic/inherent-method.rs new file mode 100644 index 00000000000..537bae7b3f0 --- /dev/null +++ b/tests/ui/c-variadic/inherent-method.rs @@ -0,0 +1,45 @@ +//@ run-pass +#![feature(c_variadic)] + +#[repr(transparent)] +struct S(i32); + +impl S { + unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { + unsafe { ap.arg() } + } + + unsafe extern "C" fn method_owned(self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::<i32>() } + } + + unsafe extern "C" fn method_ref(&self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::<i32>() } + } + + unsafe extern "C" fn method_mut(&mut self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::<i32>() } + } + + unsafe extern "C" fn fat_pointer(self: Box<Self>, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::<i32>() } + } +} + +fn main() { + unsafe { + assert_eq!(S::associated_function(32), 32); + assert_eq!(S(100).method_owned(32), 132); + assert_eq!(S(100).method_ref(32), 132); + assert_eq!(S(100).method_mut(32), 132); + assert_eq!(S::fat_pointer(Box::new(S(100)), 32), 132); + + type Method<T> = unsafe extern "C" fn(T, ...) -> i32; + + assert_eq!((S::associated_function as unsafe extern "C" fn(...) -> i32)(32), 32); + assert_eq!((S::method_owned as Method<_>)(S(100), 32), 132); + assert_eq!((S::method_ref as Method<_>)(&S(100), 32), 132); + assert_eq!((S::method_mut as Method<_>)(&mut S(100), 32), 132); + assert_eq!((S::fat_pointer as Method<_>)(Box::new(S(100)), 32), 132); + } +} diff --git a/tests/ui/c-variadic/not-async.rs b/tests/ui/c-variadic/not-async.rs index 45a7e1f8972..bdb51a9a432 100644 --- a/tests/ui/c-variadic/not-async.rs +++ b/tests/ui/c-variadic/not-async.rs @@ -2,6 +2,14 @@ #![feature(c_variadic)] #![crate_type = "lib"] -async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} +async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} //~^ ERROR functions cannot be both `async` and C-variadic //~| ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds + +struct S; + +impl S { + async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + //~^ ERROR functions cannot be both `async` and C-variadic + //~| ERROR hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds +} diff --git a/tests/ui/c-variadic/not-async.stderr b/tests/ui/c-variadic/not-async.stderr index b8caf0d8bd8..eab4c4f0822 100644 --- a/tests/ui/c-variadic/not-async.stderr +++ b/tests/ui/c-variadic/not-async.stderr @@ -1,19 +1,35 @@ error: functions cannot be both `async` and C-variadic --> $DIR/not-async.rs:5:1 | -LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} - | ^^^^^ `async` because of this ^^^ C-variadic because of this +LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} + | ^^^^^ `async` because of this ^^^ C-variadic because of this + +error: functions cannot be both `async` and C-variadic + --> $DIR/not-async.rs:12:5 + | +LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + | ^^^^^ `async` because of this ^^^ C-variadic because of this error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds - --> $DIR/not-async.rs:5:59 + --> $DIR/not-async.rs:5:62 | -LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} - | --------------------------------------------------------- ^^ +LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} + | ------------------------------------------------------------ ^^ | | | opaque type defined here | - = note: hidden type `{async fn body of cannot_be_async()}` captures lifetime `'_` + = note: hidden type `{async fn body of fn_cannot_be_async()}` captures lifetime `'_` + +error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds + --> $DIR/not-async.rs:12:70 + | +LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + | ---------------------------------------------------------------- ^^ + | | + | opaque type defined here + | + = note: hidden type `{async fn body of S::method_cannot_be_async()}` captures lifetime `'_` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/c-variadic/not-dyn-compatible.rs b/tests/ui/c-variadic/not-dyn-compatible.rs new file mode 100644 index 00000000000..b40a13e5847 --- /dev/null +++ b/tests/ui/c-variadic/not-dyn-compatible.rs @@ -0,0 +1,35 @@ +// Traits where a method is c-variadic are not dyn compatible. +// +// Creating a function pointer from a method on an `&dyn T` value creates a ReifyShim. +// This shim cannot reliably forward C-variadic arguments. Thus the trait as a whole +// is dyn-incompatible to prevent invalid shims from being created. +#![feature(c_variadic)] + +#[repr(transparent)] +struct Struct(u64); + +trait Trait { + fn get(&self) -> u64; + + unsafe extern "C" fn dyn_method_ref(&self, mut ap: ...) -> u64 { + self.get() + unsafe { ap.arg::<u64>() } + } +} + +impl Trait for Struct { + fn get(&self) -> u64 { + self.0 + } +} + +fn main() { + unsafe { + let dyn_object: &dyn Trait = &Struct(64); + //~^ ERROR the trait `Trait` is not dyn compatible + assert_eq!(dyn_object.dyn_method_ref(100), 164); + assert_eq!( + (Trait::dyn_method_ref as unsafe extern "C" fn(_, ...) -> u64)(dyn_object, 100), + 164 + ); + } +} diff --git a/tests/ui/c-variadic/not-dyn-compatible.stderr b/tests/ui/c-variadic/not-dyn-compatible.stderr new file mode 100644 index 00000000000..76630600c51 --- /dev/null +++ b/tests/ui/c-variadic/not-dyn-compatible.stderr @@ -0,0 +1,21 @@ +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/not-dyn-compatible.rs:27:30 + | +LL | let dyn_object: &dyn Trait = &Struct(64); + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> + --> $DIR/not-dyn-compatible.rs:14:26 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +... +LL | unsafe extern "C" fn dyn_method_ref(&self, mut ap: ...) -> u64 { + | ^^^^^^^^^^^^^^ ...because method `dyn_method_ref` is C-variadic + = help: consider moving `dyn_method_ref` to another trait + = help: only type `Struct` implements `Trait`; consider using it directly instead. + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/c-variadic/trait-method.rs b/tests/ui/c-variadic/trait-method.rs new file mode 100644 index 00000000000..97da0706a3a --- /dev/null +++ b/tests/ui/c-variadic/trait-method.rs @@ -0,0 +1,73 @@ +//@ run-pass +#![feature(c_variadic)] + +#[repr(transparent)] +struct Struct(i32); + +impl Struct { + unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { + unsafe { ap.arg() } + } + + unsafe extern "C" fn method(&self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::<i32>() } + } +} + +trait Trait: Sized { + fn get(&self) -> i32; + + unsafe extern "C" fn trait_associated_function(mut ap: ...) -> i32 { + unsafe { ap.arg() } + } + + unsafe extern "C" fn trait_method_owned(self, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::<i32>() } + } + + unsafe extern "C" fn trait_method_ref(&self, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::<i32>() } + } + + unsafe extern "C" fn trait_method_mut(&mut self, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::<i32>() } + } + + unsafe extern "C" fn trait_fat_pointer(self: Box<Self>, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::<i32>() } + } +} + +impl Trait for Struct { + fn get(&self) -> i32 { + self.0 + } +} + +fn main() { + unsafe { + assert_eq!(Struct::associated_function(32), 32); + assert_eq!(Struct(100).method(32), 132); + + assert_eq!(Struct::trait_associated_function(32), 32); + assert_eq!(Struct(100).trait_method_owned(32), 132); + assert_eq!(Struct(100).trait_method_ref(32), 132); + assert_eq!(Struct(100).trait_method_mut(32), 132); + assert_eq!(Struct::trait_fat_pointer(Box::new(Struct(100)), 32), 132); + + assert_eq!(<Struct as Trait>::trait_associated_function(32), 32); + assert_eq!(Trait::trait_method_owned(Struct(100), 32), 132); + assert_eq!(Trait::trait_method_ref(&Struct(100), 32), 132); + assert_eq!(Trait::trait_method_mut(&mut Struct(100), 32), 132); + assert_eq!(Trait::trait_fat_pointer(Box::new(Struct(100)), 32), 132); + + type Associated = unsafe extern "C" fn(...) -> i32; + type Method<T> = unsafe extern "C" fn(T, ...) -> i32; + + assert_eq!((Struct::trait_associated_function as Associated)(32), 32); + assert_eq!((Struct::trait_method_owned as Method<_>)(Struct(100), 32), 132); + assert_eq!((Struct::trait_method_ref as Method<_>)(&Struct(100), 32), 132); + assert_eq!((Struct::trait_method_mut as Method<_>)(&mut Struct(100), 32), 132); + assert_eq!((Struct::trait_fat_pointer as Method<_>)(Box::new(Struct(100)), 32), 132); + } +} diff --git a/tests/ui/c-variadic/unsupported-abi.rs b/tests/ui/c-variadic/unsupported-abi.rs new file mode 100644 index 00000000000..40179b164ce --- /dev/null +++ b/tests/ui/c-variadic/unsupported-abi.rs @@ -0,0 +1,123 @@ +//@ add-core-stubs +//@ needs-llvm-components: x86 +//@ compile-flags: --target=i686-pc-windows-gnu --crate-type=rlib +#![no_core] +#![feature(no_core, lang_items, c_variadic)] + +// Test that ABIs for which C-variadics are not supported report an error. + +extern crate minicore; +use minicore::*; + +#[rustfmt::skip] +mod foreign { + extern "Rust" { fn rust_foreign_explicit(_: ...); } + //~^ ERROR C-variadic functions with the "Rust" calling convention are not supported + extern "C" { fn c_foreign(_: ...); } + extern "C-unwind" { fn c_unwind_foreign(_: ...); } + extern "cdecl" { fn cdecl_foreign(_: ...); } + extern "cdecl-unwind" { fn cdecl_unwind_foreign(_: ...); } + extern "stdcall" { fn stdcall_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "stdcall" calling convention are not supported + extern "stdcall-unwind" { fn stdcall_unwind_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "stdcall-unwind" calling convention are not supported + extern "thiscall" { fn thiscall_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "thiscall" calling convention are not supported + extern "thiscall-unwind" { fn thiscall_unwind_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "thiscall-unwind" calling convention are not supported +} + +#[lang = "va_list"] +struct VaList(*mut u8); + +unsafe fn rust_free(_: ...) {} +//~^ ERROR `...` is not supported for non-extern functions +unsafe extern "Rust" fn rust_free_explicit(_: ...) {} +//~^ ERROR `...` is not supported for `extern "Rust"` functions + +unsafe extern "C" fn c_free(_: ...) {} +unsafe extern "C-unwind" fn c_unwind_free(_: ...) {} + +unsafe extern "cdecl" fn cdecl_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "cdecl"` functions +unsafe extern "cdecl-unwind" fn cdecl_unwind_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions +unsafe extern "stdcall" fn stdcall_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "stdcall"` functions +unsafe extern "stdcall-unwind" fn stdcall_unwind_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions +unsafe extern "thiscall" fn thiscall_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "thiscall"` functions +unsafe extern "thiscall-unwind" fn thiscall_unwind_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions + +struct S; + +impl S { + unsafe fn rust_method(_: ...) {} + //~^ ERROR `...` is not supported for non-extern functions + unsafe extern "Rust" fn rust_method_explicit(_: ...) {} + //~^ ERROR `...` is not supported for `extern "Rust"` functions + + unsafe extern "C" fn c_method(_: ...) {} + unsafe extern "C-unwind" fn c_unwind_method(_: ...) {} + + unsafe extern "cdecl" fn cdecl_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl"` functions + unsafe extern "cdecl-unwind" fn cdecl_unwind_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions + unsafe extern "stdcall" fn stdcall_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall"` functions + unsafe extern "stdcall-unwind" fn stdcall_unwind_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions + unsafe extern "thiscall" fn thiscall_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall"` functions + unsafe extern "thiscall-unwind" fn thiscall_unwind_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions +} + +trait T { + unsafe fn rust_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for non-extern functions + unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + //~^ ERROR `...` is not supported for `extern "Rust"` functions + + unsafe extern "C" fn c_trait_method(_: ...) {} + unsafe extern "C-unwind" fn c_unwind_trait_method(_: ...) {} + + unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl"` functions + unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions + unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall"` functions + unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions + unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall"` functions + unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions +} + +impl T for S { + unsafe fn rust_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for non-extern functions + unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + //~^ ERROR `...` is not supported for `extern "Rust"` functions + + unsafe extern "C" fn c_trait_method(_: ...) {} + unsafe extern "C-unwind" fn c_unwind_trait_method(_: ...) {} + + unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl"` functions + unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions + unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall"` functions + unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions + unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall"` functions + unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions +} diff --git a/tests/ui/c-variadic/unsupported-abi.stderr b/tests/ui/c-variadic/unsupported-abi.stderr new file mode 100644 index 00000000000..daed9171406 --- /dev/null +++ b/tests/ui/c-variadic/unsupported-abi.stderr @@ -0,0 +1,345 @@ +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:33:21 + | +LL | unsafe fn rust_free(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:35:44 + | +LL | unsafe extern "Rust" fn rust_free_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:41:37 + | +LL | unsafe extern "cdecl" fn cdecl_free(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:43:51 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_free(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:45:41 + | +LL | unsafe extern "stdcall" fn stdcall_free(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:47:55 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_free(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:49:43 + | +LL | unsafe extern "thiscall" fn thiscall_free(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:51:57 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_free(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:57:27 + | +LL | unsafe fn rust_method(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:59:50 + | +LL | unsafe extern "Rust" fn rust_method_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:65:43 + | +LL | unsafe extern "cdecl" fn cdecl_method(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:67:57 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_method(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:69:47 + | +LL | unsafe extern "stdcall" fn stdcall_method(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:71:61 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_method(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:73:49 + | +LL | unsafe extern "thiscall" fn thiscall_method(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:75:63 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_method(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:80:33 + | +LL | unsafe fn rust_trait_method(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:82:56 + | +LL | unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:88:49 + | +LL | unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:90:63 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:92:53 + | +LL | unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:94:67 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:96:55 + | +LL | unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:98:69 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:103:33 + | +LL | unsafe fn rust_trait_method(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:105:56 + | +LL | unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:111:49 + | +LL | unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:113:63 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:115:53 + | +LL | unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:117:67 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:119:55 + | +LL | unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:121:69 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error[E0045]: C-variadic functions with the "Rust" calling convention are not supported + --> $DIR/unsupported-abi.rs:14:22 + | +LL | extern "Rust" { fn rust_foreign_explicit(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "stdcall" calling convention are not supported + --> $DIR/unsupported-abi.rs:20:25 + | +LL | extern "stdcall" { fn stdcall_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "stdcall-unwind" calling convention are not supported + --> $DIR/unsupported-abi.rs:22:32 + | +LL | extern "stdcall-unwind" { fn stdcall_unwind_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "thiscall" calling convention are not supported + --> $DIR/unsupported-abi.rs:24:26 + | +LL | extern "thiscall" { fn thiscall_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "thiscall-unwind" calling convention are not supported + --> $DIR/unsupported-abi.rs:26:33 + | +LL | extern "thiscall-unwind" { fn thiscall_unwind_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error: aborting due to 37 previous errors + +For more information about this error, try `rustc --explain E0045`. diff --git a/tests/ui/feature-gates/feature-gate-c_variadic.rs b/tests/ui/feature-gates/feature-gate-c_variadic.rs index 88d91dbd081..649816b48d7 100644 --- a/tests/ui/feature-gates/feature-gate-c_variadic.rs +++ b/tests/ui/feature-gates/feature-gate-c_variadic.rs @@ -6,5 +6,4 @@ pub unsafe extern "C" fn test(_: i32, ap: ...) {} trait Trait { unsafe extern "C" fn trait_test(_: i32, ap: ...) {} //~^ ERROR C-variadic functions are unstable - //~| ERROR associated functions cannot have a C variable argument list } diff --git a/tests/ui/feature-gates/feature-gate-c_variadic.stderr b/tests/ui/feature-gates/feature-gate-c_variadic.stderr index 808aa20948d..ae880093b98 100644 --- a/tests/ui/feature-gates/feature-gate-c_variadic.stderr +++ b/tests/ui/feature-gates/feature-gate-c_variadic.stderr @@ -1,9 +1,3 @@ -error: associated functions cannot have a C variable argument list - --> $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 | @@ -24,6 +18,6 @@ LL | unsafe extern "C" fn trait_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 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index 4db056f15a5..415472176d9 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -53,30 +53,30 @@ struct X; impl X { fn i_f1(x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn i_f2(...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn i_f3(..., x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions //~| ERROR `...` must be the last argument of a C-variadic function fn i_f4(..., x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions //~| ERROR `...` must be the last argument of a C-variadic function const fn i_f5(x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions //~| 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 associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f2(x: isize, ...); - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f3(...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f4(...); - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f5(..., x: isize) {} //~^ ERROR `...` must be the last argument of a C-variadic function fn t_f6(..., x: isize); diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index 0cd78318de6..da9c9b0f760 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -132,17 +132,21 @@ error: `...` must be the last argument of a C-variadic function LL | fn e_f2(..., x: isize); | ^^^ -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:55:23 | LL | fn i_f1(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:57:13 | LL | fn i_f2(...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13 @@ -150,11 +154,13 @@ error: `...` must be the last argument of a C-variadic function LL | fn i_f3(..., x: isize, ...) {} | ^^^ -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:59:28 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:62:13 @@ -162,11 +168,13 @@ error: `...` must be the last argument of a C-variadic function LL | fn i_f4(..., x: isize, ...) {} | ^^^ -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:62:28 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: functions cannot be both `const` and C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:65:5 @@ -176,35 +184,45 @@ LL | const fn i_f5(x: isize, ...) {} | | | `const` because of this -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:72:23 | LL | fn t_f1(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:74:23 | LL | fn t_f2(x: isize, ...); | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:76:13 | LL | fn t_f3(...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:78:13 | LL | fn t_f4(...); | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:80:13 |
