From 877cfb1aad2543b3fe31d97075ea37d283afc880 Mon Sep 17 00:00:00 2001 From: marmeladema Date: Mon, 31 May 2021 13:23:44 +0100 Subject: [PATCH] Warn against boxed DST in `improper_ctypes_definitions` lint --- compiler/rustc_lint/src/types.rs | 15 ++++-- src/test/ui/lint/lint-ctypes-fn.rs | 11 +++++ src/test/ui/lint/lint-ctypes-fn.stderr | 64 ++++++++++++++++++-------- 3 files changed, 66 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 319adf42cf1ed..5d2256100ff67 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 e69d0dab49642..c18cb881032a6 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 Mirror for T { type It = Self; } @@ -74,6 +76,15 @@ pub extern "C" fn box_type(p: Box) { } pub extern "C" fn opt_box_type(p: Option>) { } +pub extern "C" fn boxed_slice(p: Box<[u8]>) { } +//~^ ERROR: uses type `Box<[u8]>` + +pub extern "C" fn boxed_string(p: Box) { } +//~^ ERROR: uses type `Box` + +pub extern "C" fn boxed_trait(p: Box) { } +//~^ ERROR: uses type `Box` + 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 e6a0778ddb25d..d591d4ad292dd 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`, which is not FFI-safe + --> $DIR/lint-ctypes-fn.rs:82:35 + | +LL | pub extern "C" fn boxed_string(p: Box) { } + | ^^^^^^^^ not FFI-safe + | + = note: box cannot be represented as a single pointer + +error: `extern` fn uses type `Box`, which is not FFI-safe + --> $DIR/lint-ctypes-fn.rs:85:34 + | +LL | pub extern "C" fn boxed_trait(p: Box) { } + | ^^^^^^^^^^^^^^ 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); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `extern` fn uses type `PhantomData`, 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 { | ^^^^^^^^^^^^^^^^^ not FFI-safe @@ -100,7 +124,7 @@ LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData { = 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`, 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() -> PhantomData { | ^^^^^^^^^^^^^^^^^ not FFI-safe @@ -143,7 +167,7 @@ LL | pub extern "C" fn unused_generic2() -> PhantomData { = note: composed only of `PhantomData` error: `extern` fn uses type `Vec`, 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(x: Vec) { } | ^^^^^^ not FFI-safe @@ -152,7 +176,7 @@ LL | pub extern "C" fn used_generic4(x: Vec) { } = note: this struct has unspecified layout error: `extern` fn uses type `Vec`, 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() -> Vec { | ^^^^^^ not FFI-safe @@ -160,5 +184,5 @@ LL | pub extern "C" fn used_generic5() -> Vec { = 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