about summary refs log tree commit diff
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
parentfb6f4b4a6e3fa850d93535c0cbee6cabfb65d6cf (diff)
downloadrust-6609501ca7d260d9d137e47d1f829eb769ef0e93.tar.gz
rust-6609501ca7d260d9d137e47d1f829eb769ef0e93.zip
Fix transmute goal
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/infcx.rs10
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs29
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs25
-rw-r--r--compiler/rustc_trait_selection/src/solve/infcx.rs28
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs2
6 files changed, 59 insertions, 39 deletions
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 4155b120e51..83d45ca78d9 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -61,6 +61,10 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
         self.region_at(i)
     }
 
+    fn const_at(self, i: usize) -> ty::Const<'tcx> {
+        self.const_at(i)
+    }
+
     fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
         GenericArgs::identity_for_item(tcx, def_id)
     }
diff --git a/compiler/rustc_next_trait_solver/src/infcx.rs b/compiler/rustc_next_trait_solver/src/infcx.rs
index e0ce6c937a0..c249eb94cf6 100644
--- a/compiler/rustc_next_trait_solver/src/infcx.rs
+++ b/compiler/rustc_next_trait_solver/src/infcx.rs
@@ -2,7 +2,7 @@ use std::fmt::Debug;
 
 use rustc_type_ir::fold::TypeFoldable;
 use rustc_type_ir::relate::Relate;
-use rustc_type_ir::solve::{Goal, NoSolution, SolverMode};
+use rustc_type_ir::solve::{Certainty, Goal, NoSolution, SolverMode};
 use rustc_type_ir::{self as ty, Interner};
 
 pub trait SolverDelegate: Sized {
@@ -194,4 +194,12 @@ pub trait SolverDelegate: Sized {
         trait_assoc_def_id: <Self::Interner as Interner>::DefId,
         impl_def_id: <Self::Interner as Interner>::DefId,
     ) -> Result<Option<<Self::Interner as Interner>::DefId>, NoSolution>;
+
+    fn is_transmutable(
+        &self,
+        param_env: <Self::Interner as Interner>::ParamEnv,
+        dst: <Self::Interner as Interner>::Ty,
+        src: <Self::Interner as Interner>::Ty,
+        assume: <Self::Interner as Interner>::Const,
+    ) -> Result<Certainty, NoSolution>;
 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 6775d6ddae4..485758b91a2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -890,25 +890,6 @@ where
         self.infcx.well_formed_goals(param_env, arg)
     }
 
-    /*
-    pub(super) fn is_transmutable(
-        &self,
-        src_and_dst: rustc_transmute::Types<I>,
-        assume: rustc_transmute::Assume,
-    ) -> Result<Certainty, NoSolution> {
-        use rustc_transmute::Answer;
-        // FIXME(transmutability): This really should be returning nested goals for `Answer::If*`
-        match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable(
-            ObligationCause::dummy(),
-            src_and_dst,
-            assume,
-        ) {
-            Answer::Yes => Ok(Certainty::Yes),
-            Answer::No(_) | Answer::If(_) => Err(NoSolution),
-        }
-    }
-    */
-
     pub(super) fn trait_ref_is_knowable(
         &mut self,
         param_env: I::ParamEnv,
@@ -1016,6 +997,16 @@ where
     ) -> Option<I::Const> {
         self.infcx.try_const_eval_resolve(param_env, unevaluated)
     }
+
+    pub(super) fn is_transmutable(
+        &mut self,
+        param_env: I::ParamEnv,
+        dst: I::Ty,
+        src: I::Ty,
+        assume: I::Const,
+    ) -> Result<Certainty, NoSolution> {
+        self.infcx.is_transmutable(param_env, dst, src, assume)
+    }
 }
 
 /// Eagerly replace aliases with inference variables, emitting `AliasRelate`
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 7f46d72cba8..d1419bf5db9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -601,12 +601,10 @@ where
     }
 
     fn consider_builtin_transmute_candidate(
-        _ecx: &mut EvalCtxt<'_, Infcx>,
-        _goal: Goal<I, Self>,
+        ecx: &mut EvalCtxt<'_, Infcx>,
+        goal: Goal<I, Self>,
     ) -> Result<Candidate<I>, NoSolution> {
-        // TODO:
-        todo!()
-        /* if goal.predicate.polarity != ty::PredicatePolarity::Positive {
+        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
             return Err(NoSolution);
         }
 
@@ -615,26 +613,17 @@ where
             return Err(NoSolution);
         }
 
-        // Erase regions because we compute layouts in `rustc_transmute`,
-        // which will ICE for region vars.
-        let args = ecx.interner().erase_regions(goal.predicate.trait_ref.args);
-
-        let Some(assume) =
-            rustc_transmute::Assume::from_const(ecx.interner(), goal.param_env, args.const_at(2))
-        else {
-            return Err(NoSolution);
-        };
-
         // FIXME: This actually should destructure the `Result` we get from transmutability and
         // register candiates. We probably need to register >1 since we may have an OR of ANDs.
         ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             let certainty = ecx.is_transmutable(
-                rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) },
-                assume,
+                goal.param_env,
+                goal.predicate.trait_ref.args.type_at(0),
+                goal.predicate.trait_ref.args.type_at(1),
+                goal.predicate.trait_ref.args.const_at(2),
             )?;
             ecx.evaluate_added_goals_and_make_canonical_response(certainty)
         })
-        */
     }
 
     /// ```ignore (builtin impl example)
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),
+        }
+    }
 }
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index c790c737fc9..64d3400976a 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -374,6 +374,8 @@ pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
 
     fn region_at(self, i: usize) -> I::Region;
 
+    fn const_at(self, i: usize) -> I::Const;
+
     fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
 
     fn extend_with_error(