diff options
| author | Yuki Okushi <jtitor@2k36.org> | 2021-11-30 17:29:09 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-30 17:29:09 +0900 |
| commit | a940c680355ab5ba59705603837939f4deabf56c (patch) | |
| tree | 4e9f72b0e7ac77f647d4494920d4b4fa6f6c9e5e | |
| parent | ae1badb0474f593a4b8b21f21736b24fb85c9d6f (diff) | |
| parent | 6c3c3e0952b63cfae51392863e94d79c2d76deb9 (diff) | |
| download | rust-a940c680355ab5ba59705603837939f4deabf56c.tar.gz rust-a940c680355ab5ba59705603837939f4deabf56c.zip | |
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```
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/intrinsics.rs | 26 | ||||
| -rw-r--r-- | library/core/src/intrinsics.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/consts/assert-type-intrinsics.rs | 22 | ||||
| -rw-r--r-- | src/test/ui/consts/assert-type-intrinsics.stderr | 39 | ||||
| -rw-r--r-- | src/test/ui/consts/assume-type-intrinsics.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/consts/assume-type-intrinsics.stderr | 15 |
6 files changed, 88 insertions, 29 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 44da27a43db..025d2998b00 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -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()?); diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 23b28766d70..edbc250eb0d 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -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. diff --git a/src/test/ui/consts/assert-type-intrinsics.rs b/src/test/ui/consts/assert-type-intrinsics.rs new file mode 100644 index 00000000000..31ff6aed03b --- /dev/null +++ b/src/test/ui/consts/assert-type-intrinsics.rs @@ -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>(); + }; +} diff --git a/src/test/ui/consts/assert-type-intrinsics.stderr b/src/test/ui/consts/assert-type-intrinsics.stderr new file mode 100644 index 00000000000..bb57ee82cc1 --- /dev/null +++ b/src/test/ui/consts/assert-type-intrinsics.stderr @@ -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 + diff --git a/src/test/ui/consts/assume-type-intrinsics.rs b/src/test/ui/consts/assume-type-intrinsics.rs deleted file mode 100644 index 77370e1ccc5..00000000000 --- a/src/test/ui/consts/assume-type-intrinsics.rs +++ /dev/null @@ -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(); - }; -} diff --git a/src/test/ui/consts/assume-type-intrinsics.stderr b/src/test/ui/consts/assume-type-intrinsics.stderr deleted file mode 100644 index e660730396f..00000000000 --- a/src/test/ui/consts/assume-type-intrinsics.stderr +++ /dev/null @@ -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 - |
