-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Result / Option of non-null / non-zero types are not FFI-safe #55615
Comments
I think this isn't an oversight; I guess in theory we could do this for |
You are right, I've posted this in the appropriate UCG thread: rust-lang/unsafe-code-guidelines#10 (comment) |
@steveklabnik that's not exactly the case, the shape is what's checked, so if you have your own But regardless of |
Sure, I was talking about the spec, not the lint. Unless I’m mistaken and the lint is the spec. I thought only Option was truly guaranteed even if we do always do the optimization for any option-like type. I could be wrong!
… On Nov 3, 2018, at 10:51 AM, Eduard-Mihai Burtescu ***@***.***> wrote:
Reopened #55615.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@steveklabnik Ah, alright, I agree then, we should spec this (via UCG, I guess). |
This kind of stuff was being discussed recently at rust-lang/unsafe-code-guidelines#10 EDIT: Oh, you already got that link. Well never mind then.^^ |
So there are two orthogonal issues convoluted in my OP. First, is whether the niche optimizations for these types of enums are guaranteed or not. If they are not guaranteed, then using these in C FFI is pretty much undefined behavior independently of what Rust currently does. That should be clarified in the UCG and the current discussion seems to suggest that these should be guaranteed. What does Rust currently do here? Does this unconditionally perform these optimizations? Second, is whether the warning raised by the |
We have a similar situation in the #[repr(C)]
pub struct __wasi_event_t {
pub userdata: u64,
pub error: u16,
pub type_: u8,
pub u: T,
}
#[repr(C)]
pub struct Event {
pub userdata: u64,
pub res: Result<(), NonZeroU16>,
pub type_: u8,
pub u: T,
}
const _ASSERT1: [(); 32] = [(); core::mem::size_of::<__wasi_event_t>()];
const _ASSERT2: [(); 32] = [(); core::mem::size_of::<Event>()];
const _ASSERT3: [(); 0] = [(); __WASI_ESUCCESS as usize]; Note the asserts. Since we check at compile time that both structs have exactly the same size, it means that niche optimization is applied, meaning that |
@eddyb I think this could be a small RFC proposing to guarantee this, and including the couple of motivating examples shown here. We don't have to wait for the UCGs to come up with an RFC. I don't know if this might also be FCP material for a PR to the reference. I would be more comfortable with it being a proper RFC. |
Resolved by RFC 3391 |
I am writing an FFI wrapper for a library that has a function returning an integer error code:
The error code of
foo
is0
on success and non-zero on error. As suggested by @kennytm , I can do the following dance to obtain aNonZeroU{width}
type that's suitable to hold ac_int
(note:NonZero<libc::c_int>
does not work anymore, and theNonZeroI{width}
variants have been removed, so more extra dance is then necessary to convert the unsigned integers to alibc::c_int
to be able to compare this with with std error codes likelibc::EINVAL
):However, when I then try to use
Result
in FFI:I get an error stating that
Result
is not FFI-safe. This type is really similar to anOption<&'static 32>
which is FFI-safe: an enum with 2 variants, one is zero sized, and the other has niches.Option<NonNull<*mut i32>>
,Option<NonZeroU32>
, andResult<(), NonZeroU32>
are not, however, FFI safe.Is this an oversight ?
cc @eddyb @SimonSapin
The text was updated successfully, but these errors were encountered: