From 33ec846f15e4afac03b95ccc67fc4cf8e58fe549 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 20 Oct 2026 11:19:58 -0700 Subject: [PATCH 1/7] Special types and traits: add `core::mem::MaybeUninit` --- src/special-types-and-traits.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/special-types-and-traits.md b/src/special-types-and-traits.md index 8e2885c0b6..c5689428b2 100644 --- a/src/special-types-and-traits.md +++ b/src/special-types-and-traits.md @@ -48,6 +48,18 @@ r[lang-types.unsafe-cell.interior-mut] r[lang-types.unsafe-cell.read-only-alloc] It also ensures that [`static` items] which have a type with interior mutability aren't placed in memory marked as read only. +r[lang-types.maybe-uninit] +## `MaybeUninit` + +r[lang-types.maybe-uninit.intro] +[`MaybeUninit`] is a wrapper type used to construct uninitialized values of type `T`. + +r[lang-types.maybe-uninit.validity] +The value of a [`MaybeUninit`] is always [valid], regardless of any validity requirements for a value of type `T`. + +r[lang-types.maybe-uninit.layout] +[`MaybeUninit`] is guaranteed to have the same [size], [alignment], and [ABI] as `T`. + r[lang-types.phantom-data] ## `PhantomData` @@ -188,6 +200,7 @@ These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound [`Arc`]: std::sync::Arc [`Deref`]: std::ops::Deref [`DerefMut`]: std::ops::DerefMut +[`MaybeUninit`]: core::mem::MaybeUninit [`Pin

`]: std::pin::Pin [`Rc`]: std::rc::Rc [`RefUnwindSafe`]: std::panic::RefUnwindSafe @@ -196,6 +209,8 @@ These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound [`Unpin`]: std::marker::Unpin [1-aligned]: layout.properties.align +[ABI]: glossary.abi +[alignment]: layout.properties.align [Arrays]: types/array.md [associated types]: items/associated-items.md#associated-types [call expressions]: expressions/call-expr.md @@ -217,12 +232,14 @@ These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound [operators]: expressions/operator-expr.md [orphan rules]: items/implementations.md#trait-implementation-coherence [`static` items]: items/static-items.md +[size]: layout.properties.size [test functions]: attributes/testing.md#the-test-attribute [the standard library]: std [trait object]: types/trait-object.md [Tuples]: types/tuple.md [Type parameters]: types/parameters.md [`VaList`]: core::ffi::VaList +[valid]: undefined.validity [variance]: subtyping.md#variance [zero-sized]: glossary.zst [Closures]: types/closure.md From 491968190dd42cdd46b0f8c9bf58661fb715305d Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 20 Oct 2026 11:23:57 -0700 Subject: [PATCH 2/7] Behavior considered undefined: `core::mem::MaybeUninit` is always valid --- src/behavior-considered-undefined.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index ff34d0af28..a6b3eb3c27 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -144,6 +144,9 @@ r[undefined.validity.struct] r[undefined.validity.union] * For a `union`, the exact validity requirements are not decided yet. Obviously, all values that can be created entirely in safe code are valid. If the union has a [zero-sized] field, then every possible value is valid. Further details are [still being debated](https://github.com/rust-lang/unsafe-code-guidelines/issues/438). +r[undefined.validity.maybe-uninit] +* A [`MaybeUninit`] is always valid (see [lang-types.maybe-uninit.validity]). + r[undefined.validity.reference-box] * A reference or [`Box`] must be aligned and non-null, it cannot be [dangling], and it must point to a valid value (in case of dynamically sized types, using the actual dynamic type of the pointee as determined by the [metadata]). Note that the last point (about pointing to a valid value) remains a subject of some debate. @@ -203,6 +206,7 @@ r[undefined.validity.undef] [`target_feature`]: attributes/codegen.md#the-target_feature-attribute [`UnsafeCell`]: std::cell::UnsafeCell [Rustonomicon]: ../nomicon/index.html +[`MaybeUninit`]: core::mem::MaybeUninit [metadata]: dynamic-sized.pointer-types [`NonNull`]: core::ptr::NonNull [`NonZero`]: core::num::NonZero From 434129bfed93743b4ec3dbc45150d5cee112e9dd Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 20 Oct 2026 11:28:23 -0700 Subject: [PATCH 3/7] Glossary: add `core::mem::MaybeUninit` as sometimes a ZST --- src/glossary.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/glossary.md b/src/glossary.md index 24f9bd3d0d..ba00b6be84 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -281,10 +281,11 @@ A type is zero sized (a ZST) if its size is 0. Such types have at most one possi - [Arrays] of length zero (see [layout.array]). - [Unions] of zero-sized types (see [items.union.common-storage]). - [`PhantomData`] for any type `T` (see [lang-types.phantom-data]). +- [`MaybeUninit`] for a type `T` that is itself a zero-sized type (see [lang-types.maybe-uninit.layout]). ```rust # use core::marker::PhantomData; -# use core::mem::{size_of, size_of_val}; +# use core::mem::{MaybeUninit, size_of, size_of_val}; fn f() {} struct S(u8); enum E { V(u8) } @@ -367,10 +368,12 @@ assert_eq!(0, size_of::()); assert_eq!(0, size_of::>()); # // `PhantomData` for a type that is not a ZST. assert_eq!(0, size_of::>()); +assert_eq!(0, size_of::>()); ``` [`extern` blocks]: items.extern [`extern fn`]: items.fn.extern +[`MaybeUninit`]: lang-types.maybe-uninit [`PhantomData`]: lang-types.phantom-data [alignment]: type-layout.md#size-and-alignment [arrays]: type.array From 398e5ae19f1f25b0d9046c27258cc9923050ea79 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 20 Oct 2026 11:29:59 -0700 Subject: [PATCH 4/7] Glossary: add `core::mem::MaybeUninit` as sometimes a 1-ZST --- src/glossary.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/glossary.md b/src/glossary.md index ba00b6be84..cb3198bfcc 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -124,10 +124,11 @@ Examples of 1-ZSTs include: - `repr(transparent)` [structs] with no fields or where all fields are 1-ZSTs (see [layout.repr.transparent.layout-abi]). - [Arrays] of 1-ZSTs (see [layout.array]). - [`PhantomData`] for any type `T` (see [lang-types.phantom-data]). +- [`MaybeUninit`] for a type `T` that is itself a 1-ZST (see [lang-types.maybe-uninit.layout]). ```rust # use core::marker::PhantomData; -# use core::mem::{align_of, size_of}; +# use core::mem::{MaybeUninit, align_of, size_of}; #[repr(C)] struct C1 {} #[repr(C)] @@ -157,6 +158,7 @@ assert!(is_1_zst::()); assert!(is_1_zst::()); assert!(is_1_zst::>()); assert!(is_1_zst::>()); +assert!(is_1_zst::>()); ``` ### Name From 72c5956419c65be99d925c46262eb723c55c8616 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 20 Oct 2026 20:07:42 +0000 Subject: [PATCH 5/7] Revise wording of `maybe-uninit.validity` rule Let's say this a bit more clearly. (The restatement in `undefined.validity.maybe-uninit` already reads OK.) --- src/special-types-and-traits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/special-types-and-traits.md b/src/special-types-and-traits.md index c5689428b2..d8c74b0628 100644 --- a/src/special-types-and-traits.md +++ b/src/special-types-and-traits.md @@ -55,7 +55,7 @@ r[lang-types.maybe-uninit.intro] [`MaybeUninit`] is a wrapper type used to construct uninitialized values of type `T`. r[lang-types.maybe-uninit.validity] -The value of a [`MaybeUninit`] is always [valid], regardless of any validity requirements for a value of type `T`. +A value of type [`MaybeUninit`] is always [valid], regardless of any validity requirements for a value of type `T`. r[lang-types.maybe-uninit.layout] [`MaybeUninit`] is guaranteed to have the same [size], [alignment], and [ABI] as `T`. From 7d5ed739de3b7c4e5a4235dc6db5913a133f24b3 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 20 Oct 2026 20:25:08 +0000 Subject: [PATCH 6/7] Fix ordering of link reference definitions The placement of the new items didn't follow the ordering convention used in this list. Let's fix the placement of these. --- src/special-types-and-traits.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/special-types-and-traits.md b/src/special-types-and-traits.md index d8c74b0628..3a6817367a 100644 --- a/src/special-types-and-traits.md +++ b/src/special-types-and-traits.md @@ -231,15 +231,15 @@ These implicit `Sized` bounds may be relaxed by using the special `?Sized` bound [moved from]: expr.move.movable-place [operators]: expressions/operator-expr.md [orphan rules]: items/implementations.md#trait-implementation-coherence -[`static` items]: items/static-items.md [size]: layout.properties.size +[`static` items]: items/static-items.md [test functions]: attributes/testing.md#the-test-attribute [the standard library]: std [trait object]: types/trait-object.md [Tuples]: types/tuple.md [Type parameters]: types/parameters.md -[`VaList`]: core::ffi::VaList [valid]: undefined.validity +[`VaList`]: core::ffi::VaList [variance]: subtyping.md#variance [zero-sized]: glossary.zst [Closures]: types/closure.md From 7b2bb6d87ebb6be11903f68d41112001ec87c78c Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 20 Oct 2026 20:39:22 +0000 Subject: [PATCH 7/7] Revise wording of `maybe-uninit.intro` The proposed wording here was taken from the documentation in the standard library. That text is a bit loose. It says that the type is "used to construct uninitialized values of type `T`", but of course we're using it to construct *initialized* values of type `T`, not *uninitialized* ones. And that's only one use case. It's indeed a bit tricky to concisely describe `MaybeUninit`. Let's try to do a bit better. --- src/special-types-and-traits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/special-types-and-traits.md b/src/special-types-and-traits.md index 3a6817367a..989a6a8fe5 100644 --- a/src/special-types-and-traits.md +++ b/src/special-types-and-traits.md @@ -52,7 +52,7 @@ r[lang-types.maybe-uninit] ## `MaybeUninit` r[lang-types.maybe-uninit.intro] -[`MaybeUninit`] is a wrapper type used to construct uninitialized values of type `T`. +[`MaybeUninit`] is a type for values that are laid out like a `T` but need not be a valid `T`. This is useful when allocating and writing to memory intended for `T` values before that memory holds a valid `T`, as when initializing such values in place. r[lang-types.maybe-uninit.validity] A value of type [`MaybeUninit`] is always [valid], regardless of any validity requirements for a value of type `T`.