-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Allow null-pointer-optimized enums in FFI if their underlying representation is FFI safe #60300
Conversation
r? @estebank (rust_highfive has picked a reviewer for you, use r? to override) |
r? @pnkfelix |
cc @rust-lang/wg-unsafe-code-guidelines |
I do think we should change the lint to accepting types that are already effectively guaranteed to participate in Option layout optimizations (at minimum, the Relatedly, there may be So I think the check " |
@Centril Thanks; I've made the changes you recommended. Let me know if there are others. @rkruppe I agree. I've revised the code to now only allow:
I'll update the top-level comment to reflect this change. |
☔ The latest upstream changes (presumably #60435) made this pull request unmergeable. Please resolve the merge conflicts. |
The idea of this change looks great to me. We want to define this behavior, carefully, and not leave it undefined. And this allows people to define safer types for FFI functions. We do need further review on the code itself, but let's get consensus on the concept: @rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
👍 now that this is the "careful" version (following #60300 (comment)) |
... why isn't there the standard list of checkboxes for all members of labelled teams (T-lang in this case) on the rfcbot comment |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
@pnkfelix perhaps it was slow -- the list exists now |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
☔ The latest upstream changes (presumably #60630) made this pull request unmergeable. Please resolve the merge conflicts. |
Here empty means that the variant has no fields, right? That is, variants with zero-sized fields are not empty, and, for example, EDIT: many C APIs return an error code of type |
…ntation is FFI safe This allows types like Option<NonZeroU8> to be used in FFI without triggering the improper_ctypes lint. This works by changing the is_repr_nullable_ptr function to consider an enum E to be FFI-safe if: - E has no explicit #[repr(...)]. - It only has two variants. - One of those variants is empty (meaning it has no fields). - The other variant has only one field. - That field is one of the following: - &T - &mut T - extern "C" fn - core::num::NonZero* - core::ptr::NonNull<T> - #[repr(transparent)] struct wrapper around one of the types in this list. - The size of E and its field are both known and are both the same size (implying E is participating in the nonnull optimization).
Thanks, I wasn't sure what Rust's policy was on this. I'll keep that in mind going forward (also: done).
Done. |
Thank you for your work and patience! @bors r+ |
📌 Commit a31dc8e has been approved by |
Allow null-pointer-optimized enums in FFI if their underlying representation is FFI safe I'm not sure if this requires an RFC. I attempted to start [a discussion on internals.rust-lang.org](https://internals.rust-lang.org/t/options-ffi-safety-and-guarantees-for-abi-compatibility-with-nonnull-optimizations/9784) and when no one really objected I figured I'd go ahead and try implementing this. This allows types like `Option<NonZeroU8>` to be used in FFI without triggering the `improper_ctypes` lint. This works by changing the `is_repr_nullable_ptr` function to consider an enum `E` to be FFI-safe if: - `E` has no explicit `#[repr(...)]`. - It only has two variants. - One of those variants is empty (meaning it has no fields). - The other variant has only one field. - That field is one of the following: - `&T` - `&mut T` - `extern "C" fn` - `core::num::NonZero*` - `core::ptr::NonNull<T>` - `#[repr(transparent)] struct` wrapper around one of the types in this list. - The size of `E` and its field are both known and are both the same size (implying `E` is participating in the nonnull optimization). This logic seems consistent with [the Rust nomicon](https://doc.rust-lang.org/nomicon/repr-rust.html).
Rollup of 8 pull requests Successful merges: - #60300 (Allow null-pointer-optimized enums in FFI if their underlying representation is FFI safe) - #60773 (Always try to project predicates when finding auto traits in rustdoc) - #60809 (Add FAQ for NLL migration) - #61023 (Migrate from recursion to iterate on qualify consts visitor impl) - #61029 (Simplify RefCell minimum_spanning_tree example) - #61030 (Make maybe_codegen_consume_direct iterate instead of doing recursion) - #61034 (rustc_metadata: parametrize schema::CrateRoot by 'tcx and rip out old unused incremental infra.) - #61037 (Update clippy submodule) Failed merges: r? @ghost
@@ -50,6 +50,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s | |||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] | |||
#[repr(transparent)] | |||
#[rustc_layout_scalar_valid_range_start(1)] | |||
#[cfg_attr(not(stage0), rustc_nonnull_optimization_guaranteed)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this just reuse the attribute in the line above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the goal was to separate "performing the optimization" from "guaranteeing the optimization".
…guaranteed, r=jieyouxu fix rustc_nonnull_optimization_guaranteed docs As far as I can tell, even back when this was [added](rust-lang#60300) it never *enabled* any optimizations. It just indicates that the FFI compat lint should accept those types for NPO.
…d, r=jieyouxu fix rustc_nonnull_optimization_guaranteed docs As far as I can tell, even back when this was [added](rust-lang/rust#60300) it never *enabled* any optimizations. It just indicates that the FFI compat lint should accept those types for NPO.
…d, r=jieyouxu fix rustc_nonnull_optimization_guaranteed docs As far as I can tell, even back when this was [added](rust-lang/rust#60300) it never *enabled* any optimizations. It just indicates that the FFI compat lint should accept those types for NPO.
I'm not sure if this requires an RFC. I attempted to start a discussion on internals.rust-lang.org and when no one really objected I figured I'd go ahead and try implementing this.
This allows types like
Option<NonZeroU8>
to be used in FFI without triggering theimproper_ctypes
lint. This works by changing theis_repr_nullable_ptr
function to consider an enumE
to be FFI-safe if:E
has no explicit#[repr(...)]
.&T
&mut T
extern "C" fn
core::num::NonZero*
core::ptr::NonNull<T>
#[repr(transparent)] struct
wrapper around one of the types in this list.E
and its field are both known and are both the same size (implyingE
is participating in the nonnull optimization).This logic seems consistent with the Rust nomicon.