Skip to content

Commit 877cfb1

Browse files
committed
Warn against boxed DST in improper_ctypes_definitions lint
1 parent 2577825 commit 877cfb1

File tree

3 files changed

+66
-24
lines changed

3 files changed

+66
-24
lines changed

compiler/rustc_lint/src/types.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -909,11 +909,18 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
909909
}
910910

911911
match *ty.kind() {
912-
ty::Adt(def, _) if def.is_box() && matches!(self.mode, CItemKind::Definition) => {
913-
FfiSafe
914-
}
915-
916912
ty::Adt(def, substs) => {
913+
if def.is_box() && matches!(self.mode, CItemKind::Definition) {
914+
if ty.boxed_ty().is_sized(tcx.at(DUMMY_SP), self.cx.param_env) {
915+
return FfiSafe;
916+
} else {
917+
return FfiUnsafe {
918+
ty,
919+
reason: format!("box cannot be represented as a single pointer"),
920+
help: None,
921+
};
922+
}
923+
}
917924
if def.is_phantom_data() {
918925
return FfiPhantom(ty);
919926
}

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

+11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ extern crate libc;
88
use std::default::Default;
99
use std::marker::PhantomData;
1010

11+
trait Trait {}
12+
1113
trait Mirror { type It: ?Sized; }
1214

1315
impl<T: ?Sized> Mirror for T { type It = Self; }
@@ -74,6 +76,15 @@ pub extern "C" fn box_type(p: Box<u32>) { }
7476

7577
pub extern "C" fn opt_box_type(p: Option<Box<u32>>) { }
7678

79+
pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
80+
//~^ ERROR: uses type `Box<[u8]>`
81+
82+
pub extern "C" fn boxed_string(p: Box<str>) { }
83+
//~^ ERROR: uses type `Box<str>`
84+
85+
pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
86+
//~^ ERROR: uses type `Box<dyn Trait>`
87+
7788
pub extern "C" fn char_type(p: char) { }
7889
//~^ ERROR uses type `char`
7990

+44-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: `extern` fn uses type `[u32]`, which is not FFI-safe
2-
--> $DIR/lint-ctypes-fn.rs:67:33
2+
--> $DIR/lint-ctypes-fn.rs:69:33
33
|
44
LL | pub extern "C" fn slice_type(p: &[u32]) { }
55
| ^^^^^^ not FFI-safe
@@ -13,16 +13,40 @@ LL | #![deny(improper_ctypes_definitions)]
1313
= note: slices have no C equivalent
1414

1515
error: `extern` fn uses type `str`, which is not FFI-safe
16-
--> $DIR/lint-ctypes-fn.rs:70:31
16+
--> $DIR/lint-ctypes-fn.rs:72:31
1717
|
1818
LL | pub extern "C" fn str_type(p: &str) { }
1919
| ^^^^ not FFI-safe
2020
|
2121
= help: consider using `*const u8` and a length instead
2222
= note: string slices have no C equivalent
2323

24+
error: `extern` fn uses type `Box<[u8]>`, which is not FFI-safe
25+
--> $DIR/lint-ctypes-fn.rs:79:34
26+
|
27+
LL | pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
28+
| ^^^^^^^^^ not FFI-safe
29+
|
30+
= note: box cannot be represented as a single pointer
31+
32+
error: `extern` fn uses type `Box<str>`, which is not FFI-safe
33+
--> $DIR/lint-ctypes-fn.rs:82:35
34+
|
35+
LL | pub extern "C" fn boxed_string(p: Box<str>) { }
36+
| ^^^^^^^^ not FFI-safe
37+
|
38+
= note: box cannot be represented as a single pointer
39+
40+
error: `extern` fn uses type `Box<dyn Trait>`, which is not FFI-safe
41+
--> $DIR/lint-ctypes-fn.rs:85:34
42+
|
43+
LL | pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
44+
| ^^^^^^^^^^^^^^ not FFI-safe
45+
|
46+
= note: box cannot be represented as a single pointer
47+
2448
error: `extern` fn uses type `char`, which is not FFI-safe
25-
--> $DIR/lint-ctypes-fn.rs:77:32
49+
--> $DIR/lint-ctypes-fn.rs:88:32
2650
|
2751
LL | pub extern "C" fn char_type(p: char) { }
2852
| ^^^^ not FFI-safe
@@ -31,23 +55,23 @@ LL | pub extern "C" fn char_type(p: char) { }
3155
= note: the `char` type has no C equivalent
3256

3357
error: `extern` fn uses type `i128`, which is not FFI-safe
34-
--> $DIR/lint-ctypes-fn.rs:80:32
58+
--> $DIR/lint-ctypes-fn.rs:91:32
3559
|
3660
LL | pub extern "C" fn i128_type(p: i128) { }
3761
| ^^^^ not FFI-safe
3862
|
3963
= note: 128-bit integers don't currently have a known stable ABI
4064

4165
error: `extern` fn uses type `u128`, which is not FFI-safe
42-
--> $DIR/lint-ctypes-fn.rs:83:32
66+
--> $DIR/lint-ctypes-fn.rs:94:32
4367
|
4468
LL | pub extern "C" fn u128_type(p: u128) { }
4569
| ^^^^ not FFI-safe
4670
|
4771
= note: 128-bit integers don't currently have a known stable ABI
4872

4973
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
50-
--> $DIR/lint-ctypes-fn.rs:86:33
74+
--> $DIR/lint-ctypes-fn.rs:97:33
5175
|
5276
LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
5377
| ^^^^^^^^^^ not FFI-safe
@@ -56,7 +80,7 @@ LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
5680
= note: tuples have unspecified layout
5781

5882
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
59-
--> $DIR/lint-ctypes-fn.rs:89:34
83+
--> $DIR/lint-ctypes-fn.rs:100:34
6084
|
6185
LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
6286
| ^^^^^^^ not FFI-safe
@@ -65,42 +89,42 @@ LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
6589
= note: tuples have unspecified layout
6690

6791
error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
68-
--> $DIR/lint-ctypes-fn.rs:92:32
92+
--> $DIR/lint-ctypes-fn.rs:103:32
6993
|
7094
LL | pub extern "C" fn zero_size(p: ZeroSize) { }
7195
| ^^^^^^^^ not FFI-safe
7296
|
7397
= help: consider adding a member to this struct
7498
= note: this struct has no fields
7599
note: the type is defined here
76-
--> $DIR/lint-ctypes-fn.rs:26:1
100+
--> $DIR/lint-ctypes-fn.rs:28:1
77101
|
78102
LL | pub struct ZeroSize;
79103
| ^^^^^^^^^^^^^^^^^^^^
80104

81105
error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
82-
--> $DIR/lint-ctypes-fn.rs:95:40
106+
--> $DIR/lint-ctypes-fn.rs:106:40
83107
|
84108
LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
85109
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
86110
|
87111
= note: composed only of `PhantomData`
88112
note: the type is defined here
89-
--> $DIR/lint-ctypes-fn.rs:61:1
113+
--> $DIR/lint-ctypes-fn.rs:63:1
90114
|
91115
LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
92116
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
93117

94118
error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
95-
--> $DIR/lint-ctypes-fn.rs:98:51
119+
--> $DIR/lint-ctypes-fn.rs:109:51
96120
|
97121
LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
98122
| ^^^^^^^^^^^^^^^^^ not FFI-safe
99123
|
100124
= note: composed only of `PhantomData`
101125

102126
error: `extern` fn uses type `fn()`, which is not FFI-safe
103-
--> $DIR/lint-ctypes-fn.rs:103:30
127+
--> $DIR/lint-ctypes-fn.rs:114:30
104128
|
105129
LL | pub extern "C" fn fn_type(p: RustFn) { }
106130
| ^^^^^^ not FFI-safe
@@ -109,7 +133,7 @@ LL | pub extern "C" fn fn_type(p: RustFn) { }
109133
= note: this function pointer has Rust-specific calling convention
110134

111135
error: `extern` fn uses type `fn()`, which is not FFI-safe
112-
--> $DIR/lint-ctypes-fn.rs:106:31
136+
--> $DIR/lint-ctypes-fn.rs:117:31
113137
|
114138
LL | pub extern "C" fn fn_type2(p: fn()) { }
115139
| ^^^^ not FFI-safe
@@ -118,15 +142,15 @@ LL | pub extern "C" fn fn_type2(p: fn()) { }
118142
= note: this function pointer has Rust-specific calling convention
119143

120144
error: `extern` fn uses type `i128`, which is not FFI-safe
121-
--> $DIR/lint-ctypes-fn.rs:111:39
145+
--> $DIR/lint-ctypes-fn.rs:122:39
122146
|
123147
LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
124148
| ^^^^^^^^^^^^^^^ not FFI-safe
125149
|
126150
= note: 128-bit integers don't currently have a known stable ABI
127151

128152
error: `extern` fn uses type `str`, which is not FFI-safe
129-
--> $DIR/lint-ctypes-fn.rs:114:38
153+
--> $DIR/lint-ctypes-fn.rs:125:38
130154
|
131155
LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
132156
| ^^^^^^^^^^^^^^ not FFI-safe
@@ -135,15 +159,15 @@ LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
135159
= note: string slices have no C equivalent
136160

137161
error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
138-
--> $DIR/lint-ctypes-fn.rs:160:43
162+
--> $DIR/lint-ctypes-fn.rs:171:43
139163
|
140164
LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
141165
| ^^^^^^^^^^^^^^^^^ not FFI-safe
142166
|
143167
= note: composed only of `PhantomData`
144168

145169
error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
146-
--> $DIR/lint-ctypes-fn.rs:173:39
170+
--> $DIR/lint-ctypes-fn.rs:184:39
147171
|
148172
LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
149173
| ^^^^^^ not FFI-safe
@@ -152,13 +176,13 @@ LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
152176
= note: this struct has unspecified layout
153177

154178
error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
155-
--> $DIR/lint-ctypes-fn.rs:176:41
179+
--> $DIR/lint-ctypes-fn.rs:187:41
156180
|
157181
LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
158182
| ^^^^^^ not FFI-safe
159183
|
160184
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
161185
= note: this struct has unspecified layout
162186

163-
error: aborting due to 17 previous errors
187+
error: aborting due to 20 previous errors
164188

0 commit comments

Comments
 (0)