Skip to content

Commit 0cb800e

Browse files
committed
differentiate root and nested goals
1 parent 1b141b6 commit 0cb800e

File tree

6 files changed

+76
-35
lines changed

6 files changed

+76
-35
lines changed

compiler/rustc_middle/src/traits/solve/inspect.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,29 @@ pub enum CacheHit {
1414
Global,
1515
}
1616

17+
#[derive(Eq, PartialEq)]
18+
pub enum GoalEvaluationKind {
19+
Root,
20+
Nested { is_normalizes_to_hack: IsNormalizesToHack },
21+
}
22+
1723
#[derive(Eq, PartialEq)]
1824
pub struct GoalEvaluation<'tcx> {
1925
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
20-
pub is_normalizes_to_hack: IsNormalizesToHack,
26+
pub kind: GoalEvaluationKind,
2127
pub evaluation: CanonicalGoalEvaluation<'tcx>,
2228
pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
2329
}
2430

2531
#[derive(Eq, PartialEq)]
2632
pub struct CanonicalGoalEvaluation<'tcx> {
2733
pub goal: CanonicalInput<'tcx>,
28-
pub kind: GoalEvaluationKind<'tcx>,
34+
pub kind: CanonicalGoalEvaluationKind<'tcx>,
2935
pub result: QueryResult<'tcx>,
3036
}
3137

3238
#[derive(Eq, PartialEq)]
33-
pub enum GoalEvaluationKind<'tcx> {
39+
pub enum CanonicalGoalEvaluationKind<'tcx> {
3440
Overflow,
3541
CacheHit(CacheHit),
3642
Uncached { revisions: Vec<GoalEvaluationStep<'tcx>> },

compiler/rustc_middle/src/traits/solve/inspect/format.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,12 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
4040
}
4141

4242
pub(super) fn format_goal_evaluation(&mut self, eval: &GoalEvaluation<'_>) -> std::fmt::Result {
43-
let goal_text = match eval.is_normalizes_to_hack {
44-
IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
45-
IsNormalizesToHack::No => "GOAL",
43+
let goal_text = match eval.kind {
44+
GoalEvaluationKind::Root => "ROOT GOAL",
45+
GoalEvaluationKind::Nested { is_normalizes_to_hack } => match is_normalizes_to_hack {
46+
IsNormalizesToHack::No => "GOAL",
47+
IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
48+
},
4649
};
4750
writeln!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?;
4851
self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))?;
@@ -68,16 +71,16 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
6871
writeln!(self.f, "GOAL: {:?}", eval.goal)?;
6972

7073
match &eval.kind {
71-
GoalEvaluationKind::Overflow => {
74+
CanonicalGoalEvaluationKind::Overflow => {
7275
writeln!(self.f, "OVERFLOW: {:?}", eval.result)
7376
}
74-
GoalEvaluationKind::CacheHit(CacheHit::Global) => {
77+
CanonicalGoalEvaluationKind::CacheHit(CacheHit::Global) => {
7578
writeln!(self.f, "GLOBAL CACHE HIT: {:?}", eval.result)
7679
}
77-
GoalEvaluationKind::CacheHit(CacheHit::Provisional) => {
80+
CanonicalGoalEvaluationKind::CacheHit(CacheHit::Provisional) => {
7881
writeln!(self.f, "PROVISIONAL CACHE HIT: {:?}", eval.result)
7982
}
80-
GoalEvaluationKind::Uncached { revisions } => {
83+
CanonicalGoalEvaluationKind::Uncached { revisions } => {
8184
for (n, step) in revisions.iter().enumerate() {
8285
writeln!(self.f, "REVISION {n}")?;
8386
self.nested(|this| this.format_evaluation_step(step))?;

compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use std::ops::ControlFlow;
2828
use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment};
2929

3030
use super::inspect::ProofTreeBuilder;
31-
use super::search_graph;
3231
use super::SolverMode;
32+
use super::{search_graph, GoalEvaluationKind};
3333
use super::{search_graph::SearchGraph, Goal};
3434
pub use select::InferCtxtSelectExt;
3535

@@ -164,7 +164,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
164164
Option<inspect::GoalEvaluation<'tcx>>,
165165
) {
166166
EvalCtxt::enter_root(self, generate_proof_tree, |ecx| {
167-
ecx.evaluate_goal(IsNormalizesToHack::No, goal)
167+
ecx.evaluate_goal(GoalEvaluationKind::Root, goal)
168168
})
169169
}
170170
}
@@ -340,11 +340,11 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
340340
/// been constrained and the certainty of the result.
341341
fn evaluate_goal(
342342
&mut self,
343-
is_normalizes_to_hack: IsNormalizesToHack,
343+
goal_evaluation_kind: GoalEvaluationKind,
344344
goal: Goal<'tcx, ty::Predicate<'tcx>>,
345345
) -> Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution> {
346346
let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
347-
let mut goal_evaluation = self.inspect.new_goal_evaluation(goal, is_normalizes_to_hack);
347+
let mut goal_evaluation = self.inspect.new_goal_evaluation(goal, goal_evaluation_kind);
348348
let encountered_overflow = self.search_graph.encountered_overflow();
349349
let canonical_response = EvalCtxt::evaluate_canonical_goal(
350350
self.tcx(),
@@ -389,7 +389,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
389389
// solver cycle.
390390
if cfg!(debug_assertions)
391391
&& has_changed
392-
&& is_normalizes_to_hack == IsNormalizesToHack::No
392+
&& !matches!(
393+
goal_evaluation_kind,
394+
GoalEvaluationKind::Nested { is_normalizes_to_hack: IsNormalizesToHack::Yes }
395+
)
393396
&& !self.search_graph.in_cycle()
394397
{
395398
// The nested evaluation has to happen with the original state
@@ -561,8 +564,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
561564
},
562565
);
563566

564-
let (_, certainty, instantiate_goals) =
565-
self.evaluate_goal(IsNormalizesToHack::Yes, unconstrained_goal)?;
567+
let (_, certainty, instantiate_goals) = self.evaluate_goal(
568+
GoalEvaluationKind::Nested { is_normalizes_to_hack: IsNormalizesToHack::Yes },
569+
unconstrained_goal,
570+
)?;
566571
self.add_goals(instantiate_goals);
567572

568573
// Finally, equate the goal's RHS with the unconstrained var.
@@ -596,8 +601,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
596601
}
597602

598603
for goal in goals.goals.drain(..) {
599-
let (has_changed, certainty, instantiate_goals) =
600-
self.evaluate_goal(IsNormalizesToHack::No, goal)?;
604+
let (has_changed, certainty, instantiate_goals) = self.evaluate_goal(
605+
GoalEvaluationKind::Nested { is_normalizes_to_hack: IsNormalizesToHack::No },
606+
goal,
607+
)?;
601608
self.add_goals(instantiate_goals);
602609
if has_changed {
603610
unchanged_certainty = None;

compiler/rustc_trait_selection/src/solve/inspect.rs

+30-12
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,62 @@ use rustc_middle::ty::{self, TyCtxt};
77
use rustc_session::config::DumpSolverProofTree;
88

99
use super::eval_ctxt::UseGlobalCache;
10-
use super::GenerateProofTree;
10+
use super::{GenerateProofTree, GoalEvaluationKind};
1111

1212
#[derive(Eq, PartialEq, Debug)]
1313
pub struct WipGoalEvaluation<'tcx> {
1414
pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
15+
pub kind: WipGoalEvaluationKind,
1516
pub evaluation: Option<WipCanonicalGoalEvaluation<'tcx>>,
16-
pub is_normalizes_to_hack: IsNormalizesToHack,
1717
pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
1818
}
1919

2020
impl<'tcx> WipGoalEvaluation<'tcx> {
2121
pub fn finalize(self) -> inspect::GoalEvaluation<'tcx> {
2222
inspect::GoalEvaluation {
2323
uncanonicalized_goal: self.uncanonicalized_goal,
24+
kind: match self.kind {
25+
WipGoalEvaluationKind::Root => inspect::GoalEvaluationKind::Root,
26+
WipGoalEvaluationKind::Nested { is_normalizes_to_hack } => {
27+
inspect::GoalEvaluationKind::Nested { is_normalizes_to_hack }
28+
}
29+
},
2430
evaluation: self.evaluation.unwrap().finalize(),
25-
is_normalizes_to_hack: self.is_normalizes_to_hack,
2631
returned_goals: self.returned_goals,
2732
}
2833
}
2934
}
3035

3136
#[derive(Eq, PartialEq, Debug)]
3237
pub enum WipGoalEvaluationKind {
38+
Root,
39+
Nested { is_normalizes_to_hack: IsNormalizesToHack },
40+
}
41+
42+
#[derive(Eq, PartialEq, Debug)]
43+
pub enum WipCanonicalGoalEvaluationKind {
3344
Overflow,
3445
CacheHit(CacheHit),
3546
}
3647

3748
#[derive(Eq, PartialEq, Debug)]
3849
pub struct WipCanonicalGoalEvaluation<'tcx> {
3950
pub goal: CanonicalInput<'tcx>,
40-
pub kind: Option<WipGoalEvaluationKind>,
51+
pub kind: Option<WipCanonicalGoalEvaluationKind>,
4152
pub revisions: Vec<WipGoalEvaluationStep<'tcx>>,
4253
pub result: Option<QueryResult<'tcx>>,
4354
}
4455

4556
impl<'tcx> WipCanonicalGoalEvaluation<'tcx> {
4657
pub fn finalize(self) -> inspect::CanonicalGoalEvaluation<'tcx> {
4758
let kind = match self.kind {
48-
Some(WipGoalEvaluationKind::Overflow) => inspect::GoalEvaluationKind::Overflow,
49-
Some(WipGoalEvaluationKind::CacheHit(hit)) => {
50-
inspect::GoalEvaluationKind::CacheHit(hit)
59+
Some(WipCanonicalGoalEvaluationKind::Overflow) => {
60+
inspect::CanonicalGoalEvaluationKind::Overflow
61+
}
62+
Some(WipCanonicalGoalEvaluationKind::CacheHit(hit)) => {
63+
inspect::CanonicalGoalEvaluationKind::CacheHit(hit)
5164
}
52-
None => inspect::GoalEvaluationKind::Uncached {
65+
None => inspect::CanonicalGoalEvaluationKind::Uncached {
5366
revisions: self
5467
.revisions
5568
.into_iter()
@@ -260,15 +273,20 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
260273
self.state.is_none()
261274
}
262275

263-
pub fn new_goal_evaluation(
276+
pub(super) fn new_goal_evaluation(
264277
&mut self,
265278
goal: Goal<'tcx, ty::Predicate<'tcx>>,
266-
is_normalizes_to_hack: IsNormalizesToHack,
279+
kind: GoalEvaluationKind,
267280
) -> ProofTreeBuilder<'tcx> {
268281
self.nested(|| WipGoalEvaluation {
269282
uncanonicalized_goal: goal,
283+
kind: match kind {
284+
GoalEvaluationKind::Root => WipGoalEvaluationKind::Root,
285+
GoalEvaluationKind::Nested { is_normalizes_to_hack } => {
286+
WipGoalEvaluationKind::Nested { is_normalizes_to_hack }
287+
}
288+
},
270289
evaluation: None,
271-
is_normalizes_to_hack,
272290
returned_goals: vec![],
273291
})
274292
}
@@ -297,7 +315,7 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
297315
}
298316
}
299317

300-
pub fn goal_evaluation_kind(&mut self, kind: WipGoalEvaluationKind) {
318+
pub fn goal_evaluation_kind(&mut self, kind: WipCanonicalGoalEvaluationKind) {
301319
if let Some(this) = self.as_mut() {
302320
match this {
303321
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {

compiler/rustc_trait_selection/src/solve/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues};
1919
use rustc_infer::traits::query::NoSolution;
2020
use rustc_middle::infer::canonical::CanonicalVarInfos;
2121
use rustc_middle::traits::solve::{
22-
CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, Response,
22+
CanonicalResponse, Certainty, ExternalConstraintsData, Goal, IsNormalizesToHack, QueryResult,
23+
Response,
2324
};
2425
use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex};
2526
use rustc_middle::ty::{
@@ -59,6 +60,12 @@ enum SolverMode {
5960
Coherence,
6061
}
6162

63+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
64+
enum GoalEvaluationKind {
65+
Root,
66+
Nested { is_normalizes_to_hack: IsNormalizesToHack },
67+
}
68+
6269
trait CanonicalResponseExt {
6370
fn has_no_inference_or_external_constraints(&self) -> bool;
6471

compiler/rustc_trait_selection/src/solve/search_graph/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl<'tcx> SearchGraph<'tcx> {
187187
last.encountered_overflow = true;
188188
}
189189

190-
inspect.goal_evaluation_kind(inspect::WipGoalEvaluationKind::Overflow);
190+
inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow);
191191
return Self::response_no_constraints(tcx, input, Certainty::OVERFLOW);
192192
};
193193

@@ -203,7 +203,7 @@ impl<'tcx> SearchGraph<'tcx> {
203203
available_depth,
204204
)
205205
{
206-
inspect.goal_evaluation_kind(inspect::WipGoalEvaluationKind::CacheHit(
206+
inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::CacheHit(
207207
CacheHit::Global,
208208
));
209209
self.on_cache_hit(reached_depth, encountered_overflow);
@@ -240,7 +240,7 @@ impl<'tcx> SearchGraph<'tcx> {
240240
// Finally we can return either the provisional response for that goal if we have a
241241
// coinductive cycle or an ambiguous result if the cycle is inductive.
242242
Entry::Occupied(entry_index) => {
243-
inspect.goal_evaluation_kind(inspect::WipGoalEvaluationKind::CacheHit(
243+
inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::CacheHit(
244244
CacheHit::Provisional,
245245
));
246246

0 commit comments

Comments
 (0)