Skip to content

Commit 2a15dec

Browse files
petertoddRalfJung
authored andcommitted
Document layout guarantee of MaybeUninit
1 parent 4bf500f commit 2a15dec

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

Diff for: src/libcore/mem.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,28 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
10531053
/// to its fields.
10541054
///
10551055
/// [ub]: ../../reference/behavior-considered-undefined.html
1056+
///
1057+
/// # Layout
1058+
///
1059+
/// `MaybeUninit<T>` is guaranteed to have the same size and alignment as `T`:
1060+
///
1061+
/// ```rust
1062+
/// use std::mem::{MaybeUninit, size_of, align_of};
1063+
/// assert_eq!(size_of::<MaybeUninit<u64>>(), size_of::<u64>());
1064+
/// assert_eq!(align_of::<MaybeUninit<u64>>(), align_of::<u64>());
1065+
/// ```
1066+
///
1067+
/// However remember that a type *containing* a `MaybeUninit<T>` is not necessarily the same
1068+
/// layout; Rust does not in general guarantee that the fields of a `Foo<T>` have the same order as
1069+
/// a `Foo<U>` even if `T` and `U` have the same size and alignment. Furthermore because any bit
1070+
/// value is valid for a `MaybeUninit<T>` the compiler can't apply non-zero/niche-filling
1071+
/// optimizations, potentially resulting in a larger size:
1072+
///
1073+
/// ```rust
1074+
/// # use std::mem::{MaybeUninit, size_of, align_of};
1075+
/// assert_eq!(size_of::<Option<bool>>(), 1);
1076+
/// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
1077+
/// ```
10561078
#[allow(missing_debug_implementations)]
10571079
#[stable(feature = "maybe_uninit", since = "1.36.0")]
10581080
#[derive(Copy)]

0 commit comments

Comments
 (0)