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

View file

@ -86,8 +86,8 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
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>;
}

View file

@ -1170,8 +1170,8 @@ where
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)

View file

@ -2781,11 +2781,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
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 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
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 {

View file

@ -294,8 +294,8 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
// 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 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
};
// 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),
}

View file

@ -365,8 +365,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, '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)?,

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 @@ mod rustc {
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()
}
}

View file

@ -232,8 +232,8 @@ impl<'db> SolverDelegate for SolverContext<'db> {
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