lint: rework some ImproperCTypes messages (especially around indirections to !Sized)
This commit is contained in:
parent
f021d99cc8
commit
1d52131043
14 changed files with 195 additions and 67 deletions
|
@ -359,7 +359,6 @@ lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stab
|
|||
lint_improper_ctypes_array_help = consider passing a pointer to the array
|
||||
|
||||
lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe
|
||||
lint_improper_ctypes_box = box cannot be represented as a single pointer
|
||||
|
||||
lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
|
||||
|
||||
|
@ -377,7 +376,9 @@ lint_improper_ctypes_enum_repr_help =
|
|||
lint_improper_ctypes_enum_repr_reason = enum has no representation hint
|
||||
lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead
|
||||
|
||||
lint_improper_ctypes_fnptr_indirect_reason = the function pointer to `{$ty}` is FFI-unsafe due to `{$inner_ty}`
|
||||
lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention
|
||||
|
||||
lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
|
||||
lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
|
||||
|
||||
|
@ -388,7 +389,11 @@ lint_improper_ctypes_opaque = opaque types have no C equivalent
|
|||
lint_improper_ctypes_pat_help = consider using the base type instead
|
||||
|
||||
lint_improper_ctypes_pat_reason = pattern types have no C equivalent
|
||||
lint_improper_ctypes_slice_help = consider using a raw pointer instead
|
||||
|
||||
lint_improper_ctypes_sized_ptr_to_unsafe_type =
|
||||
this reference (`{$ty}`) is can safely be translated into a C pointer, but `{$inner_ty}` itself is not FFI-safe
|
||||
|
||||
lint_improper_ctypes_slice_help = consider using a raw pointer to the slice's first element (and a length) instead
|
||||
|
||||
lint_improper_ctypes_slice_reason = slices have no C equivalent
|
||||
lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
|
||||
|
@ -414,6 +419,10 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re
|
|||
lint_improper_ctypes_union_layout_reason = this union has unspecified layout
|
||||
lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
|
||||
|
||||
lint_improper_ctypes_unsized_box = this box for an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
lint_improper_ctypes_unsized_ptr = this pointer to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
lint_improper_ctypes_unsized_ref = this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
lint_incomplete_include =
|
||||
include macro expected single expression in source
|
||||
|
||||
|
|
|
@ -732,8 +732,6 @@ enum FfiResult<'tcx> {
|
|||
reason: DiagMessage,
|
||||
help: Option<DiagMessage>,
|
||||
},
|
||||
// NOTE: this `allow` is only here for one retroactively-added commit
|
||||
#[allow(dead_code)]
|
||||
FfiUnsafeWrapper {
|
||||
ty: Ty<'tcx>,
|
||||
reason: DiagMessage,
|
||||
|
@ -1044,16 +1042,47 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
|
||||
match *ty.kind() {
|
||||
ty::Adt(def, args) => {
|
||||
if let Some(boxed) = ty.boxed_ty()
|
||||
&& matches!(self.mode, CItemKind::Definition)
|
||||
{
|
||||
if boxed.is_sized(tcx, self.cx.typing_env()) {
|
||||
return FfiSafe;
|
||||
if let Some(inner_ty) = ty.boxed_ty() {
|
||||
if inner_ty.is_sized(tcx, self.cx.typing_env())
|
||||
|| matches!(inner_ty.kind(), ty::Foreign(..))
|
||||
{
|
||||
// discussion on declaration vs definition:
|
||||
// see the `ty::RawPtr(inner_ty, _) | ty::Ref(_, inner_ty, _)` arm
|
||||
// of this `match *ty.kind()` block
|
||||
if matches!(self.mode, CItemKind::Definition) {
|
||||
return FfiSafe;
|
||||
} else {
|
||||
let inner_res = self.check_type_for_ffi(acc, inner_ty);
|
||||
return match inner_res {
|
||||
FfiUnsafe { .. } | FfiUnsafeWrapper { .. } => FfiUnsafeWrapper {
|
||||
ty,
|
||||
reason: fluent::lint_improper_ctypes_sized_ptr_to_unsafe_type,
|
||||
wrapped: Box::new(inner_res),
|
||||
help: None,
|
||||
},
|
||||
_ => inner_res,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
let help = match inner_ty.kind() {
|
||||
ty::Str => Some(fluent::lint_improper_ctypes_str_help),
|
||||
ty::Slice(_) => Some(fluent::lint_improper_ctypes_slice_help),
|
||||
ty::Adt(def, _)
|
||||
if matches!(def.adt_kind(), AdtKind::Struct | AdtKind::Union)
|
||||
&& matches!(
|
||||
tcx.get_diagnostic_name(def.did()),
|
||||
Some(sym::cstring_type | sym::cstr_type)
|
||||
)
|
||||
&& !acc.base_ty.is_mutable_ptr() =>
|
||||
{
|
||||
Some(fluent::lint_improper_ctypes_cstr_help)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
return FfiUnsafe {
|
||||
ty,
|
||||
reason: fluent::lint_improper_ctypes_box,
|
||||
help: None,
|
||||
reason: fluent::lint_improper_ctypes_unsized_box,
|
||||
help,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1209,15 +1238,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
help: Some(fluent::lint_improper_ctypes_tuple_help),
|
||||
},
|
||||
|
||||
ty::RawPtr(ty, _) | ty::Ref(_, ty, _)
|
||||
if {
|
||||
matches!(self.mode, CItemKind::Definition)
|
||||
&& ty.is_sized(self.cx.tcx, self.cx.typing_env())
|
||||
} =>
|
||||
{
|
||||
FfiSafe
|
||||
}
|
||||
|
||||
ty::RawPtr(ty, _)
|
||||
if match ty.kind() {
|
||||
ty::Tuple(tuple) => tuple.is_empty(),
|
||||
|
@ -1227,7 +1247,66 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
FfiSafe
|
||||
}
|
||||
|
||||
ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => self.check_type_for_ffi(acc, ty),
|
||||
ty::RawPtr(inner_ty, _) | ty::Ref(_, inner_ty, _) => {
|
||||
if inner_ty.is_sized(tcx, self.cx.typing_env())
|
||||
|| matches!(inner_ty.kind(), ty::Foreign(..))
|
||||
{
|
||||
// there's a nuance on what this lint should do for function definitions
|
||||
// (touched upon in https://github.com/rust-lang/rust/issues/66220 and https://github.com/rust-lang/rust/pull/72700)
|
||||
//
|
||||
// (`extern "C" fn fn_name(...) {...}`) versus declarations (`extern "C" {fn fn_name(...);}`).
|
||||
// The big question is: what does "ABI safety" mean? if you have something translated to a C pointer
|
||||
// (which has a stable layout) but points to FFI-unsafe type, is it safe?
|
||||
// on one hand, the function's ABI will match that of a similar C-declared function API,
|
||||
// on the other, dereferencing the pointer in not-rust will be painful.
|
||||
// In this code, the opinion is split between function declarations and function definitions.
|
||||
// For declarations, we see this as unsafe, but for definitions, we see this as safe.
|
||||
// This is mostly because, for extern function declarations, the actual definition of the function is written somewhere else,
|
||||
// so the fact that a pointer's pointee should be treated as opaque to one side or the other can be explicitely written out.
|
||||
// For extern function definitions, however, both callee and some callers can be written in rust,
|
||||
// so developers need to keep as much typing information as possible.
|
||||
if matches!(self.mode, CItemKind::Definition) {
|
||||
return FfiSafe;
|
||||
} else if matches!(ty.kind(), ty::RawPtr(..))
|
||||
&& matches!(inner_ty.kind(), ty::Tuple(tuple) if tuple.is_empty())
|
||||
{
|
||||
FfiSafe
|
||||
} else {
|
||||
let inner_res = self.check_type_for_ffi(acc, inner_ty);
|
||||
return match inner_res {
|
||||
FfiSafe => inner_res,
|
||||
_ => FfiUnsafeWrapper {
|
||||
ty,
|
||||
reason: fluent::lint_improper_ctypes_sized_ptr_to_unsafe_type,
|
||||
wrapped: Box::new(inner_res),
|
||||
help: None,
|
||||
},
|
||||
};
|
||||
}
|
||||
} else {
|
||||
let help = match inner_ty.kind() {
|
||||
ty::Str => Some(fluent::lint_improper_ctypes_str_help),
|
||||
ty::Slice(_) => Some(fluent::lint_improper_ctypes_slice_help),
|
||||
ty::Adt(def, _)
|
||||
if matches!(def.adt_kind(), AdtKind::Struct | AdtKind::Union)
|
||||
&& matches!(
|
||||
tcx.get_diagnostic_name(def.did()),
|
||||
Some(sym::cstring_type | sym::cstr_type)
|
||||
)
|
||||
&& !acc.base_ty.is_mutable_ptr() =>
|
||||
{
|
||||
Some(fluent::lint_improper_ctypes_cstr_help)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let reason = match ty.kind() {
|
||||
ty::RawPtr(..) => fluent::lint_improper_ctypes_unsized_ptr,
|
||||
ty::Ref(..) => fluent::lint_improper_ctypes_unsized_ref,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
FfiUnsafe { ty, reason, help }
|
||||
}
|
||||
}
|
||||
|
||||
ty::Array(inner_ty, _) => self.check_type_for_ffi(acc, inner_ty),
|
||||
|
||||
|
@ -1245,7 +1324,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
for arg in sig.inputs() {
|
||||
match self.check_type_for_ffi(acc, *arg) {
|
||||
FfiSafe => {}
|
||||
r => return r,
|
||||
r => {
|
||||
return FfiUnsafeWrapper {
|
||||
ty,
|
||||
reason: fluent::lint_improper_ctypes_fnptr_indirect_reason,
|
||||
help: None,
|
||||
wrapped: Box::new(r),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1254,7 +1340,15 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
return FfiSafe;
|
||||
}
|
||||
|
||||
self.check_type_for_ffi(acc, ret_ty)
|
||||
match self.check_type_for_ffi(acc, ret_ty) {
|
||||
r @ (FfiSafe | FfiPhantom(_)) => r,
|
||||
r => FfiUnsafeWrapper {
|
||||
ty: ty.clone(),
|
||||
reason: fluent::lint_improper_ctypes_fnptr_indirect_reason,
|
||||
help: None,
|
||||
wrapped: Box::new(r),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
ty::Foreign(..) => FfiSafe,
|
||||
|
|
|
@ -4,6 +4,7 @@ warning: `extern` fn uses type `CStr`, which is not FFI-safe
|
|||
LL | type Foo = extern "C" fn(::std::ffi::CStr);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: the function pointer to `extern "C" fn(CStr)` is FFI-unsafe due to `CStr`
|
||||
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
|
||||
= note: `CStr`/`CString` do not have a guaranteed layout
|
||||
= note: `#[warn(improper_ctypes_definitions)]` on by default
|
||||
|
@ -14,6 +15,7 @@ warning: `extern` block uses type `CStr`, which is not FFI-safe
|
|||
LL | fn meh(blah: Foo);
|
||||
| ^^^ not FFI-safe
|
||||
|
|
||||
= note: the function pointer to `extern "C" fn(CStr)` is FFI-unsafe due to `CStr`
|
||||
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
|
||||
= note: `CStr`/`CString` do not have a guaranteed layout
|
||||
= note: `#[warn(improper_ctypes)]` on by default
|
||||
|
|
|
@ -4,6 +4,7 @@ warning: `extern` fn uses type `str`, which is not FFI-safe
|
|||
LL | type ExternCallback = extern "C" fn(*const u8, u32, str);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: the function pointer to `extern "C" fn(*const u8, u32, str)` is FFI-unsafe due to `str`
|
||||
= help: consider using `*const u8` and a length instead
|
||||
= note: string slices have no C equivalent
|
||||
= note: `#[warn(improper_ctypes_definitions)]` on by default
|
||||
|
@ -14,6 +15,7 @@ warning: `extern` fn uses type `str`, which is not FFI-safe
|
|||
LL | pub extern "C" fn register_something(bind: ExternCallback) -> Struct {
|
||||
| ^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: the function pointer to `extern "C" fn(*const u8, u32, str)` is FFI-unsafe due to `str`
|
||||
= help: consider using `*const u8` and a length instead
|
||||
= note: string slices have no C equivalent
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// It's an improper ctype (a slice) arg in an extern "C" fnptr.
|
||||
|
||||
pub type F = extern "C" fn(&[u8]);
|
||||
//~^ ERROR: `extern` fn uses type `[u8]`, which is not FFI-safe
|
||||
//~^ ERROR: `extern` fn uses type `&[u8]`, which is not FFI-safe
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
||||
error: `extern` fn uses type `&[u8]`, which is not FFI-safe
|
||||
--> $DIR/extern-C-fnptr-lints-slices.rs:5:14
|
||||
|
|
||||
LL | pub type F = extern "C" fn(&[u8]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: slices have no C equivalent
|
||||
= note: the function pointer to `for<'a> extern "C" fn(&'a [u8])` is FFI-unsafe due to `&[u8]`
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
note: the lint level is defined here
|
||||
--> $DIR/extern-C-fnptr-lints-slices.rs:1:8
|
||||
|
|
||||
|
|
|
@ -4,6 +4,7 @@ error: `extern` block uses type `Qux`, which is not FFI-safe
|
|||
LL | fn lint_me() -> A<()>;
|
||||
| ^^^^^ not FFI-safe
|
||||
|
|
||||
= note: this reference (`&Qux`) is can safely be translated into a C pointer, but `Qux` itself is not FFI-safe
|
||||
= note: opaque types have no C equivalent
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-ctypes-73249-2.rs:2:9
|
||||
|
|
|
@ -4,7 +4,8 @@ error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
|||
LL | pub fn bad(f: extern "C" fn([u8])) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: the function pointer to `extern "C" fn([u8])` is FFI-unsafe due to `[u8]`
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: slices have no C equivalent
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-ctypes-94223.rs:2:9
|
||||
|
@ -18,7 +19,8 @@ error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
|||
LL | pub fn bad_twice(f: Result<extern "C" fn([u8]), extern "C" fn([u8])>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: the function pointer to `extern "C" fn([u8])` is FFI-unsafe due to `[u8]`
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: slices have no C equivalent
|
||||
|
||||
error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
||||
|
@ -27,7 +29,8 @@ error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
|||
LL | pub fn bad_twice(f: Result<extern "C" fn([u8]), extern "C" fn([u8])>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: the function pointer to `extern "C" fn([u8])` is FFI-unsafe due to `[u8]`
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: slices have no C equivalent
|
||||
|
||||
error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
||||
|
@ -36,7 +39,8 @@ error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
|||
LL | struct BadStruct(extern "C" fn([u8]));
|
||||
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: the function pointer to `extern "C" fn([u8])` is FFI-unsafe due to `[u8]`
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: slices have no C equivalent
|
||||
|
||||
error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
||||
|
@ -45,7 +49,8 @@ error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
|||
LL | A(extern "C" fn([u8])),
|
||||
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: the function pointer to `extern "C" fn([u8])` is FFI-unsafe due to `[u8]`
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: slices have no C equivalent
|
||||
|
||||
error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
||||
|
@ -54,7 +59,8 @@ error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
|||
LL | A(extern "C" fn([u8])),
|
||||
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: the function pointer to `extern "C" fn([u8])` is FFI-unsafe due to `[u8]`
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: slices have no C equivalent
|
||||
|
||||
error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
||||
|
@ -63,7 +69,8 @@ error: `extern` fn uses type `[u8]`, which is not FFI-safe
|
|||
LL | type Foo = extern "C" fn([u8]);
|
||||
| ^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: the function pointer to `extern "C" fn([u8])` is FFI-unsafe due to `[u8]`
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: slices have no C equivalent
|
||||
|
||||
error: `extern` fn uses type `Option<&<T as FooTrait>::FooType>`, which is not FFI-safe
|
||||
|
@ -72,6 +79,7 @@ error: `extern` fn uses type `Option<&<T as FooTrait>::FooType>`, which is not F
|
|||
LL | pub type Foo2<T> = extern "C" fn(Option<&<T as FooTrait>::FooType>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: the function pointer to `for<'a> extern "C" fn(Option<&'a <T as FooTrait>::FooType>)` is FFI-unsafe due to `Option<&<T as FooTrait>::FooType>`
|
||||
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
|
||||
= note: enum has no representation hint
|
||||
|
||||
|
@ -81,6 +89,7 @@ error: `extern` fn uses type `FfiUnsafe`, which is not FFI-safe
|
|||
LL | pub static BAD: extern "C" fn(FfiUnsafe) = f;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: the function pointer to `extern "C" fn(FfiUnsafe)` is FFI-unsafe due to `FfiUnsafe`
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
note: the type is defined here
|
||||
|
@ -95,6 +104,7 @@ error: `extern` fn uses type `FfiUnsafe`, which is not FFI-safe
|
|||
LL | pub static BAD_TWICE: Result<extern "C" fn(FfiUnsafe), extern "C" fn(FfiUnsafe)> = Ok(f);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: the function pointer to `extern "C" fn(FfiUnsafe)` is FFI-unsafe due to `FfiUnsafe`
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
note: the type is defined here
|
||||
|
@ -109,6 +119,7 @@ error: `extern` fn uses type `FfiUnsafe`, which is not FFI-safe
|
|||
LL | pub static BAD_TWICE: Result<extern "C" fn(FfiUnsafe), extern "C" fn(FfiUnsafe)> = Ok(f);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: the function pointer to `extern "C" fn(FfiUnsafe)` is FFI-unsafe due to `FfiUnsafe`
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
note: the type is defined here
|
||||
|
@ -123,6 +134,7 @@ error: `extern` fn uses type `FfiUnsafe`, which is not FFI-safe
|
|||
LL | pub const BAD_CONST: extern "C" fn(FfiUnsafe) = f;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: the function pointer to `extern "C" fn(FfiUnsafe)` is FFI-unsafe due to `FfiUnsafe`
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
note: the type is defined here
|
||||
|
|
|
@ -8,7 +8,7 @@ extern "C" {
|
|||
//~^ ERROR `extern` block uses type `CStr`, which is not FFI-safe
|
||||
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
|
||||
fn take_cstr_ref(s: &CStr);
|
||||
//~^ ERROR `extern` block uses type `CStr`, which is not FFI-safe
|
||||
//~^ ERROR `extern` block uses type `&CStr`, which is not FFI-safe
|
||||
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
|
||||
fn take_cstring(s: CString);
|
||||
//~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
|
||||
|
@ -27,7 +27,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
extern "C" fn rust_take_cstr_ref(s: &CStr) {}
|
||||
//~^ ERROR `extern` fn uses type `CStr`, which is not FFI-safe
|
||||
//~^ ERROR `extern` fn uses type `&CStr`, which is not FFI-safe
|
||||
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
|
||||
extern "C" fn rust_take_cstring(s: CString) {}
|
||||
//~^ ERROR `extern` fn uses type `CString`, which is not FFI-safe
|
||||
|
|
|
@ -12,14 +12,14 @@ note: the lint level is defined here
|
|||
LL | #![deny(improper_ctypes, improper_ctypes_definitions)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: `extern` block uses type `CStr`, which is not FFI-safe
|
||||
error: `extern` block uses type `&CStr`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-cstr.rs:10:25
|
||||
|
|
||||
LL | fn take_cstr_ref(s: &CStr);
|
||||
| ^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
|
||||
= note: `CStr`/`CString` do not have a guaranteed layout
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` block uses type `CString`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-cstr.rs:13:24
|
||||
|
@ -36,6 +36,7 @@ error: `extern` block uses type `CString`, which is not FFI-safe
|
|||
LL | fn take_cstring_ref(s: &CString);
|
||||
| ^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: this reference (`&CString`) is can safely be translated into a C pointer, but `CString` itself is not FFI-safe
|
||||
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
|
||||
= note: `CStr`/`CString` do not have a guaranteed layout
|
||||
|
||||
|
@ -45,6 +46,7 @@ error: `extern` block uses type `CString`, which is not FFI-safe
|
|||
LL | fn no_special_help_for_mut_cstring(s: *mut CString);
|
||||
| ^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: this reference (`*mut CString`) is can safely be translated into a C pointer, but `CString` itself is not FFI-safe
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
|
||||
|
@ -54,17 +56,18 @@ error: `extern` block uses type `CString`, which is not FFI-safe
|
|||
LL | fn no_special_help_for_mut_cstring_ref(s: &mut CString);
|
||||
| ^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: this reference (`&mut CString`) is can safely be translated into a C pointer, but `CString` itself is not FFI-safe
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
|
||||
error: `extern` fn uses type `CStr`, which is not FFI-safe
|
||||
error: `extern` fn uses type `&CStr`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-cstr.rs:29:37
|
||||
|
|
||||
LL | extern "C" fn rust_take_cstr_ref(s: &CStr) {}
|
||||
| ^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
|
||||
= note: `CStr`/`CString` do not have a guaranteed layout
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-ctypes-cstr.rs:2:26
|
||||
|
|
||||
|
|
|
@ -68,10 +68,10 @@ pub extern "C" fn ptr_unit(p: *const ()) { }
|
|||
pub extern "C" fn ptr_tuple(p: *const ((),)) { }
|
||||
|
||||
pub extern "C" fn slice_type(p: &[u32]) { }
|
||||
//~^ ERROR: uses type `[u32]`
|
||||
//~^ ERROR: uses type `&[u32]`
|
||||
|
||||
pub extern "C" fn str_type(p: &str) { }
|
||||
//~^ ERROR: uses type `str`
|
||||
//~^ ERROR: uses type `&str`
|
||||
|
||||
pub extern "C" fn box_type(p: Box<u32>) { }
|
||||
|
||||
|
@ -124,7 +124,7 @@ pub extern "C" fn transparent_i128(p: TransparentI128) { }
|
|||
//~^ ERROR: uses type `i128`
|
||||
|
||||
pub extern "C" fn transparent_str(p: TransparentStr) { }
|
||||
//~^ ERROR: uses type `str`
|
||||
//~^ ERROR: uses type `&str`
|
||||
|
||||
pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
|
||||
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
error: `extern` fn uses type `[u32]`, which is not FFI-safe
|
||||
error: `extern` fn uses type `&[u32]`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:70:33
|
||||
|
|
||||
LL | pub extern "C" fn slice_type(p: &[u32]) { }
|
||||
| ^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: slices have no C equivalent
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-ctypes-fn.rs:2:9
|
||||
|
|
||||
LL | #![deny(improper_ctypes_definitions)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `extern` fn uses type `str`, which is not FFI-safe
|
||||
error: `extern` fn uses type `&str`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:73:31
|
||||
|
|
||||
LL | pub extern "C" fn str_type(p: &str) { }
|
||||
| ^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using `*const u8` and a length instead
|
||||
= note: string slices have no C equivalent
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` fn uses type `Box<[u8]>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:80:34
|
||||
|
@ -27,7 +27,8 @@ error: `extern` fn uses type `Box<[u8]>`, which is not FFI-safe
|
|||
LL | pub extern "C" fn boxed_slice(p: Box<[u8]>) { }
|
||||
| ^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: box cannot be represented as a single pointer
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: this box for an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` fn uses type `Box<str>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:83:35
|
||||
|
@ -35,7 +36,8 @@ error: `extern` fn uses type `Box<str>`, which is not FFI-safe
|
|||
LL | pub extern "C" fn boxed_string(p: Box<str>) { }
|
||||
| ^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: box cannot be represented as a single pointer
|
||||
= help: consider using `*const u8` and a length instead
|
||||
= note: this box for an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` fn uses type `Box<dyn Trait>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:86:34
|
||||
|
@ -43,7 +45,7 @@ error: `extern` fn uses type `Box<dyn Trait>`, which is not FFI-safe
|
|||
LL | pub extern "C" fn boxed_trait(p: Box<dyn Trait>) { }
|
||||
| ^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: box cannot be represented as a single pointer
|
||||
= note: this box for an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` fn uses type `char`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:89:32
|
||||
|
@ -149,14 +151,14 @@ LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
|
|||
|
|
||||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` fn uses type `str`, which is not FFI-safe
|
||||
error: `extern` fn uses type `&str`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:126:38
|
||||
|
|
||||
LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
|
||||
| ^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using `*const u8` and a length instead
|
||||
= note: string slices have no C equivalent
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` fn uses type `PhantomData<bool>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-fn.rs:172:43
|
||||
|
|
|
@ -48,15 +48,15 @@ extern "C" {
|
|||
pub fn ptr_type2(size: *const Foo); //~ ERROR: uses type `Foo`
|
||||
pub fn ptr_unit(p: *const ());
|
||||
pub fn ptr_tuple(p: *const ((),)); //~ ERROR: uses type `((),)`
|
||||
pub fn slice_type(p: &[u32]); //~ ERROR: uses type `[u32]`
|
||||
pub fn str_type(p: &str); //~ ERROR: uses type `str`
|
||||
pub fn slice_type(p: &[u32]); //~ ERROR: uses type `&[u32]`
|
||||
pub fn str_type(p: &str); //~ ERROR: uses type `&str`
|
||||
pub fn box_type(p: Box<u32>); //~ ERROR uses type `Box<u32>`
|
||||
pub fn opt_box_type(p: Option<Box<u32>>);
|
||||
//~^ ERROR uses type `Option<Box<u32>>`
|
||||
pub fn char_type(p: char); //~ ERROR uses type `char`
|
||||
pub fn i128_type(p: i128); //~ ERROR uses type `i128`
|
||||
pub fn u128_type(p: u128); //~ ERROR uses type `u128`
|
||||
pub fn trait_type(p: &dyn Bar); //~ ERROR uses type `dyn Bar`
|
||||
pub fn trait_type(p: &dyn Bar); //~ ERROR uses type `&dyn Bar`
|
||||
pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
|
||||
pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
|
||||
pub fn zero_size(p: ZeroSize); //~ ERROR uses type `ZeroSize`
|
||||
|
@ -68,7 +68,7 @@ extern "C" {
|
|||
pub fn fn_type2(p: fn()); //~ ERROR uses type `fn()`
|
||||
pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `Box<u32>`
|
||||
pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
|
||||
pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
|
||||
pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `&str`
|
||||
pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `Box<u32>`
|
||||
pub fn raw_array(arr: [u8; 8]); //~ ERROR: uses type `[u8; 8]`
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ error: `extern` block uses type `Foo`, which is not FFI-safe
|
|||
LL | pub fn ptr_type1(size: *const Foo);
|
||||
| ^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: this reference (`*const Foo`) is can safely be translated into a C pointer, but `Foo` itself is not FFI-safe
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
note: the type is defined here
|
||||
|
@ -23,6 +24,7 @@ error: `extern` block uses type `Foo`, which is not FFI-safe
|
|||
LL | pub fn ptr_type2(size: *const Foo);
|
||||
| ^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: this reference (`*const Foo`) is can safely be translated into a C pointer, but `Foo` itself is not FFI-safe
|
||||
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
|
||||
= note: this struct has unspecified layout
|
||||
note: the type is defined here
|
||||
|
@ -37,26 +39,27 @@ error: `extern` block uses type `((),)`, which is not FFI-safe
|
|||
LL | pub fn ptr_tuple(p: *const ((),));
|
||||
| ^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: this reference (`*const ((),)`) is can safely be translated into a C pointer, but `((),)` itself is not FFI-safe
|
||||
= help: consider using a struct instead
|
||||
= note: tuples have unspecified layout
|
||||
|
||||
error: `extern` block uses type `[u32]`, which is not FFI-safe
|
||||
error: `extern` block uses type `&[u32]`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes.rs:51:26
|
||||
|
|
||||
LL | pub fn slice_type(p: &[u32]);
|
||||
| ^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using a raw pointer instead
|
||||
= note: slices have no C equivalent
|
||||
= help: consider using a raw pointer to the slice's first element (and a length) instead
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` block uses type `str`, which is not FFI-safe
|
||||
error: `extern` block uses type `&str`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes.rs:52:24
|
||||
|
|
||||
LL | pub fn str_type(p: &str);
|
||||
| ^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using `*const u8` and a length instead
|
||||
= note: string slices have no C equivalent
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes.rs:53:24
|
||||
|
@ -101,13 +104,13 @@ LL | pub fn u128_type(p: u128);
|
|||
|
|
||||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: `extern` block uses type `dyn Bar`, which is not FFI-safe
|
||||
error: `extern` block uses type `&dyn Bar`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes.rs:59:26
|
||||
|
|
||||
LL | pub fn trait_type(p: &dyn Bar);
|
||||
| ^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= note: trait objects have no C equivalent
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes.rs:60:26
|
||||
|
@ -197,14 +200,14 @@ LL | pub 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` block uses type `&str`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes.rs:71:31
|
||||
|
|
||||
LL | pub fn transparent_str(p: TransparentStr);
|
||||
| ^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
|
||||
= help: consider using `*const u8` and a length instead
|
||||
= note: string slices have no C equivalent
|
||||
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
|
||||
|
||||
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes.rs:72:30
|
||||
|
@ -259,4 +262,3 @@ LL | pub static static_u128_array_type: [u128; 16];
|
|||
= note: 128-bit integers don't currently have a known stable ABI
|
||||
|
||||
error: aborting due to 27 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue