From d8ed2fb0bb8aecfe7622134d5aba7b670056ee6d Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Tue, 4 Apr 2023 23:07:10 -0700 Subject: [PATCH] Fix transmute intrinsic mir validation ICE --- .../rustc_const_eval/src/transform/validate.rs | 12 ++++++++++-- tests/ui/mir/validate/transmute_cast_sized.rs | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/ui/mir/validate/transmute_cast_sized.rs diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 0f56fda18f5..d4bed97380b 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -679,13 +679,21 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // Unlike `mem::transmute`, a MIR `Transmute` is well-formed // for any two `Sized` types, just potentially UB to run. - if !op_ty.is_sized(self.tcx, self.param_env) { + if !self + .tcx + .normalize_erasing_regions(self.param_env, op_ty) + .is_sized(self.tcx, self.param_env) + { self.fail( location, format!("Cannot transmute from non-`Sized` type {op_ty:?}"), ); } - if !target_type.is_sized(self.tcx, self.param_env) { + if !self + .tcx + .normalize_erasing_regions(self.param_env, *target_type) + .is_sized(self.tcx, self.param_env) + { self.fail( location, format!("Cannot transmute to non-`Sized` type {target_type:?}"), diff --git a/tests/ui/mir/validate/transmute_cast_sized.rs b/tests/ui/mir/validate/transmute_cast_sized.rs new file mode 100644 index 00000000000..eaaf7eb3ecd --- /dev/null +++ b/tests/ui/mir/validate/transmute_cast_sized.rs @@ -0,0 +1,17 @@ +// build-pass +// compile-flags: -Zvalidate-mir +// edition: 2021 + +#![crate_type = "lib"] + +// Use `PhantomData` to get target-independent size +async fn get(_r: std::marker::PhantomData<&i32>) { + loop {} +} + +pub fn check() { + let mut v = get(loop {}); + let _ = || unsafe { + v = std::mem::transmute([0_u8; 1]); + }; +}