Make some of MaybeUninit's methods const
This commit is contained in:
parent
18aa5ee209
commit
8bd80e25f0
@ -407,6 +407,30 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
sym::transmute => {
|
||||
self.copy_op_transmute(args[0], dest)?;
|
||||
}
|
||||
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
|
||||
let ty = instance.substs.type_at(0);
|
||||
let layout = self.layout_of(ty)?;
|
||||
|
||||
if layout.abi.is_uninhabited() {
|
||||
throw_ub_format!("attempted to instantiate uninhabited type `{}`", ty);
|
||||
}
|
||||
if intrinsic_name == sym::assert_zero_valid
|
||||
&& !layout.might_permit_raw_init(self, /*zero:*/ true).unwrap()
|
||||
{
|
||||
throw_ub_format!(
|
||||
"attempted to zero-initialize type `{}`, which is invalid",
|
||||
ty
|
||||
);
|
||||
}
|
||||
if intrinsic_name == sym::assert_uninit_valid
|
||||
&& !layout.might_permit_raw_init(self, /*zero:*/ false).unwrap()
|
||||
{
|
||||
throw_ub_format!(
|
||||
"attempted to leave type `{}` uninitialized, which is invalid",
|
||||
ty
|
||||
);
|
||||
}
|
||||
}
|
||||
sym::simd_insert => {
|
||||
let index = u64::from(self.read_scalar(args[1])?.to_u32()?);
|
||||
let elem = args[2];
|
||||
|
@ -815,6 +815,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_maybe_assume_init", issue = "none")]
|
||||
pub fn assert_inhabited<T>();
|
||||
|
||||
/// A guard for unsafe functions that cannot ever be executed if `T` does not permit
|
||||
|
@ -100,6 +100,7 @@
|
||||
#![feature(const_type_name)]
|
||||
#![feature(const_likely)]
|
||||
#![feature(const_unreachable_unchecked)]
|
||||
#![feature(const_maybe_assume_init)]
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(doc_cfg)]
|
||||
|
@ -314,8 +314,10 @@ impl<T> MaybeUninit<T> {
|
||||
/// let data = read(&mut buf);
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
|
||||
#[rustc_const_unstable(feature = "const_maybe_assume_init", issue = "none")]
|
||||
#[rustc_allow_const_fn_unstable(const_maybe_assume_init)]
|
||||
#[inline(always)]
|
||||
pub fn uninit_array<const LEN: usize>() -> [Self; LEN] {
|
||||
pub const fn uninit_array<const LEN: usize>() -> [Self; LEN] {
|
||||
// SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
|
||||
unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() }
|
||||
}
|
||||
@ -503,9 +505,10 @@ 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_assume_init", issue = "none")]
|
||||
#[inline(always)]
|
||||
#[rustc_diagnostic_item = "assume_init"]
|
||||
pub unsafe fn assume_init(self) -> T {
|
||||
pub const unsafe fn assume_init(self) -> T {
|
||||
// SAFETY: the caller must guarantee that `self` is initialized.
|
||||
// This also means that `self` must be a `value` variant.
|
||||
unsafe {
|
||||
|
Loading…
x
Reference in New Issue
Block a user