Rollup merge of #142933 - compiler-errors:refactor-solver-api, r=lcnr

Simplify root goal API of solver a bit

Root goal API is more easily distinguished between proof tree and non-proof tree, rather than `eval_goal` vs `eval_goal_raw`.

r? lcnr
This commit is contained in:
Guillaume Gomez 2025-06-24 11:20:10 +02:00 committed by GitHub
commit 7b864ac190
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 41 additions and 68 deletions

View file

@ -147,13 +147,9 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
fn evaluate_root_goal(
&self,
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
generate_proof_tree: GenerateProofTree,
span: <Self::Interner as Interner>::Span,
stalled_on: Option<GoalStalledOn<Self::Interner>>,
) -> (
Result<GoalEvaluation<Self::Interner>, NoSolution>,
Option<inspect::GoalEvaluation<Self::Interner>>,
);
) -> Result<GoalEvaluation<Self::Interner>, NoSolution>;
/// Check whether evaluating `goal` with a depth of `root_depth` may
/// succeed. This only returns `false` if the goal is guaranteed to
@ -170,17 +166,16 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
// FIXME: This is only exposed because we need to use it in `analyse.rs`
// which is not yet uplifted. Once that's done, we should remove this.
fn evaluate_root_goal_raw(
fn evaluate_root_goal_for_proof_tree(
&self,
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
generate_proof_tree: GenerateProofTree,
stalled_on: Option<GoalStalledOn<Self::Interner>>,
span: <Self::Interner as Interner>::Span,
) -> (
Result<
(NestedNormalizationGoals<Self::Interner>, GoalEvaluation<Self::Interner>),
NoSolution,
>,
Option<inspect::GoalEvaluation<Self::Interner>>,
inspect::GoalEvaluation<Self::Interner>,
);
}
@ -193,13 +188,17 @@ where
fn evaluate_root_goal(
&self,
goal: Goal<I, I::Predicate>,
generate_proof_tree: GenerateProofTree,
span: I::Span,
stalled_on: Option<GoalStalledOn<I>>,
) -> (Result<GoalEvaluation<I>, NoSolution>, Option<inspect::GoalEvaluation<I>>) {
EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, span, |ecx| {
ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal, stalled_on)
})
) -> Result<GoalEvaluation<I>, NoSolution> {
EvalCtxt::enter_root(
self,
self.cx().recursion_limit(),
GenerateProofTree::No,
span,
|ecx| ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal, stalled_on),
)
.0
}
fn root_goal_may_hold_with_depth(
@ -217,24 +216,22 @@ where
}
#[instrument(level = "debug", skip(self))]
fn evaluate_root_goal_raw(
fn evaluate_root_goal_for_proof_tree(
&self,
goal: Goal<I, I::Predicate>,
generate_proof_tree: GenerateProofTree,
stalled_on: Option<GoalStalledOn<I>>,
span: I::Span,
) -> (
Result<(NestedNormalizationGoals<I>, GoalEvaluation<I>), NoSolution>,
Option<inspect::GoalEvaluation<I>>,
inspect::GoalEvaluation<I>,
) {
EvalCtxt::enter_root(
let (result, proof_tree) = EvalCtxt::enter_root(
self,
self.cx().recursion_limit(),
generate_proof_tree,
I::Span::dummy(),
|ecx| {
ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal, stalled_on)
},
)
GenerateProofTree::Yes,
span,
|ecx| ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal, None),
);
(result, proof_tree.unwrap())
}
}

View file

@ -14,7 +14,7 @@ use rustc_middle::ty::{
};
use rustc_next_trait_solver::delegate::SolverDelegate as _;
use rustc_next_trait_solver::solve::{
GenerateProofTree, GoalEvaluation, GoalStalledOn, HasChanged, SolverDelegateEvalExt as _,
GoalEvaluation, GoalStalledOn, HasChanged, SolverDelegateEvalExt as _,
};
use rustc_span::Span;
use thin_vec::ThinVec;
@ -106,14 +106,11 @@ impl<'tcx> ObligationStorage<'tcx> {
self.overflowed.extend(
ExtractIf::new(&mut self.pending, |(o, stalled_on)| {
let goal = o.as_goal();
let result = <&SolverDelegate<'tcx>>::from(infcx)
.evaluate_root_goal(
goal,
GenerateProofTree::No,
o.cause.span,
stalled_on.take(),
)
.0;
let result = <&SolverDelegate<'tcx>>::from(infcx).evaluate_root_goal(
goal,
o.cause.span,
stalled_on.take(),
);
matches!(result, Ok(GoalEvaluation { has_changed: HasChanged::Yes, .. }))
})
.map(|(o, _)| o),
@ -207,14 +204,7 @@ where
continue;
}
let result = delegate
.evaluate_root_goal(
goal,
GenerateProofTree::No,
obligation.cause.span,
stalled_on,
)
.0;
let result = delegate.evaluate_root_goal(goal, obligation.cause.span, stalled_on);
self.inspect_evaluated_obligation(infcx, &obligation, &result);
let GoalEvaluation { certainty, has_changed, stalled_on } = match result {
Ok(result) => result,

View file

@ -11,9 +11,7 @@ use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_next_trait_solver::solve::{
GenerateProofTree, GoalEvaluation, SolverDelegateEvalExt as _,
};
use rustc_next_trait_solver::solve::{GoalEvaluation, SolverDelegateEvalExt as _};
use tracing::{instrument, trace};
use crate::solve::delegate::SolverDelegate;
@ -90,15 +88,11 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>(
root_obligation: PredicateObligation<'tcx>,
) -> FulfillmentError<'tcx> {
let (code, refine_obligation) = infcx.probe(|_| {
match <&SolverDelegate<'tcx>>::from(infcx)
.evaluate_root_goal(
root_obligation.as_goal(),
GenerateProofTree::No,
root_obligation.cause.span,
None,
)
.0
{
match <&SolverDelegate<'tcx>>::from(infcx).evaluate_root_goal(
root_obligation.as_goal(),
root_obligation.cause.span,
None,
) {
Ok(GoalEvaluation { certainty: Certainty::Maybe(MaybeCause::Ambiguity), .. }) => {
(FulfillmentErrorCode::Ambiguity { overflow: None }, true)
}

View file

@ -20,7 +20,7 @@ use rustc_middle::ty::{TyCtxt, VisitorResult, try_visit};
use rustc_middle::{bug, ty};
use rustc_next_trait_solver::resolve::eager_resolve_vars;
use rustc_next_trait_solver::solve::inspect::{self, instantiate_canonical_state};
use rustc_next_trait_solver::solve::{GenerateProofTree, MaybeCause, SolverDelegateEvalExt as _};
use rustc_next_trait_solver::solve::{MaybeCause, SolverDelegateEvalExt as _};
use rustc_span::Span;
use tracing::instrument;
@ -248,9 +248,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
// considering the constrained RHS, and pass the resulting certainty to
// `InspectGoal::new` so that the goal has the right result (and maintains
// the impression that we don't do this normalizes-to infer hack at all).
let (nested, proof_tree) =
infcx.evaluate_root_goal_raw(goal, GenerateProofTree::Yes, None);
let proof_tree = proof_tree.unwrap();
let (nested, proof_tree) = infcx.evaluate_root_goal_for_proof_tree(goal, span);
let nested_goals_result = nested.and_then(|(nested, _)| {
normalizes_to_term_hack.constrain_and(
infcx,
@ -284,9 +282,8 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
// into another candidate who ends up with different inference
// constraints, we get an ICE if we already applied the constraints
// from the chosen candidate.
let proof_tree = infcx
.probe(|_| infcx.evaluate_root_goal(goal, GenerateProofTree::Yes, span, None).1)
.unwrap();
let proof_tree =
infcx.probe(|_| infcx.evaluate_root_goal_for_proof_tree(goal, span).1);
InspectGoal::new(infcx, self.goal.depth + 1, proof_tree, None, source)
}
}
@ -488,13 +485,8 @@ impl<'tcx> InferCtxt<'tcx> {
depth: usize,
visitor: &mut V,
) -> V::Result {
let (_, proof_tree) = <&SolverDelegate<'tcx>>::from(self).evaluate_root_goal(
goal,
GenerateProofTree::Yes,
visitor.span(),
None,
);
let proof_tree = proof_tree.unwrap();
let (_, proof_tree) = <&SolverDelegate<'tcx>>::from(self)
.evaluate_root_goal_for_proof_tree(goal, visitor.span());
visitor.visit_goal(&InspectGoal::new(self, depth, proof_tree, None, GoalSource::Misc))
}
}