improper_ctypes_definitions: allow Box

This commit stops linting against `Box` in `extern "C" fn`s for the
`improper_ctypes_definitions` lint - boxes are documented to be
FFI-safe.

Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
David Wood 2020-07-17 17:23:18 +01:00
parent e2e29de5e8
commit 95df8024e7
No known key found for this signature in database
GPG Key ID: 2592E76C87381FD9
5 changed files with 58 additions and 64 deletions

View File

@ -531,6 +531,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
match ty.kind {
ty::FnPtr(_) => true,
ty::Ref(..) => true,
ty::Adt(def, _)
if def.is_box() && matches!(self.mode, ImproperCTypesMode::Definitions) =>
{
true
}
ty::Adt(def, substs) if def.repr.transparent() && !def.is_union() => {
let guaranteed_nonnull_optimization = self
.cx
@ -558,7 +563,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}
/// Check if this enum can be safely exported based on the "nullable pointer optimization".
/// Currently restricted to function pointers, references, `core::num::NonZero*`,
/// Currently restricted to function pointers, boxes, references, `core::num::NonZero*`,
/// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes.
fn is_repr_nullable_ptr(
&self,
@ -692,6 +697,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}
match ty.kind {
ty::Adt(def, _)
if def.is_box() && matches!(self.mode, ImproperCTypesMode::Definitions) =>
{
FfiSafe
}
ty::Adt(def, substs) => {
if def.is_phantom_data() {
return FfiPhantom(ty);

View File

@ -71,7 +71,8 @@ pub extern "C" fn str_type(p: &str) { }
//~^ ERROR: uses type `str`
pub extern "C" fn box_type(p: Box<u32>) { }
//~^ ERROR uses type `std::boxed::Box<u32>`
pub extern "C" fn opt_box_type(p: Option<Box<u32>>) { }
pub extern "C" fn char_type(p: char) { }
//~^ ERROR uses type `char`
@ -106,7 +107,6 @@ pub extern "C" fn fn_type2(p: fn()) { }
//~^ ERROR uses type `fn()`
pub extern "C" fn fn_contained(p: RustBadRet) { }
//~^ ERROR: uses type `std::boxed::Box<u32>`
pub extern "C" fn transparent_i128(p: TransparentI128) { }
//~^ ERROR: uses type `i128`
@ -115,7 +115,6 @@ pub extern "C" fn transparent_str(p: TransparentStr) { }
//~^ ERROR: uses type `str`
pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
//~^ ERROR: uses type `std::boxed::Box<u32>`
pub extern "C" fn good3(fptr: Option<extern fn()>) { }

View File

@ -21,17 +21,8 @@ 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 `std::boxed::Box<u32>`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:73:31
|
LL | pub extern "C" fn box_type(p: Box<u32>) { }
| ^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
error: `extern` fn uses type `char`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:76:32
--> $DIR/lint-ctypes-fn.rs:77:32
|
LL | pub extern "C" fn char_type(p: char) { }
| ^^^^ not FFI-safe
@ -40,7 +31,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:79:32
--> $DIR/lint-ctypes-fn.rs:80:32
|
LL | pub extern "C" fn i128_type(p: i128) { }
| ^^^^ not FFI-safe
@ -48,7 +39,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:82:32
--> $DIR/lint-ctypes-fn.rs:83:32
|
LL | pub extern "C" fn u128_type(p: u128) { }
| ^^^^ not FFI-safe
@ -56,7 +47,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:85:33
--> $DIR/lint-ctypes-fn.rs:86:33
|
LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
| ^^^^^^^^^^ not FFI-safe
@ -65,7 +56,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:88:34
--> $DIR/lint-ctypes-fn.rs:89:34
|
LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
| ^^^^^^^ not FFI-safe
@ -74,7 +65,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:91:32
--> $DIR/lint-ctypes-fn.rs:92:32
|
LL | pub extern "C" fn zero_size(p: ZeroSize) { }
| ^^^^^^^^ not FFI-safe
@ -88,7 +79,7 @@ LL | pub struct ZeroSize;
| ^^^^^^^^^^^^^^^^^^^^
error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:94:40
--> $DIR/lint-ctypes-fn.rs:95:40
|
LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -101,7 +92,7 @@ LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:97:51
--> $DIR/lint-ctypes-fn.rs:98:51
|
LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
| ^^^^^^^^^^^^^^^^^ not FFI-safe
@ -109,7 +100,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:102:30
--> $DIR/lint-ctypes-fn.rs:103:30
|
LL | pub extern "C" fn fn_type(p: RustFn) { }
| ^^^^^^ not FFI-safe
@ -118,7 +109,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:105:31
--> $DIR/lint-ctypes-fn.rs:106:31
|
LL | pub extern "C" fn fn_type2(p: fn()) { }
| ^^^^ not FFI-safe
@ -126,15 +117,6 @@ LL | pub extern "C" fn fn_type2(p: fn()) { }
= help: consider using an `extern fn(...) -> ...` function pointer instead
= note: this function pointer has Rust-specific calling convention
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:108:35
|
LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
| ^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
error: `extern` fn uses type `i128`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:111:39
|
@ -152,17 +134,8 @@ LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
= help: consider using `*const u8` and a length instead
= note: string slices have no C equivalent
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:117:37
|
LL | pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
| ^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:161:43
--> $DIR/lint-ctypes-fn.rs:160:43
|
LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
| ^^^^^^^^^^^^^^^^^ not FFI-safe
@ -170,7 +143,7 @@ LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
= note: composed only of `PhantomData`
error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:174:39
--> $DIR/lint-ctypes-fn.rs:173:39
|
LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
| ^^^^^^ not FFI-safe
@ -179,7 +152,7 @@ LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
= note: this struct has unspecified layout
error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
--> $DIR/lint-ctypes-fn.rs:177:41
--> $DIR/lint-ctypes-fn.rs:176:41
|
LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
| ^^^^^^ not FFI-safe
@ -187,5 +160,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 20 previous errors
error: aborting due to 17 previous errors

View File

@ -48,6 +48,8 @@ extern {
pub fn slice_type(p: &[u32]); //~ ERROR: uses type `[u32]`
pub fn str_type(p: &str); //~ ERROR: uses type `str`
pub fn box_type(p: Box<u32>); //~ ERROR uses type `std::boxed::Box<u32>`
pub fn opt_box_type(p: Option<Box<u32>>);
//~^ ERROR uses type `std::option::Option<std::boxed::Box<u32>>`
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`

View File

@ -58,8 +58,17 @@ LL | pub fn box_type(p: Box<u32>);
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= 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
|
LL | pub fn opt_box_type(p: Option<Box<u32>>);
| ^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint
error: `extern` block uses type `char`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:51:25
--> $DIR/lint-ctypes.rs:53:25
|
LL | pub fn char_type(p: char);
| ^^^^ not FFI-safe
@ -68,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:52:25
--> $DIR/lint-ctypes.rs:54:25
|
LL | pub fn i128_type(p: i128);
| ^^^^ not FFI-safe
@ -76,7 +85,7 @@ 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:53:25
--> $DIR/lint-ctypes.rs:55:25
|
LL | pub fn u128_type(p: u128);
| ^^^^ not FFI-safe
@ -84,7 +93,7 @@ LL | pub fn u128_type(p: u128);
= 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:54:26
--> $DIR/lint-ctypes.rs:56:26
|
LL | pub fn trait_type(p: &dyn Clone);
| ^^^^^^^^^^ not FFI-safe
@ -92,7 +101,7 @@ LL | pub fn trait_type(p: &dyn Clone);
= note: trait objects have no C equivalent
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:55:26
--> $DIR/lint-ctypes.rs:57:26
|
LL | pub fn tuple_type(p: (i32, i32));
| ^^^^^^^^^^ not FFI-safe
@ -101,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:56:27
--> $DIR/lint-ctypes.rs:58:27
|
LL | pub fn tuple_type2(p: I32Pair);
| ^^^^^^^ not FFI-safe
@ -110,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:57:25
--> $DIR/lint-ctypes.rs:59:25
|
LL | pub fn zero_size(p: ZeroSize);
| ^^^^^^^^ not FFI-safe
@ -124,7 +133,7 @@ LL | pub struct ZeroSize;
| ^^^^^^^^^^^^^^^^^^^^
error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:58:33
--> $DIR/lint-ctypes.rs:60:33
|
LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -137,7 +146,7 @@ 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:61:12
--> $DIR/lint-ctypes.rs:63:12
|
LL | -> ::std::marker::PhantomData<bool>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -145,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:62:23
--> $DIR/lint-ctypes.rs:64:23
|
LL | pub fn fn_type(p: RustFn);
| ^^^^^^ not FFI-safe
@ -154,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:63:24
--> $DIR/lint-ctypes.rs:65:24
|
LL | pub fn fn_type2(p: fn());
| ^^^^ not FFI-safe
@ -163,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:64:28
--> $DIR/lint-ctypes.rs:66:28
|
LL | pub fn fn_contained(p: RustBadRet);
| ^^^^^^^^^^ not FFI-safe
@ -172,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:65:32
--> $DIR/lint-ctypes.rs:67:32
|
LL | pub fn transparent_i128(p: TransparentI128);
| ^^^^^^^^^^^^^^^ not FFI-safe
@ -180,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:66:31
--> $DIR/lint-ctypes.rs:68:31
|
LL | pub fn transparent_str(p: TransparentStr);
| ^^^^^^^^^^^^^^ not FFI-safe
@ -189,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:67:30
--> $DIR/lint-ctypes.rs:69:30
|
LL | pub fn transparent_fn(p: TransparentBadFn);
| ^^^^^^^^^^^^^^^^ not FFI-safe
@ -198,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:68:27
--> $DIR/lint-ctypes.rs:70:27
|
LL | pub fn raw_array(arr: [u8; 8]);
| ^^^^^^^ not FFI-safe
@ -207,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:70:34
--> $DIR/lint-ctypes.rs:72:34
|
LL | pub static static_u128_type: u128;
| ^^^^ not FFI-safe
@ -215,12 +224,12 @@ 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:71:40
--> $DIR/lint-ctypes.rs:73:40
|
LL | pub static static_u128_array_type: [u128; 16];
| ^^^^^^^^^^ not FFI-safe
|
= note: 128-bit integers don't currently have a known stable ABI
error: aborting due to 23 previous errors
error: aborting due to 24 previous errors