Giter Club home page Giter Club logo

Comments (1)

danielhenrymantilla avatar danielhenrymantilla commented on July 28, 2024 1

Yeah, in this regard safer-ffi may be a bit ahead of Rust; basically Rust guarantees discriminant elision for things like Option<NonZero…>, but it doesn't guarantee that yet for things like Option<(NonZero…, usize)>: technically, a future version of rustc may choose to lay out the latter as:

struct Option_NonZero_and_usize {
    discriminant: Discriminant,
    payload: MaybeUninit<(NonZero, usize)>,
}

enum Discriminant { Some, None }

which indeed wouldn't be FFI-safe.


That being said, in current versions of rustc, we do have size_of::<Option<(NonZero…, usize)>>() == size_of::<(NonZero…, usize)>(), which necessarily implies that discriminant elision is happening (this is true for any T where Option<T> and T have the same size). In this instance, it implies that Option<(NonZero…, usize)> is laid out as (Option<NonZero…>, usize).

In our case (c_slice::Ref & co.), these structures are #[repr(C)] structures with a single non-nullable field and usizes for the other fields, and safer-ffi does check, at compile-time, that they have the same size as their Option-wrapped versions.

This means that what safer-ffi does is sound, and that the warning is mostly a false positive:

  • Option<c_slice::Ref…> does have a well-defined layout (in C, that of struct { /* nullable */ Foo_t const * ptr; size_t count; });

  • but it is true that it is technically possible that a future version of rustc would choose a different layout for such a type, which would lead to the compile-time check failing and thus to safer-ffi no longer compiling.

    In practice, this is only a pedantic theoretical concern, since not only there is no reason not to use discriminant elision here, it would also lead generally to major performance regressions across Rust code out there. It's only a matter of time before an RFC guarantees that this elision applies to compound structs with no padding and a single-niched field, hence the practical choice made by safer-ffi here.

The development branch of safer-ffi (the ditto branch) does thus annotate #[ffi-export]-ed functions with an #[allow(improper_ctypes)] to silence this false positive. Feel free to do the same in the meantime.


That being said, if there were to be users of safer-ffi who find this situation unacceptable, then safer-ffi could feature-gate this "practical approach" so as to offer a way to opt out of it (to dodge the compile-time-check failing and causing breakage), and cumbersome but correct alternatives; this way users wanting to export a function with, for instance, a optional c_slice::Ref parameter where the ptr would be NULL to express None would write something like:

#[ffi_export]
fn foo<'a>(
    p0: Option<char_p::Ref>,
    p1: c_slice::Option::Ref<'a, Foo<'a>>, // Option::Ref would be a special distinct Rust type
) -> i32 {
    let p1: Option<c_slice::Ref<'a, Foo<'a>> = p1.into();
}

Aside

Using twice the same named lifetime on a single type is likely to be wrong; I recommend that you write:

#[ffi_export]
fn foo<'a, 'b>(
    p0: Option<char_p::Ref<'_>>,
    p1: Option<c_slice::<Ref<'a, Foo<'b>>>,

for the cases where #[ffi-export] does not accept full lifetime elision (note it is planned that a future version of #[ffi-export] will fix the issue with full lifetime elision not being supported 🙂)

from safer_ffi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.