about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2019-10-27 14:05:38 +0000
committerDavid Wood <david@davidtw.co>2019-11-05 12:44:09 +0000
commitcb60654f78468a76e55836aae97b71ceb19f2284 (patch)
tree56fbd6781215194ed211acd076386aa95d0486ed
parent0128f8ee11c31c905205ff6019dcd240b6331d84 (diff)
improper ctypes: adjust lint msg for extern fns
Signed-off-by: David Wood <david@davidtw.co>
-rw-r--r--src/librustc_lint/types.rs37
-rw-r--r--src/test/ui/lint/lint-ctypes-fn.stderr48
2 files changed, 49 insertions, 36 deletions
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index cea57fc6293..f2ad400d5dd 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -891,11 +891,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         sp: Span,
         note: &str,
         help: Option<&str>,
+        is_foreign_item: bool,
     ) {
         let mut diag = self.cx.struct_span_lint(
             IMPROPER_CTYPES,
             sp,
-            &format!("`extern` block uses type `{}`, which is not FFI-safe", ty),
+            &format!(
+                "`extern` {} uses type `{}`, which is not FFI-safe",
+                if is_foreign_item { "block" } else { "fn" },
+                ty,
+            ),
         );
         diag.span_label(sp, "not FFI-safe");
         if let Some(help) = help {
@@ -910,7 +915,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         diag.emit();
     }
 
-    fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
+    fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>, is_foreign_item: bool) -> bool {
         struct ProhibitOpaqueTypes<'tcx> {
             ty: Option<Ty<'tcx>>,
         };
@@ -934,6 +939,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                 sp,
                 "opaque types have no C equivalent",
                 None,
+                is_foreign_item,
             );
             true
         } else {
@@ -941,10 +947,15 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         }
     }
 
-    fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
+    fn check_type_for_ffi_and_report_errors(
+        &mut self,
+        sp: Span,
+        ty: Ty<'tcx>,
+        is_foreign_item: bool,
+    ) {
         // We have to check for opaque types before `normalize_erasing_regions`,
         // which will replace opaque types with their underlying concrete type.
-        if self.check_for_opaque_ty(sp, ty) {
+        if self.check_for_opaque_ty(sp, ty, is_foreign_item) {
             // We've already emitted an error due to an opaque type.
             return;
         }
@@ -953,27 +964,29 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
             FfiResult::FfiSafe => {}
             FfiResult::FfiPhantom(ty) => {
-                self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
+                self.emit_ffi_unsafe_type_lint(
+                    ty, sp, "composed only of `PhantomData`", None, is_foreign_item);
             }
             FfiResult::FfiUnsafe { ty, reason, help } => {
-                self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
+                self.emit_ffi_unsafe_type_lint(
+                    ty, sp, reason, help, is_foreign_item);
             }
         }
     }
 
-    fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) {
+    fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl, is_foreign_item: bool) {
         let def_id = self.cx.tcx.hir().local_def_id(id);
         let sig = self.cx.tcx.fn_sig(def_id);
         let sig = self.cx.tcx.erase_late_bound_regions(&sig);
 
         for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
-            self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty);
+            self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, is_foreign_item);
         }
 
         if let hir::Return(ref ret_hir) = decl.output {
             let ret_ty = sig.output();
             if !ret_ty.is_unit() {
-                self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
+                self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, is_foreign_item);
             }
         }
     }
@@ -981,7 +994,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
         let def_id = self.cx.tcx.hir().local_def_id(id);
         let ty = self.cx.tcx.type_of(def_id);
-        self.check_type_for_ffi_and_report_errors(span, ty);
+        self.check_type_for_ffi_and_report_errors(span, ty, true);
     }
 
     fn is_internal_abi(&self, abi: Abi) -> bool {
@@ -1000,7 +1013,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
         if !vis.is_internal_abi(abi) {
             match it.kind {
                 hir::ForeignItemKind::Fn(ref decl, _, _) => {
-                    vis.check_foreign_fn(it.hir_id, decl);
+                    vis.check_foreign_fn(it.hir_id, decl, true);
                 }
                 hir::ForeignItemKind::Static(ref ty, _) => {
                     vis.check_foreign_static(it.hir_id, ty.span);
@@ -1029,7 +1042,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
 
         let mut vis = ImproperCTypesVisitor { cx };
         if !vis.is_internal_abi(abi) {
-            vis.check_foreign_fn(hir_id, decl);
+            vis.check_foreign_fn(hir_id, decl, false);
         }
     }
 }
diff --git a/src/test/ui/lint/lint-ctypes-fn.stderr b/src/test/ui/lint/lint-ctypes-fn.stderr
index c0ce1a1cfb9..59bd6bfc5af 100644
--- a/src/test/ui/lint/lint-ctypes-fn.stderr
+++ b/src/test/ui/lint/lint-ctypes-fn.stderr
@@ -1,4 +1,4 @@
-error: `extern` block uses type `Foo`, which is not FFI-safe
+error: `extern` fn uses type `Foo`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:63:35
    |
 LL | pub extern "C" fn ptr_type1(size: *const Foo) { }
@@ -17,7 +17,7 @@ note: type defined here
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `Foo`, which is not FFI-safe
+error: `extern` fn uses type `Foo`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:66:35
    |
 LL | pub extern "C" fn ptr_type2(size: *const Foo) { }
@@ -31,7 +31,7 @@ note: type defined here
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `[u32]`, which is not FFI-safe
+error: `extern` fn uses type `[u32]`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:69:33
    |
 LL | pub extern "C" fn slice_type(p: &[u32]) { }
@@ -40,7 +40,7 @@ LL | pub extern "C" fn slice_type(p: &[u32]) { }
    = help: consider using a raw pointer instead
    = note: slices have no C equivalent
 
-error: `extern` block uses type `str`, which is not FFI-safe
+error: `extern` fn uses type `str`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:72:31
    |
 LL | pub extern "C" fn str_type(p: &str) { }
@@ -49,7 +49,7 @@ LL | pub extern "C" fn str_type(p: &str) { }
    = help: consider using `*const u8` and a length instead
    = note: string slices have no C equivalent
 
-error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
+error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:75:31
    |
 LL | pub extern "C" fn box_type(p: Box<u32>) { }
@@ -58,7 +58,7 @@ LL | pub extern "C" fn box_type(p: Box<u32>) { }
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 
-error: `extern` block uses type `char`, which is not FFI-safe
+error: `extern` fn uses type `char`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:78:32
    |
 LL | pub extern "C" fn char_type(p: char) { }
@@ -67,7 +67,7 @@ LL | pub extern "C" fn char_type(p: char) { }
    = help: consider using `u32` or `libc::wchar_t` instead
    = note: the `char` type has no C equivalent
 
-error: `extern` block uses type `i128`, which is not FFI-safe
+error: `extern` fn uses type `i128`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:81:32
    |
 LL | pub extern "C" fn i128_type(p: i128) { }
@@ -75,7 +75,7 @@ LL | pub extern "C" fn i128_type(p: i128) { }
    |
    = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `u128`, which is not FFI-safe
+error: `extern` fn uses type `u128`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:84:32
    |
 LL | pub extern "C" fn u128_type(p: u128) { }
@@ -83,7 +83,7 @@ LL | pub extern "C" fn u128_type(p: u128) { }
    |
    = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
+error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:87:33
    |
 LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
@@ -92,7 +92,7 @@ LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
    = help: consider using a struct instead
    = note: tuples have unspecified layout
 
-error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
+error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:90:34
    |
 LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
@@ -101,7 +101,7 @@ LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
    = help: consider using a struct instead
    = note: tuples have unspecified layout
 
-error: `extern` block uses type `ZeroSize`, which is not FFI-safe
+error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:93:32
    |
 LL | pub extern "C" fn zero_size(p: ZeroSize) { }
@@ -115,7 +115,7 @@ note: type defined here
 LL | pub struct ZeroSize;
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
+error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:96:40
    |
 LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
@@ -128,7 +128,7 @@ note: type defined here
 LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
+error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:99:51
    |
 LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
@@ -136,7 +136,7 @@ LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
    |
    = note: composed only of `PhantomData`
 
-error: `extern` block uses type `fn()`, which is not FFI-safe
+error: `extern` fn uses type `fn()`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:104:30
    |
 LL | pub extern "C" fn fn_type(p: RustFn) { }
@@ -145,7 +145,7 @@ LL | pub extern "C" fn fn_type(p: RustFn) { }
    = help: consider using an `extern fn(...) -> ...` function pointer instead
    = note: this function pointer has Rust-specific calling convention
 
-error: `extern` block uses type `fn()`, which is not FFI-safe
+error: `extern` fn uses type `fn()`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:107:31
    |
 LL | pub extern "C" fn fn_type2(p: fn()) { }
@@ -154,7 +154,7 @@ LL | pub extern "C" fn fn_type2(p: fn()) { }
    = help: consider using an `extern fn(...) -> ...` function pointer instead
    = note: this function pointer has Rust-specific calling convention
 
-error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
+error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:110:35
    |
 LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
@@ -163,7 +163,7 @@ LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 
-error: `extern` block uses type `i128`, which is not FFI-safe
+error: `extern` fn uses type `i128`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:113:39
    |
 LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
@@ -171,7 +171,7 @@ LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
    |
    = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `str`, which is not FFI-safe
+error: `extern` fn uses type `str`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:116:38
    |
 LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
@@ -180,7 +180,7 @@ LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
    = help: consider using `*const u8` and a length instead
    = note: string slices have no C equivalent
 
-error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
+error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:119:37
    |
 LL | pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
@@ -189,7 +189,7 @@ LL | pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 
-error: `extern` block uses type `Foo`, which is not FFI-safe
+error: `extern` fn uses type `Foo`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:161:44
    |
 LL | pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
@@ -203,7 +203,7 @@ note: type defined here
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
+error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:164:43
    |
 LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
@@ -211,7 +211,7 @@ LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
    |
    = note: composed only of `PhantomData`
 
-error: `extern` block uses type `Foo`, which is not FFI-safe
+error: `extern` fn uses type `Foo`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:171:48
    |
 LL | pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
@@ -225,7 +225,7 @@ note: type defined here
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `std::vec::Vec<T>`, which is not FFI-safe
+error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:178:39
    |
 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>) { }
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 
-error: `extern` block uses type `std::vec::Vec<T>`, which is not FFI-safe
+error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
   --> $DIR/lint-ctypes-fn.rs:181:41
    |
 LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {