Rollup merge of #142124 - oli-obk:transmute-cast, r=scottmcm

Allow transmute casts in pre-runtime-MIR

r? ``@scottmcm``

cc ``@BoxyUwU``

turns out in https://github.com/rust-lang/rust/pull/138393 I erroneously used transmute casts in fd3da4bebd/compiler/rustc_mir_build/src/builder/matches/test.rs (L209)

I don't think they have any issues using them before runtime, we just checked for them because we didn't have code exercising those code paths
This commit is contained in:
León Orell Valerian Liehr 2025-06-10 16:54:50 +02:00 committed by GitHub
commit e8be230f1f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 19 additions and 30 deletions

View file

@ -1531,8 +1531,6 @@ pub enum CastKind {
///
/// MIR is well-formed if the input and output types have different sizes,
/// but running a transmute between differently-sized types is UB.
///
/// Allowed only in [`MirPhase::Runtime`]; Earlier it's a [`TerminatorKind::Call`].
Transmute,
}

View file

@ -1308,37 +1308,27 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
CastKind::Transmute => {
if let MirPhase::Runtime(..) = self.body.phase {
// Unlike `mem::transmute`, a MIR `Transmute` is well-formed
// for any two `Sized` types, just potentially UB to run.
// Unlike `mem::transmute`, a MIR `Transmute` is well-formed
// for any two `Sized` types, just potentially UB to run.
if !self
.tcx
.normalize_erasing_regions(self.typing_env, op_ty)
.is_sized(self.tcx, self.typing_env)
{
self.fail(
location,
format!("Cannot transmute from non-`Sized` type {op_ty}"),
);
}
if !self
.tcx
.normalize_erasing_regions(self.typing_env, *target_type)
.is_sized(self.tcx, self.typing_env)
{
self.fail(
location,
format!("Cannot transmute to non-`Sized` type {target_type:?}"),
);
}
} else {
if !self
.tcx
.normalize_erasing_regions(self.typing_env, op_ty)
.is_sized(self.tcx, self.typing_env)
{
self.fail(
location,
format!(
"Transmute is not supported in non-runtime phase {:?}.",
self.body.phase
),
format!("Cannot transmute from non-`Sized` type {op_ty}"),
);
}
if !self
.tcx
.normalize_erasing_regions(self.typing_env, *target_type)
.is_sized(self.tcx, self.typing_env)
{
self.fail(
location,
format!("Cannot transmute to non-`Sized` type {target_type:?}"),
);
}
}

View file

@ -1,6 +1,7 @@
#![feature(pattern_types, pattern_type_macro, structural_match)]
//@ check-pass
//@ compile-flags: -Zvalidate-mir
use std::marker::StructuralPartialEq;
use std::pat::pattern_type;