summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-06-19 01:52:03 +0200
committerGitHub <noreply@github.com>2019-06-19 01:52:03 +0200
commite416932bab05b70da73f0d7d9f6b751c433324fd (patch)
tree856de4eacb7c85a76e090e4241745709483f740f /src/libcore
parent06d2a891c72fa29477114d67c8672e0eaacddd0b (diff)
parent0f9dc6c48e51637a5d54fc791df94d104c1e0aee (diff)
downloadrust-e416932bab05b70da73f0d7d9f6b751c433324fd.tar.gz
rust-e416932bab05b70da73f0d7d9f6b751c433324fd.zip
Rollup merge of #61802 - mjbshaw:maybe-uninit-transparent, r=cramertj
Make MaybeUninit #[repr(transparent)]

Tracking issue: #60405
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/mem/maybe_uninit.rs16
2 files changed, 16 insertions, 1 deletions
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 030f4f1d12c..1bfb852424d 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -100,6 +100,7 @@
 #![feature(staged_api)]
 #![feature(std_internals)]
 #![feature(stmt_expr_attributes)]
+#![cfg_attr(not(bootstrap), feature(transparent_unions))]
 #![feature(unboxed_closures)]
 #![feature(unsized_locals)]
 #![feature(untagged_unions)]
diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs
index eeff9d0303a..28e1e22ba7f 100644
--- a/src/libcore/mem/maybe_uninit.rs
+++ b/src/libcore/mem/maybe_uninit.rs
@@ -172,7 +172,7 @@ use crate::mem::ManuallyDrop;
 ///
 /// # Layout
 ///
-/// `MaybeUninit<T>` is guaranteed to have the same size and alignment as `T`:
+/// `MaybeUninit<T>` is guaranteed to have the same size, alignment, and ABI as `T`:
 ///
 /// ```rust
 /// use std::mem::{MaybeUninit, size_of, align_of};
@@ -191,9 +191,23 @@ use crate::mem::ManuallyDrop;
 /// assert_eq!(size_of::<Option<bool>>(), 1);
 /// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
 /// ```
+///
+/// If `T` is FFI-safe, then so is `MaybeUninit<T>`.
+///
+/// While `MaybeUninit` is `#[repr(transparent)]` (indicating it guarantees the same size,
+/// alignment, and ABI as `T`), this does *not* change any of the previous caveats. `Option<T>` and
+/// `Option<MaybeUninit<T>>` may still have different sizes, and types containing a field of type
+/// `T` may be laid out (and sized) differently than if that field were `MaybeUninit<T>`.
+/// `MaybeUninit` is a union type, and `#[repr(transparent)]` on unions is unstable (see [the
+/// tracking issue](https://github.com/rust-lang/rust/issues/60405)). Over time, the exact
+/// guarantees of `#[repr(transparent)]` on unions may evolve, and `MaybeUninit` may or may not
+/// 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.
 #[allow(missing_debug_implementations)]
 #[stable(feature = "maybe_uninit", since = "1.36.0")]
 #[derive(Copy)]
+#[cfg_attr(not(bootstrap), repr(transparent))]
 pub union MaybeUninit<T> {
     uninit: (),
     value: ManuallyDrop<T>,