Skip to content

Commit 64a27c2

Browse files
committed
resuse eagerly resolved goal from previous iteration
1 parent 0b323ea commit 64a27c2

File tree

4 files changed

+37
-13
lines changed

4 files changed

+37
-13
lines changed

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,14 @@ where
5353
{
5454
/// Canonicalizes the goal remembering the original values
5555
/// for each bound variable.
56+
///
57+
/// This expects `goal` and `opaque_types` to be eager resolved.
5658
pub(super) fn canonicalize_goal(
5759
&self,
5860
is_hir_typeck_root_goal: bool,
5961
goal: Goal<I, I::Predicate>,
62+
opaque_types: Vec<(ty::OpaqueTypeKey<I>, I::Ty)>,
6063
) -> (Vec<I::GenericArg>, CanonicalInput<I, I::Predicate>) {
61-
// We only care about one entry per `OpaqueTypeKey` here,
62-
// so we only canonicalize the lookup table and ignore
63-
// duplicate entries.
64-
let opaque_types = self.delegate.clone_opaque_types_lookup_table();
65-
let (goal, opaque_types) = eager_resolve_vars(self.delegate, (goal, opaque_types));
66-
6764
let mut orig_values = Default::default();
6865
let canonical = Canonicalizer::canonicalize_input(
6966
self.delegate,

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

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use super::has_only_region_constraints;
2020
use crate::coherence;
2121
use crate::delegate::SolverDelegate;
2222
use crate::placeholder::BoundVarReplacer;
23+
use crate::resolve::eager_resolve_vars;
2324
use crate::solve::inspect::{self, ProofTreeBuilder};
2425
use crate::solve::search_graph::SearchGraph;
2526
use crate::solve::ty::may_use_unstable_feature;
@@ -440,17 +441,24 @@ where
440441
return Ok((
441442
NestedNormalizationGoals::empty(),
442443
GoalEvaluation {
444+
goal,
443445
certainty: Certainty::Maybe(stalled_on.stalled_cause),
444446
has_changed: HasChanged::No,
445447
stalled_on: Some(stalled_on),
446448
},
447449
));
448450
}
449451

452+
// We only care about one entry per `OpaqueTypeKey` here,
453+
// so we only canonicalize the lookup table and ignore
454+
// duplicate entries.
455+
let opaque_types = self.delegate.clone_opaque_types_lookup_table();
456+
let (goal, opaque_types) = eager_resolve_vars(self.delegate, (goal, opaque_types));
457+
450458
let is_hir_typeck_root_goal = matches!(goal_evaluation_kind, GoalEvaluationKind::Root)
451459
&& self.delegate.in_hir_typeck();
452-
453-
let (orig_values, canonical_goal) = self.canonicalize_goal(is_hir_typeck_root_goal, goal);
460+
let (orig_values, canonical_goal) =
461+
self.canonicalize_goal(is_hir_typeck_root_goal, goal, opaque_types);
454462
let mut goal_evaluation =
455463
self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
456464
let canonical_result = self.search_graph.evaluate_goal(
@@ -528,7 +536,10 @@ where
528536
},
529537
};
530538

531-
Ok((normalization_nested_goals, GoalEvaluation { certainty, has_changed, stalled_on }))
539+
Ok((
540+
normalization_nested_goals,
541+
GoalEvaluation { goal, certainty, has_changed, stalled_on },
542+
))
532543
}
533544

534545
pub(super) fn compute_goal(&mut self, goal: Goal<I, I::Predicate>) -> QueryResult<I> {
@@ -664,7 +675,7 @@ where
664675

665676
let (
666677
NestedNormalizationGoals(nested_goals),
667-
GoalEvaluation { certainty, stalled_on, has_changed: _ },
678+
GoalEvaluation { goal, certainty, stalled_on, has_changed: _ },
668679
) = self.evaluate_goal_raw(
669680
GoalEvaluationKind::Nested,
670681
source,
@@ -702,7 +713,15 @@ where
702713
// FIXME: Do we need to eagerly resolve here? Or should we check
703714
// if the cache key has any changed vars?
704715
let with_resolved_vars = self.resolve_vars_if_possible(goal);
705-
if pred.alias != goal.predicate.as_normalizes_to().unwrap().skip_binder().alias {
716+
if pred.alias
717+
!= with_resolved_vars
718+
.predicate
719+
.as_normalizes_to()
720+
.unwrap()
721+
.no_bound_vars()
722+
.unwrap()
723+
.alias
724+
{
706725
unchanged_certainty = None;
707726
}
708727

@@ -714,7 +733,7 @@ where
714733
}
715734
}
716735
} else {
717-
let GoalEvaluation { certainty, has_changed, stalled_on } =
736+
let GoalEvaluation { goal, certainty, has_changed, stalled_on } =
718737
self.evaluate_goal(GoalEvaluationKind::Nested, source, goal, stalled_on)?;
719738
if has_changed == HasChanged::Yes {
720739
unchanged_certainty = None;

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ fn response_no_constraints_raw<I: Interner>(
386386

387387
/// The result of evaluating a goal.
388388
pub struct GoalEvaluation<I: Interner> {
389+
/// The goal we've evaluated. This is the input goal, but potentially with its
390+
/// inference variables resolved. This never applies any inference constraints
391+
/// from evaluating the goal.
392+
pub goal: Goal<I, I::Predicate>,
389393
pub certainty: Certainty,
390394
pub has_changed: HasChanged,
391395
/// If the [`Certainty`] was `Maybe`, then keep track of whether the goal has changed

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ where
207207

208208
let result = delegate.evaluate_root_goal(goal, obligation.cause.span, stalled_on);
209209
self.inspect_evaluated_obligation(infcx, &obligation, &result);
210-
let GoalEvaluation { certainty, has_changed, stalled_on } = match result {
210+
let GoalEvaluation { goal, certainty, has_changed, stalled_on } = match result {
211211
Ok(result) => result,
212212
Err(NoSolution) => {
213213
errors.push(E::from_solver_error(
@@ -218,6 +218,10 @@ where
218218
}
219219
};
220220

221+
// We've resolved the goal in `evaluate_root_goal`, avoid redoing this work
222+
// in the next iteration. This does not resolve the inference variables
223+
// constrained by evaluating the goal.
224+
obligation.predicate = goal.predicate;
221225
if has_changed == HasChanged::Yes {
222226
// We increment the recursion depth here to track the number of times
223227
// this goal has resulted in inference progress. This doesn't precisely

0 commit comments

Comments
 (0)