]> git.lizzy.rs Git - rust.git/commitdiff
Document layout guarantee of MaybeUninit
authorPeter Todd <pete@petertodd.org>
Mon, 6 May 2019 21:39:39 +0000 (17:39 -0400)
committerRalf Jung <post@ralfj.de>
Mon, 20 May 2019 08:44:02 +0000 (10:44 +0200)
src/libcore/mem.rs

index b7af9c0cef9c71558346ddde56af6282e2a0e64c..24bee6355a7ccfe41f9e868b32a71718b52a2fcb 100644 (file)
@@ -1053,6 +1053,28 @@ fn deref_mut(&mut self) -> &mut T {
 /// to its fields.
 ///
 /// [ub]: ../../reference/behavior-considered-undefined.html
+///
+/// # Layout
+///
+/// `MaybeUninit<T>` is guaranteed to have the same size and alignment as `T`:
+///
+/// ```rust
+/// use std::mem::{MaybeUninit, size_of, align_of};
+/// assert_eq!(size_of::<MaybeUninit<u64>>(), size_of::<u64>());
+/// assert_eq!(align_of::<MaybeUninit<u64>>(), align_of::<u64>());
+/// ```
+///
+/// However remember that a type *containing* a `MaybeUninit<T>` is not necessarily the same
+/// layout; Rust does not in general guarantee that the fields of a `Foo<T>` have the same order as
+/// a `Foo<U>` even if `T` and `U` have the same size and alignment. Furthermore because any bit
+/// value is valid for a `MaybeUninit<T>` 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::<Option<bool>>(), 1);
+/// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
+/// ```
 #[allow(missing_debug_implementations)]
 #[stable(feature = "maybe_uninit", since = "1.36.0")]
 #[derive(Copy)]