Skip to content

Commit

Permalink
docs: transmute<&mut T, &mut MaybeUninit<T>> is unsound when expose…
Browse files Browse the repository at this point in the history
…d to safe code

In the playground the example program terminates with an unpredictable exit
code. The undefined behavior is also detected by miri:

    error: Undefined Behavior: using uninitialized data
  • Loading branch information
Enselic committed Dec 22, 2024
1 parent 8a1f803 commit 2305012
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,26 @@ use crate::{fmt, intrinsics, ptr, slice};
/// remain `#[repr(transparent)]`. That said, `MaybeUninit<T>` will *always* guarantee that it has
/// the same size, alignment, and ABI as `T`; it's just that the way `MaybeUninit` implements that
/// guarantee may evolve.
///
/// Note that even though `T` and `MaybeUninit<T>` are ABI compatible it is still unsound to
/// transmute `&mut T` to `&mut MaybeUninit<T>` and expose that to safe code because it would allow
/// safe code to access uninitialized memory:
///
/// ```rust,no_run
/// use core::mem::MaybeUninit;
///
/// fn unsound_transmute<T>(val: &mut T) -> &mut MaybeUninit<T> {
/// unsafe { core::mem::transmute(val) }
/// }
///
/// fn main() {
/// let mut code = 0;
/// let code = &mut code;
/// let code2 = unsound_transmute(code);
/// *code2 = MaybeUninit::uninit();
/// std::process::exit(*code); // UB! Accessing uninitialized memory.
/// }
/// ```
#[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"]
Expand Down

0 comments on commit 2305012

Please sign in to comment.