From 95df8024e7e934aec9f985a6680b65fd0d40a428 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 17 Jul 2020 17:23:18 +0100 Subject: [PATCH] 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 --- src/librustc_lint/types.rs | 13 +++++- src/test/ui/lint/lint-ctypes-fn.rs | 5 +-- src/test/ui/lint/lint-ctypes-fn.stderr | 55 +++++++------------------- src/test/ui/lint/lint-ctypes.rs | 2 + src/test/ui/lint/lint-ctypes.stderr | 47 +++++++++++++--------- 5 files changed, 58 insertions(+), 64 deletions(-) diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 46741fcf2ba0c..7014722bab824 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -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); diff --git a/src/test/ui/lint/lint-ctypes-fn.rs b/src/test/ui/lint/lint-ctypes-fn.rs index 67dd7abcf79ef..aa02e57866328 100644 --- a/src/test/ui/lint/lint-ctypes-fn.rs +++ b/src/test/ui/lint/lint-ctypes-fn.rs @@ -71,7 +71,8 @@ pub extern "C" fn str_type(p: &str) { } //~^ ERROR: uses type `str` pub extern "C" fn box_type(p: Box) { } -//~^ ERROR uses type `std::boxed::Box` + +pub extern "C" fn opt_box_type(p: Option>) { } 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` 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` pub extern "C" fn good3(fptr: Option) { } diff --git a/src/test/ui/lint/lint-ctypes-fn.stderr b/src/test/ui/lint/lint-ctypes-fn.stderr index 66cf195327890..d0a449514e50e 100644 --- a/src/test/ui/lint/lint-ctypes-fn.stderr +++ b/src/test/ui/lint/lint-ctypes-fn.stderr @@ -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`, which is not FFI-safe - --> $DIR/lint-ctypes-fn.rs:73:31 - | -LL | pub extern "C" fn box_type(p: Box) { } - | ^^^^^^^^ 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); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `extern` fn uses type `std::marker::PhantomData`, 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 { | ^^^^^^^^^^^^^^^^^ not FFI-safe @@ -109,7 +100,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: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`, 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`, 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`, 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() -> PhantomData { | ^^^^^^^^^^^^^^^^^ not FFI-safe @@ -170,7 +143,7 @@ LL | pub extern "C" fn unused_generic2() -> PhantomData { = note: composed only of `PhantomData` error: `extern` fn uses type `std::vec::Vec`, 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(x: Vec) { } | ^^^^^^ not FFI-safe @@ -179,7 +152,7 @@ LL | pub extern "C" fn used_generic4(x: Vec) { } = note: this struct has unspecified layout error: `extern` fn uses type `std::vec::Vec`, 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() -> Vec { | ^^^^^^ not FFI-safe @@ -187,5 +160,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 20 previous errors +error: aborting due to 17 previous errors diff --git a/src/test/ui/lint/lint-ctypes.rs b/src/test/ui/lint/lint-ctypes.rs index a439a1f339aea..bdf95350c7045 100644 --- a/src/test/ui/lint/lint-ctypes.rs +++ b/src/test/ui/lint/lint-ctypes.rs @@ -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); //~ ERROR uses type `std::boxed::Box` + pub fn opt_box_type(p: Option>); + //~^ ERROR uses type `std::option::Option>` 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` diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr index 9821f858d9caf..13b9adca3f9f5 100644 --- a/src/test/ui/lint/lint-ctypes.stderr +++ b/src/test/ui/lint/lint-ctypes.stderr @@ -58,8 +58,17 @@ LL | pub fn box_type(p: Box); = 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>`, which is not FFI-safe + --> $DIR/lint-ctypes.rs:51:28 + | +LL | pub fn opt_box_type(p: Option>); + | ^^^^^^^^^^^^^^^^ 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); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `extern` block uses type `std::marker::PhantomData`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:61:12 + --> $DIR/lint-ctypes.rs:63:12 | LL | -> ::std::marker::PhantomData; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -145,7 +154,7 @@ LL | -> ::std::marker::PhantomData; = 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`, 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`, 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