about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-06-05 06:13:38 +0900
committerGitHub <noreply@github.com>2021-06-05 06:13:38 +0900
commitec9e7d5df1f3cec1889573f9fb470c174cf96dfa (patch)
tree0461c04bd0684e6b73fcfa55fe9bbd6995b49757
parent01b0e6e645ccee1b12c9d415f30f4701f78ba704 (diff)
parent877cfb1aad2543b3fe31d97075ea37d283afc880 (diff)
downloadrust-ec9e7d5df1f3cec1889573f9fb470c174cf96dfa.tar.gz
rust-ec9e7d5df1f3cec1889573f9fb470c174cf96dfa.zip
Rollup merge of #85853 - marmeladema:improper-ctypes-definitions-boxed-dst, r=petrochenkov
Warn against boxed DST in `improper_ctypes_definitions` lint

Fixes #85714
-rw-r--r--compiler/rustc_lint/src/types.rs15
-rw-r--r--src/test/ui/lint/lint-ctypes-fn.rs11
-rw-r--r--src/test/ui/lint/lint-ctypes-fn.stderr64
3 files changed, 66 insertions, 24 deletions
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 319adf42cf1..5d2256100ff 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -909,11 +909,18 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         }
 
         match *ty.kind() {
-            ty::Adt(def, _) if def.is_box() && matches!(self.mode, CItemKind::Definition) => {
-                FfiSafe
-            }
-
             ty::Adt(def, substs) => {
+                if def.is_box() && matches!(self.mode, CItemKind::Definition) {
+                    if ty.boxed_ty().is_sized(tcx.at(DUMMY_SP), self.cx.param_env) {
+                        return FfiSafe;
+                    } else {
+                        return FfiUnsafe {
+                            ty,
+                            reason: format!("box cannot be represented as a single pointer"),
+                            help: None,
+                        };
+                    }
+                }
                 if def.is_phantom_data() {
                     return FfiPhantom(ty);
                 }
diff --git a/src/test/ui/lint/lint-ctypes-fn.rs b/src/test/ui/lint/lint-ctypes-fn.rs
index e69d0dab496..c18cb881032 100644
--- a/src/test/ui/lint/lint-ctypes-fn.rs
+++ b/src/test/ui/lint/lint-ctypes-fn.rs
@@ -8,6 +8,8 @@ extern crate libc;
 use std::default::Default;
 use std::marker::PhantomData;
 
+trait Trait {}
+
 trait Mirror { type It: ?Sized; }
 
 impl<T: ?Sized> Mirror for T { type It = Self; }
@@ -74,6 +76,15 @@ pub extern "C" fn box_type(p: Box<u32>) { }
 
 pub extern "C" fn opt_box_type(p: Option<Box<u32>>) { }
 
+pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
+//~^ ERROR: uses type `Box<[u8]>`
+
+pub extern "C" fn boxed_string(p: Box<str>) { }
+//~^ ERROR: uses type `Box<str>`
+
+pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
+//~^ ERROR: uses type `Box<dyn Trait>`
+
 pub extern "C" fn char_type(p: char) { }
 //~^ ERROR uses type `char`
 
diff --git a/src/test/ui/lint/lint-ctypes-fn.stderr b/src/test/ui/lint/lint-ctypes-fn.stderr
index e6a0778ddb2..d591d4ad292 100644
--- a/src/test/ui/lint/lint-ctypes-fn.stderr
+++ b/src/test/ui/lint/lint-ctypes-fn.stderr
@@ -1,5 +1,5 @@
 error: `extern` fn uses type `[u32]`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:67:33
+  --> $DIR/lint-ctypes-fn.rs:69:33
    |
 LL | pub extern "C" fn slice_type(p: &[u32]) { }
    |                                 ^^^^^^ not FFI-safe
@@ -13,7 +13,7 @@ LL | #![deny(improper_ctypes_definitions)]
    = note: slices have no C equivalent
 
 error: `extern` fn uses type `str`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:70:31
+  --> $DIR/lint-ctypes-fn.rs:72:31
    |
 LL | pub extern "C" fn str_type(p: &str) { }
    |                               ^^^^ not FFI-safe
@@ -21,8 +21,32 @@ LL | pub extern "C" fn str_type(p: &str) { }
    = help: consider using `*const u8` and a length instead
    = note: string slices have no C equivalent
 
+error: `extern` fn uses type `Box<[u8]>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:79:34
+   |
+LL | pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
+   |                                  ^^^^^^^^^ not FFI-safe
+   |
+   = note: box cannot be represented as a single pointer
+
+error: `extern` fn uses type `Box<str>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:82:35
+   |
+LL | pub extern "C" fn boxed_string(p: Box<str>) { }
+   |                                   ^^^^^^^^ not FFI-safe
+   |
+   = note: box cannot be represented as a single pointer
+
+error: `extern` fn uses type `Box<dyn Trait>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:85:34
+   |
+LL | pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
+   |                                  ^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: box cannot be represented as a single pointer
+
 error: `extern` fn uses type `char`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:77:32
+  --> $DIR/lint-ctypes-fn.rs:88:32
    |
 LL | pub extern "C" fn char_type(p: char) { }
    |                                ^^^^ not FFI-safe
@@ -31,7 +55,7 @@ LL | pub extern "C" fn char_type(p: char) { }
    = note: the `char` type has no C equivalent
 
 error: `extern` fn uses type `i128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:80:32
+  --> $DIR/lint-ctypes-fn.rs:91:32
    |
 LL | pub extern "C" fn i128_type(p: i128) { }
    |                                ^^^^ not FFI-safe
@@ -39,7 +63,7 @@ LL | pub extern "C" fn i128_type(p: i128) { }
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` fn uses type `u128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:83:32
+  --> $DIR/lint-ctypes-fn.rs:94:32
    |
 LL | pub extern "C" fn u128_type(p: u128) { }
    |                                ^^^^ not FFI-safe
@@ -47,7 +71,7 @@ LL | pub extern "C" fn u128_type(p: u128) { }
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:86:33
+  --> $DIR/lint-ctypes-fn.rs:97:33
    |
 LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
    |                                 ^^^^^^^^^^ not FFI-safe
@@ -56,7 +80,7 @@ LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
    = note: tuples have unspecified layout
 
 error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:89:34
+  --> $DIR/lint-ctypes-fn.rs:100:34
    |
 LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
    |                                  ^^^^^^^ not FFI-safe
@@ -65,7 +89,7 @@ LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
    = note: tuples have unspecified layout
 
 error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:92:32
+  --> $DIR/lint-ctypes-fn.rs:103:32
    |
 LL | pub extern "C" fn zero_size(p: ZeroSize) { }
    |                                ^^^^^^^^ not FFI-safe
@@ -73,26 +97,26 @@ LL | pub extern "C" 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-fn.rs:26:1
+  --> $DIR/lint-ctypes-fn.rs:28:1
    |
 LL | pub struct ZeroSize;
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:95:40
+  --> $DIR/lint-ctypes-fn.rs:106:40
    |
 LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = note: composed only of `PhantomData`
 note: the type is defined here
-  --> $DIR/lint-ctypes-fn.rs:61:1
+  --> $DIR/lint-ctypes-fn.rs:63:1
    |
 LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:98:51
+  --> $DIR/lint-ctypes-fn.rs:109:51
    |
 LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
    |                                                   ^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -100,7 +124,7 @@ LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
    = note: composed only of `PhantomData`
 
 error: `extern` fn uses type `fn()`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:103:30
+  --> $DIR/lint-ctypes-fn.rs:114:30
    |
 LL | pub extern "C" fn fn_type(p: RustFn) { }
    |                              ^^^^^^ not FFI-safe
@@ -109,7 +133,7 @@ LL | pub extern "C" fn fn_type(p: RustFn) { }
    = note: this function pointer has Rust-specific calling convention
 
 error: `extern` fn uses type `fn()`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:106:31
+  --> $DIR/lint-ctypes-fn.rs:117:31
    |
 LL | pub extern "C" fn fn_type2(p: fn()) { }
    |                               ^^^^ not FFI-safe
@@ -118,7 +142,7 @@ LL | pub extern "C" fn fn_type2(p: fn()) { }
    = note: this function pointer has Rust-specific calling convention
 
 error: `extern` fn uses type `i128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:111:39
+  --> $DIR/lint-ctypes-fn.rs:122:39
    |
 LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
    |                                       ^^^^^^^^^^^^^^^ not FFI-safe
@@ -126,7 +150,7 @@ LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` fn uses type `str`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:114:38
+  --> $DIR/lint-ctypes-fn.rs:125:38
    |
 LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
    |                                      ^^^^^^^^^^^^^^ not FFI-safe
@@ -135,7 +159,7 @@ LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
    = note: string slices have no C equivalent
 
 error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:160:43
+  --> $DIR/lint-ctypes-fn.rs:171:43
    |
 LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
    |                                           ^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -143,7 +167,7 @@ LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
    = note: composed only of `PhantomData`
 
 error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:173:39
+  --> $DIR/lint-ctypes-fn.rs:184:39
    |
 LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
    |                                       ^^^^^^ not FFI-safe
@@ -152,7 +176,7 @@ LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
    = note: this struct has unspecified layout
 
 error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-fn.rs:176:41
+  --> $DIR/lint-ctypes-fn.rs:187:41
    |
 LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
    |                                         ^^^^^^ not FFI-safe
@@ -160,5 +184,5 @@ LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 
-error: aborting due to 17 previous errors
+error: aborting due to 20 previous errors