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 diff --git a/src/glossary.md b/src/glossary.md index 24f9bd3d0d..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 @@ -281,10 +283,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 +370,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 diff --git a/src/special-types-and-traits.md b/src/special-types-and-traits.md index 8e2885c0b6..989a6a8fe5 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 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`. + +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 @@ -216,12 +231,14 @@ 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 +[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 +[valid]: undefined.validity [`VaList`]: core::ffi::VaList [variance]: subtyping.md#variance [zero-sized]: glossary.zst