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:
Yuki Okushi 2021-11-30 17:29:09 +09:00 committed by GitHub
commit a940c68035
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 29 deletions

View file

@ -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()?);