about summary refs log tree commit diff
path: root/tests/ui/c-variadic
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/c-variadic')
-rw-r--r--tests/ui/c-variadic/inherent-method.rs45
-rw-r--r--tests/ui/c-variadic/not-async.rs10
-rw-r--r--tests/ui/c-variadic/not-async.stderr30
-rw-r--r--tests/ui/c-variadic/not-dyn-compatible.rs35
-rw-r--r--tests/ui/c-variadic/not-dyn-compatible.stderr21
-rw-r--r--tests/ui/c-variadic/trait-method.rs73
-rw-r--r--tests/ui/c-variadic/unsupported-abi.rs123
-rw-r--r--tests/ui/c-variadic/unsupported-abi.stderr345
8 files changed, 674 insertions, 8 deletions
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`.