Rollup merge of #137323 - joshlf:transmute-npo, r=RalfJung

Guarantee behavior of transmuting `Option::<T>::None` subject to NPO

In https://github.com/rust-lang/rust/pull/115333, we added a guarantee that transmuting from `[0u8; N]` to `Option<P>` is sound where `P` is a pointer type subject to the null pointer optimization (NPO). It would be useful to be able to guarantee the inverse - that a `None::<P>` value can be transmutes to an array and that will yield `[0u8; N]`.

Closes #117591
This commit is contained in:
Matthias Krüger 2025-05-24 16:08:45 +02:00 committed by GitHub
commit 334d7bd698
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -120,20 +120,22 @@
//!
//! Rust guarantees to optimize the following types `T` such that
//! [`Option<T>`] has the same size, alignment, and [function call ABI] as `T`. In some
//! of these cases, Rust further guarantees that
//! `transmute::<_, Option<T>>([0u8; size_of::<T>()])` is sound and
//! produces `Option::<T>::None`. These cases are identified by the
//! second column:
//! of these cases, Rust further guarantees the following:
//! - `transmute::<_, Option<T>>([0u8; size_of::<T>()])` is sound and produces
//! `Option::<T>::None`
//! - `transmute::<_, [u8; size_of::<T>()]>(Option::<T>::None)` is sound and produces
//! `[0u8; size_of::<T>()]`
//! These cases are identified by the second column:
//!
//! | `T` | `transmute::<_, Option<T>>([0u8; size_of::<T>()])` sound? |
//! |---------------------------------------------------------------------|----------------------------------------------------------------------|
//! | [`Box<U>`] (specifically, only `Box<U, Global>`) | when `U: Sized` |
//! | `&U` | when `U: Sized` |
//! | `&mut U` | when `U: Sized` |
//! | `fn`, `extern "C" fn`[^extern_fn] | always |
//! | [`num::NonZero*`] | always |
//! | [`ptr::NonNull<U>`] | when `U: Sized` |
//! | `#[repr(transparent)]` struct around one of the types in this list. | when it holds for the inner type |
//! | `T` | Transmuting between `[0u8; size_of::<T>()]` and `Option::<T>::None` sound? |
//! |---------------------------------------------------------------------|----------------------------------------------------------------------------|
//! | [`Box<U>`] (specifically, only `Box<U, Global>`) | when `U: Sized` |
//! | `&U` | when `U: Sized` |
//! | `&mut U` | when `U: Sized` |
//! | `fn`, `extern "C" fn`[^extern_fn] | always |
//! | [`num::NonZero*`] | always |
//! | [`ptr::NonNull<U>`] | when `U: Sized` |
//! | `#[repr(transparent)]` struct around one of the types in this list. | when it holds for the inner type |
//!
//! [^extern_fn]: this remains true for any argument/return types and any other ABI: `extern "abi" fn` (_e.g._, `extern "system" fn`)
//!