split GoalEvaluation and CanonicalGoalEvaluation
the unnormalized goal is in the callers inference context, while anything inside of the `CanonicalGoalEvaluation` is inside of a new one.
This commit is contained in:
parent
7d1e416d32
commit
fc452e2ed3
@ -16,12 +16,15 @@ pub enum CacheHit {
|
|||||||
#[derive(Eq, PartialEq, Hash, HashStable)]
|
#[derive(Eq, PartialEq, Hash, HashStable)]
|
||||||
pub struct GoalEvaluation<'tcx> {
|
pub struct GoalEvaluation<'tcx> {
|
||||||
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||||
pub canonicalized_goal: CanonicalInput<'tcx>,
|
|
||||||
|
|
||||||
pub kind: GoalEvaluationKind<'tcx>,
|
|
||||||
pub is_normalizes_to_hack: IsNormalizesToHack,
|
pub is_normalizes_to_hack: IsNormalizesToHack,
|
||||||
|
pub evaluation: CanonicalGoalEvaluation<'tcx>,
|
||||||
pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
|
pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Hash, HashStable)]
|
||||||
|
pub struct CanonicalGoalEvaluation<'tcx> {
|
||||||
|
pub goal: CanonicalInput<'tcx>,
|
||||||
|
pub kind: GoalEvaluationKind<'tcx>,
|
||||||
pub result: QueryResult<'tcx>,
|
pub result: QueryResult<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,30 +44,20 @@ pub struct AddedGoalsEvaluation<'tcx> {
|
|||||||
pub evaluations: Vec<Vec<GoalEvaluation<'tcx>>>,
|
pub evaluations: Vec<Vec<GoalEvaluation<'tcx>>>,
|
||||||
pub result: Result<Certainty, NoSolution>,
|
pub result: Result<Certainty, NoSolution>,
|
||||||
}
|
}
|
||||||
impl Debug for AddedGoalsEvaluation<'_> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
ProofTreeFormatter::new(f).format_nested_goal_evaluation(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Hash, HashStable)]
|
#[derive(Eq, PartialEq, Hash, HashStable)]
|
||||||
pub struct GoalEvaluationStep<'tcx> {
|
pub struct GoalEvaluationStep<'tcx> {
|
||||||
pub instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>,
|
pub instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>,
|
||||||
|
|
||||||
pub nested_goal_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
|
pub added_goals_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
|
||||||
pub candidates: Vec<GoalCandidate<'tcx>>,
|
pub candidates: Vec<GoalCandidate<'tcx>>,
|
||||||
|
|
||||||
pub result: QueryResult<'tcx>,
|
pub result: QueryResult<'tcx>,
|
||||||
}
|
}
|
||||||
impl Debug for GoalEvaluationStep<'_> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
ProofTreeFormatter::new(f).format_evaluation_step(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Hash, HashStable)]
|
#[derive(Eq, PartialEq, Hash, HashStable)]
|
||||||
pub struct GoalCandidate<'tcx> {
|
pub struct GoalCandidate<'tcx> {
|
||||||
pub nested_goal_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
|
pub added_goals_evaluations: Vec<AddedGoalsEvaluation<'tcx>>,
|
||||||
pub candidates: Vec<GoalCandidate<'tcx>>,
|
pub candidates: Vec<GoalCandidate<'tcx>>,
|
||||||
pub kind: CandidateKind<'tcx>,
|
pub kind: CandidateKind<'tcx>,
|
||||||
}
|
}
|
||||||
@ -83,8 +76,3 @@ pub enum CandidateKind<'tcx> {
|
|||||||
/// the source type upholds all of the target type's object bounds.
|
/// the source type upholds all of the target type's object bounds.
|
||||||
UpcastProbe,
|
UpcastProbe,
|
||||||
}
|
}
|
||||||
impl Debug for GoalCandidate<'_> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
ProofTreeFormatter::new(f).format_candidate(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -39,44 +39,49 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
|||||||
func(&mut ProofTreeFormatter { f: &mut Indentor { f: self.f, on_newline: true } })
|
func(&mut ProofTreeFormatter { f: &mut Indentor { f: self.f, on_newline: true } })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn format_goal_evaluation(&mut self, goal: &GoalEvaluation<'_>) -> std::fmt::Result {
|
pub(super) fn format_goal_evaluation(&mut self, eval: &GoalEvaluation<'_>) -> std::fmt::Result {
|
||||||
let goal_text = match goal.is_normalizes_to_hack {
|
let goal_text = match eval.is_normalizes_to_hack {
|
||||||
IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
|
IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
|
||||||
IsNormalizesToHack::No => "GOAL",
|
IsNormalizesToHack::No => "GOAL",
|
||||||
};
|
};
|
||||||
|
writeln!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?;
|
||||||
|
self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))?;
|
||||||
|
if eval.returned_goals.len() > 0 {
|
||||||
|
writeln!(self.f, "NESTED GOALS ADDED TO CALLER: [")?;
|
||||||
|
self.nested(|this| {
|
||||||
|
for goal in eval.returned_goals.iter() {
|
||||||
|
writeln!(this.f, "ADDED GOAL: {goal:?},")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
writeln!(self.f, "{}: {:?}", goal_text, goal.uncanonicalized_goal)?;
|
writeln!(self.f, "]")
|
||||||
writeln!(self.f, "CANONICALIZED: {:?}", goal.canonicalized_goal)?;
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match &goal.kind {
|
pub(super) fn format_canonical_goal_evaluation(
|
||||||
|
&mut self,
|
||||||
|
eval: &CanonicalGoalEvaluation<'_>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
|
writeln!(self.f, "GOAL: {:?}", eval.goal)?;
|
||||||
|
|
||||||
|
match &eval.kind {
|
||||||
GoalEvaluationKind::CacheHit(CacheHit::Global) => {
|
GoalEvaluationKind::CacheHit(CacheHit::Global) => {
|
||||||
writeln!(self.f, "GLOBAL CACHE HIT: {:?}", goal.result)
|
writeln!(self.f, "GLOBAL CACHE HIT: {:?}", eval.result)
|
||||||
}
|
}
|
||||||
GoalEvaluationKind::CacheHit(CacheHit::Provisional) => {
|
GoalEvaluationKind::CacheHit(CacheHit::Provisional) => {
|
||||||
writeln!(self.f, "PROVISIONAL CACHE HIT: {:?}", goal.result)
|
writeln!(self.f, "PROVISIONAL CACHE HIT: {:?}", eval.result)
|
||||||
}
|
}
|
||||||
GoalEvaluationKind::Uncached { revisions } => {
|
GoalEvaluationKind::Uncached { revisions } => {
|
||||||
for (n, step) in revisions.iter().enumerate() {
|
for (n, step) in revisions.iter().enumerate() {
|
||||||
writeln!(self.f, "REVISION {n}: {:?}", step.result)?;
|
writeln!(self.f, "REVISION {n}: {:?}", step.result)?;
|
||||||
self.nested(|this| this.format_evaluation_step(step))?;
|
self.nested(|this| this.format_evaluation_step(step))?;
|
||||||
}
|
}
|
||||||
writeln!(self.f, "RESULT: {:?}", goal.result)
|
writeln!(self.f, "RESULT: {:?}", eval.result)
|
||||||
}
|
}
|
||||||
}?;
|
|
||||||
|
|
||||||
if goal.returned_goals.len() > 0 {
|
|
||||||
writeln!(self.f, "NESTED GOALS ADDED TO CALLER: [")?;
|
|
||||||
self.nested(|this| {
|
|
||||||
for goal in goal.returned_goals.iter() {
|
|
||||||
writeln!(this.f, "ADDED GOAL: {goal:?},")?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
writeln!(self.f, "]")?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn format_evaluation_step(
|
pub(super) fn format_evaluation_step(
|
||||||
@ -88,8 +93,8 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
|||||||
for candidate in &evaluation_step.candidates {
|
for candidate in &evaluation_step.candidates {
|
||||||
self.nested(|this| this.format_candidate(candidate))?;
|
self.nested(|this| this.format_candidate(candidate))?;
|
||||||
}
|
}
|
||||||
for nested in &evaluation_step.nested_goal_evaluations {
|
for nested in &evaluation_step.added_goals_evaluations {
|
||||||
self.nested(|this| this.format_nested_goal_evaluation(nested))?;
|
self.nested(|this| this.format_added_goals_evaluation(nested))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -115,20 +120,20 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
|||||||
for candidate in &candidate.candidates {
|
for candidate in &candidate.candidates {
|
||||||
this.format_candidate(candidate)?;
|
this.format_candidate(candidate)?;
|
||||||
}
|
}
|
||||||
for nested in &candidate.nested_goal_evaluations {
|
for nested in &candidate.added_goals_evaluations {
|
||||||
this.format_nested_goal_evaluation(nested)?;
|
this.format_added_goals_evaluation(nested)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn format_nested_goal_evaluation(
|
pub(super) fn format_added_goals_evaluation(
|
||||||
&mut self,
|
&mut self,
|
||||||
nested_goal_evaluation: &AddedGoalsEvaluation<'_>,
|
added_goals_evaluation: &AddedGoalsEvaluation<'_>,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", nested_goal_evaluation.result)?;
|
writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", added_goals_evaluation.result)?;
|
||||||
|
|
||||||
for (n, revision) in nested_goal_evaluation.evaluations.iter().enumerate() {
|
for (n, revision) in added_goals_evaluation.evaluations.iter().enumerate() {
|
||||||
writeln!(self.f, "REVISION {n}")?;
|
writeln!(self.f, "REVISION {n}")?;
|
||||||
self.nested(|this| {
|
self.nested(|this| {
|
||||||
for goal_evaluation in revision {
|
for goal_evaluation in revision {
|
||||||
|
@ -237,7 +237,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
search_graph: &'a mut search_graph::SearchGraph<'tcx>,
|
search_graph: &'a mut search_graph::SearchGraph<'tcx>,
|
||||||
canonical_input: CanonicalInput<'tcx>,
|
canonical_input: CanonicalInput<'tcx>,
|
||||||
goal_evaluation: &mut ProofTreeBuilder<'tcx>,
|
canonical_goal_evaluation: &mut ProofTreeBuilder<'tcx>,
|
||||||
f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>, Goal<'tcx, ty::Predicate<'tcx>>) -> R,
|
f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>, Goal<'tcx, ty::Predicate<'tcx>>) -> R,
|
||||||
) -> R {
|
) -> R {
|
||||||
let intercrate = match search_graph.solver_mode() {
|
let intercrate = match search_graph.solver_mode() {
|
||||||
@ -260,7 +260,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||||||
search_graph,
|
search_graph,
|
||||||
nested_goals: NestedGoals::new(),
|
nested_goals: NestedGoals::new(),
|
||||||
tainted: Ok(()),
|
tainted: Ok(()),
|
||||||
inspect: goal_evaluation.new_goal_evaluation_step(input),
|
inspect: canonical_goal_evaluation.new_goal_evaluation_step(input),
|
||||||
};
|
};
|
||||||
|
|
||||||
for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
|
for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
|
||||||
@ -274,7 +274,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
let result = f(&mut ecx, input.goal);
|
let result = f(&mut ecx, input.goal);
|
||||||
|
|
||||||
goal_evaluation.goal_evaluation_step(ecx.inspect);
|
canonical_goal_evaluation.goal_evaluation_step(ecx.inspect);
|
||||||
|
|
||||||
// When creating a query response we clone the opaque type constraints
|
// When creating a query response we clone the opaque type constraints
|
||||||
// instead of taking them. This would cause an ICE here, since we have
|
// instead of taking them. This would cause an ICE here, since we have
|
||||||
@ -302,24 +302,25 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
search_graph: &'a mut search_graph::SearchGraph<'tcx>,
|
search_graph: &'a mut search_graph::SearchGraph<'tcx>,
|
||||||
canonical_input: CanonicalInput<'tcx>,
|
canonical_input: CanonicalInput<'tcx>,
|
||||||
mut goal_evaluation: &mut ProofTreeBuilder<'tcx>,
|
goal_evaluation: &mut ProofTreeBuilder<'tcx>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
goal_evaluation.canonicalized_goal(canonical_input);
|
let mut canonical_goal_evaluation =
|
||||||
|
goal_evaluation.new_canonical_goal_evaluation(canonical_input);
|
||||||
|
|
||||||
// Deal with overflow, caching, and coinduction.
|
// Deal with overflow, caching, and coinduction.
|
||||||
//
|
//
|
||||||
// The actual solver logic happens in `ecx.compute_goal`.
|
// The actual solver logic happens in `ecx.compute_goal`.
|
||||||
ensure_sufficient_stack(|| {
|
let result = ensure_sufficient_stack(|| {
|
||||||
search_graph.with_new_goal(
|
search_graph.with_new_goal(
|
||||||
tcx,
|
tcx,
|
||||||
canonical_input,
|
canonical_input,
|
||||||
goal_evaluation,
|
&mut canonical_goal_evaluation,
|
||||||
|search_graph, goal_evaluation| {
|
|search_graph, canonical_goal_evaluation| {
|
||||||
EvalCtxt::enter_canonical(
|
EvalCtxt::enter_canonical(
|
||||||
tcx,
|
tcx,
|
||||||
search_graph,
|
search_graph,
|
||||||
canonical_input,
|
canonical_input,
|
||||||
goal_evaluation,
|
canonical_goal_evaluation,
|
||||||
|ecx, goal| {
|
|ecx, goal| {
|
||||||
let result = ecx.compute_goal(goal);
|
let result = ecx.compute_goal(goal);
|
||||||
ecx.inspect.query_result(result);
|
ecx.inspect.query_result(result);
|
||||||
@ -328,7 +329,11 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
});
|
||||||
|
|
||||||
|
canonical_goal_evaluation.query_result(result);
|
||||||
|
goal_evaluation.canonical_goal_evaluation(canonical_goal_evaluation);
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively evaluates `goal`, returning whether any inference vars have
|
/// Recursively evaluates `goal`, returning whether any inference vars have
|
||||||
@ -347,7 +352,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||||||
canonical_goal,
|
canonical_goal,
|
||||||
&mut goal_evaluation,
|
&mut goal_evaluation,
|
||||||
);
|
);
|
||||||
goal_evaluation.query_result(canonical_response);
|
|
||||||
let canonical_response = match canonical_response {
|
let canonical_response = match canonical_response {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.inspect.goal_evaluation(goal_evaluation);
|
self.inspect.goal_evaluation(goal_evaluation);
|
||||||
|
@ -12,36 +12,47 @@ use super::GenerateProofTree;
|
|||||||
#[derive(Eq, PartialEq, Debug, Hash, HashStable)]
|
#[derive(Eq, PartialEq, Debug, Hash, HashStable)]
|
||||||
pub struct WipGoalEvaluation<'tcx> {
|
pub struct WipGoalEvaluation<'tcx> {
|
||||||
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||||
pub canonicalized_goal: Option<CanonicalInput<'tcx>>,
|
pub evaluation: Option<WipCanonicalGoalEvaluation<'tcx>>,
|
||||||
|
|
||||||
pub evaluation_steps: Vec<WipGoalEvaluationStep<'tcx>>,
|
|
||||||
|
|
||||||
pub cache_hit: Option<CacheHit>,
|
|
||||||
pub is_normalizes_to_hack: IsNormalizesToHack,
|
pub is_normalizes_to_hack: IsNormalizesToHack,
|
||||||
pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
|
pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
|
||||||
|
|
||||||
pub result: Option<QueryResult<'tcx>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> WipGoalEvaluation<'tcx> {
|
impl<'tcx> WipGoalEvaluation<'tcx> {
|
||||||
pub fn finalize(self) -> inspect::GoalEvaluation<'tcx> {
|
pub fn finalize(self) -> inspect::GoalEvaluation<'tcx> {
|
||||||
inspect::GoalEvaluation {
|
inspect::GoalEvaluation {
|
||||||
uncanonicalized_goal: self.uncanonicalized_goal,
|
uncanonicalized_goal: self.uncanonicalized_goal,
|
||||||
canonicalized_goal: self.canonicalized_goal.unwrap(),
|
evaluation: self.evaluation.unwrap().finalize(),
|
||||||
kind: match self.cache_hit {
|
is_normalizes_to_hack: self.is_normalizes_to_hack,
|
||||||
Some(hit) => inspect::GoalEvaluationKind::CacheHit(hit),
|
returned_goals: self.returned_goals,
|
||||||
None => inspect::GoalEvaluationKind::Uncached {
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Debug, Hash, HashStable)]
|
||||||
|
pub struct WipCanonicalGoalEvaluation<'tcx> {
|
||||||
|
pub goal: CanonicalInput<'tcx>,
|
||||||
|
pub cache_hit: Option<CacheHit>,
|
||||||
|
pub evaluation_steps: Vec<WipGoalEvaluationStep<'tcx>>,
|
||||||
|
pub result: Option<QueryResult<'tcx>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> WipCanonicalGoalEvaluation<'tcx> {
|
||||||
|
pub fn finalize(self) -> inspect::CanonicalGoalEvaluation<'tcx> {
|
||||||
|
let kind = match self.cache_hit {
|
||||||
|
Some(hit) => inspect::GoalEvaluationKind::CacheHit(hit),
|
||||||
|
None => {
|
||||||
|
assert!(!self.evaluation_steps.is_empty());
|
||||||
|
inspect::GoalEvaluationKind::Uncached {
|
||||||
revisions: self
|
revisions: self
|
||||||
.evaluation_steps
|
.evaluation_steps
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(WipGoalEvaluationStep::finalize)
|
.map(WipGoalEvaluationStep::finalize)
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
is_normalizes_to_hack: self.is_normalizes_to_hack,
|
};
|
||||||
returned_goals: self.returned_goals,
|
|
||||||
result: self.result.unwrap(),
|
inspect::CanonicalGoalEvaluation { goal: self.goal, kind, result: self.result.unwrap() }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +81,7 @@ impl<'tcx> WipAddedGoalsEvaluation<'tcx> {
|
|||||||
pub struct WipGoalEvaluationStep<'tcx> {
|
pub struct WipGoalEvaluationStep<'tcx> {
|
||||||
pub instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>,
|
pub instantiated_goal: QueryInput<'tcx, ty::Predicate<'tcx>>,
|
||||||
|
|
||||||
pub nested_goal_evaluations: Vec<WipAddedGoalsEvaluation<'tcx>>,
|
pub added_goals_evaluations: Vec<WipAddedGoalsEvaluation<'tcx>>,
|
||||||
pub candidates: Vec<WipGoalCandidate<'tcx>>,
|
pub candidates: Vec<WipGoalCandidate<'tcx>>,
|
||||||
|
|
||||||
pub result: Option<QueryResult<'tcx>>,
|
pub result: Option<QueryResult<'tcx>>,
|
||||||
@ -80,8 +91,8 @@ impl<'tcx> WipGoalEvaluationStep<'tcx> {
|
|||||||
pub fn finalize(self) -> inspect::GoalEvaluationStep<'tcx> {
|
pub fn finalize(self) -> inspect::GoalEvaluationStep<'tcx> {
|
||||||
inspect::GoalEvaluationStep {
|
inspect::GoalEvaluationStep {
|
||||||
instantiated_goal: self.instantiated_goal,
|
instantiated_goal: self.instantiated_goal,
|
||||||
nested_goal_evaluations: self
|
added_goals_evaluations: self
|
||||||
.nested_goal_evaluations
|
.added_goals_evaluations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(WipAddedGoalsEvaluation::finalize)
|
.map(WipAddedGoalsEvaluation::finalize)
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -93,7 +104,7 @@ impl<'tcx> WipGoalEvaluationStep<'tcx> {
|
|||||||
|
|
||||||
#[derive(Eq, PartialEq, Debug, Hash, HashStable)]
|
#[derive(Eq, PartialEq, Debug, Hash, HashStable)]
|
||||||
pub struct WipGoalCandidate<'tcx> {
|
pub struct WipGoalCandidate<'tcx> {
|
||||||
pub nested_goal_evaluations: Vec<WipAddedGoalsEvaluation<'tcx>>,
|
pub added_goals_evaluations: Vec<WipAddedGoalsEvaluation<'tcx>>,
|
||||||
pub candidates: Vec<WipGoalCandidate<'tcx>>,
|
pub candidates: Vec<WipGoalCandidate<'tcx>>,
|
||||||
pub kind: Option<CandidateKind<'tcx>>,
|
pub kind: Option<CandidateKind<'tcx>>,
|
||||||
}
|
}
|
||||||
@ -101,8 +112,8 @@ pub struct WipGoalCandidate<'tcx> {
|
|||||||
impl<'tcx> WipGoalCandidate<'tcx> {
|
impl<'tcx> WipGoalCandidate<'tcx> {
|
||||||
pub fn finalize(self) -> inspect::GoalCandidate<'tcx> {
|
pub fn finalize(self) -> inspect::GoalCandidate<'tcx> {
|
||||||
inspect::GoalCandidate {
|
inspect::GoalCandidate {
|
||||||
nested_goal_evaluations: self
|
added_goals_evaluations: self
|
||||||
.nested_goal_evaluations
|
.added_goals_evaluations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(WipAddedGoalsEvaluation::finalize)
|
.map(WipAddedGoalsEvaluation::finalize)
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -116,6 +127,7 @@ impl<'tcx> WipGoalCandidate<'tcx> {
|
|||||||
pub enum DebugSolver<'tcx> {
|
pub enum DebugSolver<'tcx> {
|
||||||
Root,
|
Root,
|
||||||
GoalEvaluation(WipGoalEvaluation<'tcx>),
|
GoalEvaluation(WipGoalEvaluation<'tcx>),
|
||||||
|
CanonicalGoalEvaluation(WipCanonicalGoalEvaluation<'tcx>),
|
||||||
AddedGoalsEvaluation(WipAddedGoalsEvaluation<'tcx>),
|
AddedGoalsEvaluation(WipAddedGoalsEvaluation<'tcx>),
|
||||||
GoalEvaluationStep(WipGoalEvaluationStep<'tcx>),
|
GoalEvaluationStep(WipGoalEvaluationStep<'tcx>),
|
||||||
GoalCandidate(WipGoalCandidate<'tcx>),
|
GoalCandidate(WipGoalCandidate<'tcx>),
|
||||||
@ -127,6 +139,12 @@ impl<'tcx> From<WipGoalEvaluation<'tcx>> for DebugSolver<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> From<WipCanonicalGoalEvaluation<'tcx>> for DebugSolver<'tcx> {
|
||||||
|
fn from(g: WipCanonicalGoalEvaluation<'tcx>) -> DebugSolver<'tcx> {
|
||||||
|
DebugSolver::CanonicalGoalEvaluation(g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> From<WipAddedGoalsEvaluation<'tcx>> for DebugSolver<'tcx> {
|
impl<'tcx> From<WipAddedGoalsEvaluation<'tcx>> for DebugSolver<'tcx> {
|
||||||
fn from(g: WipAddedGoalsEvaluation<'tcx>) -> DebugSolver<'tcx> {
|
fn from(g: WipAddedGoalsEvaluation<'tcx>) -> DebugSolver<'tcx> {
|
||||||
DebugSolver::AddedGoalsEvaluation(g)
|
DebugSolver::AddedGoalsEvaluation(g)
|
||||||
@ -243,21 +261,35 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
|
|||||||
|
|
||||||
self.nested(WipGoalEvaluation {
|
self.nested(WipGoalEvaluation {
|
||||||
uncanonicalized_goal: goal,
|
uncanonicalized_goal: goal,
|
||||||
canonicalized_goal: None,
|
evaluation: None,
|
||||||
evaluation_steps: vec![],
|
|
||||||
is_normalizes_to_hack,
|
is_normalizes_to_hack,
|
||||||
cache_hit: None,
|
|
||||||
returned_goals: vec![],
|
returned_goals: vec![],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_canonical_goal_evaluation(
|
||||||
|
&mut self,
|
||||||
|
goal: CanonicalInput<'tcx>,
|
||||||
|
) -> ProofTreeBuilder<'tcx> {
|
||||||
|
if self.state.is_none() {
|
||||||
|
return ProofTreeBuilder { state: None };
|
||||||
|
}
|
||||||
|
|
||||||
|
self.nested(WipCanonicalGoalEvaluation {
|
||||||
|
goal,
|
||||||
|
cache_hit: None,
|
||||||
|
evaluation_steps: vec![],
|
||||||
result: None,
|
result: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn canonicalized_goal(&mut self, canonical_goal: CanonicalInput<'tcx>) {
|
pub fn canonical_goal_evaluation(&mut self, canonical_goal_evaluation: ProofTreeBuilder<'tcx>) {
|
||||||
if let Some(this) = self.as_mut() {
|
if let Some(this) = self.as_mut() {
|
||||||
match this {
|
match (this, canonical_goal_evaluation.state.unwrap().tree) {
|
||||||
DebugSolver::GoalEvaluation(goal_evaluation) => {
|
(
|
||||||
assert_eq!(goal_evaluation.canonicalized_goal.replace(canonical_goal), None);
|
DebugSolver::GoalEvaluation(goal_evaluation),
|
||||||
}
|
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation),
|
||||||
|
) => goal_evaluation.evaluation = Some(canonical_goal_evaluation),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,8 +298,8 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
|
|||||||
pub fn cache_hit(&mut self, cache_hit: CacheHit) {
|
pub fn cache_hit(&mut self, cache_hit: CacheHit) {
|
||||||
if let Some(this) = self.as_mut() {
|
if let Some(this) = self.as_mut() {
|
||||||
match this {
|
match this {
|
||||||
DebugSolver::GoalEvaluation(goal_evaluation) => {
|
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {
|
||||||
assert_eq!(goal_evaluation.cache_hit.replace(cache_hit), None);
|
assert_eq!(canonical_goal_evaluation.cache_hit.replace(cache_hit), None);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
@ -310,16 +342,19 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
|
|||||||
|
|
||||||
self.nested(WipGoalEvaluationStep {
|
self.nested(WipGoalEvaluationStep {
|
||||||
instantiated_goal,
|
instantiated_goal,
|
||||||
nested_goal_evaluations: vec![],
|
added_goals_evaluations: vec![],
|
||||||
candidates: vec![],
|
candidates: vec![],
|
||||||
result: None,
|
result: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn goal_evaluation_step(&mut self, goal_eval_step: ProofTreeBuilder<'tcx>) {
|
pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<'tcx>) {
|
||||||
if let Some(this) = self.as_mut() {
|
if let Some(this) = self.as_mut() {
|
||||||
match (this, goal_eval_step.state.unwrap().tree) {
|
match (this, goal_evaluation_step.state.unwrap().tree) {
|
||||||
(DebugSolver::GoalEvaluation(goal_eval), DebugSolver::GoalEvaluationStep(step)) => {
|
(
|
||||||
goal_eval.evaluation_steps.push(step);
|
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluations),
|
||||||
|
DebugSolver::GoalEvaluationStep(goal_evaluation_step),
|
||||||
|
) => {
|
||||||
|
canonical_goal_evaluations.evaluation_steps.push(goal_evaluation_step);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@ -332,7 +367,7 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.nested(WipGoalCandidate {
|
self.nested(WipGoalCandidate {
|
||||||
nested_goal_evaluations: vec![],
|
added_goals_evaluations: vec![],
|
||||||
candidates: vec![],
|
candidates: vec![],
|
||||||
kind: None,
|
kind: None,
|
||||||
})
|
})
|
||||||
@ -392,19 +427,19 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn added_goals_evaluation(&mut self, goals_evaluation: ProofTreeBuilder<'tcx>) {
|
pub fn added_goals_evaluation(&mut self, added_goals_evaluation: ProofTreeBuilder<'tcx>) {
|
||||||
if let Some(this) = self.as_mut() {
|
if let Some(this) = self.as_mut() {
|
||||||
match (this, goals_evaluation.state.unwrap().tree) {
|
match (this, added_goals_evaluation.state.unwrap().tree) {
|
||||||
(
|
(
|
||||||
DebugSolver::GoalEvaluationStep(WipGoalEvaluationStep {
|
DebugSolver::GoalEvaluationStep(WipGoalEvaluationStep {
|
||||||
nested_goal_evaluations,
|
added_goals_evaluations,
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
| DebugSolver::GoalCandidate(WipGoalCandidate {
|
| DebugSolver::GoalCandidate(WipGoalCandidate {
|
||||||
nested_goal_evaluations, ..
|
added_goals_evaluations, ..
|
||||||
}),
|
}),
|
||||||
DebugSolver::AddedGoalsEvaluation(added_goals_evaluation),
|
DebugSolver::AddedGoalsEvaluation(added_goals_evaluation),
|
||||||
) => nested_goal_evaluations.push(added_goals_evaluation),
|
) => added_goals_evaluations.push(added_goals_evaluation),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,15 +448,13 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
|
|||||||
pub fn query_result(&mut self, result: QueryResult<'tcx>) {
|
pub fn query_result(&mut self, result: QueryResult<'tcx>) {
|
||||||
if let Some(this) = self.as_mut() {
|
if let Some(this) = self.as_mut() {
|
||||||
match this {
|
match this {
|
||||||
DebugSolver::GoalEvaluation(goal_evaluation) => {
|
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {
|
||||||
assert_eq!(goal_evaluation.result.replace(result), None);
|
assert_eq!(canonical_goal_evaluation.result.replace(result), None);
|
||||||
}
|
}
|
||||||
DebugSolver::GoalEvaluationStep(evaluation_step) => {
|
DebugSolver::GoalEvaluationStep(evaluation_step) => {
|
||||||
assert_eq!(evaluation_step.result.replace(result), None);
|
assert_eq!(evaluation_step.result.replace(result), None);
|
||||||
}
|
}
|
||||||
DebugSolver::Root
|
_ => unreachable!(),
|
||||||
| DebugSolver::AddedGoalsEvaluation(_)
|
|
||||||
| DebugSolver::GoalCandidate(_) => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,7 @@ impl<'tcx> SearchGraph<'tcx> {
|
|||||||
available_depth,
|
available_depth,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
inspect.cache_hit(CacheHit::Global);
|
||||||
self.on_cache_hit(reached_depth, encountered_overflow);
|
self.on_cache_hit(reached_depth, encountered_overflow);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user