Rollup merge of #109959 - JakobDegen:transmute-validate, r=compiler-errors

Fix transmute intrinsic mir validation ICE

I stumbled across this at work, the minimal reproducer is included as a test which ICEs before this change.

I'm not 100% sure this is the right fix, but it matches what we do in `mir_assign_valid_types` so seems reasonable at least.

fixes #110151

r? `@lcnr` since they've been keeping the relevant logic correct, cc `@scottmcm`
This commit is contained in:
Matthias Krüger 2023-04-12 17:04:30 +02:00 committed by GitHub
commit fd40f519c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 2 deletions

View File

@ -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:?}"),

View File

@ -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]);
};
}