@@ -152,6 +152,36 @@ impl<'tcx> TyCtxtExt<'tcx> for TyCtxt<'tcx> {
152152 }
153153}
154154
155+ pub trait InferCtxtEvalExt<'tcx> {
156+ /// Evaluates a goal from **outside** of the trait solver.
157+ ///
158+ /// Using this while inside of the solver is wrong as it uses a new
159+ /// search graph which would break cycle detection.
160+ fn evaluate_root_goal(
161+ &self,
162+ goal: Goal<'tcx, ty::Predicate<'tcx>>,
163+ ) -> Result<(bool, Certainty), NoSolution>;
164+ }
165+
166+ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
167+ fn evaluate_root_goal(
168+ &self,
169+ goal: Goal<'tcx, ty::Predicate<'tcx>>,
170+ ) -> Result<(bool, Certainty), NoSolution> {
171+ let mut search_graph = search_graph::SearchGraph::new(self.tcx);
172+
173+ let result = EvalCtxt {
174+ search_graph: &mut search_graph,
175+ infcx: self,
176+ var_values: CanonicalVarValues::dummy(),
177+ }
178+ .evaluate_goal(goal);
179+
180+ assert!(search_graph.is_empty());
181+ result
182+ }
183+ }
184+
155185struct EvalCtxt<'a, 'tcx> {
156186 infcx: &'a InferCtxt<'tcx>,
157187 var_values: CanonicalVarValues<'tcx>,
@@ -164,18 +194,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
164194 self.infcx.tcx
165195 }
166196
167- /// Creates a new evaluation context outside of the trait solver.
168- ///
169- /// With this solver making a canonical response doesn't make much sense.
170- /// The `search_graph` for this solver has to be completely empty.
171- fn new_outside_solver(
172- infcx: &'a InferCtxt<'tcx>,
173- search_graph: &'a mut search_graph::SearchGraph<'tcx>,
174- ) -> EvalCtxt<'a, 'tcx> {
175- assert!(search_graph.is_empty());
176- EvalCtxt { infcx, var_values: CanonicalVarValues::dummy(), search_graph }
177- }
178-
179197 #[instrument(level = "debug", skip(tcx, search_graph), ret)]
180198 fn evaluate_canonical_goal(
181199 tcx: TyCtxt<'tcx>,
0 commit comments