Skip to content
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

Expose unique_ptr nullability more idiomatically in Rust #115

Open
dtolnay opened this issue Apr 14, 2020 · 1 comment
Open

Expose unique_ptr nullability more idiomatically in Rust #115

dtolnay opened this issue Apr 14, 2020 · 1 comment

Comments

@dtolnay
Copy link
Owner

dtolnay commented Apr 14, 2020

Currently cxx::UniquePtr<T> in Rust is equivalent to std::unique_ptr<T> in C++, which is sensible.

However, sometimes we know a particular UniquePtr is never supposed to be null:

mod ffi {
    extern "C++" {
        type C;
        fn create() -> UniquePtr<C>; // never supposed to be null
        fn with_ref(c: &C);
    }
}

This ends up being inconvenient from the Rust side because every call to with_ref is going to do a nullness check as part of turning &UniquePtr<C> into &C to pass as the argument.

Some possibilities that would maybe be better:

  • Expose an optional second generic parameter on UniquePtr which declares non-nullability of the pointer.

    extern "C++" {
        fn create() -> UniquePtr<C, NonNull>;
    }

    Such a pointer would be checked for null as part of the return, and subsequently not require any runtime check when derefing to &C.

    This isn't great because currently we promise that none of our generated code involves any runtime checking. Maybe something with an attribute would be able to make it more obvious that the programmer is requesting a check.

    extern "C++" {
        fn create() -> #[check_nonnull] UniquePtr<C>;
    }
  • Or, break the equivalence between cxx::UniquePtr<T> and std::unique_ptr<T> and declare that UniquePtr is non-nullable, requiring Option<UniquePtr<T>> if the programmer really intends a nullable one.

    This isn't great either, because we want to build a real equivalency between corresponding types on either side of the language boundary, but it could turn out to be the least bad approach in this case.

@myronahn
Copy link
Contributor

Perhaps we could define a NonNullUniquePtr<T> which has a corresponding non_null_unique_ptr<T> in C++.

There would be a runtime check for NULL when you construct the non_null_unique_ptr<T> but there would be no check as the value moves across the FFI boundary, so it would basically push the runtime check into the C++ code (maybe where it belongs).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants