Skip to content

Commit 9b59dd8

Browse files
committed
lint ImproperCTypes: confirm that Box<FfiSafeType> and Option<Box<FfiSafeType>> are FFI-safe in function declarations too
1 parent d857bc8 commit 9b59dd8

File tree

3 files changed

+27
-63
lines changed

3 files changed

+27
-63
lines changed

compiler/rustc_lint/src/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ fn ty_is_known_nonnull<'tcx>(
866866
match ty.kind() {
867867
ty::FnPtr(..) => true,
868868
ty::Ref(..) => true,
869-
ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true,
869+
ty::Adt(def, _) if def.is_box() => true,
870870
ty::Adt(def, args) if def.repr().transparent() && !def.is_union() => {
871871
let marked_non_null = nonnull_optimization_guaranteed(tcx, *def);
872872

tests/ui/lint/lint-ctypes.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ pub type I32Pair = (i32, i32);
2323
#[repr(C)]
2424
pub struct ZeroSize;
2525
pub type RustFn = fn();
26-
pub type RustBadRet = extern "C" fn() -> Box<u32>;
26+
pub type RustBoxRet = extern "C" fn() -> Box<u32>;
2727
pub type CVoidRet = ();
2828
pub struct Foo;
2929
#[repr(transparent)]
3030
pub struct TransparentI128(i128);
3131
#[repr(transparent)]
3232
pub struct TransparentStr(&'static str);
3333
#[repr(transparent)]
34-
pub struct TransparentBadFn(RustBadRet);
34+
pub struct TransparentBoxFn(RustBoxRet);
3535
#[repr(transparent)]
3636
pub struct TransparentInt(u32);
3737
#[repr(transparent)]
@@ -63,9 +63,8 @@ extern "C" {
6363
pub fn ptr_tuple(p: *const ((),)); //~ ERROR: uses type `((),)`
6464
pub fn slice_type(p: &[u32]); //~ ERROR: uses type `&[u32]`
6565
pub fn str_type(p: &str); //~ ERROR: uses type `&str`
66-
pub fn box_type(p: Box<u32>); //~ ERROR uses type `Box<u32>`
66+
pub fn box_type(p: Box<u32>);
6767
pub fn opt_box_type(p: Option<Box<u32>>);
68-
//~^ ERROR uses type `Option<Box<u32>>`
6968
pub fn char_type(p: char); //~ ERROR uses type `char`
7069
pub fn i128_type(p: i128); //~ ERROR uses type `i128`
7170
pub fn u128_type(p: u128); //~ ERROR uses type `u128`
@@ -79,10 +78,10 @@ extern "C" {
7978
-> ::std::marker::PhantomData<bool>; //~ ERROR uses type `PhantomData<bool>`
8079
pub fn fn_type(p: RustFn); //~ ERROR uses type `fn()`
8180
pub fn fn_type2(p: fn()); //~ ERROR uses type `fn()`
82-
pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `Box<u32>`
81+
pub fn fn_contained(p: RustBoxRet);
8382
pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
8483
pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `&str`
85-
pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `Box<u32>`
84+
pub fn transparent_fn(p: TransparentBoxFn);
8685
pub fn raw_array(arr: [u8; 8]); //~ ERROR: uses type `[u8; 8]`
8786

8887
pub fn struct_unsized_ptr_no_metadata(p: &UnsizedStructBecauseForeign);

tests/ui/lint/lint-ctypes.stderr

+21-56
Original file line numberDiff line numberDiff line change
@@ -61,26 +61,8 @@ LL | pub fn str_type(p: &str);
6161
= help: consider using `*const u8` and a length instead
6262
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
6363

64-
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
65-
--> $DIR/lint-ctypes.rs:53:24
66-
|
67-
LL | pub fn box_type(p: Box<u32>);
68-
| ^^^^^^^^ not FFI-safe
69-
|
70-
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
71-
= note: this struct has unspecified layout
72-
73-
error: `extern` block uses type `Option<Box<u32>>`, which is not FFI-safe
74-
--> $DIR/lint-ctypes.rs:67:28
75-
|
76-
LL | pub fn opt_box_type(p: Option<Box<u32>>);
77-
| ^^^^^^^^^^^^^^^^ not FFI-safe
78-
|
79-
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
80-
= note: enum has no representation hint
81-
8264
error: `extern` block uses type `char`, which is not FFI-safe
83-
--> $DIR/lint-ctypes.rs:69:25
65+
--> $DIR/lint-ctypes.rs:68:25
8466
|
8567
LL | pub fn char_type(p: char);
8668
| ^^^^ not FFI-safe
@@ -89,31 +71,31 @@ LL | pub fn char_type(p: char);
8971
= note: the `char` type has no C equivalent
9072

9173
error: `extern` block uses type `i128`, which is not FFI-safe
92-
--> $DIR/lint-ctypes.rs:70:25
74+
--> $DIR/lint-ctypes.rs:69:25
9375
|
9476
LL | pub fn i128_type(p: i128);
9577
| ^^^^ not FFI-safe
9678
|
9779
= note: 128-bit integers don't currently have a known stable ABI
9880

9981
error: `extern` block uses type `u128`, which is not FFI-safe
100-
--> $DIR/lint-ctypes.rs:71:25
82+
--> $DIR/lint-ctypes.rs:70:25
10183
|
10284
LL | pub fn u128_type(p: u128);
10385
| ^^^^ not FFI-safe
10486
|
10587
= note: 128-bit integers don't currently have a known stable ABI
10688

10789
error: `extern` block uses type `&dyn Bar`, which is not FFI-safe
108-
--> $DIR/lint-ctypes.rs:72:26
90+
--> $DIR/lint-ctypes.rs:71:26
10991
|
11092
LL | pub fn trait_type(p: &dyn Bar);
11193
| ^^^^^^^^ not FFI-safe
11294
|
11395
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
11496

11597
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
116-
--> $DIR/lint-ctypes.rs:73:26
98+
--> $DIR/lint-ctypes.rs:72:26
11799
|
118100
LL | pub fn tuple_type(p: (i32, i32));
119101
| ^^^^^^^^^^ not FFI-safe
@@ -122,7 +104,7 @@ LL | pub fn tuple_type(p: (i32, i32));
122104
= note: tuples have unspecified layout
123105

124106
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
125-
--> $DIR/lint-ctypes.rs:74:27
107+
--> $DIR/lint-ctypes.rs:73:27
126108
|
127109
LL | pub fn tuple_type2(p: I32Pair);
128110
| ^^^^^^^ not FFI-safe
@@ -131,7 +113,7 @@ LL | pub fn tuple_type2(p: I32Pair);
131113
= note: tuples have unspecified layout
132114

133115
error: `extern` block uses type `ZeroSize`, which is not FFI-safe
134-
--> $DIR/lint-ctypes.rs:75:25
116+
--> $DIR/lint-ctypes.rs:74:25
135117
|
136118
LL | pub fn zero_size(p: ZeroSize);
137119
| ^^^^^^^^ not FFI-safe
@@ -145,7 +127,7 @@ LL | pub struct ZeroSize;
145127
| ^^^^^^^^^^^^^^^^^^^
146128

147129
error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
148-
--> $DIR/lint-ctypes.rs:76:33
130+
--> $DIR/lint-ctypes.rs:75:33
149131
|
150132
LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
151133
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -158,15 +140,15 @@ LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
158140
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
159141

160142
error: `extern` block uses type `PhantomData<bool>`, which is not FFI-safe
161-
--> $DIR/lint-ctypes.rs:79:12
143+
--> $DIR/lint-ctypes.rs:78:12
162144
|
163145
LL | -> ::std::marker::PhantomData<bool>;
164146
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
165147
|
166148
= note: composed only of `PhantomData`
167149

168150
error: `extern` block uses type `fn()`, which is not FFI-safe
169-
--> $DIR/lint-ctypes.rs:80:23
151+
--> $DIR/lint-ctypes.rs:79:23
170152
|
171153
LL | pub fn fn_type(p: RustFn);
172154
| ^^^^^^ not FFI-safe
@@ -175,51 +157,33 @@ LL | pub fn fn_type(p: RustFn);
175157
= note: this function pointer has Rust-specific calling convention
176158

177159
error: `extern` block uses type `fn()`, which is not FFI-safe
178-
--> $DIR/lint-ctypes.rs:81:24
160+
--> $DIR/lint-ctypes.rs:80:24
179161
|
180162
LL | pub fn fn_type2(p: fn());
181163
| ^^^^ not FFI-safe
182164
|
183165
= help: consider using an `extern fn(...) -> ...` function pointer instead
184166
= note: this function pointer has Rust-specific calling convention
185167

186-
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
187-
--> $DIR/lint-ctypes.rs:69:28
188-
|
189-
LL | pub fn fn_contained(p: RustBadRet);
190-
| ^^^^^^^^^^ not FFI-safe
191-
|
192-
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
193-
= note: this struct has unspecified layout
194-
195168
error: `extern` block uses type `i128`, which is not FFI-safe
196-
--> $DIR/lint-ctypes.rs:83:32
169+
--> $DIR/lint-ctypes.rs:82:32
197170
|
198171
LL | pub fn transparent_i128(p: TransparentI128);
199172
| ^^^^^^^^^^^^^^^ not FFI-safe
200173
|
201174
= note: 128-bit integers don't currently have a known stable ABI
202175

203176
error: `extern` block uses type `&str`, which is not FFI-safe
204-
--> $DIR/lint-ctypes.rs:84:31
177+
--> $DIR/lint-ctypes.rs:83:31
205178
|
206179
LL | pub fn transparent_str(p: TransparentStr);
207180
| ^^^^^^^^^^^^^^ not FFI-safe
208181
|
209182
= help: consider using `*const u8` and a length instead
210183
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
211184

212-
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
213-
--> $DIR/lint-ctypes.rs:72:30
214-
|
215-
LL | pub fn transparent_fn(p: TransparentBadFn);
216-
| ^^^^^^^^^^^^^^^^ not FFI-safe
217-
|
218-
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
219-
= note: this struct has unspecified layout
220-
221185
error: `extern` block uses type `[u8; 8]`, which is not FFI-safe
222-
--> $DIR/lint-ctypes.rs:86:27
186+
--> $DIR/lint-ctypes.rs:85:27
223187
|
224188
LL | pub fn raw_array(arr: [u8; 8]);
225189
| ^^^^^^^ not FFI-safe
@@ -228,15 +192,15 @@ LL | pub fn raw_array(arr: [u8; 8]);
228192
= note: passing raw arrays by value is not FFI-safe
229193

230194
error: `extern` block uses type `&UnsizedStructBecauseDyn`, which is not FFI-safe
231-
--> $DIR/lint-ctypes.rs:89:47
195+
--> $DIR/lint-ctypes.rs:88:47
232196
|
233197
LL | pub fn struct_unsized_ptr_has_metadata(p: &UnsizedStructBecauseDyn);
234198
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
235199
|
236200
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
237201

238202
error: `extern` block uses type `Option<UnsafeCell<extern "C" fn()>>`, which is not FFI-safe
239-
--> $DIR/lint-ctypes.rs:91:26
203+
--> $DIR/lint-ctypes.rs:90:26
240204
|
241205
LL | pub fn no_niche_a(a: Option<UnsafeCell<extern fn()>>);
242206
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -245,7 +209,7 @@ LL | pub fn no_niche_a(a: Option<UnsafeCell<extern fn()>>);
245209
= note: enum has no representation hint
246210

247211
error: `extern` block uses type `Option<UnsafeCell<&i32>>`, which is not FFI-safe
248-
--> $DIR/lint-ctypes.rs:93:26
212+
--> $DIR/lint-ctypes.rs:92:26
249213
|
250214
LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
251215
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -254,19 +218,20 @@ LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
254218
= note: enum has no representation hint
255219

256220
error: `extern` block uses type `u128`, which is not FFI-safe
257-
--> $DIR/lint-ctypes.rs:96:34
221+
--> $DIR/lint-ctypes.rs:95:34
258222
|
259223
LL | pub static static_u128_type: u128;
260224
| ^^^^ not FFI-safe
261225
|
262226
= note: 128-bit integers don't currently have a known stable ABI
263227

264228
error: `extern` block uses type `u128`, which is not FFI-safe
265-
--> $DIR/lint-ctypes.rs:97:40
229+
--> $DIR/lint-ctypes.rs:96:40
266230
|
267231
LL | pub static static_u128_array_type: [u128; 16];
268232
| ^^^^^^^^^^ not FFI-safe
269233
|
270234
= note: 128-bit integers don't currently have a known stable ABI
271235

272-
error: aborting due to 29 previous errors
236+
error: aborting due to 24 previous errors
237+

0 commit comments

Comments
 (0)