mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Rollup merge of #91323 - RalfJung:assert-type, r=oli-obk
CTFE: support assert_zero_valid and assert_uninit_valid This ensures the implementation of all three type-based assert_ intrinsics remains consistent in Miri. `assert_inhabited` recently got stabilized in https://github.com/rust-lang/rust/pull/90896 (meaning stable `const fn` can call it), so do the same with these other intrinsics. Cc ```@rust-lang/wg-const-eval```
This commit is contained in:
commit
a940c68035
@ -394,10 +394,12 @@ 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_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
|
||||
let ty = instance.substs.type_at(0);
|
||||
let layout = self.layout_of(ty)?;
|
||||
|
||||
// For *all* intrinsics we first check `is_uninhabited` to give a more specific
|
||||
// error message.
|
||||
if layout.abi.is_uninhabited() {
|
||||
// The run-time intrinsic panics just to get a good backtrace; here we abort
|
||||
// since there is no problem showing a backtrace even for aborts.
|
||||
@ -409,6 +411,28 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
),
|
||||
)?;
|
||||
}
|
||||
if intrinsic_name == sym::assert_zero_valid
|
||||
&& !layout.might_permit_raw_init(self, /*zero:*/ true)
|
||||
{
|
||||
M::abort(
|
||||
self,
|
||||
format!(
|
||||
"aborted execution: attempted to zero-initialize type `{}`, which is invalid",
|
||||
ty
|
||||
),
|
||||
)?;
|
||||
}
|
||||
if intrinsic_name == sym::assert_uninit_valid
|
||||
&& !layout.might_permit_raw_init(self, /*zero:*/ false)
|
||||
{
|
||||
M::abort(
|
||||
self,
|
||||
format!(
|
||||
"aborted execution: attempted to leave type `{}` uninitialized, which is invalid",
|
||||
ty
|
||||
),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
sym::simd_insert => {
|
||||
let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
|
||||
|
@ -860,12 +860,14 @@ extern "rust-intrinsic" {
|
||||
/// zero-initialization: This will statically either panic, or do nothing.
|
||||
///
|
||||
/// This intrinsic does not have a stable counterpart.
|
||||
#[rustc_const_unstable(feature = "const_assert_type2", issue = "none")]
|
||||
pub fn assert_zero_valid<T>();
|
||||
|
||||
/// A guard for unsafe functions that cannot ever be executed if `T` has invalid
|
||||
/// bit patterns: This will statically either panic, or do nothing.
|
||||
///
|
||||
/// This intrinsic does not have a stable counterpart.
|
||||
#[rustc_const_unstable(feature = "const_assert_type2", issue = "none")]
|
||||
pub fn assert_uninit_valid<T>();
|
||||
|
||||
/// Gets a reference to a static `Location` indicating where it was called.
|
||||
|
22
src/test/ui/consts/assert-type-intrinsics.rs
Normal file
22
src/test/ui/consts/assert-type-intrinsics.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// error-pattern: any use of this value will cause an error
|
||||
|
||||
#![feature(never_type)]
|
||||
#![feature(const_maybe_uninit_assume_init, const_assert_type2)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics;
|
||||
|
||||
#[allow(invalid_value)]
|
||||
fn main() {
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
const _BAD1: () = unsafe {
|
||||
MaybeUninit::<!>::uninit().assume_init();
|
||||
};
|
||||
const _BAD2: () = unsafe {
|
||||
intrinsics::assert_uninit_valid::<bool>();
|
||||
};
|
||||
const _BAD3: () = unsafe {
|
||||
intrinsics::assert_zero_valid::<&'static i32>();
|
||||
};
|
||||
}
|
39
src/test/ui/consts/assert-type-intrinsics.stderr
Normal file
39
src/test/ui/consts/assert-type-intrinsics.stderr
Normal file
@ -0,0 +1,39 @@
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/assert-type-intrinsics.rs:14:9
|
||||
|
|
||||
LL | / const _BAD1: () = unsafe {
|
||||
LL | | MaybeUninit::<!>::uninit().assume_init();
|
||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
|
||||
LL | | };
|
||||
| |______-
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/assert-type-intrinsics.rs:17:9
|
||||
|
|
||||
LL | / const _BAD2: () = unsafe {
|
||||
LL | | intrinsics::assert_uninit_valid::<bool>();
|
||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid
|
||||
LL | | };
|
||||
| |______-
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/assert-type-intrinsics.rs:20:9
|
||||
|
|
||||
LL | / const _BAD3: () = unsafe {
|
||||
LL | | intrinsics::assert_zero_valid::<&'static i32>();
|
||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid
|
||||
LL | | };
|
||||
| |______-
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -1,13 +0,0 @@
|
||||
// error-pattern: any use of this value will cause an error
|
||||
|
||||
#![feature(never_type)]
|
||||
#![feature(const_maybe_uninit_assume_init)]
|
||||
|
||||
#[allow(invalid_value)]
|
||||
fn main() {
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
const _BAD: () = unsafe {
|
||||
MaybeUninit::<!>::uninit().assume_init();
|
||||
};
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/assume-type-intrinsics.rs:11:9
|
||||
|
|
||||
LL | / const _BAD: () = unsafe {
|
||||
LL | | MaybeUninit::<!>::uninit().assume_init();
|
||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
|
||||
LL | | };
|
||||
| |______-
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user