summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/solve
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-06-17 19:27:23 -0400
committerMichael Goulet <michael@errs.io>2024-06-18 11:04:01 -0400
commit6609501ca7d260d9d137e47d1f829eb769ef0e93 (patch)
tree97fad2e29f220bf25bb8371f5505783c77a40cb4 /compiler/rustc_trait_selection/src/solve
parentfb6f4b4a6e3fa850d93535c0cbee6cabfb65d6cf (diff)
downloadrust-6609501ca7d260d9d137e47d1f829eb769ef0e93.tar.gz
rust-6609501ca7d260d9d137e47d1f829eb769ef0e93.zip
Fix transmute goal
Diffstat (limited to 'compiler/rustc_trait_selection/src/solve')
-rw-r--r--compiler/rustc_trait_selection/src/solve/infcx.rs28
1 files changed, 27 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/infcx.rs b/compiler/rustc_trait_selection/src/solve/infcx.rs
index 2a5aaa26f3f..e574166cbfc 100644
--- a/compiler/rustc_trait_selection/src/solve/infcx.rs
+++ b/compiler/rustc_trait_selection/src/solve/infcx.rs
@@ -16,7 +16,7 @@ use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _};
 use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
 use rustc_type_ir::relate::Relate;
-use rustc_type_ir::solve::{NoSolution, SolverMode};
+use rustc_type_ir::solve::{Certainty, NoSolution, SolverMode};
 
 use crate::traits::coherence::trait_ref_is_knowable;
 use crate::traits::specialization_graph;
@@ -406,4 +406,30 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc
         // FIXME: Check for defaultness here may cause diagnostics problems.
         if eligible { Ok(Some(node_item.item.def_id)) } else { Ok(None) }
     }
+
+    fn is_transmutable(
+        &self,
+        param_env: ty::ParamEnv<'tcx>,
+        dst: Ty<'tcx>,
+        src: Ty<'tcx>,
+        assume: ty::Const<'tcx>,
+    ) -> Result<Certainty, NoSolution> {
+        // Erase regions because we compute layouts in `rustc_transmute`,
+        // which will ICE for region vars.
+        let (dst, src) = self.tcx.erase_regions((dst, src));
+
+        let Some(assume) = rustc_transmute::Assume::from_const(self.tcx, param_env, assume) else {
+            return Err(NoSolution);
+        };
+
+        // FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
+        match rustc_transmute::TransmuteTypeEnv::new(&self.0).is_transmutable(
+            ObligationCause::dummy(),
+            rustc_transmute::Types { src, dst },
+            assume,
+        ) {
+            rustc_transmute::Answer::Yes => Ok(Certainty::Yes),
+            rustc_transmute::Answer::No(_) | rustc_transmute::Answer::If(_) => Err(NoSolution),
+        }
+    }
 }