Clean up src/dst transmute mess.

- Remove the vacuous `Types`, which provides extremely little value.
- Make sure `src` comes before `dst` in all transmute-related functions.
  (Currently it's a mix: sometimes `src` is first, sometimes it is
  second`.)
This commit is contained in:
Nicholas Nethercote
2026-01-09 15:42:37 +11:00
parent 5e510929c6
commit 46d8c2beeb
7 changed files with 11 additions and 29 deletions
@@ -86,8 +86,8 @@ fn fetch_eligible_assoc_item(
fn is_transmutable(
&self,
dst: <Self::Interner as Interner>::Ty,
src: <Self::Interner as Interner>::Ty,
dst: <Self::Interner as Interner>::Ty,
assume: <Self::Interner as Interner>::Const,
) -> Result<Certainty, NoSolution>;
}
@@ -1170,8 +1170,8 @@ pub(super) fn evaluate_const(
pub(super) fn is_transmutable(
&mut self,
dst: I::Ty,
src: I::Ty,
dst: I::Ty,
assume: I::Const,
) -> Result<Certainty, NoSolution> {
self.delegate.is_transmutable(dst, src, assume)
@@ -2781,11 +2781,6 @@ fn get_safe_transmute_error_and_reason(
self.tcx.instantiate_bound_regions_with_erased(trait_pred),
);
let src_and_dst = rustc_transmute::Types {
dst: trait_pred.trait_ref.args.type_at(0),
src: trait_pred.trait_ref.args.type_at(1),
};
let ocx = ObligationCtxt::new(self);
let Ok(assume) = ocx.structurally_normalize_const(
&obligation.cause,
@@ -2812,7 +2807,7 @@ fn get_safe_transmute_error_and_reason(
let err_msg = format!("`{src}` cannot be safely transmuted into `{dst}`");
match rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx)
.is_transmutable(src_and_dst, assume)
.is_transmutable(src, dst, assume)
{
Answer::No(reason) => {
let safe_transmute_explanation = match reason {
@@ -294,8 +294,8 @@ fn fetch_eligible_assoc_item(
// register candidates. We probably need to register >1 since we may have an OR of ANDs.
fn is_transmutable(
&self,
dst: Ty<'tcx>,
src: Ty<'tcx>,
dst: Ty<'tcx>,
assume: ty::Const<'tcx>,
) -> Result<Certainty, NoSolution> {
// Erase regions because we compute layouts in `rustc_transmute`,
@@ -307,9 +307,7 @@ fn is_transmutable(
};
// FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx)
.is_transmutable(rustc_transmute::Types { src, dst }, assume)
{
match rustc_transmute::TransmuteTypeEnv::new(self.0.tcx).is_transmutable(src, dst, assume) {
rustc_transmute::Answer::Yes => Ok(Certainty::Yes),
rustc_transmute::Answer::No(_) | rustc_transmute::Answer::If(_) => Err(NoSolution),
}
@@ -365,8 +365,7 @@ fn flatten_answer_tree<'tcx>(
debug!(?src, ?dst);
let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx);
let maybe_transmutable =
transmute_env.is_transmutable(rustc_transmute::Types { dst, src }, assume);
let maybe_transmutable = transmute_env.is_transmutable(src, dst, assume);
let fully_flattened = match maybe_transmutable {
Answer::No(_) => Err(SelectionError::Unimplemented)?,
+4 -14
View File
@@ -93,15 +93,6 @@ mod rustc {
use super::*;
/// The source and destination types of a transmutation.
#[derive(Debug, Clone, Copy)]
pub struct Types<'tcx> {
/// The source type.
pub src: Ty<'tcx>,
/// The destination type.
pub dst: Ty<'tcx>,
}
pub struct TransmuteTypeEnv<'tcx> {
tcx: TyCtxt<'tcx>,
}
@@ -113,13 +104,12 @@ pub fn new(tcx: TyCtxt<'tcx>) -> Self {
pub fn is_transmutable(
&mut self,
types: Types<'tcx>,
src: Ty<'tcx>,
dst: Ty<'tcx>,
assume: crate::Assume,
) -> crate::Answer<Region<'tcx>, Ty<'tcx>> {
crate::maybe_transmutable::MaybeTransmutableQuery::new(
types.src, types.dst, assume, self.tcx,
)
.answer()
crate::maybe_transmutable::MaybeTransmutableQuery::new(src, dst, assume, self.tcx)
.answer()
}
}
@@ -232,8 +232,8 @@ fn fetch_eligible_assoc_item(
fn is_transmutable(
&self,
_dst: Ty<'db>,
_src: Ty<'db>,
_dst: Ty<'db>,
_assume: <Self::Interner as rustc_type_ir::Interner>::Const,
) -> Result<Certainty, NoSolution> {
// It's better to return some value while not fully implement