Skip to content

Commit 0f9dc6c

Browse files
committed
Make MaybeUninit #[repr(transparent)]
Tracking issue: #60405
1 parent 5f3656c commit 0f9dc6c

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
#![feature(staged_api)]
101101
#![feature(std_internals)]
102102
#![feature(stmt_expr_attributes)]
103+
#![cfg_attr(not(bootstrap), feature(transparent_unions))]
103104
#![feature(unboxed_closures)]
104105
#![feature(unsized_locals)]
105106
#![feature(untagged_unions)]

src/libcore/mem/maybe_uninit.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ use crate::mem::ManuallyDrop;
172172
///
173173
/// # Layout
174174
///
175-
/// `MaybeUninit<T>` is guaranteed to have the same size and alignment as `T`:
175+
/// `MaybeUninit<T>` is guaranteed to have the same size, alignment, and ABI as `T`:
176176
///
177177
/// ```rust
178178
/// use std::mem::{MaybeUninit, size_of, align_of};
@@ -191,9 +191,23 @@ use crate::mem::ManuallyDrop;
191191
/// assert_eq!(size_of::<Option<bool>>(), 1);
192192
/// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
193193
/// ```
194+
///
195+
/// If `T` is FFI-safe, then so is `MaybeUninit<T>`.
196+
///
197+
/// While `MaybeUninit` is `#[repr(transparent)]` (indicating it guarantees the same size,
198+
/// alignment, and ABI as `T`), this does *not* change any of the previous caveats. `Option<T>` and
199+
/// `Option<MaybeUninit<T>>` may still have different sizes, and types containing a field of type
200+
/// `T` may be laid out (and sized) differently than if that field were `MaybeUninit<T>`.
201+
/// `MaybeUninit` is a union type, and `#[repr(transparent)]` on unions is unstable (see [the
202+
/// tracking issue](https://github.com/rust-lang/rust/issues/60405)). Over time, the exact
203+
/// guarantees of `#[repr(transparent)]` on unions may evolve, and `MaybeUninit` may or may not
204+
/// remain `#[repr(transparent)]`. That said, `MaybeUninit<T>` will *always* guarantee that it has
205+
/// the same size, alignment, and ABI as `T`; it's just that the way `MaybeUninit` implements that
206+
/// guarantee may evolve.
194207
#[allow(missing_debug_implementations)]
195208
#[stable(feature = "maybe_uninit", since = "1.36.0")]
196209
#[derive(Copy)]
210+
#[cfg_attr(not(bootstrap), repr(transparent))]
197211
pub union MaybeUninit<T> {
198212
uninit: (),
199213
value: ManuallyDrop<T>,

0 commit comments

Comments
 (0)