Skip to content

Commit af0cf34

Browse files
authored
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
2 parents 27d5935 + 44b5b83 commit af0cf34

File tree

5 files changed

+41
-8
lines changed

5 files changed

+41
-8
lines changed

library/core/src/intrinsics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,7 @@ extern "rust-intrinsic" {
853853
/// This will statically either panic, or do nothing.
854854
///
855855
/// This intrinsic does not have a stable counterpart.
856-
#[rustc_const_unstable(feature = "const_assert_type", issue = "none")]
856+
#[rustc_const_stable(feature = "const_assert_type", since = "1.59.0")]
857857
pub fn assert_inhabited<T>();
858858

859859
/// A guard for unsafe functions that cannot ever be executed if `T` does not permit

library/core/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@
101101
#![feature(const_align_of_val)]
102102
#![feature(const_alloc_layout)]
103103
#![feature(const_arguments_as_str)]
104-
#![feature(const_assert_type)]
105104
#![feature(const_bigint_helper_methods)]
106105
#![feature(const_caller_location)]
107106
#![feature(const_cell_into_inner)]
@@ -117,7 +116,7 @@
117116
#![feature(const_intrinsic_copy)]
118117
#![feature(const_intrinsic_forget)]
119118
#![feature(const_likely)]
120-
#![feature(const_maybe_uninit_as_ptr)]
119+
#![feature(const_maybe_uninit_as_mut_ptr)]
121120
#![feature(const_maybe_uninit_assume_init)]
122121
#![feature(const_num_from_num)]
123122
#![feature(const_ops)]

library/core/src/mem/maybe_uninit.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ impl<T> MaybeUninit<T> {
528528
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
529529
/// until they are, it is advisable to avoid them.)
530530
#[stable(feature = "maybe_uninit", since = "1.36.0")]
531-
#[rustc_const_unstable(feature = "const_maybe_uninit_as_ptr", issue = "75251")]
531+
#[rustc_const_stable(feature = "const_maybe_uninit_as_ptr", since = "1.59.0")]
532532
#[inline(always)]
533533
pub const fn as_ptr(&self) -> *const T {
534534
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
@@ -567,7 +567,7 @@ impl<T> MaybeUninit<T> {
567567
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
568568
/// until they are, it is advisable to avoid them.)
569569
#[stable(feature = "maybe_uninit", since = "1.36.0")]
570-
#[rustc_const_unstable(feature = "const_maybe_uninit_as_ptr", issue = "75251")]
570+
#[rustc_const_unstable(feature = "const_maybe_uninit_as_mut_ptr", issue = "75251")]
571571
#[inline(always)]
572572
pub const fn as_mut_ptr(&mut self) -> *mut T {
573573
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
@@ -620,7 +620,7 @@ impl<T> MaybeUninit<T> {
620620
/// // `x` had not been initialized yet, so this last line caused undefined behavior. ⚠️
621621
/// ```
622622
#[stable(feature = "maybe_uninit", since = "1.36.0")]
623-
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
623+
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")]
624624
#[inline(always)]
625625
#[rustc_diagnostic_item = "assume_init"]
626626
#[track_caller]
@@ -788,7 +788,8 @@ impl<T> MaybeUninit<T> {
788788
/// }
789789
/// ```
790790
#[stable(feature = "maybe_uninit_ref", since = "1.55.0")]
791-
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
791+
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init", since = "1.59.0")]
792+
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_raw_ptr_deref))]
792793
#[inline(always)]
793794
pub const unsafe fn assume_init_ref(&self) -> &T {
794795
// SAFETY: the caller must guarantee that `self` is initialized.
@@ -968,7 +969,7 @@ impl<T> MaybeUninit<T> {
968969
///
969970
/// [`assume_init_ref`]: MaybeUninit::assume_init_ref
970971
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
971-
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
972+
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
972973
#[inline(always)]
973974
pub const unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
974975
// SAFETY: casting slice to a `*const [T]` is safe since the caller guarantees that

library/core/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#![feature(const_assume)]
1111
#![feature(const_cell_into_inner)]
1212
#![feature(const_convert)]
13+
#![feature(const_maybe_uninit_as_mut_ptr)]
1314
#![feature(const_maybe_uninit_assume_init)]
1415
#![feature(const_ptr_read)]
1516
#![feature(const_ptr_write)]

library/core/tests/mem.rs

+32
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,35 @@ fn uninit_const_assume_init_read() {
269269
const FOO: u32 = unsafe { MaybeUninit::new(42).assume_init_read() };
270270
assert_eq!(FOO, 42);
271271
}
272+
273+
#[test]
274+
fn const_maybe_uninit() {
275+
use std::ptr;
276+
277+
#[derive(Debug, PartialEq)]
278+
struct Foo {
279+
x: u8,
280+
y: u8,
281+
}
282+
283+
const FIELD_BY_FIELD: Foo = unsafe {
284+
let mut val = MaybeUninit::uninit();
285+
init_y(&mut val); // order shouldn't matter
286+
init_x(&mut val);
287+
val.assume_init()
288+
};
289+
290+
const fn init_x(foo: &mut MaybeUninit<Foo>) {
291+
unsafe {
292+
*ptr::addr_of_mut!((*foo.as_mut_ptr()).x) = 1;
293+
}
294+
}
295+
296+
const fn init_y(foo: &mut MaybeUninit<Foo>) {
297+
unsafe {
298+
*ptr::addr_of_mut!((*foo.as_mut_ptr()).y) = 2;
299+
}
300+
}
301+
302+
assert_eq!(FIELD_BY_FIELD, Foo { x: 1, y: 2 });
303+
}

0 commit comments

Comments
 (0)