Skip to content

Commit ef65bda

Browse files
committed
proof tree cleanup 1/n
1 parent 43a2166 commit ef65bda

File tree

4 files changed

+61
-113
lines changed

4 files changed

+61
-113
lines changed

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 48 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ use crate::solve::inspect::{self, ProofTreeBuilder};
2424
use crate::solve::search_graph::SearchGraph;
2525
use crate::solve::ty::may_use_unstable_feature;
2626
use crate::solve::{
27-
CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluation, GoalEvaluationKind,
28-
GoalSource, GoalStalledOn, HasChanged, NestedNormalizationGoals, NoSolution, QueryInput,
29-
QueryResult,
27+
CanonicalInput, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluation, GoalSource,
28+
GoalStalledOn, HasChanged, NestedNormalizationGoals, NoSolution, QueryInput, QueryResult,
3029
};
3130

3231
pub(super) mod canonical;
@@ -172,10 +171,7 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
172171
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
173172
span: <Self::Interner as Interner>::Span,
174173
) -> (
175-
Result<
176-
(NestedNormalizationGoals<Self::Interner>, GoalEvaluation<Self::Interner>),
177-
NoSolution,
178-
>,
174+
Result<NestedNormalizationGoals<Self::Interner>, NoSolution>,
179175
inspect::GoalEvaluation<Self::Interner>,
180176
);
181177
}
@@ -192,14 +188,9 @@ where
192188
span: I::Span,
193189
stalled_on: Option<GoalStalledOn<I>>,
194190
) -> Result<GoalEvaluation<I>, NoSolution> {
195-
EvalCtxt::enter_root(
196-
self,
197-
self.cx().recursion_limit(),
198-
GenerateProofTree::No,
199-
span,
200-
|ecx| ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal, stalled_on),
201-
)
202-
.0
191+
EvalCtxt::enter_root(self, self.cx().recursion_limit(), span, |ecx| {
192+
ecx.evaluate_goal(GoalSource::Misc, goal, stalled_on)
193+
})
203194
}
204195

205196
fn root_goal_may_hold_with_depth(
@@ -208,10 +199,9 @@ where
208199
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
209200
) -> bool {
210201
self.probe(|| {
211-
EvalCtxt::enter_root(self, root_depth, GenerateProofTree::No, I::Span::dummy(), |ecx| {
212-
ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal, None)
202+
EvalCtxt::enter_root(self, root_depth, I::Span::dummy(), |ecx| {
203+
ecx.evaluate_goal(GoalSource::Misc, goal, None)
213204
})
214-
.0
215205
})
216206
.is_ok()
217207
}
@@ -221,18 +211,10 @@ where
221211
&self,
222212
goal: Goal<I, I::Predicate>,
223213
span: I::Span,
224-
) -> (
225-
Result<(NestedNormalizationGoals<I>, GoalEvaluation<I>), NoSolution>,
226-
inspect::GoalEvaluation<I>,
227-
) {
228-
let (result, proof_tree) = EvalCtxt::enter_root(
229-
self,
230-
self.cx().recursion_limit(),
231-
GenerateProofTree::Yes,
232-
span,
233-
|ecx| ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal, None),
234-
);
235-
(result, proof_tree.unwrap())
214+
) -> (Result<NestedNormalizationGoals<I>, NoSolution>, inspect::GoalEvaluation<I>) {
215+
EvalCtxt::enter_root(self, self.cx().recursion_limit(), span, |ecx| {
216+
ecx.evaluate_goal_for_proof_tree(goal)
217+
})
236218
}
237219
}
238220

@@ -301,17 +283,16 @@ where
301283
pub(super) fn enter_root<R>(
302284
delegate: &D,
303285
root_depth: usize,
304-
generate_proof_tree: GenerateProofTree,
305286
origin_span: I::Span,
306287
f: impl FnOnce(&mut EvalCtxt<'_, D>) -> R,
307-
) -> (R, Option<inspect::GoalEvaluation<I>>) {
288+
) -> R {
308289
let mut search_graph = SearchGraph::new(root_depth);
309290

310291
let mut ecx = EvalCtxt {
311292
delegate,
312293
search_graph: &mut search_graph,
313294
nested_goals: Default::default(),
314-
inspect: ProofTreeBuilder::new_maybe_root(generate_proof_tree),
295+
inspect: ProofTreeBuilder::new_noop(),
315296

316297
// Only relevant when canonicalizing the response,
317298
// which we don't do within this evaluation context.
@@ -324,15 +305,12 @@ where
324305
tainted: Ok(()),
325306
};
326307
let result = f(&mut ecx);
327-
328-
let proof_tree = ecx.inspect.finalize();
329308
assert!(
330309
ecx.nested_goals.is_empty(),
331310
"root `EvalCtxt` should not have any goals added to it"
332311
);
333-
334312
assert!(search_graph.is_empty());
335-
(result, proof_tree)
313+
result
336314
}
337315

338316
/// Creates a nested evaluation context that shares the same search graph as the
@@ -406,13 +384,12 @@ where
406384
/// been constrained and the certainty of the result.
407385
fn evaluate_goal(
408386
&mut self,
409-
goal_evaluation_kind: GoalEvaluationKind,
410387
source: GoalSource,
411388
goal: Goal<I, I::Predicate>,
412389
stalled_on: Option<GoalStalledOn<I>>,
413390
) -> Result<GoalEvaluation<I>, NoSolution> {
414391
let (normalization_nested_goals, goal_evaluation) =
415-
self.evaluate_goal_raw(goal_evaluation_kind, source, goal, stalled_on)?;
392+
self.evaluate_goal_raw(source, goal, stalled_on)?;
416393
assert!(normalization_nested_goals.is_empty());
417394
Ok(goal_evaluation)
418395
}
@@ -426,7 +403,6 @@ where
426403
/// storage.
427404
pub(super) fn evaluate_goal_raw(
428405
&mut self,
429-
goal_evaluation_kind: GoalEvaluationKind,
430406
source: GoalSource,
431407
goal: Goal<I, I::Predicate>,
432408
stalled_on: Option<GoalStalledOn<I>>,
@@ -459,16 +435,12 @@ where
459435
let (goal, opaque_types) = eager_resolve_vars(self.delegate, (goal, opaque_types));
460436

461437
let (orig_values, canonical_goal) = self.canonicalize_goal(goal, opaque_types);
462-
let mut goal_evaluation =
463-
self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
464438
let canonical_result = self.search_graph.evaluate_goal(
465439
self.cx(),
466440
canonical_goal,
467441
self.step_kind_for_source(source),
468-
&mut goal_evaluation,
442+
&mut ProofTreeBuilder::new_noop(),
469443
);
470-
goal_evaluation.query_result(canonical_result);
471-
self.inspect.goal_evaluation(goal_evaluation);
472444
let response = match canonical_result {
473445
Err(e) => return Err(e),
474446
Ok(response) => response,
@@ -542,6 +514,35 @@ where
542514
))
543515
}
544516

517+
/// Evaluate a goal to build a proof tree. This is a copy of [EvalCtxt::evaluate_goal_raw].
518+
pub(super) fn evaluate_goal_for_proof_tree(
519+
&mut self,
520+
goal: Goal<I, I::Predicate>,
521+
) -> (Result<NestedNormalizationGoals<I>, NoSolution>, inspect::GoalEvaluation<I>) {
522+
let opaque_types = self.delegate.clone_opaque_types_lookup_table();
523+
let (goal, opaque_types) = eager_resolve_vars(self.delegate, (goal, opaque_types));
524+
525+
let (orig_values, canonical_goal) = self.canonicalize_goal(goal, opaque_types);
526+
let mut goal_evaluation = ProofTreeBuilder::new_goal_evaluation(goal, &orig_values);
527+
let canonical_result = self.search_graph.evaluate_goal(
528+
self.cx(),
529+
canonical_goal,
530+
self.step_kind_for_source(GoalSource::Misc),
531+
&mut goal_evaluation,
532+
);
533+
goal_evaluation.query_result(canonical_result);
534+
let proof_tree = goal_evaluation.finalize();
535+
let response = match canonical_result {
536+
Err(e) => return (Err(e), proof_tree),
537+
Ok(response) => response,
538+
};
539+
540+
let (normalization_nested_goals, _certainty) =
541+
self.instantiate_and_apply_query_response(goal.param_env, &orig_values, response);
542+
543+
(Ok(normalization_nested_goals), proof_tree)
544+
}
545+
545546
pub(super) fn compute_goal(&mut self, goal: Goal<I, I::Predicate>) -> QueryResult<I> {
546547
let Goal { param_env, predicate } = goal;
547548
let kind = predicate.kind();
@@ -676,12 +677,7 @@ where
676677
let (
677678
NestedNormalizationGoals(nested_goals),
678679
GoalEvaluation { goal, certainty, stalled_on, has_changed: _ },
679-
) = self.evaluate_goal_raw(
680-
GoalEvaluationKind::Nested,
681-
source,
682-
unconstrained_goal,
683-
stalled_on,
684-
)?;
680+
) = self.evaluate_goal_raw(source, unconstrained_goal, stalled_on)?;
685681
// Add the nested goals from normalization to our own nested goals.
686682
trace!(?nested_goals);
687683
self.nested_goals.extend(nested_goals.into_iter().map(|(s, g)| (s, g, None)));
@@ -734,7 +730,7 @@ where
734730
}
735731
} else {
736732
let GoalEvaluation { goal, certainty, has_changed, stalled_on } =
737-
self.evaluate_goal(GoalEvaluationKind::Nested, source, goal, stalled_on)?;
733+
self.evaluate_goal(source, goal, stalled_on)?;
738734
if has_changed == HasChanged::Yes {
739735
unchanged_certainty = None;
740736
}

compiler/rustc_next_trait_solver/src/solve/inspect/build.rs

Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ use rustc_type_ir::{self as ty, Interner};
1212

1313
use crate::delegate::SolverDelegate;
1414
use crate::solve::eval_ctxt::canonical;
15-
use crate::solve::{
16-
Certainty, GenerateProofTree, Goal, GoalEvaluationKind, GoalSource, QueryResult, inspect,
17-
};
15+
use crate::solve::{Certainty, Goal, GoalSource, QueryResult, inspect};
1816

1917
/// The core data structure when building proof trees.
2018
///
@@ -51,7 +49,6 @@ where
5149
/// We simply ICE in case that assumption is broken.
5250
#[derive_where(Debug; I: Interner)]
5351
enum DebugSolver<I: Interner> {
54-
Root,
5552
GoalEvaluation(WipGoalEvaluation<I>),
5653
CanonicalGoalEvaluationStep(WipCanonicalGoalEvaluationStep<I>),
5754
}
@@ -182,17 +179,6 @@ impl<I: Interner> WipProbeStep<I> {
182179
}
183180

184181
impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
185-
fn new(state: impl Into<DebugSolver<I>>) -> ProofTreeBuilder<D> {
186-
ProofTreeBuilder { state: Some(Box::new(state.into())), _infcx: PhantomData }
187-
}
188-
189-
fn opt_nested<T: Into<DebugSolver<I>>>(&self, state: impl FnOnce() -> Option<T>) -> Self {
190-
ProofTreeBuilder {
191-
state: self.state.as_ref().and_then(|_| Some(state()?.into())).map(Box::new),
192-
_infcx: PhantomData,
193-
}
194-
}
195-
196182
fn nested<T: Into<DebugSolver<I>>>(&self, state: impl FnOnce() -> T) -> Self {
197183
ProofTreeBuilder {
198184
state: self.state.as_ref().map(|_| Box::new(state().into())),
@@ -210,50 +196,35 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
210196
nested
211197
}
212198

213-
pub(crate) fn finalize(self) -> Option<inspect::GoalEvaluation<I>> {
214-
match *self.state? {
215-
DebugSolver::GoalEvaluation(wip_goal_evaluation) => {
216-
Some(wip_goal_evaluation.finalize())
217-
}
199+
pub(crate) fn finalize(self) -> inspect::GoalEvaluation<I> {
200+
match *self.state.unwrap() {
201+
DebugSolver::GoalEvaluation(wip_goal_evaluation) => wip_goal_evaluation.finalize(),
218202
root => unreachable!("unexpected proof tree builder root node: {:?}", root),
219203
}
220204
}
221205

222-
pub(crate) fn new_maybe_root(generate_proof_tree: GenerateProofTree) -> ProofTreeBuilder<D> {
223-
match generate_proof_tree {
224-
GenerateProofTree::No => ProofTreeBuilder::new_noop(),
225-
GenerateProofTree::Yes => ProofTreeBuilder::new_root(),
226-
}
227-
}
228-
229-
fn new_root() -> ProofTreeBuilder<D> {
230-
ProofTreeBuilder::new(DebugSolver::Root)
206+
pub(crate) fn is_noop(&self) -> bool {
207+
self.state.is_none()
231208
}
232209

233-
fn new_noop() -> ProofTreeBuilder<D> {
210+
pub(crate) fn new_noop() -> ProofTreeBuilder<D> {
234211
ProofTreeBuilder { state: None, _infcx: PhantomData }
235212
}
236213

237-
pub(crate) fn is_noop(&self) -> bool {
238-
self.state.is_none()
239-
}
240-
241214
pub(in crate::solve) fn new_goal_evaluation(
242-
&mut self,
243215
uncanonicalized_goal: Goal<I, I::Predicate>,
244216
orig_values: &[I::GenericArg],
245-
kind: GoalEvaluationKind,
246217
) -> ProofTreeBuilder<D> {
247-
self.opt_nested(|| match kind {
248-
GoalEvaluationKind::Root => Some(WipGoalEvaluation {
218+
ProofTreeBuilder {
219+
state: Some(Box::new(DebugSolver::GoalEvaluation(WipGoalEvaluation {
249220
uncanonicalized_goal,
250221
orig_values: orig_values.to_vec(),
251222
encountered_overflow: false,
252223
final_revision: None,
253224
result: None,
254-
}),
255-
GoalEvaluationKind::Nested => None,
256-
})
225+
}))),
226+
_infcx: PhantomData,
227+
}
257228
}
258229

259230
pub(crate) fn canonical_goal_evaluation_overflow(&mut self) {
@@ -267,18 +238,6 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
267238
}
268239
}
269240

270-
pub(crate) fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<D>) {
271-
if let Some(this) = self.as_mut() {
272-
match this {
273-
DebugSolver::Root => *this = *goal_evaluation.state.unwrap(),
274-
DebugSolver::CanonicalGoalEvaluationStep(_) => {
275-
assert!(goal_evaluation.state.is_none())
276-
}
277-
_ => unreachable!(),
278-
}
279-
}
280-
}
281-
282241
pub(crate) fn new_goal_evaluation_step(
283242
&mut self,
284243
var_values: ty::CanonicalVarValues<I>,
@@ -457,7 +416,6 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
457416
None
458417
);
459418
}
460-
_ => unreachable!(),
461419
}
462420
}
463421
}

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,6 @@ use crate::solve::assembly::Candidate;
4242
/// recursion limit again. However, this feels very unlikely.
4343
const FIXPOINT_STEP_LIMIT: usize = 8;
4444

45-
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
46-
enum GoalEvaluationKind {
47-
Root,
48-
Nested,
49-
}
50-
5145
/// Whether evaluating this goal ended up changing the
5246
/// inference state.
5347
#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)]

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
249249
// `InspectGoal::new` so that the goal has the right result (and maintains
250250
// the impression that we don't do this normalizes-to infer hack at all).
251251
let (nested, proof_tree) = infcx.evaluate_root_goal_for_proof_tree(goal, span);
252-
let nested_goals_result = nested.and_then(|(nested, _)| {
252+
let nested_goals_result = nested.and_then(|nested| {
253253
normalizes_to_term_hack.constrain_and(
254254
infcx,
255255
span,

0 commit comments

Comments
 (0)