Skip to content

Commit 4397428

Browse files
committed
Auto merge of rust-lang#79621 - usbalbin:constier_maybe_uninit, r=RalfJung
Constier maybe uninit I was playing around trying to make `[T; N]::zip()` in rust-lang#79451 be `const fn`. One of the things I bumped into was `MaybeUninit::assume_init`. Is there any reason for the intrinsic `assert_inhabited<T>()` and therefore `MaybeUninit::assume_init` not being `const`? --- I have as best as I could tried to follow the instruction in [library/core/src/intrinsics.rs](https://github.com/rust-lang/rust/blob/master/library/core/src/intrinsics.rs#L11). I have no idea what I am doing but it seems to compile after some slight changes after the copy paste. Is this anywhere near how this should be done? Also any ideas for name of the feature gate? I guess `const_maybe_assume_init` is quite misleading since I have added some more methods. Should I add test? If so what should be tested?
2 parents 7b9cfe0 + 8cca168 commit 4397428

File tree

5 files changed

+34
-11
lines changed

5 files changed

+34
-11
lines changed

core/src/intrinsics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ extern "rust-intrinsic" {
815815
/// This will statically either panic, or do nothing.
816816
///
817817
/// This intrinsic does not have a stable counterpart.
818+
#[rustc_const_unstable(feature = "const_assert_type", issue = "none")]
818819
pub fn assert_inhabited<T>();
819820

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

core/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#![feature(cfg_target_has_atomic)]
7171
#![cfg_attr(not(bootstrap), feature(const_heap))]
7272
#![feature(const_alloc_layout)]
73+
#![feature(const_assert_type)]
7374
#![feature(const_discriminant)]
7475
#![feature(const_cell_into_inner)]
7576
#![feature(const_checked_int_methods)]
@@ -93,6 +94,7 @@
9394
#![feature(const_ptr_offset)]
9495
#![feature(const_ptr_offset_from)]
9596
#![feature(const_raw_ptr_comparison)]
97+
#![feature(const_raw_ptr_deref)]
9698
#![feature(const_slice_from_raw_parts)]
9799
#![feature(const_slice_ptr_len)]
98100
#![feature(const_size_of_val)]
@@ -101,6 +103,8 @@
101103
#![feature(const_type_name)]
102104
#![feature(const_likely)]
103105
#![feature(const_unreachable_unchecked)]
106+
#![feature(const_maybe_uninit_assume_init)]
107+
#![feature(const_maybe_uninit_as_ptr)]
104108
#![feature(custom_inner_attributes)]
105109
#![feature(decl_macro)]
106110
#![feature(doc_cfg)]

core/src/mem/maybe_uninit.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,9 @@ impl<T> MaybeUninit<T> {
314314
/// let data = read(&mut buf);
315315
/// ```
316316
#[unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
317+
#[rustc_const_unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
317318
#[inline(always)]
318-
pub fn uninit_array<const LEN: usize>() -> [Self; LEN] {
319+
pub const fn uninit_array<const LEN: usize>() -> [Self; LEN] {
319320
// SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
320321
unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() }
321322
}
@@ -372,8 +373,9 @@ impl<T> MaybeUninit<T> {
372373
/// skip running the destructor. For your convenience, this also returns a mutable
373374
/// reference to the (now safely initialized) contents of `self`.
374375
#[unstable(feature = "maybe_uninit_extra", issue = "63567")]
376+
#[rustc_const_unstable(feature = "maybe_uninit_extra", issue = "63567")]
375377
#[inline(always)]
376-
pub fn write(&mut self, val: T) -> &mut T {
378+
pub const fn write(&mut self, val: T) -> &mut T {
377379
*self = MaybeUninit::new(val);
378380
// SAFETY: We just initialized this value.
379381
unsafe { self.assume_init_mut() }
@@ -503,9 +505,10 @@ impl<T> MaybeUninit<T> {
503505
/// // `x` had not been initialized yet, so this last line caused undefined behavior. ⚠️
504506
/// ```
505507
#[stable(feature = "maybe_uninit", since = "1.36.0")]
508+
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
506509
#[inline(always)]
507510
#[rustc_diagnostic_item = "assume_init"]
508-
pub unsafe fn assume_init(self) -> T {
511+
pub const unsafe fn assume_init(self) -> T {
509512
// SAFETY: the caller must guarantee that `self` is initialized.
510513
// This also means that `self` must be a `value` variant.
511514
unsafe {
@@ -666,13 +669,14 @@ impl<T> MaybeUninit<T> {
666669
/// }
667670
/// ```
668671
#[unstable(feature = "maybe_uninit_ref", issue = "63568")]
672+
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
669673
#[inline(always)]
670-
pub unsafe fn assume_init_ref(&self) -> &T {
674+
pub const unsafe fn assume_init_ref(&self) -> &T {
671675
// SAFETY: the caller must guarantee that `self` is initialized.
672676
// This also means that `self` must be a `value` variant.
673677
unsafe {
674678
intrinsics::assert_inhabited::<T>();
675-
&*self.value
679+
&*self.as_ptr()
676680
}
677681
}
678682

@@ -788,13 +792,14 @@ impl<T> MaybeUninit<T> {
788792
// to uninitialized data (e.g., in `libcore/fmt/float.rs`). We should make
789793
// a final decision about the rules before stabilization.
790794
#[unstable(feature = "maybe_uninit_ref", issue = "63568")]
795+
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
791796
#[inline(always)]
792-
pub unsafe fn assume_init_mut(&mut self) -> &mut T {
797+
pub const unsafe fn assume_init_mut(&mut self) -> &mut T {
793798
// SAFETY: the caller must guarantee that `self` is initialized.
794799
// This also means that `self` must be a `value` variant.
795800
unsafe {
796801
intrinsics::assert_inhabited::<T>();
797-
&mut *self.value
802+
&mut *self.as_mut_ptr()
798803
}
799804
}
800805

@@ -810,8 +815,9 @@ impl<T> MaybeUninit<T> {
810815
///
811816
/// [`assume_init_ref`]: MaybeUninit::assume_init_ref
812817
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
818+
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
813819
#[inline(always)]
814-
pub unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
820+
pub const unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
815821
// SAFETY: casting slice to a `*const [T]` is safe since the caller guarantees that
816822
// `slice` is initialized, and`MaybeUninit` is guaranteed to have the same layout as `T`.
817823
// The pointer obtained is valid since it refers to memory owned by `slice` which is a
@@ -831,24 +837,27 @@ impl<T> MaybeUninit<T> {
831837
///
832838
/// [`assume_init_mut`]: MaybeUninit::assume_init_mut
833839
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
840+
#[rustc_const_unstable(feature = "const_maybe_uninit_assume_init", issue = "none")]
834841
#[inline(always)]
835-
pub unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
842+
pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
836843
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
837844
// mutable reference which is also guaranteed to be valid for writes.
838845
unsafe { &mut *(slice as *mut [Self] as *mut [T]) }
839846
}
840847

841848
/// Gets a pointer to the first element of the array.
842849
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
850+
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
843851
#[inline(always)]
844-
pub fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
852+
pub const fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
845853
this.as_ptr() as *const T
846854
}
847855

848856
/// Gets a mutable pointer to the first element of the array.
849857
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
858+
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
850859
#[inline(always)]
851-
pub fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
860+
pub const fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
852861
this.as_mut_ptr() as *mut T
853862
}
854863
}

core/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![feature(cfg_target_has_atomic)]
1212
#![feature(const_assume)]
1313
#![feature(const_cell_into_inner)]
14+
#![feature(const_maybe_uninit_assume_init)]
1415
#![feature(core_intrinsics)]
1516
#![feature(core_private_bignum)]
1617
#![feature(core_private_diy_float)]

core/tests/mem.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,11 @@ fn test_discriminant_send_sync() {
129129
is_send_sync::<Discriminant<Regular>>();
130130
is_send_sync::<Discriminant<NotSendSync>>();
131131
}
132+
133+
#[test]
134+
#[cfg(not(bootstrap))]
135+
fn assume_init_good() {
136+
const TRUE: bool = unsafe { MaybeUninit::<bool>::new(true).assume_init() };
137+
138+
assert!(TRUE);
139+
}

0 commit comments

Comments
 (0)