Skip to content

PhantomData<T> doesn't trigger improper_ctypes_definitions lint #94000

Closed as not planned
@PonasKovas

Description

@PonasKovas

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsL-improper_ctypesLint: improper_ctypesT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions