about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-05-24 16:08:45 +0200
committerGitHub <noreply@github.com>2025-05-24 16:08:45 +0200
commit334d7bd698ca8a6c90824afe42a4c307d0692fea (patch)
treea1f6e0aaffb2876e333d3150425d7fd1f9f0bd39
parent3de4f1ccf3873782fae2a3883d029ed3d4542581 (diff)
parent0fdeab95250126d135a4bf14cb8959038481204c (diff)
downloadrust-334d7bd698ca8a6c90824afe42a4c307d0692fea.tar.gz
rust-334d7bd698ca8a6c90824afe42a4c307d0692fea.zip
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
-rw-r--r--library/core/src/option.rs30
1 files changed, 16 insertions, 14 deletions
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index aed5a043c11..1d264b26076 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -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:
-//!
-//! | `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                                     |
+//! 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`                                                                 | 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`)
 //!