Description
Rust warns that pointers to structs tagged with non_exhaustive
aren't FFI safe in downstream crates. We ran into this in the sdl3-sys
crate, where I've marked some FFI types, e.g. SDL_Surface
, as non_exhaustive because the internal definition of the type used by the SDL library is larger than the public definition, and the non-public part isn't stable. Marking it with non_exhaustive
prevents code from manually constructing their own value that would cause immediate UB if passed to SDL. The non_exhaustive structs are only used through pointers.
Reproduction
Crate a
, lib.rs
:
#[repr(C)]
#[non_exhaustive]
pub struct Struct {
pub field: u8
}
extern "C" {
pub fn create_struct() -> *mut Struct;
pub fn destroy_struct(s: *mut Struct);
}
Crate b
, lib.rs
:
use a::Struct;
extern "C" {
pub fn use_struct(s: *mut Struct);
}
I expected to see this happen:
Either neither crate should warn about this, or both should. non_exhaustive
is as useful for FFI types as it is for native Rust types, so I'd prefer that neither crate warned.
If the warning is intentional, I'd like a way to disable it on the type itself (assuming it's safe, but I don't see why it wouldn't be)
Instead, this happened:
Crate b warns that Struct
isn't FFI safe. There's no warning for crate a.
warning: `extern` block uses type `Struct`, which is not FFI-safe
--> b/src/lib.rs:4:26
|
4 | pub fn use_struct(s: *mut Struct);
| ^^^^^^^^^^^ not FFI-safe
|
= note: this struct is non-exhaustive
= note: `#[warn(improper_ctypes)]` on by default
warning: `b` (lib) generated 1 warning
Meta
rustc --version --verbose
:
% rustc --version --verbose
rustc 1.82.0 (f6e511eec 2024-10-15)
binary: rustc
commit-hash: f6e511eec7342f59a25f7c0534f1dbea00d01b14
commit-date: 2024-10-15
host: aarch64-apple-darwin
release: 1.82.0
LLVM version: 19.1.1
% rustc +nightly --version --verbose
rustc 1.84.0-nightly (798fb83f7 2024-10-16)
binary: rustc
commit-hash: 798fb83f7d24e31b16acca113496f39ff168c143
commit-date: 2024-10-16
host: aarch64-apple-darwin
release: 1.84.0-nightly
LLVM version: 19.1.1