Skip to content

Commit 3950c0a

Browse files
committed
ImproperCTypes: change handling of FnPtrs
Notably, those FnPtrs are treated as "the item impacted by the error", instead of the functions/structs making use of them.
1 parent 25322b1 commit 3950c0a

12 files changed

+123
-189
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ lint_improper_ctypes_enum_repr_reason = enum has no representation hint
362362
lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead
363363
364364
lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention
365+
365366
lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
366367
lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
367368

compiler/rustc_lint/src/types/improper_ctypes.rs

Lines changed: 71 additions & 103 deletions
Large diffs are not rendered by default.

tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ type Foo = extern "C" fn(::std::ffi::CStr);
88
//~^ WARN `extern` callback uses type
99
extern "C" {
1010
fn meh(blah: Foo);
11-
//~^ WARN `extern` block uses type
1211
}
1312

1413
fn main() {
Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
11
warning: `extern` callback uses type `CStr`, which is not FFI-safe
2-
--> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:7:12
2+
--> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:7:26
33
|
44
LL | type Foo = extern "C" fn(::std::ffi::CStr);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
5+
| ^^^^^^^^^^^^^^^^ not FFI-safe
66
|
77
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
88
= note: `CStr`/`CString` do not have a guaranteed layout
99
= note: `#[warn(improper_ctypes)]` (part of `#[warn(improper_c_boundaries)]`) on by default
1010

11-
warning: `extern` block uses type `CStr`, which is not FFI-safe
12-
--> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:10:18
13-
|
14-
LL | fn meh(blah: Foo);
15-
| ^^^ not FFI-safe
16-
|
17-
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
18-
= note: `CStr`/`CString` do not have a guaranteed layout
19-
20-
warning: 2 warnings emitted
11+
warning: 1 warning emitted
2112

tests/ui/extern/extern-C-str-arg-ice-80125.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ pub struct Struct(ExternCallback);
77

88
#[no_mangle]
99
pub extern "C" fn register_something(bind: ExternCallback) -> Struct {
10-
//~^ WARN `extern` fn uses type `str`, which is not FFI-safe
11-
//~^^ WARN `extern` fn uses type `Struct`, which is not FFI-safe
10+
//~^ WARN `extern` fn uses type `Struct`, which is not FFI-safe
1211
Struct(bind)
1312
}
1413

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
warning: `extern` callback uses type `str`, which is not FFI-safe
2-
--> $DIR/extern-C-str-arg-ice-80125.rs:3:23
2+
--> $DIR/extern-C-str-arg-ice-80125.rs:3:53
33
|
44
LL | type ExternCallback = extern "C" fn(*const u8, u32, str);
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
5+
| ^^^ not FFI-safe
66
|
77
= help: consider using `*const u8` and a length instead
88
= note: string slices have no C equivalent
99
= note: `#[warn(improper_ctypes)]` (part of `#[warn(improper_c_boundaries)]`) on by default
1010

11-
warning: `extern` fn uses type `str`, which is not FFI-safe
12-
--> $DIR/extern-C-str-arg-ice-80125.rs:9:44
13-
|
14-
LL | pub extern "C" fn register_something(bind: ExternCallback) -> Struct {
15-
| ^^^^^^^^^^^^^^ not FFI-safe
16-
|
17-
= help: consider using `*const u8` and a length instead
18-
= note: string slices have no C equivalent
19-
= note: `#[warn(improper_ctypes_definitions)]` (part of `#[warn(improper_c_boundaries)]`) on by default
20-
2111
warning: `extern` fn uses type `Struct`, which is not FFI-safe
2212
--> $DIR/extern-C-str-arg-ice-80125.rs:9:63
2313
|
@@ -31,6 +21,7 @@ note: the type is defined here
3121
|
3222
LL | pub struct Struct(ExternCallback);
3323
| ^^^^^^^^^^^^^^^^^
24+
= note: `#[warn(improper_ctypes_definitions)]` (part of `#[warn(improper_c_boundaries)]`) on by default
3425

35-
warning: 3 warnings emitted
26+
warning: 2 warnings emitted
3627

tests/ui/lint/extern-C-fnptr-lints-slices.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: `extern` callback uses type `[u8]`, which is not FFI-safe
2-
--> $DIR/extern-C-fnptr-lints-slices.rs:5:14
2+
--> $DIR/extern-C-fnptr-lints-slices.rs:5:28
33
|
44
LL | pub type F = extern "C" fn(&[u8]);
5-
| ^^^^^^^^^^^^^^^^^^^^ not FFI-safe
5+
| ^^^^^ not FFI-safe
66
|
77
= help: consider using a raw pointer instead
88
= note: slices have no C equivalent

tests/ui/lint/improper-ctypes/lint-94223.stderr

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: `extern` callback uses type `[u8]`, which is not FFI-safe
2-
--> $DIR/lint-94223.rs:4:15
2+
--> $DIR/lint-94223.rs:4:29
33
|
44
LL | pub fn bad(f: extern "C" fn([u8])) {}
5-
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
5+
| ^^^^ not FFI-safe
66
|
77
= help: consider using a raw pointer instead
88
= note: slices have no C equivalent
@@ -13,73 +13,73 @@ LL | #![deny(improper_ctypes_definitions, improper_ctypes)]
1313
| ^^^^^^^^^^^^^^^
1414

1515
error: `extern` callback uses type `[u8]`, which is not FFI-safe
16-
--> $DIR/lint-94223.rs:7:28
16+
--> $DIR/lint-94223.rs:7:42
1717
|
1818
LL | pub fn bad_twice(f: Result<extern "C" fn([u8]), extern "C" fn([u8])>) {}
19-
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
19+
| ^^^^ not FFI-safe
2020
|
2121
= help: consider using a raw pointer instead
2222
= note: slices have no C equivalent
2323

2424
error: `extern` callback uses type `[u8]`, which is not FFI-safe
25-
--> $DIR/lint-94223.rs:7:49
25+
--> $DIR/lint-94223.rs:7:63
2626
|
2727
LL | pub fn bad_twice(f: Result<extern "C" fn([u8]), extern "C" fn([u8])>) {}
28-
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
28+
| ^^^^ not FFI-safe
2929
|
3030
= help: consider using a raw pointer instead
3131
= note: slices have no C equivalent
3232

3333
error: `extern` callback uses type `[u8]`, which is not FFI-safe
34-
--> $DIR/lint-94223.rs:11:18
34+
--> $DIR/lint-94223.rs:11:32
3535
|
3636
LL | struct BadStruct(extern "C" fn([u8]));
37-
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
37+
| ^^^^ not FFI-safe
3838
|
3939
= help: consider using a raw pointer instead
4040
= note: slices have no C equivalent
4141

4242
error: `extern` callback uses type `[u8]`, which is not FFI-safe
43-
--> $DIR/lint-94223.rs:15:7
43+
--> $DIR/lint-94223.rs:15:21
4444
|
4545
LL | A(extern "C" fn([u8])),
46-
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
46+
| ^^^^ not FFI-safe
4747
|
4848
= help: consider using a raw pointer instead
4949
= note: slices have no C equivalent
5050

5151
error: `extern` callback uses type `[u8]`, which is not FFI-safe
52-
--> $DIR/lint-94223.rs:20:7
52+
--> $DIR/lint-94223.rs:20:21
5353
|
5454
LL | A(extern "C" fn([u8])),
55-
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
55+
| ^^^^ not FFI-safe
5656
|
5757
= help: consider using a raw pointer instead
5858
= note: slices have no C equivalent
5959

6060
error: `extern` callback uses type `[u8]`, which is not FFI-safe
61-
--> $DIR/lint-94223.rs:24:12
61+
--> $DIR/lint-94223.rs:24:26
6262
|
6363
LL | type Foo = extern "C" fn([u8]);
64-
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
64+
| ^^^^ not FFI-safe
6565
|
6666
= help: consider using a raw pointer instead
6767
= note: slices have no C equivalent
6868

6969
error: `extern` callback uses type `Option<&<T as FooTrait>::FooType>`, which is not FFI-safe
70-
--> $DIR/lint-94223.rs:31:20
70+
--> $DIR/lint-94223.rs:31:34
7171
|
7272
LL | pub type Foo2<T> = extern "C" fn(Option<&<T as FooTrait>::FooType>);
73-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
73+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
7474
|
7575
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
7676
= note: enum has no representation hint
7777

7878
error: `extern` callback uses type `FfiUnsafe`, which is not FFI-safe
79-
--> $DIR/lint-94223.rs:41:17
79+
--> $DIR/lint-94223.rs:41:31
8080
|
8181
LL | pub static BAD: extern "C" fn(FfiUnsafe) = f;
82-
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
82+
| ^^^^^^^^^ not FFI-safe
8383
|
8484
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
8585
= note: this struct has unspecified layout
@@ -90,10 +90,10 @@ LL | pub struct FfiUnsafe;
9090
| ^^^^^^^^^^^^^^^^^^^^
9191

9292
error: `extern` callback uses type `FfiUnsafe`, which is not FFI-safe
93-
--> $DIR/lint-94223.rs:44:30
93+
--> $DIR/lint-94223.rs:44:44
9494
|
9595
LL | pub static BAD_TWICE: Result<extern "C" fn(FfiUnsafe), extern "C" fn(FfiUnsafe)> = Ok(f);
96-
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
96+
| ^^^^^^^^^ not FFI-safe
9797
|
9898
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
9999
= note: this struct has unspecified layout
@@ -104,10 +104,10 @@ LL | pub struct FfiUnsafe;
104104
| ^^^^^^^^^^^^^^^^^^^^
105105

106106
error: `extern` callback uses type `FfiUnsafe`, which is not FFI-safe
107-
--> $DIR/lint-94223.rs:44:56
107+
--> $DIR/lint-94223.rs:44:70
108108
|
109109
LL | pub static BAD_TWICE: Result<extern "C" fn(FfiUnsafe), extern "C" fn(FfiUnsafe)> = Ok(f);
110-
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
110+
| ^^^^^^^^^ not FFI-safe
111111
|
112112
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
113113
= note: this struct has unspecified layout
@@ -118,10 +118,10 @@ LL | pub struct FfiUnsafe;
118118
| ^^^^^^^^^^^^^^^^^^^^
119119

120120
error: `extern` callback uses type `FfiUnsafe`, which is not FFI-safe
121-
--> $DIR/lint-94223.rs:48:22
121+
--> $DIR/lint-94223.rs:48:36
122122
|
123123
LL | pub const BAD_CONST: extern "C" fn(FfiUnsafe) = f;
124-
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
124+
| ^^^^^^^^^ not FFI-safe
125125
|
126126
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
127127
= note: this struct has unspecified layout

tests/ui/lint/improper-ctypes/lint-ctypes.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ extern "C" {
6363
-> ::std::marker::PhantomData<bool>; //~ ERROR uses type `PhantomData<bool>`
6464
pub fn fn_type(p: RustFn); //~ ERROR uses type `fn()`
6565
pub fn fn_type2(p: fn()); //~ ERROR uses type `fn()`
66-
pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `Box<u32>`
66+
pub fn fn_contained(p: RustBadRet);
6767
pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
68-
pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `Box<u32>`
68+
pub fn transparent_fn(p: TransparentBadFn);
6969
pub fn raw_array(arr: [u8; 8]); //~ ERROR: uses type `[u8; 8]`
7070

7171
pub fn no_niche_a(a: Option<UnsafeCell<extern "C" fn()>>);

tests/ui/lint/improper-ctypes/lint-ctypes.stderr

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,6 @@ LL | pub fn fn_type2(p: fn());
155155
= help: consider using an `extern fn(...) -> ...` function pointer instead
156156
= note: this function pointer has Rust-specific calling convention
157157

158-
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
159-
--> $DIR/lint-ctypes.rs:66:28
160-
|
161-
LL | pub fn fn_contained(p: RustBadRet);
162-
| ^^^^^^^^^^ not FFI-safe
163-
|
164-
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
165-
= note: this struct has unspecified layout
166-
167158
error: `extern` block uses type `str`, which is not FFI-safe
168159
--> $DIR/lint-ctypes.rs:67:31
169160
|
@@ -173,15 +164,6 @@ LL | pub fn transparent_str(p: TransparentStr);
173164
= help: consider using `*const u8` and a length instead
174165
= note: string slices have no C equivalent
175166

176-
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
177-
--> $DIR/lint-ctypes.rs:68:30
178-
|
179-
LL | pub fn transparent_fn(p: TransparentBadFn);
180-
| ^^^^^^^^^^^^^^^^ not FFI-safe
181-
|
182-
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
183-
= note: this struct has unspecified layout
184-
185167
error: `extern` block uses type `[u8; 8]`, which is not FFI-safe
186168
--> $DIR/lint-ctypes.rs:69:27
187169
|
@@ -209,5 +191,5 @@ LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
209191
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
210192
= note: enum has no representation hint
211193

212-
error: aborting due to 21 previous errors
194+
error: aborting due to 19 previous errors
213195

0 commit comments

Comments
 (0)