Skip to content

nightly/beta regression: fnptrs with types containing () is warned to be not FFI-safe, while it is before #113436

Closed
@oxalica

Description

@oxalica

Code

#![deny(improper_ctypes_definitions)]

#[repr(C)]
pub struct Wrap<T>(u8, T);

pub extern "C" fn f() -> Wrap<()> { todo!() } // This does not warn.

const _: extern "C" fn() -> Wrap<()> = f; // This warns.

Current output

error: `extern` fn uses type `()`, which is not FFI-safe
 --> src/lib.rs:8:10
  |
8 | const _: extern "C" fn() -> Wrap<()> = f; // This warns.
  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
  |
  = help: consider using a struct instead
  = note: tuples have unspecified layout
note: the lint level is defined here
 --> src/lib.rs:1:9
  |
1 | #![deny(improper_ctypes_definitions)]
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Desired output

<no errors or warnings>

Rationale and extra context

The function itself extern "C" fn f() -> Wrap<()> is considered FFI-safe and does not trigger the warning (#72890). Its function pointer should also be allowed, to be consistent.

Other cases

Discovered on CI https://github.com/oxalica/async-ffi/actions/runs/5450150255/jobs/9915116819#step:4:37

The original code has several more levels of indirection, but is also considered FFI-safe before.

Extracted original code
#![deny(improper_ctypes_definitions)]
use std::marker::PhantomData;

pub type FfiFuture<T> = BorrowingFfiFuture<'static, T>;

#[repr(transparent)]
pub struct BorrowingFfiFuture<'a, T>(LocalBorrowingFfiFuture<'a, T>);

// Does not matter here, but is repr(C).
#[repr(C)]
struct FfiContext(u8);

#[repr(C)]
pub struct LocalBorrowingFfiFuture<'a, T> {
    fut_ptr: *mut (),
    poll_fn: unsafe extern "C" fn(fut_ptr: *mut (), context_ptr: *mut FfiContext) -> FfiPoll<T>,
    drop_fn: unsafe extern "C" fn(*mut ()),
    _marker: PhantomData<&'a ()>,
}

#[repr(C, u8)]
pub enum FfiPoll<T> {
    Ready(T),
    Pending,
    Panicked,
}

pub extern "C" fn f() -> FfiFuture<()> { todo!() }
const _: extern "C" fn() -> FfiFuture<()> = f;

Anything else?

According to CI logs, the warning occurs since rust 1.72.0-nightly (0ab38e9 2023-07-03). Probably caused by #108611. cc @davidtwco

Metadata

Metadata

Assignees

Labels

A-FFIArea: Foreign function interface (FFI)A-diagnosticsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-betaPerformance or correctness regression from stable to beta.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions