From 4607447e66024ed5e163057893f74f2832cad033 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Mon, 6 May 2019 17:39:39 -0400 Subject: [PATCH 1/2] Document layout guarantee of MaybeUninit --- src/libcore/mem.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 733c5985c33ed..b378ed89bad00 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1110,6 +1110,28 @@ impl DerefMut for ManuallyDrop { /// to its fields. /// /// [ub]: ../../reference/behavior-considered-undefined.html +/// +/// # Layout +/// +/// `MaybeUninit` is guaranteed to have the same size and alignment as `T`: +/// +/// ```rust +/// use std::mem::{MaybeUninit, size_of, align_of}; +/// assert_eq!(size_of::>(), size_of::()); +/// assert_eq!(align_of::>(), size_of::()); +/// ``` +/// +/// However remember that a type *containing* a `MaybeUninit` is not necessarily the same +/// layout; Rust does not in general guarantee that the fields of a `Foo` have the same order as +/// a `Foo` even if `T` and `U` have the same size and alignment. Furthermore because any bit +/// value is valid for a `MaybeUninit` the compiler can't apply non-zero/niche-filling +/// optimizations, potentially resulting in a larger size: +/// +/// ```rust +/// # use std::mem::{MaybeUninit, size_of, align_of}; +/// assert_eq!(size_of::>(), 1); +/// assert_eq!(size_of::>>(), 2); +/// ``` #[allow(missing_debug_implementations)] #[stable(feature = "maybe_uninit", since = "1.36.0")] #[derive(Copy)] From b992528568352571019a55b71778cb7f7e3bbb3c Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Wed, 8 May 2019 13:22:32 -0400 Subject: [PATCH 2/2] Fix typo --- src/libcore/mem.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index b378ed89bad00..ae24cc7eaf10f 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1118,7 +1118,7 @@ impl DerefMut for ManuallyDrop { /// ```rust /// use std::mem::{MaybeUninit, size_of, align_of}; /// assert_eq!(size_of::>(), size_of::()); -/// assert_eq!(align_of::>(), size_of::()); +/// assert_eq!(align_of::>(), align_of::()); /// ``` /// /// However remember that a type *containing* a `MaybeUninit` is not necessarily the same