]> git.lizzy.rs Git - rust.git/commitdiff
`new_outside_solver` -> `evaluate_root_goal`
authorlcnr <rust@lcnr.de>
Mon, 23 Jan 2023 14:34:11 +0000 (15:34 +0100)
committerlcnr <rust@lcnr.de>
Mon, 23 Jan 2023 14:58:28 +0000 (15:58 +0100)
compiler/rustc_trait_selection/src/solve/fulfill.rs
compiler/rustc_trait_selection/src/solve/mod.rs

index 40b9bedc84fd3afd8292c2c721bee97d1d8b62de..d59fa71406c31197c75a4bedbe1545463f302b8a 100644 (file)
@@ -1,5 +1,6 @@
 use std::mem;
 
+use super::{Certainty, InferCtxtEvalExt};
 use rustc_infer::{
     infer::InferCtxt,
     traits::{
@@ -8,8 +9,6 @@
     },
 };
 
-use super::{search_graph, Certainty, EvalCtxt};
-
 /// A trait engine using the new trait solver.
 ///
 /// This is mostly identical to how `evaluate_all` works inside of the
@@ -66,9 +65,7 @@ fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentE
             let mut has_changed = false;
             for obligation in mem::take(&mut self.obligations) {
                 let goal = obligation.clone().into();
-                let search_graph = &mut search_graph::SearchGraph::new(infcx.tcx);
-                let mut ecx = EvalCtxt::new_outside_solver(infcx, search_graph);
-                let (changed, certainty) = match ecx.evaluate_goal(goal) {
+                let (changed, certainty) = match infcx.evaluate_root_goal(goal) {
                     Ok(result) => result,
                     Err(NoSolution) => {
                         errors.push(FulfillmentError {
index da2a1a19957e128f491b8a1bbc3b3384da637581..70f094014453edfcca6960ef8a09c64a5ab4798f 100644 (file)
@@ -152,6 +152,36 @@ fn evaluate_goal(self, goal: CanonicalGoal<'tcx>) -> QueryResult<'tcx> {
     }
 }
 
+pub trait InferCtxtEvalExt<'tcx> {
+    /// Evaluates a goal from **outside** of the trait solver.
+    ///
+    /// Using this while inside of the solver is wrong as it uses a new
+    /// search graph which would break cycle detection.
+    fn evaluate_root_goal(
+        &self,
+        goal: Goal<'tcx, ty::Predicate<'tcx>>,
+    ) -> Result<(bool, Certainty), NoSolution>;
+}
+
+impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
+    fn evaluate_root_goal(
+        &self,
+        goal: Goal<'tcx, ty::Predicate<'tcx>>,
+    ) -> Result<(bool, Certainty), NoSolution> {
+        let mut search_graph = search_graph::SearchGraph::new(self.tcx);
+
+        let result = EvalCtxt {
+            search_graph: &mut search_graph,
+            infcx: self,
+            var_values: CanonicalVarValues::dummy(),
+        }
+        .evaluate_goal(goal);
+
+        assert!(search_graph.is_empty());
+        result
+    }
+}
+
 struct EvalCtxt<'a, 'tcx> {
     infcx: &'a InferCtxt<'tcx>,
     var_values: CanonicalVarValues<'tcx>,
@@ -164,18 +194,6 @@ fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
-    /// Creates a new evaluation context outside of the trait solver.
-    ///
-    /// With this solver making a canonical response doesn't make much sense.
-    /// The `search_graph` for this solver has to be completely empty.
-    fn new_outside_solver(
-        infcx: &'a InferCtxt<'tcx>,
-        search_graph: &'a mut search_graph::SearchGraph<'tcx>,
-    ) -> EvalCtxt<'a, 'tcx> {
-        assert!(search_graph.is_empty());
-        EvalCtxt { infcx, var_values: CanonicalVarValues::dummy(), search_graph }
-    }
-
     #[instrument(level = "debug", skip(tcx, search_graph), ret)]
     fn evaluate_canonical_goal(
         tcx: TyCtxt<'tcx>,