Rollup merge of #107227 - lcnr:solver-new-external-api, r=compiler-errors

`new_outside_solver` ->  `evaluate_root_goal`

r? ```@rust-lang/initiative-trait-system-refactor```
This commit is contained in:
Dylan DPC 2023-01-25 17:01:44 +05:30 committed by GitHub
commit 139a3c5b0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 17 deletions

View File

@ -1,5 +1,6 @@
use std::mem;
use super::{Certainty, InferCtxtEvalExt};
use rustc_infer::{
infer::InferCtxt,
traits::{
@ -8,8 +9,6 @@ use rustc_infer::{
},
};
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 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
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 {

View File

@ -152,6 +152,36 @@ impl<'tcx> TyCtxtExt<'tcx> for TyCtxt<'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 @@ impl<'a, 'tcx> EvalCtxt<'a, '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>,