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(); /// 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 MaybeUninit { /// (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 MaybeUninit { /// (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 MaybeUninit { /// // `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 MaybeUninit { /// } /// ``` #[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 MaybeUninit { /// /// [`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) { + unsafe { + *ptr::addr_of_mut!((*foo.as_mut_ptr()).x) = 1; + } + } + + const fn init_y(foo: &mut MaybeUninit) { + unsafe { + *ptr::addr_of_mut!((*foo.as_mut_ptr()).y) = 2; + } + } + + assert_eq!(FIELD_BY_FIELD, Foo { x: 1, y: 2 }); +}