-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Document MaybeUninit bit validity #140463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -252,6 +252,44 @@ use crate::{fmt, intrinsics, ptr, slice}; | |
/// std::process::exit(*code); // UB! Accessing uninitialized memory. | ||
/// } | ||
/// ``` | ||
/// | ||
/// # Validity | ||
/// | ||
/// A `MaybeUninit<T>` has no validity requirement – any sequence of bytes of the appropriate length, | ||
/// initialized to any value or uninitialized, are a valid value of `MaybeUninit<T>`. Equivalently, | ||
/// it is always sound to perform `transmute::<[MaybeUninit<u8>; size_of::<T>()], MaybeUninit<T>>(...)`. | ||
/// | ||
/// Note that "round-tripping" via `MaybeUninit` does not always result in the original value. | ||
/// Concretely, given distinct `T` and `U` where `size_of::<T>() == size_of::<U>()`, the following | ||
/// code is not guaranteed to be sound: | ||
/// | ||
/// ```rust,no_run | ||
/// # use core::mem::{MaybeUninit, transmute}; | ||
/// # struct T; struct U; | ||
/// fn identity(t: T) -> T { | ||
/// unsafe { | ||
/// let u: MaybeUninit<U> = transmute(t); | ||
/// transmute(u) | ||
/// } | ||
/// } | ||
/// ``` | ||
/// | ||
/// If `T` contains initialized bytes at byte offsets where `U` contains padding bytes, these | ||
/// may not be preserved in `MaybeUninit<U>`, and so `transmute(u)` may produce a `T` with | ||
/// uninitialized bytes in these positions. This is an active area of discussion, and this code | ||
/// may become sound in the future. | ||
Comment on lines
+277
to
+280
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @RalfJung I'd like some advice on this. I'm confident that this is correct as written, but could we perhaps make a stronger statement? In particular, what happens if we round-trip a value which is invalid for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per rust-lang/unsafe-code-guidelines#555 (comment), I've updated to the following text. Does that look good? /// Note that, so long as every byte position which is initialized in `T` is also initialized
/// in `U`, then the preceding `identity` example *is* sound.
|
||
/// | ||
/// Note that, so long as every byte position which is initialized in `T` is also initialized | ||
/// in `U`, then the preceding `identity` example *is* sound. | ||
/// | ||
/// # Provenance | ||
/// | ||
/// `MaybeUninit` values may contain [pointer provenance][provenance]. Concretely, for any | ||
/// pointer type, `P`, which contains provenance, transmuting `p: P` to | ||
/// `MaybeUninit<[u8; size_of::<P>]>` and then back to `P` will produce a value identical to | ||
/// `p`, including provenance. | ||
/// | ||
/// [provenance]: ../ptr/index.html#provenance | ||
#[stable(feature = "maybe_uninit", since = "1.36.0")] | ||
// Lang item so we can wrap other types in it. This is useful for coroutines. | ||
#[lang = "maybe_uninit"] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving this discussion here:
@RalfJung would you like me to add language like this to this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: I've added the following as a more concrete and fleshed out draft. I can edit or remove as preferred.