Skip to content

Commit c70b35e

Browse files
committed
Auto merge of #84267 - dtolnay:ptrunit, r=nagisa
Make *const (), *mut () okay for FFI Pointer-to-() is used occasionally in the standard library to mean "pointer to none-of-your-business". Examples: - `RawWakerVTable::new` https://doc.rust-lang.org/1.51.0/std/task/struct.RawWakerVTable.html#method.new - `<*const T>::to_raw_parts` https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.to_raw_parts I believe it's useful for the same purpose in FFI signatures, even while `()` itself is not FFI safe. The following should be allowed: ```rust extern "C" { fn demo(pc: *const (), pm: *mut ()); } ``` Prior to this PR, those pointers were not considered okay for an extern signature. ```console warning: `extern` block uses type `()`, which is not FFI-safe --> src/main.rs:2:17 | 2 | fn demo(pc: *const (), pm: *mut ()); | ^^^^^^^^^ not FFI-safe | = note: `#[warn(improper_ctypes)]` on by default = help: consider using a struct instead = note: tuples have unspecified layout warning: `extern` block uses type `()`, which is not FFI-safe --> src/main.rs:2:32 | 2 | fn demo(pc: *const (), pm: *mut ()); | ^^^^^^^ not FFI-safe | = help: consider using a struct instead = note: tuples have unspecified layout ```
2 parents 2801a77 + abfad74 commit c70b35e

File tree

5 files changed

+69
-45
lines changed

5 files changed

+69
-45
lines changed

compiler/rustc_lint/src/types.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,15 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10561056
FfiSafe
10571057
}
10581058

1059+
ty::RawPtr(ty::TypeAndMut { ty, .. })
1060+
if match ty.kind() {
1061+
ty::Tuple(tuple) => tuple.is_empty(),
1062+
_ => false,
1063+
} =>
1064+
{
1065+
FfiSafe
1066+
}
1067+
10591068
ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => {
10601069
self.check_type_for_ffi(cache, ty)
10611070
}

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

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ pub extern "C" fn ptr_type1(size: *const Foo) { }
6666

6767
pub extern "C" fn ptr_type2(size: *const Foo) { }
6868

69+
pub extern "C" fn ptr_unit(p: *const ()) { }
70+
71+
pub extern "C" fn ptr_tuple(p: *const ((),)) { }
72+
6973
pub extern "C" fn slice_type(p: &[u32]) { }
7074
//~^ ERROR: uses type `[u32]`
7175

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

+20-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:69:33
2+
--> $DIR/lint-ctypes-fn.rs:73:33
33
|
44
LL | pub extern "C" fn slice_type(p: &[u32]) { }
55
| ^^^^^^ not FFI-safe
@@ -13,7 +13,7 @@ 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:72:31
16+
--> $DIR/lint-ctypes-fn.rs:76:31
1717
|
1818
LL | pub extern "C" fn str_type(p: &str) { }
1919
| ^^^^ not FFI-safe
@@ -22,31 +22,31 @@ LL | pub extern "C" fn str_type(p: &str) { }
2222
= note: string slices have no C equivalent
2323

2424
error: `extern` fn uses type `Box<[u8]>`, which is not FFI-safe
25-
--> $DIR/lint-ctypes-fn.rs:79:34
25+
--> $DIR/lint-ctypes-fn.rs:83:34
2626
|
2727
LL | pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
2828
| ^^^^^^^^^ not FFI-safe
2929
|
3030
= note: box cannot be represented as a single pointer
3131

3232
error: `extern` fn uses type `Box<str>`, which is not FFI-safe
33-
--> $DIR/lint-ctypes-fn.rs:82:35
33+
--> $DIR/lint-ctypes-fn.rs:86:35
3434
|
3535
LL | pub extern "C" fn boxed_string(p: Box<str>) { }
3636
| ^^^^^^^^ not FFI-safe
3737
|
3838
= note: box cannot be represented as a single pointer
3939

4040
error: `extern` fn uses type `Box<dyn Trait>`, which is not FFI-safe
41-
--> $DIR/lint-ctypes-fn.rs:85:34
41+
--> $DIR/lint-ctypes-fn.rs:89:34
4242
|
4343
LL | pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
4444
| ^^^^^^^^^^^^^^ not FFI-safe
4545
|
4646
= note: box cannot be represented as a single pointer
4747

4848
error: `extern` fn uses type `char`, which is not FFI-safe
49-
--> $DIR/lint-ctypes-fn.rs:88:32
49+
--> $DIR/lint-ctypes-fn.rs:92:32
5050
|
5151
LL | pub extern "C" fn char_type(p: char) { }
5252
| ^^^^ not FFI-safe
@@ -55,23 +55,23 @@ LL | pub extern "C" fn char_type(p: char) { }
5555
= note: the `char` type has no C equivalent
5656

5757
error: `extern` fn uses type `i128`, which is not FFI-safe
58-
--> $DIR/lint-ctypes-fn.rs:91:32
58+
--> $DIR/lint-ctypes-fn.rs:95:32
5959
|
6060
LL | pub extern "C" fn i128_type(p: i128) { }
6161
| ^^^^ not FFI-safe
6262
|
6363
= note: 128-bit integers don't currently have a known stable ABI
6464

6565
error: `extern` fn uses type `u128`, which is not FFI-safe
66-
--> $DIR/lint-ctypes-fn.rs:94:32
66+
--> $DIR/lint-ctypes-fn.rs:98:32
6767
|
6868
LL | pub extern "C" fn u128_type(p: u128) { }
6969
| ^^^^ not FFI-safe
7070
|
7171
= note: 128-bit integers don't currently have a known stable ABI
7272

7373
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
74-
--> $DIR/lint-ctypes-fn.rs:97:33
74+
--> $DIR/lint-ctypes-fn.rs:101:33
7575
|
7676
LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
7777
| ^^^^^^^^^^ not FFI-safe
@@ -80,7 +80,7 @@ LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
8080
= note: tuples have unspecified layout
8181

8282
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
83-
--> $DIR/lint-ctypes-fn.rs:100:34
83+
--> $DIR/lint-ctypes-fn.rs:104:34
8484
|
8585
LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
8686
| ^^^^^^^ not FFI-safe
@@ -89,7 +89,7 @@ LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
8989
= note: tuples have unspecified layout
9090

9191
error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
92-
--> $DIR/lint-ctypes-fn.rs:103:32
92+
--> $DIR/lint-ctypes-fn.rs:107:32
9393
|
9494
LL | pub extern "C" fn zero_size(p: ZeroSize) { }
9595
| ^^^^^^^^ not FFI-safe
@@ -103,7 +103,7 @@ LL | pub struct ZeroSize;
103103
| ^^^^^^^^^^^^^^^^^^^^
104104

105105
error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
106-
--> $DIR/lint-ctypes-fn.rs:106:40
106+
--> $DIR/lint-ctypes-fn.rs:110:40
107107
|
108108
LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
109109
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -116,15 +116,15 @@ LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
116116
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
117117

118118
error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
119-
--> $DIR/lint-ctypes-fn.rs:109:51
119+
--> $DIR/lint-ctypes-fn.rs:113:51
120120
|
121121
LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
122122
| ^^^^^^^^^^^^^^^^^ not FFI-safe
123123
|
124124
= note: composed only of `PhantomData`
125125

126126
error: `extern` fn uses type `fn()`, which is not FFI-safe
127-
--> $DIR/lint-ctypes-fn.rs:114:30
127+
--> $DIR/lint-ctypes-fn.rs:118:30
128128
|
129129
LL | pub extern "C" fn fn_type(p: RustFn) { }
130130
| ^^^^^^ not FFI-safe
@@ -133,7 +133,7 @@ LL | pub extern "C" fn fn_type(p: RustFn) { }
133133
= note: this function pointer has Rust-specific calling convention
134134

135135
error: `extern` fn uses type `fn()`, which is not FFI-safe
136-
--> $DIR/lint-ctypes-fn.rs:117:31
136+
--> $DIR/lint-ctypes-fn.rs:121:31
137137
|
138138
LL | pub extern "C" fn fn_type2(p: fn()) { }
139139
| ^^^^ not FFI-safe
@@ -142,15 +142,15 @@ LL | pub extern "C" fn fn_type2(p: fn()) { }
142142
= note: this function pointer has Rust-specific calling convention
143143

144144
error: `extern` fn uses type `i128`, which is not FFI-safe
145-
--> $DIR/lint-ctypes-fn.rs:122:39
145+
--> $DIR/lint-ctypes-fn.rs:126:39
146146
|
147147
LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
148148
| ^^^^^^^^^^^^^^^ not FFI-safe
149149
|
150150
= note: 128-bit integers don't currently have a known stable ABI
151151

152152
error: `extern` fn uses type `str`, which is not FFI-safe
153-
--> $DIR/lint-ctypes-fn.rs:125:38
153+
--> $DIR/lint-ctypes-fn.rs:129:38
154154
|
155155
LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
156156
| ^^^^^^^^^^^^^^ not FFI-safe
@@ -159,15 +159,15 @@ LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
159159
= note: string slices have no C equivalent
160160

161161
error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
162-
--> $DIR/lint-ctypes-fn.rs:171:43
162+
--> $DIR/lint-ctypes-fn.rs:175:43
163163
|
164164
LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
165165
| ^^^^^^^^^^^^^^^^^ not FFI-safe
166166
|
167167
= note: composed only of `PhantomData`
168168

169169
error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
170-
--> $DIR/lint-ctypes-fn.rs:184:39
170+
--> $DIR/lint-ctypes-fn.rs:188:39
171171
|
172172
LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
173173
| ^^^^^^ not FFI-safe
@@ -176,7 +176,7 @@ LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
176176
= note: this struct has unspecified layout
177177

178178
error: `extern` fn uses type `Vec<T>`, which is not FFI-safe
179-
--> $DIR/lint-ctypes-fn.rs:187:41
179+
--> $DIR/lint-ctypes-fn.rs:191:41
180180
|
181181
LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
182182
| ^^^^^^ not FFI-safe

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

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
4747
extern "C" {
4848
pub fn ptr_type1(size: *const Foo); //~ ERROR: uses type `Foo`
4949
pub fn ptr_type2(size: *const Foo); //~ ERROR: uses type `Foo`
50+
pub fn ptr_unit(p: *const ());
51+
pub fn ptr_tuple(p: *const ((),)); //~ ERROR: uses type `((),)`
5052
pub fn slice_type(p: &[u32]); //~ ERROR: uses type `[u32]`
5153
pub fn str_type(p: &str); //~ ERROR: uses type `str`
5254
pub fn box_type(p: Box<u32>); //~ ERROR uses type `Box<u32>`

0 commit comments

Comments
 (0)