Skip to content

Commit 5c86348

Browse files
committed
improper_ctypes: allow pointers to sized types
This commit changes the improper ctypes lint (when operating on definitions) to consider raw pointers or references to sized types as FFI-safe. Signed-off-by: David Wood <david@davidtw.co>
1 parent 14ea7a7 commit 5c86348

File tree

3 files changed

+34
-85
lines changed

3 files changed

+34
-85
lines changed

src/librustc_lint/types.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::ty::subst::SubstsRef;
1414
use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt, TypeFoldable};
1515
use rustc_span::source_map;
1616
use rustc_span::symbol::sym;
17-
use rustc_span::Span;
17+
use rustc_span::{Span, DUMMY_SP};
1818
use rustc_target::abi::{Integer, LayoutOf, TagEncoding, VariantIdx, Variants};
1919
use rustc_target::spec::abi::Abi;
2020

@@ -818,6 +818,15 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
818818
help: Some("consider using a struct instead".into()),
819819
},
820820

821+
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _)
822+
if {
823+
matches!(self.mode, ImproperCTypesMode::Definitions)
824+
&& ty.is_sized(self.cx.tcx.at(DUMMY_SP), self.cx.param_env)
825+
} =>
826+
{
827+
FfiSafe
828+
}
829+
821830
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => {
822831
self.check_type_for_ffi(cache, ty)
823832
}

src/test/ui/lint/lint-ctypes-fn.rs

-4
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,8 @@ pub struct TransparentCustomZst(i32, ZeroSize);
6161
pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
6262

6363
pub extern "C" fn ptr_type1(size: *const Foo) { }
64-
//~^ ERROR: uses type `Foo`
6564

6665
pub extern "C" fn ptr_type2(size: *const Foo) { }
67-
//~^ ERROR: uses type `Foo`
6866

6967
pub extern "C" fn slice_type(p: &[u32]) { }
7068
//~^ ERROR: uses type `[u32]`
@@ -159,7 +157,6 @@ pub extern "C" fn good1(size: *const libc::c_int) { }
159157
pub extern "C" fn good2(size: *const libc::c_uint) { }
160158

161159
pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
162-
//~^ ERROR: uses type `Foo`
163160

164161
pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
165162
//~^ ERROR uses type `std::marker::PhantomData<bool>`
@@ -169,7 +166,6 @@ pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
169166
pub extern "C" fn used_generic1<T>(x: T) { }
170167

171168
pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
172-
//~^ ERROR: uses type `Foo`
173169

174170
pub extern "C" fn used_generic3<T: Default>() -> T {
175171
Default::default()
+24-80
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,19 @@
1-
error: `extern` fn uses type `Foo`, which is not FFI-safe
2-
--> $DIR/lint-ctypes-fn.rs:63:35
1+
error: `extern` fn uses type `[u32]`, which is not FFI-safe
2+
--> $DIR/lint-ctypes-fn.rs:67:33
33
|
4-
LL | pub extern "C" fn ptr_type1(size: *const Foo) { }
5-
| ^^^^^^^^^^ not FFI-safe
4+
LL | pub extern "C" fn slice_type(p: &[u32]) { }
5+
| ^^^^^^ not FFI-safe
66
|
77
note: the lint level is defined here
88
--> $DIR/lint-ctypes-fn.rs:4:9
99
|
1010
LL | #![deny(improper_ctypes_definitions)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
13-
= note: this struct has unspecified layout
14-
note: the type is defined here
15-
--> $DIR/lint-ctypes-fn.rs:34:1
16-
|
17-
LL | pub struct Foo;
18-
| ^^^^^^^^^^^^^^^
19-
20-
error: `extern` fn uses type `Foo`, which is not FFI-safe
21-
--> $DIR/lint-ctypes-fn.rs:66:35
22-
|
23-
LL | pub extern "C" fn ptr_type2(size: *const Foo) { }
24-
| ^^^^^^^^^^ not FFI-safe
25-
|
26-
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
27-
= note: this struct has unspecified layout
28-
note: the type is defined here
29-
--> $DIR/lint-ctypes-fn.rs:34:1
30-
|
31-
LL | pub struct Foo;
32-
| ^^^^^^^^^^^^^^^
33-
34-
error: `extern` fn uses type `[u32]`, which is not FFI-safe
35-
--> $DIR/lint-ctypes-fn.rs:69:33
36-
|
37-
LL | pub extern "C" fn slice_type(p: &[u32]) { }
38-
| ^^^^^^ not FFI-safe
39-
|
4012
= help: consider using a raw pointer instead
4113
= note: slices have no C equivalent
4214

4315
error: `extern` fn uses type `str`, which is not FFI-safe
44-
--> $DIR/lint-ctypes-fn.rs:72:31
16+
--> $DIR/lint-ctypes-fn.rs:70:31
4517
|
4618
LL | pub extern "C" fn str_type(p: &str) { }
4719
| ^^^^ not FFI-safe
@@ -50,7 +22,7 @@ LL | pub extern "C" fn str_type(p: &str) { }
5022
= note: string slices have no C equivalent
5123

5224
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
53-
--> $DIR/lint-ctypes-fn.rs:75:31
25+
--> $DIR/lint-ctypes-fn.rs:73:31
5426
|
5527
LL | pub extern "C" fn box_type(p: Box<u32>) { }
5628
| ^^^^^^^^ not FFI-safe
@@ -59,7 +31,7 @@ LL | pub extern "C" fn box_type(p: Box<u32>) { }
5931
= note: this struct has unspecified layout
6032

6133
error: `extern` fn uses type `char`, which is not FFI-safe
62-
--> $DIR/lint-ctypes-fn.rs:78:32
34+
--> $DIR/lint-ctypes-fn.rs:76:32
6335
|
6436
LL | pub extern "C" fn char_type(p: char) { }
6537
| ^^^^ not FFI-safe
@@ -68,23 +40,23 @@ LL | pub extern "C" fn char_type(p: char) { }
6840
= note: the `char` type has no C equivalent
6941

7042
error: `extern` fn uses type `i128`, which is not FFI-safe
71-
--> $DIR/lint-ctypes-fn.rs:81:32
43+
--> $DIR/lint-ctypes-fn.rs:79:32
7244
|
7345
LL | pub extern "C" fn i128_type(p: i128) { }
7446
| ^^^^ not FFI-safe
7547
|
7648
= note: 128-bit integers don't currently have a known stable ABI
7749

7850
error: `extern` fn uses type `u128`, which is not FFI-safe
79-
--> $DIR/lint-ctypes-fn.rs:84:32
51+
--> $DIR/lint-ctypes-fn.rs:82:32
8052
|
8153
LL | pub extern "C" fn u128_type(p: u128) { }
8254
| ^^^^ not FFI-safe
8355
|
8456
= note: 128-bit integers don't currently have a known stable ABI
8557

8658
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
87-
--> $DIR/lint-ctypes-fn.rs:87:33
59+
--> $DIR/lint-ctypes-fn.rs:85:33
8860
|
8961
LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
9062
| ^^^^^^^^^^ not FFI-safe
@@ -93,7 +65,7 @@ LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
9365
= note: tuples have unspecified layout
9466

9567
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
96-
--> $DIR/lint-ctypes-fn.rs:90:34
68+
--> $DIR/lint-ctypes-fn.rs:88:34
9769
|
9870
LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
9971
| ^^^^^^^ not FFI-safe
@@ -102,7 +74,7 @@ LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
10274
= note: tuples have unspecified layout
10375

10476
error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
105-
--> $DIR/lint-ctypes-fn.rs:93:32
77+
--> $DIR/lint-ctypes-fn.rs:91:32
10678
|
10779
LL | pub extern "C" fn zero_size(p: ZeroSize) { }
10880
| ^^^^^^^^ not FFI-safe
@@ -116,7 +88,7 @@ LL | pub struct ZeroSize;
11688
| ^^^^^^^^^^^^^^^^^^^^
11789

11890
error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
119-
--> $DIR/lint-ctypes-fn.rs:96:40
91+
--> $DIR/lint-ctypes-fn.rs:94:40
12092
|
12193
LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
12294
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -129,15 +101,15 @@ LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
129101
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
130102

131103
error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
132-
--> $DIR/lint-ctypes-fn.rs:99:51
104+
--> $DIR/lint-ctypes-fn.rs:97:51
133105
|
134106
LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
135107
| ^^^^^^^^^^^^^^^^^ not FFI-safe
136108
|
137109
= note: composed only of `PhantomData`
138110

139111
error: `extern` fn uses type `fn()`, which is not FFI-safe
140-
--> $DIR/lint-ctypes-fn.rs:104:30
112+
--> $DIR/lint-ctypes-fn.rs:102:30
141113
|
142114
LL | pub extern "C" fn fn_type(p: RustFn) { }
143115
| ^^^^^^ not FFI-safe
@@ -146,7 +118,7 @@ LL | pub extern "C" fn fn_type(p: RustFn) { }
146118
= note: this function pointer has Rust-specific calling convention
147119

148120
error: `extern` fn uses type `fn()`, which is not FFI-safe
149-
--> $DIR/lint-ctypes-fn.rs:107:31
121+
--> $DIR/lint-ctypes-fn.rs:105:31
150122
|
151123
LL | pub extern "C" fn fn_type2(p: fn()) { }
152124
| ^^^^ not FFI-safe
@@ -155,7 +127,7 @@ LL | pub extern "C" fn fn_type2(p: fn()) { }
155127
= note: this function pointer has Rust-specific calling convention
156128

157129
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
158-
--> $DIR/lint-ctypes-fn.rs:110:35
130+
--> $DIR/lint-ctypes-fn.rs:108:35
159131
|
160132
LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
161133
| ^^^^^^^^^^ not FFI-safe
@@ -164,15 +136,15 @@ LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
164136
= note: this struct has unspecified layout
165137

166138
error: `extern` fn uses type `i128`, which is not FFI-safe
167-
--> $DIR/lint-ctypes-fn.rs:113:39
139+
--> $DIR/lint-ctypes-fn.rs:111:39
168140
|
169141
LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
170142
| ^^^^^^^^^^^^^^^ not FFI-safe
171143
|
172144
= note: 128-bit integers don't currently have a known stable ABI
173145

174146
error: `extern` fn uses type `str`, which is not FFI-safe
175-
--> $DIR/lint-ctypes-fn.rs:116:38
147+
--> $DIR/lint-ctypes-fn.rs:114:38
176148
|
177149
LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
178150
| ^^^^^^^^^^^^^^ not FFI-safe
@@ -181,52 +153,24 @@ LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
181153
= note: string slices have no C equivalent
182154

183155
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
184-
--> $DIR/lint-ctypes-fn.rs:119:37
156+
--> $DIR/lint-ctypes-fn.rs:117:37
185157
|
186158
LL | pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
187159
| ^^^^^^^^^^^^^^^^ not FFI-safe
188160
|
189161
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
190162
= note: this struct has unspecified layout
191163

192-
error: `extern` fn uses type `Foo`, which is not FFI-safe
193-
--> $DIR/lint-ctypes-fn.rs:161:44
194-
|
195-
LL | pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
196-
| ^^^^^^^^^^ not FFI-safe
197-
|
198-
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
199-
= note: this struct has unspecified layout
200-
note: the type is defined here
201-
--> $DIR/lint-ctypes-fn.rs:34:1
202-
|
203-
LL | pub struct Foo;
204-
| ^^^^^^^^^^^^^^^
205-
206164
error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
207-
--> $DIR/lint-ctypes-fn.rs:164:43
165+
--> $DIR/lint-ctypes-fn.rs:161:43
208166
|
209167
LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
210168
| ^^^^^^^^^^^^^^^^^ not FFI-safe
211169
|
212170
= note: composed only of `PhantomData`
213171

214-
error: `extern` fn uses type `Foo`, which is not FFI-safe
215-
--> $DIR/lint-ctypes-fn.rs:171:48
216-
|
217-
LL | pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
218-
| ^^^^^^^^^^ not FFI-safe
219-
|
220-
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
221-
= note: this struct has unspecified layout
222-
note: the type is defined here
223-
--> $DIR/lint-ctypes-fn.rs:34:1
224-
|
225-
LL | pub struct Foo;
226-
| ^^^^^^^^^^^^^^^
227-
228172
error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
229-
--> $DIR/lint-ctypes-fn.rs:178:39
173+
--> $DIR/lint-ctypes-fn.rs:174:39
230174
|
231175
LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
232176
| ^^^^^^ not FFI-safe
@@ -235,13 +179,13 @@ LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
235179
= note: this struct has unspecified layout
236180

237181
error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
238-
--> $DIR/lint-ctypes-fn.rs:181:41
182+
--> $DIR/lint-ctypes-fn.rs:177:41
239183
|
240184
LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
241185
| ^^^^^^ not FFI-safe
242186
|
243187
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
244188
= note: this struct has unspecified layout
245189

246-
error: aborting due to 24 previous errors
190+
error: aborting due to 20 previous errors
247191

0 commit comments

Comments
 (0)