Skip to content

Commit 0792da3

Browse files
authored
Document MaybeUninit bit validity
1 parent efcbb94 commit 0792da3

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

library/core/src/mem/maybe_uninit.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,30 @@ use crate::{fmt, intrinsics, ptr, slice};
252252
/// std::process::exit(*code); // UB! Accessing uninitialized memory.
253253
/// }
254254
/// ```
255+
///
256+
/// # Validity
257+
///
258+
/// A `MaybeUninit<T>` has no validity requirement – any sequence of bytes of the appropriate length,
259+
/// initialized to any value or uninitialized, are a valid value of `MaybeUninit<T>`. Equivalently,
260+
/// it is always sound to perform `transmute::<[MaybeUninit<u8>; size_of::<T>()], MaybeUninit<T>>(...)`.
261+
///
262+
/// Note that "round-tripping" via `MaybeUninit` does not always result in the original value.
263+
/// Concretely, given distinct `T` and `U` where `size_of::<T>() == size_of::<U>()`, the following
264+
/// code is not guaranteed to be sound:
265+
///
266+
/// ```rust,no_run
267+
/// # use core::mem::{MaybeUninit, transmute};
268+
/// # struct T; struct U;
269+
/// fn identity(t: T) -> T {
270+
/// let u: MaybeUninit<U> = transmute(t);
271+
/// transmute(u)
272+
/// }
273+
/// ```
274+
///
275+
/// If `T` contains initialized bytes at byte offsets where `U` contains padding bytes, these
276+
/// may not be preserved in `MaybeUninit<U>`, and so `transmute(u)` may produce a `T` with
277+
/// uninitialized bytes in these positions. This is an active area of discussion, and this code
278+
/// may become sound in the future.
255279
#[stable(feature = "maybe_uninit", since = "1.36.0")]
256280
// Lang item so we can wrap other types in it. This is useful for coroutines.
257281
#[lang = "maybe_uninit"]

0 commit comments

Comments
 (0)