Skip to content

Commit cb60654

Browse files
committed
improper ctypes: adjust lint msg for extern fns
Signed-off-by: David Wood <[email protected]>
1 parent 0128f8e commit cb60654

File tree

2 files changed

+49
-36
lines changed

2 files changed

+49
-36
lines changed

src/librustc_lint/types.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -891,11 +891,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
891891
sp: Span,
892892
note: &str,
893893
help: Option<&str>,
894+
is_foreign_item: bool,
894895
) {
895896
let mut diag = self.cx.struct_span_lint(
896897
IMPROPER_CTYPES,
897898
sp,
898-
&format!("`extern` block uses type `{}`, which is not FFI-safe", ty),
899+
&format!(
900+
"`extern` {} uses type `{}`, which is not FFI-safe",
901+
if is_foreign_item { "block" } else { "fn" },
902+
ty,
903+
),
899904
);
900905
diag.span_label(sp, "not FFI-safe");
901906
if let Some(help) = help {
@@ -910,7 +915,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
910915
diag.emit();
911916
}
912917

913-
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
918+
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>, is_foreign_item: bool) -> bool {
914919
struct ProhibitOpaqueTypes<'tcx> {
915920
ty: Option<Ty<'tcx>>,
916921
};
@@ -934,17 +939,23 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
934939
sp,
935940
"opaque types have no C equivalent",
936941
None,
942+
is_foreign_item,
937943
);
938944
true
939945
} else {
940946
false
941947
}
942948
}
943949

944-
fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
950+
fn check_type_for_ffi_and_report_errors(
951+
&mut self,
952+
sp: Span,
953+
ty: Ty<'tcx>,
954+
is_foreign_item: bool,
955+
) {
945956
// We have to check for opaque types before `normalize_erasing_regions`,
946957
// which will replace opaque types with their underlying concrete type.
947-
if self.check_for_opaque_ty(sp, ty) {
958+
if self.check_for_opaque_ty(sp, ty, is_foreign_item) {
948959
// We've already emitted an error due to an opaque type.
949960
return;
950961
}
@@ -953,35 +964,37 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
953964
match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
954965
FfiResult::FfiSafe => {}
955966
FfiResult::FfiPhantom(ty) => {
956-
self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
967+
self.emit_ffi_unsafe_type_lint(
968+
ty, sp, "composed only of `PhantomData`", None, is_foreign_item);
957969
}
958970
FfiResult::FfiUnsafe { ty, reason, help } => {
959-
self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
971+
self.emit_ffi_unsafe_type_lint(
972+
ty, sp, reason, help, is_foreign_item);
960973
}
961974
}
962975
}
963976

964-
fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) {
977+
fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl, is_foreign_item: bool) {
965978
let def_id = self.cx.tcx.hir().local_def_id(id);
966979
let sig = self.cx.tcx.fn_sig(def_id);
967980
let sig = self.cx.tcx.erase_late_bound_regions(&sig);
968981

969982
for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
970-
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty);
983+
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, is_foreign_item);
971984
}
972985

973986
if let hir::Return(ref ret_hir) = decl.output {
974987
let ret_ty = sig.output();
975988
if !ret_ty.is_unit() {
976-
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
989+
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, is_foreign_item);
977990
}
978991
}
979992
}
980993

981994
fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
982995
let def_id = self.cx.tcx.hir().local_def_id(id);
983996
let ty = self.cx.tcx.type_of(def_id);
984-
self.check_type_for_ffi_and_report_errors(span, ty);
997+
self.check_type_for_ffi_and_report_errors(span, ty, true);
985998
}
986999

9871000
fn is_internal_abi(&self, abi: Abi) -> bool {
@@ -1000,7 +1013,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
10001013
if !vis.is_internal_abi(abi) {
10011014
match it.kind {
10021015
hir::ForeignItemKind::Fn(ref decl, _, _) => {
1003-
vis.check_foreign_fn(it.hir_id, decl);
1016+
vis.check_foreign_fn(it.hir_id, decl, true);
10041017
}
10051018
hir::ForeignItemKind::Static(ref ty, _) => {
10061019
vis.check_foreign_static(it.hir_id, ty.span);
@@ -1029,7 +1042,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
10291042

10301043
let mut vis = ImproperCTypesVisitor { cx };
10311044
if !vis.is_internal_abi(abi) {
1032-
vis.check_foreign_fn(hir_id, decl);
1045+
vis.check_foreign_fn(hir_id, decl, false);
10331046
}
10341047
}
10351048
}

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

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: `extern` block uses type `Foo`, which is not FFI-safe
1+
error: `extern` fn uses type `Foo`, which is not FFI-safe
22
--> $DIR/lint-ctypes-fn.rs:63:35
33
|
44
LL | pub extern "C" fn ptr_type1(size: *const Foo) { }
@@ -17,7 +17,7 @@ note: type defined here
1717
LL | pub struct Foo;
1818
| ^^^^^^^^^^^^^^^
1919

20-
error: `extern` block uses type `Foo`, which is not FFI-safe
20+
error: `extern` fn uses type `Foo`, which is not FFI-safe
2121
--> $DIR/lint-ctypes-fn.rs:66:35
2222
|
2323
LL | pub extern "C" fn ptr_type2(size: *const Foo) { }
@@ -31,7 +31,7 @@ note: type defined here
3131
LL | pub struct Foo;
3232
| ^^^^^^^^^^^^^^^
3333

34-
error: `extern` block uses type `[u32]`, which is not FFI-safe
34+
error: `extern` fn uses type `[u32]`, which is not FFI-safe
3535
--> $DIR/lint-ctypes-fn.rs:69:33
3636
|
3737
LL | pub extern "C" fn slice_type(p: &[u32]) { }
@@ -40,7 +40,7 @@ LL | pub extern "C" fn slice_type(p: &[u32]) { }
4040
= help: consider using a raw pointer instead
4141
= note: slices have no C equivalent
4242

43-
error: `extern` block uses type `str`, which is not FFI-safe
43+
error: `extern` fn uses type `str`, which is not FFI-safe
4444
--> $DIR/lint-ctypes-fn.rs:72:31
4545
|
4646
LL | pub extern "C" fn str_type(p: &str) { }
@@ -49,7 +49,7 @@ LL | pub extern "C" fn str_type(p: &str) { }
4949
= help: consider using `*const u8` and a length instead
5050
= note: string slices have no C equivalent
5151

52-
error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
52+
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
5353
--> $DIR/lint-ctypes-fn.rs:75:31
5454
|
5555
LL | pub extern "C" fn box_type(p: Box<u32>) { }
@@ -58,7 +58,7 @@ LL | pub extern "C" fn box_type(p: Box<u32>) { }
5858
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
5959
= note: this struct has unspecified layout
6060

61-
error: `extern` block uses type `char`, which is not FFI-safe
61+
error: `extern` fn uses type `char`, which is not FFI-safe
6262
--> $DIR/lint-ctypes-fn.rs:78:32
6363
|
6464
LL | pub extern "C" fn char_type(p: char) { }
@@ -67,23 +67,23 @@ LL | pub extern "C" fn char_type(p: char) { }
6767
= help: consider using `u32` or `libc::wchar_t` instead
6868
= note: the `char` type has no C equivalent
6969

70-
error: `extern` block uses type `i128`, which is not FFI-safe
70+
error: `extern` fn uses type `i128`, which is not FFI-safe
7171
--> $DIR/lint-ctypes-fn.rs:81:32
7272
|
7373
LL | pub extern "C" fn i128_type(p: i128) { }
7474
| ^^^^ not FFI-safe
7575
|
7676
= note: 128-bit integers don't currently have a known stable ABI
7777

78-
error: `extern` block uses type `u128`, which is not FFI-safe
78+
error: `extern` fn uses type `u128`, which is not FFI-safe
7979
--> $DIR/lint-ctypes-fn.rs:84:32
8080
|
8181
LL | pub extern "C" fn u128_type(p: u128) { }
8282
| ^^^^ not FFI-safe
8383
|
8484
= note: 128-bit integers don't currently have a known stable ABI
8585

86-
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
86+
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
8787
--> $DIR/lint-ctypes-fn.rs:87:33
8888
|
8989
LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
@@ -92,7 +92,7 @@ LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
9292
= help: consider using a struct instead
9393
= note: tuples have unspecified layout
9494

95-
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
95+
error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
9696
--> $DIR/lint-ctypes-fn.rs:90:34
9797
|
9898
LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
@@ -101,7 +101,7 @@ LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
101101
= help: consider using a struct instead
102102
= note: tuples have unspecified layout
103103

104-
error: `extern` block uses type `ZeroSize`, which is not FFI-safe
104+
error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
105105
--> $DIR/lint-ctypes-fn.rs:93:32
106106
|
107107
LL | pub extern "C" fn zero_size(p: ZeroSize) { }
@@ -115,7 +115,7 @@ note: type defined here
115115
LL | pub struct ZeroSize;
116116
| ^^^^^^^^^^^^^^^^^^^^
117117

118-
error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
118+
error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
119119
--> $DIR/lint-ctypes-fn.rs:96:40
120120
|
121121
LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
@@ -128,15 +128,15 @@ note: type defined here
128128
LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
129129
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
130130

131-
error: `extern` block uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
131+
error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
132132
--> $DIR/lint-ctypes-fn.rs:99:51
133133
|
134134
LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
135135
| ^^^^^^^^^^^^^^^^^ not FFI-safe
136136
|
137137
= note: composed only of `PhantomData`
138138

139-
error: `extern` block uses type `fn()`, which is not FFI-safe
139+
error: `extern` fn uses type `fn()`, which is not FFI-safe
140140
--> $DIR/lint-ctypes-fn.rs:104:30
141141
|
142142
LL | pub extern "C" fn fn_type(p: RustFn) { }
@@ -145,7 +145,7 @@ LL | pub extern "C" fn fn_type(p: RustFn) { }
145145
= help: consider using an `extern fn(...) -> ...` function pointer instead
146146
= note: this function pointer has Rust-specific calling convention
147147

148-
error: `extern` block uses type `fn()`, which is not FFI-safe
148+
error: `extern` fn uses type `fn()`, which is not FFI-safe
149149
--> $DIR/lint-ctypes-fn.rs:107:31
150150
|
151151
LL | pub extern "C" fn fn_type2(p: fn()) { }
@@ -154,7 +154,7 @@ LL | pub extern "C" fn fn_type2(p: fn()) { }
154154
= help: consider using an `extern fn(...) -> ...` function pointer instead
155155
= note: this function pointer has Rust-specific calling convention
156156

157-
error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
157+
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
158158
--> $DIR/lint-ctypes-fn.rs:110:35
159159
|
160160
LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
@@ -163,15 +163,15 @@ LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
163163
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
164164
= note: this struct has unspecified layout
165165

166-
error: `extern` block uses type `i128`, which is not FFI-safe
166+
error: `extern` fn uses type `i128`, which is not FFI-safe
167167
--> $DIR/lint-ctypes-fn.rs:113:39
168168
|
169169
LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
170170
| ^^^^^^^^^^^^^^^ not FFI-safe
171171
|
172172
= note: 128-bit integers don't currently have a known stable ABI
173173

174-
error: `extern` block uses type `str`, which is not FFI-safe
174+
error: `extern` fn uses type `str`, which is not FFI-safe
175175
--> $DIR/lint-ctypes-fn.rs:116:38
176176
|
177177
LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
@@ -180,7 +180,7 @@ LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
180180
= help: consider using `*const u8` and a length instead
181181
= note: string slices have no C equivalent
182182

183-
error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
183+
error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
184184
--> $DIR/lint-ctypes-fn.rs:119:37
185185
|
186186
LL | pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
@@ -189,7 +189,7 @@ LL | pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
189189
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
190190
= note: this struct has unspecified layout
191191

192-
error: `extern` block uses type `Foo`, which is not FFI-safe
192+
error: `extern` fn uses type `Foo`, which is not FFI-safe
193193
--> $DIR/lint-ctypes-fn.rs:161:44
194194
|
195195
LL | pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
@@ -203,15 +203,15 @@ note: type defined here
203203
LL | pub struct Foo;
204204
| ^^^^^^^^^^^^^^^
205205

206-
error: `extern` block uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
206+
error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
207207
--> $DIR/lint-ctypes-fn.rs:164:43
208208
|
209209
LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
210210
| ^^^^^^^^^^^^^^^^^ not FFI-safe
211211
|
212212
= note: composed only of `PhantomData`
213213

214-
error: `extern` block uses type `Foo`, which is not FFI-safe
214+
error: `extern` fn uses type `Foo`, which is not FFI-safe
215215
--> $DIR/lint-ctypes-fn.rs:171:48
216216
|
217217
LL | pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
@@ -225,7 +225,7 @@ note: type defined here
225225
LL | pub struct Foo;
226226
| ^^^^^^^^^^^^^^^
227227

228-
error: `extern` block uses type `std::vec::Vec<T>`, which is not FFI-safe
228+
error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
229229
--> $DIR/lint-ctypes-fn.rs:178:39
230230
|
231231
LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
@@ -234,7 +234,7 @@ LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
234234
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
235235
= note: this struct has unspecified layout
236236

237-
error: `extern` block uses type `std::vec::Vec<T>`, which is not FFI-safe
237+
error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
238238
--> $DIR/lint-ctypes-fn.rs:181:41
239239
|
240240
LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {

0 commit comments

Comments
 (0)