mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
[improper_ctypes] Overhaul primary label
- Always name the non-FFI-safe - Explain *why* the type is not FFI-safe - Stop vaguely gesturing at structs/enums/unions if the non-FFI-safe types occured in a field. The last part is arguably a regression, but it's minor now that the non-FFI-safe type is actually named. Removing it avoids some code duplication.
This commit is contained in:
parent
ae92dfac50
commit
9b5f47ec48
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use rustc::hir::def_id::DefId;
|
|
||||||
use rustc::hir::map as hir_map;
|
use rustc::hir::map as hir_map;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::{self, AdtKind, Ty, TyCtxt};
|
use rustc::ty::{self, AdtKind, Ty, TyCtxt};
|
||||||
@ -352,18 +351,14 @@ struct ImproperCTypesVisitor<'a, 'tcx: 'a> {
|
|||||||
cx: &'a LateContext<'a, 'tcx>,
|
cx: &'a LateContext<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FfiError {
|
enum FfiResult<'tcx> {
|
||||||
message: &'static str,
|
|
||||||
help: Option<&'static str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum FfiResult {
|
|
||||||
FfiSafe,
|
FfiSafe,
|
||||||
FfiPhantom,
|
FfiPhantom(Ty<'tcx>),
|
||||||
FfiUnsafe(FfiError),
|
FfiUnsafe {
|
||||||
FfiBadStruct(DefId, FfiError),
|
ty: Ty<'tcx>,
|
||||||
FfiBadUnion(DefId, FfiError),
|
reason: &'static str,
|
||||||
FfiBadEnum(DefId, FfiError),
|
help: Option<&'static str>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if this enum can be safely exported based on the
|
/// Check if this enum can be safely exported based on the
|
||||||
@ -406,7 +401,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
/// representation which can be exported to C code).
|
/// representation which can be exported to C code).
|
||||||
fn check_type_for_ffi(&self,
|
fn check_type_for_ffi(&self,
|
||||||
cache: &mut FxHashSet<Ty<'tcx>>,
|
cache: &mut FxHashSet<Ty<'tcx>>,
|
||||||
ty: Ty<'tcx>) -> FfiResult {
|
ty: Ty<'tcx>) -> FfiResult<'tcx> {
|
||||||
use self::FfiResult::*;
|
use self::FfiResult::*;
|
||||||
|
|
||||||
let cx = self.cx.tcx;
|
let cx = self.cx.tcx;
|
||||||
@ -422,23 +417,24 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyAdt(def, substs) => {
|
ty::TyAdt(def, substs) => {
|
||||||
if def.is_phantom_data() {
|
if def.is_phantom_data() {
|
||||||
return FfiPhantom;
|
return FfiPhantom(ty);
|
||||||
}
|
}
|
||||||
match def.adt_kind() {
|
match def.adt_kind() {
|
||||||
AdtKind::Struct => {
|
AdtKind::Struct => {
|
||||||
if !def.repr.c() && !def.repr.transparent() {
|
if !def.repr.c() && !def.repr.transparent() {
|
||||||
return FfiUnsafe(FfiError {
|
return FfiUnsafe {
|
||||||
message: "found struct without foreign-function-safe \
|
ty: ty,
|
||||||
representation annotation in foreign module",
|
reason: "this struct has unspecified layout",
|
||||||
help: Some("consider adding a #[repr(C)] attribute to the type"),
|
help: Some("consider adding a #[repr(C)] attribute to this struct"),
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if def.non_enum_variant().fields.is_empty() {
|
if def.non_enum_variant().fields.is_empty() {
|
||||||
return FfiUnsafe(FfiError {
|
return FfiUnsafe {
|
||||||
message: "found zero-size struct in foreign module",
|
ty: ty,
|
||||||
|
reason: "this struct has no fields",
|
||||||
help: Some("consider adding a member to this struct"),
|
help: Some("consider adding a member to this struct"),
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can't completely trust repr(C) and repr(transparent) markings;
|
// We can't completely trust repr(C) and repr(transparent) markings;
|
||||||
@ -464,32 +460,30 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
FfiSafe => {
|
FfiSafe => {
|
||||||
all_phantom = false;
|
all_phantom = false;
|
||||||
}
|
}
|
||||||
FfiPhantom => {}
|
FfiPhantom(..) => {}
|
||||||
FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => {
|
FfiUnsafe { .. } => {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
FfiUnsafe(err) => {
|
|
||||||
return FfiBadStruct(def.did, err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if all_phantom { FfiPhantom } else { FfiSafe }
|
if all_phantom { FfiPhantom(ty) } else { FfiSafe }
|
||||||
}
|
}
|
||||||
AdtKind::Union => {
|
AdtKind::Union => {
|
||||||
if !def.repr.c() {
|
if !def.repr.c() {
|
||||||
return FfiUnsafe(FfiError {
|
return FfiUnsafe {
|
||||||
message: "found union without foreign-function-safe \
|
ty: ty,
|
||||||
representation annotation in foreign module",
|
reason: "this union has unspecified layout",
|
||||||
help: Some("consider adding a #[repr(C)] attribute to the type"),
|
help: Some("consider adding a #[repr(C)] attribute to this union"),
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if def.non_enum_variant().fields.is_empty() {
|
if def.non_enum_variant().fields.is_empty() {
|
||||||
return FfiUnsafe(FfiError {
|
return FfiUnsafe {
|
||||||
message: "found zero-size union in foreign module",
|
ty: ty,
|
||||||
help: Some("consider adding a member to this union"),
|
reason: "this union has no fields",
|
||||||
});
|
help: Some("consider adding a field to this union"),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut all_phantom = true;
|
let mut all_phantom = true;
|
||||||
@ -502,17 +496,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
FfiSafe => {
|
FfiSafe => {
|
||||||
all_phantom = false;
|
all_phantom = false;
|
||||||
}
|
}
|
||||||
FfiPhantom => {}
|
FfiPhantom(..) => {}
|
||||||
FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => {
|
FfiUnsafe { .. } => {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
FfiUnsafe(err) => {
|
|
||||||
return FfiBadUnion(def.did, err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if all_phantom { FfiPhantom } else { FfiSafe }
|
if all_phantom { FfiPhantom(ty) } else { FfiSafe }
|
||||||
}
|
}
|
||||||
AdtKind::Enum => {
|
AdtKind::Enum => {
|
||||||
if def.variants.is_empty() {
|
if def.variants.is_empty() {
|
||||||
@ -525,12 +516,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
if !def.repr.c() && def.repr.int.is_none() {
|
if !def.repr.c() && def.repr.int.is_none() {
|
||||||
// Special-case types like `Option<extern fn()>`.
|
// Special-case types like `Option<extern fn()>`.
|
||||||
if !is_repr_nullable_ptr(cx, def, substs) {
|
if !is_repr_nullable_ptr(cx, def, substs) {
|
||||||
return FfiUnsafe(FfiError {
|
return FfiUnsafe {
|
||||||
message: "found enum without foreign-function-safe \
|
ty: ty,
|
||||||
representation annotation in foreign module",
|
reason: "enum has no representation hint",
|
||||||
help: Some("consider adding a #[repr(...)] attribute \
|
help: Some("consider adding a #[repr(...)] attribute \
|
||||||
to the type"),
|
to this enum"),
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,17 +534,15 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
let r = self.check_type_for_ffi(cache, arg);
|
let r = self.check_type_for_ffi(cache, arg);
|
||||||
match r {
|
match r {
|
||||||
FfiSafe => {}
|
FfiSafe => {}
|
||||||
FfiBadStruct(..) | FfiBadUnion(..) | FfiBadEnum(..) => {
|
FfiUnsafe { .. } => {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
FfiPhantom => {
|
FfiPhantom(..) => {
|
||||||
return FfiBadEnum(def.did, FfiError {
|
return FfiUnsafe {
|
||||||
message: "Found phantom data in enum variant",
|
ty: ty,
|
||||||
|
reason: "this enum contains a PhantomData field",
|
||||||
help: None,
|
help: None,
|
||||||
});
|
};
|
||||||
}
|
|
||||||
FfiUnsafe(err) => {
|
|
||||||
return FfiBadEnum(def.did, err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -563,59 +552,44 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::TyChar => {
|
ty::TyChar => FfiUnsafe {
|
||||||
FfiUnsafe(FfiError {
|
ty: ty,
|
||||||
message: "found Rust type `char` in foreign module",
|
reason: "the `char` type has no C equivalent",
|
||||||
help: Some("consider using `u32` or `libc::wchar_t`"),
|
help: Some("consider using `u32` or `libc::wchar_t` instead"),
|
||||||
})
|
},
|
||||||
}
|
|
||||||
|
|
||||||
ty::TyInt(ast::IntTy::I128) => {
|
ty::TyInt(ast::IntTy::I128) | ty::TyUint(ast::UintTy::U128) => FfiUnsafe {
|
||||||
FfiUnsafe(FfiError {
|
ty: ty,
|
||||||
message: "found Rust type `i128` in foreign module, but 128-bit \
|
reason: "128-bit integers don't currently have a known stable ABI",
|
||||||
integers don't currently have a known stable ABI",
|
help: None,
|
||||||
help: None,
|
},
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::TyUint(ast::UintTy::U128) => {
|
|
||||||
FfiUnsafe(FfiError {
|
|
||||||
message: "found Rust type `u128` in foreign module, but 128-bit \
|
|
||||||
integers don't currently have a known stable ABI",
|
|
||||||
help: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Primitive types with a stable representation.
|
// Primitive types with a stable representation.
|
||||||
ty::TyBool | ty::TyInt(..) | ty::TyUint(..) | ty::TyFloat(..) | ty::TyNever => FfiSafe,
|
ty::TyBool | ty::TyInt(..) | ty::TyUint(..) | ty::TyFloat(..) | ty::TyNever => FfiSafe,
|
||||||
|
|
||||||
ty::TySlice(_) => {
|
ty::TySlice(_) => FfiUnsafe {
|
||||||
FfiUnsafe(FfiError {
|
ty: ty,
|
||||||
message: "found Rust slice type in foreign module",
|
reason: "slices have no C equivalent",
|
||||||
help: Some("consider using a raw pointer instead"),
|
help: Some("consider using a raw pointer instead"),
|
||||||
})
|
},
|
||||||
}
|
|
||||||
|
|
||||||
ty::TyDynamic(..) => {
|
ty::TyDynamic(..) => FfiUnsafe {
|
||||||
FfiUnsafe(FfiError {
|
ty: ty,
|
||||||
message: "found Rust trait type in foreign module",
|
reason: "trait objects have no C equivalent",
|
||||||
help: Some("consider using a raw pointer instead"),
|
help: Some("consider using a raw pointer instead"),
|
||||||
})
|
},
|
||||||
}
|
|
||||||
|
|
||||||
ty::TyStr => {
|
ty::TyStr => FfiUnsafe {
|
||||||
FfiUnsafe(FfiError {
|
ty: ty,
|
||||||
message: "found Rust type `str` in foreign module",
|
reason: "string slices have no C equivalent",
|
||||||
help: Some("consider using a `*const libc::c_char`"),
|
help: Some("consider using `*const u8` and a length instead"),
|
||||||
})
|
},
|
||||||
}
|
|
||||||
|
|
||||||
ty::TyTuple(..) => {
|
ty::TyTuple(..) => FfiUnsafe {
|
||||||
FfiUnsafe(FfiError {
|
ty: ty,
|
||||||
message: "found Rust tuple type in foreign module",
|
reason: "tuples have unspecified layout",
|
||||||
help: Some("consider using a struct instead"),
|
help: Some("consider using a struct instead"),
|
||||||
})
|
},
|
||||||
}
|
|
||||||
|
|
||||||
ty::TyRawPtr(ref m) |
|
ty::TyRawPtr(ref m) |
|
||||||
ty::TyRef(_, ref m) => self.check_type_for_ffi(cache, m.ty),
|
ty::TyRef(_, ref m) => self.check_type_for_ffi(cache, m.ty),
|
||||||
@ -625,11 +599,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
ty::TyFnPtr(sig) => {
|
ty::TyFnPtr(sig) => {
|
||||||
match sig.abi() {
|
match sig.abi() {
|
||||||
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
|
Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
|
||||||
return FfiUnsafe(FfiError {
|
return FfiUnsafe {
|
||||||
message: "found function pointer with Rust calling convention in \
|
ty: ty,
|
||||||
foreign module",
|
reason: "this function pointer has Rust-specific calling convention",
|
||||||
help: Some("consider using an `extern` function pointer"),
|
help: Some("consider using an `fn \"extern\"(...) -> ...` \
|
||||||
})
|
function pointer instead"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -677,48 +652,17 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
match self.check_type_for_ffi(&mut FxHashSet(), ty) {
|
match self.check_type_for_ffi(&mut FxHashSet(), ty) {
|
||||||
FfiResult::FfiSafe => {}
|
FfiResult::FfiSafe => {}
|
||||||
FfiResult::FfiPhantom => {
|
FfiResult::FfiPhantom(ty) => {
|
||||||
self.cx.span_lint(IMPROPER_CTYPES,
|
self.cx.span_lint(IMPROPER_CTYPES,
|
||||||
sp,
|
sp,
|
||||||
&format!("found zero-sized type composed only \
|
&format!("`extern` block uses type `{}` which is not FFI-safe: \
|
||||||
of phantom-data in a foreign-function."));
|
composed only of PhantomData", ty));
|
||||||
}
|
}
|
||||||
FfiResult::FfiUnsafe(err) => {
|
FfiResult::FfiUnsafe { ty: unsafe_ty, reason, help } => {
|
||||||
let mut diag = self.cx.struct_span_lint(IMPROPER_CTYPES, sp, err.message);
|
let msg = format!("`extern` block uses type `{}` which is not FFI-safe: {}",
|
||||||
if let Some(s) = err.help {
|
unsafe_ty, reason);
|
||||||
diag.help(s);
|
|
||||||
}
|
|
||||||
diag.emit();
|
|
||||||
}
|
|
||||||
FfiResult::FfiBadStruct(_, err) => {
|
|
||||||
// FIXME: This diagnostic is difficult to read, and doesn't
|
|
||||||
// point at the relevant field.
|
|
||||||
let msg = format!("found non-foreign-function-safe member in struct \
|
|
||||||
marked #[repr(C)]: {}", err.message);
|
|
||||||
let mut diag = self.cx.struct_span_lint(IMPROPER_CTYPES, sp, &msg);
|
let mut diag = self.cx.struct_span_lint(IMPROPER_CTYPES, sp, &msg);
|
||||||
if let Some(s) = err.help {
|
if let Some(s) = help {
|
||||||
diag.help(s);
|
|
||||||
}
|
|
||||||
diag.emit();
|
|
||||||
}
|
|
||||||
FfiResult::FfiBadUnion(_, err) => {
|
|
||||||
// FIXME: This diagnostic is difficult to read, and doesn't
|
|
||||||
// point at the relevant field.
|
|
||||||
let msg = format!("found non-foreign-function-safe member in union \
|
|
||||||
marked #[repr(C)]: {}", err.message);
|
|
||||||
let mut diag = self.cx.struct_span_lint(IMPROPER_CTYPES, sp, &msg);
|
|
||||||
if let Some(s) = err.help {
|
|
||||||
diag.help(s);
|
|
||||||
}
|
|
||||||
diag.emit();
|
|
||||||
}
|
|
||||||
FfiResult::FfiBadEnum(_, err) => {
|
|
||||||
// FIXME: This diagnostic is difficult to read, and doesn't
|
|
||||||
// point at the relevant variant.
|
|
||||||
let msg = format!("found non-foreign-function-safe member in enum: {}",
|
|
||||||
err.message);
|
|
||||||
let mut diag = self.cx.struct_span_lint(IMPROPER_CTYPES, sp, &msg);
|
|
||||||
if let Some(s) = err.help {
|
|
||||||
diag.help(s);
|
diag.help(s);
|
||||||
}
|
}
|
||||||
diag.emit();
|
diag.emit();
|
||||||
|
@ -37,13 +37,13 @@ struct D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn foo(x: A); //~ ERROR found struct without foreign-function-safe
|
fn foo(x: A); //~ ERROR type `A` which is not FFI-safe
|
||||||
fn bar(x: B); //~ ERROR foreign-function-safe
|
fn bar(x: B); //~ ERROR type `A`
|
||||||
fn baz(x: C);
|
fn baz(x: C);
|
||||||
fn qux(x: A2); //~ ERROR foreign-function-safe
|
fn qux(x: A2); //~ ERROR type `A`
|
||||||
fn quux(x: B2); //~ ERROR foreign-function-safe
|
fn quux(x: B2); //~ ERROR type `A`
|
||||||
fn corge(x: C2);
|
fn corge(x: C2);
|
||||||
fn fred(x: D); //~ ERROR foreign-function-safe
|
fn fred(x: D); //~ ERROR type `A`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
pub struct Foo;
|
pub struct Foo;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
pub fn foo(x: (Foo)); //~ ERROR found struct without
|
pub fn foo(x: (Foo)); //~ ERROR unspecified layout
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -27,9 +27,9 @@ enum Isize { A, B, C }
|
|||||||
|
|
||||||
extern {
|
extern {
|
||||||
fn zf(x: Z);
|
fn zf(x: Z);
|
||||||
fn uf(x: U); //~ ERROR found enum without foreign-function-safe
|
fn uf(x: U); //~ ERROR enum has no representation hint
|
||||||
fn bf(x: B); //~ ERROR found enum without foreign-function-safe
|
fn bf(x: B); //~ ERROR enum has no representation hint
|
||||||
fn tf(x: T); //~ ERROR found enum without foreign-function-safe
|
fn tf(x: T); //~ ERROR enum has no representation hint
|
||||||
fn reprc(x: ReprC);
|
fn reprc(x: ReprC);
|
||||||
fn u8(x: U8);
|
fn u8(x: U8);
|
||||||
fn isize(x: Isize);
|
fn isize(x: Isize);
|
||||||
|
@ -22,7 +22,7 @@ union W {
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static FOREIGN1: U; // OK
|
static FOREIGN1: U; // OK
|
||||||
static FOREIGN2: W; //~ ERROR found union without foreign-function-safe representation
|
static FOREIGN2: W; //~ ERROR union has unspecified layout
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -51,27 +51,27 @@ pub struct TransparentCustomZst(i32, ZeroSize);
|
|||||||
pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
|
pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
pub fn ptr_type1(size: *const Foo); //~ ERROR: found struct without
|
pub fn ptr_type1(size: *const Foo); //~ ERROR: uses type `Foo`
|
||||||
pub fn ptr_type2(size: *const Foo); //~ ERROR: found struct without
|
pub fn ptr_type2(size: *const Foo); //~ ERROR: uses type `Foo`
|
||||||
pub fn slice_type(p: &[u32]); //~ ERROR: found Rust slice type
|
pub fn slice_type(p: &[u32]); //~ ERROR: uses type `[u32]`
|
||||||
pub fn str_type(p: &str); //~ ERROR: found Rust type
|
pub fn str_type(p: &str); //~ ERROR: uses type `str`
|
||||||
pub fn box_type(p: Box<u32>); //~ ERROR found struct without
|
pub fn box_type(p: Box<u32>); //~ ERROR uses type `std::boxed::Box<u32>`
|
||||||
pub fn char_type(p: char); //~ ERROR found Rust type
|
pub fn char_type(p: char); //~ ERROR uses type `char`
|
||||||
pub fn i128_type(p: i128); //~ ERROR found Rust type
|
pub fn i128_type(p: i128); //~ ERROR uses type `i128`
|
||||||
pub fn u128_type(p: u128); //~ ERROR found Rust type
|
pub fn u128_type(p: u128); //~ ERROR uses type `u128`
|
||||||
pub fn trait_type(p: &Clone); //~ ERROR found Rust trait type
|
pub fn trait_type(p: &Clone); //~ ERROR uses type `std::clone::Clone`
|
||||||
pub fn tuple_type(p: (i32, i32)); //~ ERROR found Rust tuple type
|
pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
|
||||||
pub fn tuple_type2(p: I32Pair); //~ ERROR found Rust tuple type
|
pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
|
||||||
pub fn zero_size(p: ZeroSize); //~ ERROR found zero-size struct
|
pub fn zero_size(p: ZeroSize); //~ ERROR struct has no fields
|
||||||
pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); //~ ERROR found zero-sized type
|
pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); //~ ERROR composed only of PhantomData
|
||||||
pub fn zero_size_phantom_toplevel()
|
pub fn zero_size_phantom_toplevel()
|
||||||
-> ::std::marker::PhantomData<bool>; //~ ERROR: found zero-sized type
|
-> ::std::marker::PhantomData<bool>; //~ ERROR: composed only of PhantomData
|
||||||
pub fn fn_type(p: RustFn); //~ ERROR found function pointer with Rust
|
pub fn fn_type(p: RustFn); //~ ERROR function pointer has Rust-specific
|
||||||
pub fn fn_type2(p: fn()); //~ ERROR found function pointer with Rust
|
pub fn fn_type2(p: fn()); //~ ERROR function pointer has Rust-specific
|
||||||
pub fn fn_contained(p: RustBadRet); //~ ERROR: found struct without
|
pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `std::boxed::Box<u32>`
|
||||||
pub fn transparent_i128(p: TransparentI128); //~ ERROR: found Rust type `i128`
|
pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
|
||||||
pub fn transparent_str(p: TransparentStr); //~ ERROR: found Rust type `str`
|
pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
|
||||||
pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: found struct without
|
pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `std::boxed::Box<u32>`
|
||||||
|
|
||||||
pub fn good3(fptr: Option<extern fn()>);
|
pub fn good3(fptr: Option<extern fn()>);
|
||||||
pub fn good4(aptr: &[u8; 4 as usize]);
|
pub fn good4(aptr: &[u8; 4 as usize]);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
error: found struct without foreign-function-safe representation annotation in foreign module
|
error: `extern` block uses type `Foo` which is not FFI-safe: this struct has unspecified layout
|
||||||
--> $DIR/lint-ctypes.rs:54:28
|
--> $DIR/lint-ctypes.rs:54:28
|
||||||
|
|
|
|
||||||
54 | pub fn ptr_type1(size: *const Foo); //~ ERROR: found struct without
|
54 | pub fn ptr_type1(size: *const Foo); //~ ERROR: uses type `Foo`
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
@ -9,149 +9,149 @@ note: lint level defined here
|
|||||||
|
|
|
|
||||||
11 | #![deny(improper_ctypes)]
|
11 | #![deny(improper_ctypes)]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
= help: consider adding a #[repr(C)] attribute to the type
|
= help: consider adding a #[repr(C)] attribute to this struct
|
||||||
|
|
||||||
error: found struct without foreign-function-safe representation annotation in foreign module
|
error: `extern` block uses type `Foo` which is not FFI-safe: this struct has unspecified layout
|
||||||
--> $DIR/lint-ctypes.rs:55:28
|
--> $DIR/lint-ctypes.rs:55:28
|
||||||
|
|
|
|
||||||
55 | pub fn ptr_type2(size: *const Foo); //~ ERROR: found struct without
|
55 | pub fn ptr_type2(size: *const Foo); //~ ERROR: uses type `Foo`
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider adding a #[repr(C)] attribute to the type
|
= help: consider adding a #[repr(C)] attribute to this struct
|
||||||
|
|
||||||
error: found Rust slice type in foreign module
|
error: `extern` block uses type `[u32]` which is not FFI-safe: slices have no C equivalent
|
||||||
--> $DIR/lint-ctypes.rs:56:26
|
--> $DIR/lint-ctypes.rs:56:26
|
||||||
|
|
|
|
||||||
56 | pub fn slice_type(p: &[u32]); //~ ERROR: found Rust slice type
|
56 | pub fn slice_type(p: &[u32]); //~ ERROR: uses type `[u32]`
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider using a raw pointer instead
|
= help: consider using a raw pointer instead
|
||||||
|
|
||||||
error: found Rust type `str` in foreign module
|
error: `extern` block uses type `str` which is not FFI-safe: string slices have no C equivalent
|
||||||
--> $DIR/lint-ctypes.rs:57:24
|
--> $DIR/lint-ctypes.rs:57:24
|
||||||
|
|
|
|
||||||
57 | pub fn str_type(p: &str); //~ ERROR: found Rust type
|
57 | pub fn str_type(p: &str); //~ ERROR: uses type `str`
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
= help: consider using a `*const libc::c_char`
|
= help: consider using `*const u8` and a length instead
|
||||||
|
|
||||||
error: found struct without foreign-function-safe representation annotation in foreign module
|
error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: this struct has unspecified layout
|
||||||
--> $DIR/lint-ctypes.rs:58:24
|
--> $DIR/lint-ctypes.rs:58:24
|
||||||
|
|
|
|
||||||
58 | pub fn box_type(p: Box<u32>); //~ ERROR found struct without
|
58 | pub fn box_type(p: Box<u32>); //~ ERROR uses type `std::boxed::Box<u32>`
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider adding a #[repr(C)] attribute to the type
|
= help: consider adding a #[repr(C)] attribute to this struct
|
||||||
|
|
||||||
error: found Rust type `char` in foreign module
|
error: `extern` block uses type `char` which is not FFI-safe: the `char` type has no C equivalent
|
||||||
--> $DIR/lint-ctypes.rs:59:25
|
--> $DIR/lint-ctypes.rs:59:25
|
||||||
|
|
|
|
||||||
59 | pub fn char_type(p: char); //~ ERROR found Rust type
|
59 | pub fn char_type(p: char); //~ ERROR uses type `char`
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
= help: consider using `u32` or `libc::wchar_t`
|
= help: consider using `u32` or `libc::wchar_t` instead
|
||||||
|
|
||||||
error: found Rust type `i128` in foreign module, but 128-bit integers don't currently have a known stable ABI
|
error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
||||||
--> $DIR/lint-ctypes.rs:60:25
|
--> $DIR/lint-ctypes.rs:60:25
|
||||||
|
|
|
|
||||||
60 | pub fn i128_type(p: i128); //~ ERROR found Rust type
|
60 | pub fn i128_type(p: i128); //~ ERROR uses type `i128`
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: found Rust type `u128` in foreign module, but 128-bit integers don't currently have a known stable ABI
|
error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
||||||
--> $DIR/lint-ctypes.rs:61:25
|
--> $DIR/lint-ctypes.rs:61:25
|
||||||
|
|
|
|
||||||
61 | pub fn u128_type(p: u128); //~ ERROR found Rust type
|
61 | pub fn u128_type(p: u128); //~ ERROR uses type `u128`
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: found Rust trait type in foreign module
|
error: `extern` block uses type `std::clone::Clone` which is not FFI-safe: trait objects have no C equivalent
|
||||||
--> $DIR/lint-ctypes.rs:62:26
|
--> $DIR/lint-ctypes.rs:62:26
|
||||||
|
|
|
|
||||||
62 | pub fn trait_type(p: &Clone); //~ ERROR found Rust trait type
|
62 | pub fn trait_type(p: &Clone); //~ ERROR uses type `std::clone::Clone`
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider using a raw pointer instead
|
= help: consider using a raw pointer instead
|
||||||
|
|
||||||
error: found Rust tuple type in foreign module
|
error: `extern` block uses type `(i32, i32)` which is not FFI-safe: tuples have unspecified layout
|
||||||
--> $DIR/lint-ctypes.rs:63:26
|
--> $DIR/lint-ctypes.rs:63:26
|
||||||
|
|
|
|
||||||
63 | pub fn tuple_type(p: (i32, i32)); //~ ERROR found Rust tuple type
|
63 | pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider using a struct instead
|
= help: consider using a struct instead
|
||||||
|
|
||||||
error: found Rust tuple type in foreign module
|
error: `extern` block uses type `(i32, i32)` which is not FFI-safe: tuples have unspecified layout
|
||||||
--> $DIR/lint-ctypes.rs:64:27
|
--> $DIR/lint-ctypes.rs:64:27
|
||||||
|
|
|
|
||||||
64 | pub fn tuple_type2(p: I32Pair); //~ ERROR found Rust tuple type
|
64 | pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider using a struct instead
|
= help: consider using a struct instead
|
||||||
|
|
||||||
error: found zero-size struct in foreign module
|
error: `extern` block uses type `ZeroSize` which is not FFI-safe: this struct has no fields
|
||||||
--> $DIR/lint-ctypes.rs:65:25
|
--> $DIR/lint-ctypes.rs:65:25
|
||||||
|
|
|
|
||||||
65 | pub fn zero_size(p: ZeroSize); //~ ERROR found zero-size struct
|
65 | pub fn zero_size(p: ZeroSize); //~ ERROR struct has no fields
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider adding a member to this struct
|
= help: consider adding a member to this struct
|
||||||
|
|
||||||
error: found zero-sized type composed only of phantom-data in a foreign-function.
|
error: `extern` block uses type `ZeroSizeWithPhantomData` which is not FFI-safe: composed only of PhantomData
|
||||||
--> $DIR/lint-ctypes.rs:66:33
|
--> $DIR/lint-ctypes.rs:66:33
|
||||||
|
|
|
|
||||||
66 | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); //~ ERROR found zero-sized type
|
66 | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); //~ ERROR composed only of PhantomData
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: found zero-sized type composed only of phantom-data in a foreign-function.
|
error: `extern` block uses type `std::marker::PhantomData<bool>` which is not FFI-safe: composed only of PhantomData
|
||||||
--> $DIR/lint-ctypes.rs:68:12
|
--> $DIR/lint-ctypes.rs:68:12
|
||||||
|
|
|
|
||||||
68 | -> ::std::marker::PhantomData<bool>; //~ ERROR: found zero-sized type
|
68 | -> ::std::marker::PhantomData<bool>; //~ ERROR: composed only of PhantomData
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: found function pointer with Rust calling convention in foreign module
|
error: `extern` block uses type `fn()` which is not FFI-safe: this function pointer has Rust-specific calling convention
|
||||||
--> $DIR/lint-ctypes.rs:69:23
|
--> $DIR/lint-ctypes.rs:69:23
|
||||||
|
|
|
|
||||||
69 | pub fn fn_type(p: RustFn); //~ ERROR found function pointer with Rust
|
69 | pub fn fn_type(p: RustFn); //~ ERROR function pointer has Rust-specific
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider using an `extern` function pointer
|
= help: consider using an `fn "extern"(...) -> ...` function pointer instead
|
||||||
|
|
||||||
error: found function pointer with Rust calling convention in foreign module
|
error: `extern` block uses type `fn()` which is not FFI-safe: this function pointer has Rust-specific calling convention
|
||||||
--> $DIR/lint-ctypes.rs:70:24
|
--> $DIR/lint-ctypes.rs:70:24
|
||||||
|
|
|
|
||||||
70 | pub fn fn_type2(p: fn()); //~ ERROR found function pointer with Rust
|
70 | pub fn fn_type2(p: fn()); //~ ERROR function pointer has Rust-specific
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
= help: consider using an `extern` function pointer
|
= help: consider using an `fn "extern"(...) -> ...` function pointer instead
|
||||||
|
|
||||||
error: found struct without foreign-function-safe representation annotation in foreign module
|
error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: this struct has unspecified layout
|
||||||
--> $DIR/lint-ctypes.rs:71:28
|
--> $DIR/lint-ctypes.rs:71:28
|
||||||
|
|
|
|
||||||
71 | pub fn fn_contained(p: RustBadRet); //~ ERROR: found struct without
|
71 | pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `std::boxed::Box<u32>`
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider adding a #[repr(C)] attribute to the type
|
= help: consider adding a #[repr(C)] attribute to this struct
|
||||||
|
|
||||||
error: found non-foreign-function-safe member in struct marked #[repr(C)]: found Rust type `i128` in foreign module, but 128-bit integers don't currently have a known stable ABI
|
error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
|
||||||
--> $DIR/lint-ctypes.rs:72:32
|
--> $DIR/lint-ctypes.rs:72:32
|
||||||
|
|
|
|
||||||
72 | pub fn transparent_i128(p: TransparentI128); //~ ERROR: found Rust type `i128`
|
72 | pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: found non-foreign-function-safe member in struct marked #[repr(C)]: found Rust type `str` in foreign module
|
error: `extern` block uses type `str` which is not FFI-safe: string slices have no C equivalent
|
||||||
--> $DIR/lint-ctypes.rs:73:31
|
--> $DIR/lint-ctypes.rs:73:31
|
||||||
|
|
|
|
||||||
73 | pub fn transparent_str(p: TransparentStr); //~ ERROR: found Rust type `str`
|
73 | pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider using a `*const libc::c_char`
|
= help: consider using `*const u8` and a length instead
|
||||||
|
|
||||||
error: found non-foreign-function-safe member in struct marked #[repr(C)]: found struct without foreign-function-safe representation annotation in foreign module
|
error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: this struct has unspecified layout
|
||||||
--> $DIR/lint-ctypes.rs:74:30
|
--> $DIR/lint-ctypes.rs:74:30
|
||||||
|
|
|
|
||||||
74 | pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: found struct without
|
74 | pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `std::boxed::Box<u32>`
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider adding a #[repr(C)] attribute to the type
|
= help: consider adding a #[repr(C)] attribute to this struct
|
||||||
|
|
||||||
error: aborting due to 20 previous errors
|
error: aborting due to 20 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user