Skip to content

Commit 8bd80e2

Browse files
committed
Make some of MaybeUninit's methods const
1 parent 18aa5ee commit 8bd80e2

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

compiler/rustc_mir/src/interpret/intrinsics.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,30 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
407407
sym::transmute => {
408408
self.copy_op_transmute(args[0], dest)?;
409409
}
410+
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
411+
let ty = instance.substs.type_at(0);
412+
let layout = self.layout_of(ty)?;
413+
414+
if layout.abi.is_uninhabited() {
415+
throw_ub_format!("attempted to instantiate uninhabited type `{}`", ty);
416+
}
417+
if intrinsic_name == sym::assert_zero_valid
418+
&& !layout.might_permit_raw_init(self, /*zero:*/ true).unwrap()
419+
{
420+
throw_ub_format!(
421+
"attempted to zero-initialize type `{}`, which is invalid",
422+
ty
423+
);
424+
}
425+
if intrinsic_name == sym::assert_uninit_valid
426+
&& !layout.might_permit_raw_init(self, /*zero:*/ false).unwrap()
427+
{
428+
throw_ub_format!(
429+
"attempted to leave type `{}` uninitialized, which is invalid",
430+
ty
431+
);
432+
}
433+
}
410434
sym::simd_insert => {
411435
let index = u64::from(self.read_scalar(args[1])?.to_u32()?);
412436
let elem = args[2];

library/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_maybe_assume_init", 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

library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
#![feature(const_type_name)]
101101
#![feature(const_likely)]
102102
#![feature(const_unreachable_unchecked)]
103+
#![feature(const_maybe_assume_init)]
103104
#![feature(custom_inner_attributes)]
104105
#![feature(decl_macro)]
105106
#![feature(doc_cfg)]

library/core/src/mem/maybe_uninit.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,10 @@ 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 = "const_maybe_assume_init", issue = "none")]
318+
#[rustc_allow_const_fn_unstable(const_maybe_assume_init)]
317319
#[inline(always)]
318-
pub fn uninit_array<const LEN: usize>() -> [Self; LEN] {
320+
pub const fn uninit_array<const LEN: usize>() -> [Self; LEN] {
319321
// SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
320322
unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() }
321323
}
@@ -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_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 {

0 commit comments

Comments
 (0)