Closed as not planned
Description
Given the following code:
use std::marker::PhantomData;
#[repr(C)]
struct Ptr<T> {
ptr: *const T,
_phantom: PhantomData<T>,
}
extern "C" fn test(ptr: Ptr<String>) {}
Based on the documentation of PhantomData
:
Adding a PhantomData field to your type tells the compiler that your type acts as though it stores a value of type T, even though it doesn’t really.
I would think that it should trigger the improper_ctypes_definitions
compiler lint, like this example would:
#[repr(C)]
struct Ptr<T> {
inner: T
}
extern "C" fn test(ptr: Ptr<String>) {}
warning: `extern` fn uses type `String`, which is not FFI-safe
--> src/lib.rs:6:25
|
6 | extern "C" fn test(ptr: Ptr<String>) {}
| ^^^^^^^^^^^ not FFI-safe
|
= note: `#[warn(improper_ctypes_definitions)]` on by default
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
I think that it is intuitive that PhantomData<T>
should be marked as not FFI-safe if T
is not FFI-safe.
There is a workaround to this by using [T; 0]
instead of PhantomData<T>
, but it is very hacky:
#[repr(C, packed)]
struct PhantomType<T>([T; 0]);
#[repr(C)]
struct Ptr<T> {
ptr: *const T,
_phantom: PhantomType<T>,
}
extern "C" fn test(ptr: Ptr<String>) {} // gives warning