about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2020-06-13 19:37:25 +0100
committerDavid Wood <david@davidtw.co>2020-07-20 10:28:12 +0100
commitceac273e60447014038e511e5af43841c359547c (patch)
treee98e9448955656f43736ec024a740b808fb62295 /src/test
parent891e6fee572009ff2be4d4057fb33483610c36a7 (diff)
downloadrust-ceac273e60447014038e511e5af43841c359547c.tar.gz
rust-ceac273e60447014038e511e5af43841c359547c.zip
wf: check foreign fn decls for well-formedness
This commit extends current well-formedness checking to apply to foreign
function declarations, re-using the existing machinery for regular
functions. In doing this, later parts of the compiler (such as the
`improper_ctypes` lint) can rely on being operations not failing as a
result of invalid code which would normally be caught earlier.

Signed-off-by: David Wood <david@davidtw.co>
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/lint/lint-ctypes.rs3
-rw-r--r--src/test/ui/lint/lint-ctypes.stderr62
-rw-r--r--src/test/ui/wf/wf-foreign-fn-decl-ret.rs18
-rw-r--r--src/test/ui/wf/wf-foreign-fn-decl-ret.stderr18
4 files changed, 69 insertions, 32 deletions
diff --git a/src/test/ui/lint/lint-ctypes.rs b/src/test/ui/lint/lint-ctypes.rs
index bdf95350c70..f485766bcd3 100644
--- a/src/test/ui/lint/lint-ctypes.rs
+++ b/src/test/ui/lint/lint-ctypes.rs
@@ -7,6 +7,7 @@ extern crate libc;
 
 use std::marker::PhantomData;
 
+trait Bar { }
 trait Mirror { type It: ?Sized; }
 impl<T: ?Sized> Mirror for T { type It = Self; }
 #[repr(C)]
@@ -53,7 +54,7 @@ extern {
     pub fn char_type(p: char); //~ ERROR uses type `char`
     pub fn i128_type(p: i128); //~ ERROR uses type `i128`
     pub fn u128_type(p: u128); //~ ERROR uses type `u128`
-    pub fn trait_type(p: &dyn Clone); //~ ERROR uses type `dyn std::clone::Clone`
+    pub fn trait_type(p: &dyn Bar); //~ ERROR uses type `dyn Bar`
     pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
     pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
     pub fn zero_size(p: ZeroSize); //~ ERROR uses type `ZeroSize`
diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr
index 13b9adca3f9..a54226a7fc4 100644
--- a/src/test/ui/lint/lint-ctypes.stderr
+++ b/src/test/ui/lint/lint-ctypes.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `Foo`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:46:28
+  --> $DIR/lint-ctypes.rs:47:28
    |
 LL |     pub fn ptr_type1(size: *const Foo);
    |                            ^^^^^^^^^^ not FFI-safe
@@ -12,13 +12,13 @@ LL | #![deny(improper_ctypes)]
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
-  --> $DIR/lint-ctypes.rs:24:1
+  --> $DIR/lint-ctypes.rs:25:1
    |
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `Foo`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:47:28
+  --> $DIR/lint-ctypes.rs:48:28
    |
 LL |     pub fn ptr_type2(size: *const Foo);
    |                            ^^^^^^^^^^ not FFI-safe
@@ -26,13 +26,13 @@ LL |     pub fn ptr_type2(size: *const Foo);
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 note: the type is defined here
-  --> $DIR/lint-ctypes.rs:24:1
+  --> $DIR/lint-ctypes.rs:25:1
    |
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `[u32]`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:48:26
+  --> $DIR/lint-ctypes.rs:49:26
    |
 LL |     pub fn slice_type(p: &[u32]);
    |                          ^^^^^^ not FFI-safe
@@ -41,7 +41,7 @@ LL |     pub fn slice_type(p: &[u32]);
    = note: slices have no C equivalent
 
 error: `extern` block uses type `str`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:49:24
+  --> $DIR/lint-ctypes.rs:50:24
    |
 LL |     pub fn str_type(p: &str);
    |                        ^^^^ not FFI-safe
@@ -50,7 +50,7 @@ LL |     pub fn str_type(p: &str);
    = note: string slices have no C equivalent
 
 error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:50:24
+  --> $DIR/lint-ctypes.rs:51:24
    |
 LL |     pub fn box_type(p: Box<u32>);
    |                        ^^^^^^^^ not FFI-safe
@@ -59,7 +59,7 @@ LL |     pub fn box_type(p: Box<u32>);
    = note: this struct has unspecified layout
 
 error: `extern` block uses type `std::option::Option<std::boxed::Box<u32>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:51:28
+  --> $DIR/lint-ctypes.rs:52:28
    |
 LL |     pub fn opt_box_type(p: Option<Box<u32>>);
    |                            ^^^^^^^^^^^^^^^^ not FFI-safe
@@ -68,7 +68,7 @@ LL |     pub fn opt_box_type(p: Option<Box<u32>>);
    = note: enum has no representation hint
 
 error: `extern` block uses type `char`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:53:25
+  --> $DIR/lint-ctypes.rs:54:25
    |
 LL |     pub fn char_type(p: char);
    |                         ^^^^ not FFI-safe
@@ -77,7 +77,7 @@ LL |     pub fn char_type(p: char);
    = note: the `char` type has no C equivalent
 
 error: `extern` block uses type `i128`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:54:25
+  --> $DIR/lint-ctypes.rs:55:25
    |
 LL |     pub fn i128_type(p: i128);
    |                         ^^^^ not FFI-safe
@@ -85,23 +85,23 @@ LL |     pub fn i128_type(p: i128);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `u128`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:55:25
+  --> $DIR/lint-ctypes.rs:56:25
    |
 LL |     pub fn u128_type(p: u128);
    |                         ^^^^ not FFI-safe
    |
    = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `dyn std::clone::Clone`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:56:26
+error: `extern` block uses type `dyn Bar`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:57:26
    |
-LL |     pub fn trait_type(p: &dyn Clone);
-   |                          ^^^^^^^^^^ not FFI-safe
+LL |     pub fn trait_type(p: &dyn Bar);
+   |                          ^^^^^^^^ not FFI-safe
    |
    = note: trait objects have no C equivalent
 
 error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:57:26
+  --> $DIR/lint-ctypes.rs:58:26
    |
 LL |     pub fn tuple_type(p: (i32, i32));
    |                          ^^^^^^^^^^ not FFI-safe
@@ -110,7 +110,7 @@ LL |     pub fn tuple_type(p: (i32, i32));
    = note: tuples have unspecified layout
 
 error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:58:27
+  --> $DIR/lint-ctypes.rs:59:27
    |
 LL |     pub fn tuple_type2(p: I32Pair);
    |                           ^^^^^^^ not FFI-safe
@@ -119,7 +119,7 @@ LL |     pub fn tuple_type2(p: I32Pair);
    = note: tuples have unspecified layout
 
 error: `extern` block uses type `ZeroSize`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:59:25
+  --> $DIR/lint-ctypes.rs:60:25
    |
 LL |     pub fn zero_size(p: ZeroSize);
    |                         ^^^^^^^^ not FFI-safe
@@ -127,26 +127,26 @@ LL |     pub fn zero_size(p: ZeroSize);
    = help: consider adding a member to this struct
    = note: this struct has no fields
 note: the type is defined here
-  --> $DIR/lint-ctypes.rs:20:1
+  --> $DIR/lint-ctypes.rs:21:1
    |
 LL | pub struct ZeroSize;
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:60:33
+  --> $DIR/lint-ctypes.rs:61:33
    |
 LL |     pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = note: composed only of `PhantomData`
 note: the type is defined here
-  --> $DIR/lint-ctypes.rs:43:1
+  --> $DIR/lint-ctypes.rs:44:1
    |
 LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:63:12
+  --> $DIR/lint-ctypes.rs:64:12
    |
 LL |         -> ::std::marker::PhantomData<bool>;
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -154,7 +154,7 @@ LL |         -> ::std::marker::PhantomData<bool>;
    = note: composed only of `PhantomData`
 
 error: `extern` block uses type `fn()`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:64:23
+  --> $DIR/lint-ctypes.rs:65:23
    |
 LL |     pub fn fn_type(p: RustFn);
    |                       ^^^^^^ not FFI-safe
@@ -163,7 +163,7 @@ LL |     pub fn fn_type(p: RustFn);
    = note: this function pointer has Rust-specific calling convention
 
 error: `extern` block uses type `fn()`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:65:24
+  --> $DIR/lint-ctypes.rs:66:24
    |
 LL |     pub fn fn_type2(p: fn());
    |                        ^^^^ not FFI-safe
@@ -172,7 +172,7 @@ LL |     pub fn fn_type2(p: fn());
    = note: this function pointer has Rust-specific calling convention
 
 error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:66:28
+  --> $DIR/lint-ctypes.rs:67:28
    |
 LL |     pub fn fn_contained(p: RustBadRet);
    |                            ^^^^^^^^^^ not FFI-safe
@@ -181,7 +181,7 @@ LL |     pub fn fn_contained(p: RustBadRet);
    = note: this struct has unspecified layout
 
 error: `extern` block uses type `i128`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:67:32
+  --> $DIR/lint-ctypes.rs:68:32
    |
 LL |     pub fn transparent_i128(p: TransparentI128);
    |                                ^^^^^^^^^^^^^^^ not FFI-safe
@@ -189,7 +189,7 @@ LL |     pub fn transparent_i128(p: TransparentI128);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `str`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:68:31
+  --> $DIR/lint-ctypes.rs:69:31
    |
 LL |     pub fn transparent_str(p: TransparentStr);
    |                               ^^^^^^^^^^^^^^ not FFI-safe
@@ -198,7 +198,7 @@ LL |     pub fn transparent_str(p: TransparentStr);
    = note: string slices have no C equivalent
 
 error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:69:30
+  --> $DIR/lint-ctypes.rs:70:30
    |
 LL |     pub fn transparent_fn(p: TransparentBadFn);
    |                              ^^^^^^^^^^^^^^^^ not FFI-safe
@@ -207,7 +207,7 @@ LL |     pub fn transparent_fn(p: TransparentBadFn);
    = note: this struct has unspecified layout
 
 error: `extern` block uses type `[u8; 8]`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:70:27
+  --> $DIR/lint-ctypes.rs:71:27
    |
 LL |     pub fn raw_array(arr: [u8; 8]);
    |                           ^^^^^^^ not FFI-safe
@@ -216,7 +216,7 @@ LL |     pub fn raw_array(arr: [u8; 8]);
    = note: passing raw arrays by value is not FFI-safe
 
 error: `extern` block uses type `u128`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:72:34
+  --> $DIR/lint-ctypes.rs:73:34
    |
 LL |     pub static static_u128_type: u128;
    |                                  ^^^^ not FFI-safe
@@ -224,7 +224,7 @@ LL |     pub static static_u128_type: u128;
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `u128`, which is not FFI-safe
-  --> $DIR/lint-ctypes.rs:73:40
+  --> $DIR/lint-ctypes.rs:74:40
    |
 LL |     pub static static_u128_array_type: [u128; 16];
    |                                        ^^^^^^^^^^ not FFI-safe
diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.rs b/src/test/ui/wf/wf-foreign-fn-decl-ret.rs
new file mode 100644
index 00000000000..b9d956c0568
--- /dev/null
+++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.rs
@@ -0,0 +1,18 @@
+pub trait Unsatisfied {}
+
+#[repr(transparent)]
+pub struct Bar<T: Unsatisfied>(T);
+
+pub trait Foo {
+    type Assoc;
+}
+
+extern "C" {
+    pub fn lint_me() -> <() as Foo>::Assoc;
+    //~^ ERROR: the trait bound `(): Foo` is not satisfied [E0277]
+
+    pub fn lint_me_aswell() -> Bar<u32>;
+    //~^ ERROR: the trait bound `u32: Unsatisfied` is not satisfied [E0277]
+}
+
+fn main() {}
diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
new file mode 100644
index 00000000000..9081b7929d9
--- /dev/null
+++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `(): Foo` is not satisfied
+  --> $DIR/wf-foreign-fn-decl-ret.rs:11:5
+   |
+LL |     pub fn lint_me() -> <() as Foo>::Assoc;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
+
+error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied
+  --> $DIR/wf-foreign-fn-decl-ret.rs:14:32
+   |
+LL | pub struct Bar<T: Unsatisfied>(T);
+   |                   ----------- required by this bound in `Bar`
+...
+LL |     pub fn lint_me_aswell() -> Bar<u32>;
+   |                                ^^^^^^^^ the trait `Unsatisfied` is not implemented for `u32`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.