Skip to content

Commit 4607447

Browse files
committed
Document layout guarantee of MaybeUninit
1 parent 165d6d6 commit 4607447

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

src/libcore/mem.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,28 @@ impl<T: ?Sized> DerefMut for ManuallyDrop<T> {
11101110
/// to its fields.
11111111
///
11121112
/// [ub]: ../../reference/behavior-considered-undefined.html
1113+
///
1114+
/// # Layout
1115+
///
1116+
/// `MaybeUninit<T>` is guaranteed to have the same size and alignment as `T`:
1117+
///
1118+
/// ```rust
1119+
/// use std::mem::{MaybeUninit, size_of, align_of};
1120+
/// assert_eq!(size_of::<MaybeUninit<u64>>(), size_of::<u64>());
1121+
/// assert_eq!(align_of::<MaybeUninit<u64>>(), size_of::<u64>());
1122+
/// ```
1123+
///
1124+
/// However remember that a type *containing* a `MaybeUninit<T>` is not necessarily the same
1125+
/// layout; Rust does not in general guarantee that the fields of a `Foo<T>` have the same order as
1126+
/// a `Foo<U>` even if `T` and `U` have the same size and alignment. Furthermore because any bit
1127+
/// value is valid for a `MaybeUninit<T>` the compiler can't apply non-zero/niche-filling
1128+
/// optimizations, potentially resulting in a larger size:
1129+
///
1130+
/// ```rust
1131+
/// # use std::mem::{MaybeUninit, size_of, align_of};
1132+
/// assert_eq!(size_of::<Option<bool>>(), 1);
1133+
/// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
1134+
/// ```
11131135
#[allow(missing_debug_implementations)]
11141136
#[stable(feature = "maybe_uninit", since = "1.36.0")]
11151137
#[derive(Copy)]

0 commit comments

Comments
 (0)