about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-11-28 10:42:38 +0100
committerGitHub <noreply@github.com>2021-11-28 10:42:38 +0100
commitaf0cf347875b696a1f01634e9a761bbccccd1de6 (patch)
treefe55be6c1bc0f9750f271b703106e5546deaa030
parent27d5935df18d7035c9bd8dc5c1dfbbad6ac59793 (diff)
parent44b5b838d2a58fb683324e2336a6766d450b0626 (diff)
Rollup merge of #90896 - jhpratt:stabilize_const_maybe_uninit, r=oli-obk
Stabilize some `MaybeUninit` behavior as const

This stabilizes the `MaybeUninit::as_ptr`, `MaybeUninit::assume_init`, and `MaybeUninit::assume_init_ref` as `const fn`. `MaybeUninit::as_mut_ptr` has been moved to a new flag: `const_maybe_uninit_as_mut_ptr`, which is blocked on #57349. `MaybeUninit::slice_assume_init_ref` can be `const fn` when the method is stabilized in general.

The relevant intrinsic has been stabilized as `const` as well, though this isn't user-visible. Due to the seemingly unrelated feature name I performed `rg const_assert_type` and found no other instances of it being used.

r? `@oli-obk`

`@rustbot` label: +A-const-fn +S-waiting-on-review +T-libs-api
-rw-r--r--library/core/src/intrinsics.rs2
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/mem/maybe_uninit.rs11
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/mem.rs32
5 files changed, 41 insertions, 8 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 0f57fb5b141..23b28766d70 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -853,7 +853,7 @@ extern "rust-intrinsic" {
     /// This will statically either panic, or do nothing.
     ///
     /// This intrinsic does not have a stable counterpart.
-    #[rustc_const_unstable(feature = "const_assert_type", issue = "none")]
+    #[rustc_const_stable(feature = "const_assert_type", since = "1.59.0")]
     pub fn assert_inhabited<T>();
 
     /// A guard for unsafe functions that cannot ever be executed if `T` does not permit
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index fdb23529599..102e6f89eb8 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -101,7 +101,6 @@
 #![feature(const_align_of_val)]
 #![feature(const_alloc_layout)]
 #![feature(const_arguments_as_str)]
-#![feature(const_assert_type)]
 #![feature(const_bigint_helper_methods)]
 #![feature(const_caller_location)]
 #![feature(const_cell_into_inner)]
@@ -117,7 +116,7 @@
 #![feature(const_intrinsic_copy)]
 #![feature(const_intrinsic_forget)]
 #![feature(const_likely)]
-#![feature(const_maybe_uninit_as_ptr)]
+#![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_maybe_uninit_assume_init)]
 #![feature(const_num_from_num)]
 #![feature(const_ops)]
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 624e8795502..a6e31452edc 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -528,7 +528,7 @@ impl<T> MaybeUninit<T> {
     /// (Notice that the rules around references to uninitialized data are not finalized yet, but
     /// until they are, it is advisable to avoid them.)
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
-    #[rustc_const_unstable(feature = "const_maybe_uninit_as_ptr", issue = "75251")]
+    #[rustc_const_stable(feature = "const_maybe_uninit_as_ptr", since = "1.59.0")]
     #[inline(always)]
     pub const fn as_ptr(&self) -> *const T {
         // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
@@ -567,7 +567,7 @@ impl<T> MaybeUninit<T> {
     /// (Notice that the rules around references to uninitialized data are not finalized yet, but
     /// until they are, it is advisable to avoid them.)
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
-    #[rustc_const_unstable(feature = "const_maybe_uninit_as_ptr", issue = "75251")]
+    #[rustc_const_unstable(feature = "const_maybe_uninit_as_mut_ptr", issue = "75251")]
     #[inline(always)]
     pub const fn as_mut_ptr(&mut self) -> *mut T {
         // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
@@ -620,7 +620,7 @@ impl<T> MaybeUninit<T> {
     /// // `x` had not been initialized yet, so this last line caused undefined behavior. ⚠️
     /// ```
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
-    #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
+    #[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")]
     #[inline(always)]
     #[rustc_diagnostic_item = "assume_init"]
     #[track_caller]
@@ -788,7 +788,8 @@ impl<T> MaybeUninit<T> {
     /// }
     /// ```
     #[stable(feature = "maybe_uninit_ref", since = "1.55.0")]
-    #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
+    #[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")]
+    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_raw_ptr_deref))]
     #[inline(always)]
     pub const unsafe fn assume_init_ref(&self) -> &T {
         // SAFETY: the caller must guarantee that `self` is initialized.
@@ -968,7 +969,7 @@ impl<T> MaybeUninit<T> {
     ///
     /// [`assume_init_ref`]: MaybeUninit::assume_init_ref
     #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
-    #[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
+    #[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
     #[inline(always)]
     pub const unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
         // SAFETY: casting slice to a `*const [T]` is safe since the caller guarantees that
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 4563c2085c1..00d0259321d 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -10,6 +10,7 @@
 #![feature(const_assume)]
 #![feature(const_cell_into_inner)]
 #![feature(const_convert)]
+#![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_maybe_uninit_assume_init)]
 #![feature(const_ptr_read)]
 #![feature(const_ptr_write)]
diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs
index c780bb32ca9..3b13dc0832f 100644
--- a/library/core/tests/mem.rs
+++ b/library/core/tests/mem.rs
@@ -269,3 +269,35 @@ fn uninit_const_assume_init_read() {
     const FOO: u32 = unsafe { MaybeUninit::new(42).assume_init_read() };
     assert_eq!(FOO, 42);
 }
+
+#[test]
+fn const_maybe_uninit() {
+    use std::ptr;
+
+    #[derive(Debug, PartialEq)]
+    struct Foo {
+        x: u8,
+        y: u8,
+    }
+
+    const FIELD_BY_FIELD: Foo = unsafe {
+        let mut val = MaybeUninit::uninit();
+        init_y(&mut val); // order shouldn't matter
+        init_x(&mut val);
+        val.assume_init()
+    };
+
+    const fn init_x(foo: &mut MaybeUninit<Foo>) {
+        unsafe {
+            *ptr::addr_of_mut!((*foo.as_mut_ptr()).x) = 1;
+        }
+    }
+
+    const fn init_y(foo: &mut MaybeUninit<Foo>) {
+        unsafe {
+            *ptr::addr_of_mut!((*foo.as_mut_ptr()).y) = 2;
+        }
+    }
+
+    assert_eq!(FIELD_BY_FIELD, Foo { x: 1, y: 2 });
+}