@@ -22,8 +22,8 @@ use crate::delegate::SolverDelegate;
2222use crate :: solve:: inspect:: { self , ProofTreeBuilder } ;
2323use crate :: solve:: search_graph:: SearchGraph ;
2424use crate :: solve:: {
25- CanonicalGoalCacheKey , CanonicalInput , Certainty , FIXPOINT_STEP_LIMIT , Goal ,
26- GoalEvaluationKind , GoalSource , HasChanged , NestedNormalizationGoals , NoSolution , QueryInput ,
25+ CanonicalInput , Certainty , FIXPOINT_STEP_LIMIT , Goal , GoalEvaluation , GoalEvaluationKind ,
26+ GoalSource , GoalStalledOn , HasChanged , NestedNormalizationGoals , NoSolution , QueryInput ,
2727 QueryResult ,
2828} ;
2929
@@ -116,7 +116,7 @@ where
116116
117117 pub ( super ) search_graph : & ' a mut SearchGraph < D > ,
118118
119- nested_goals : Vec < ( GoalSource , Goal < I , I :: Predicate > , Option < CanonicalGoalCacheKey < I > > ) > ,
119+ nested_goals : Vec < ( GoalSource , Goal < I , I :: Predicate > , Option < GoalStalledOn < I > > ) > ,
120120
121121 pub ( super ) origin_span : I :: Span ,
122122
@@ -148,9 +148,9 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
148148 goal : Goal < Self :: Interner , <Self :: Interner as Interner >:: Predicate > ,
149149 generate_proof_tree : GenerateProofTree ,
150150 span : <Self :: Interner as Interner >:: Span ,
151- cache_key : Option < CanonicalGoalCacheKey < Self :: Interner > > ,
151+ stalled_on : Option < GoalStalledOn < Self :: Interner > > ,
152152 ) -> (
153- Result < ( HasChanged , Certainty , CanonicalGoalCacheKey < Self :: Interner > ) , NoSolution > ,
153+ Result < GoalEvaluation < Self :: Interner > , NoSolution > ,
154154 Option < inspect:: GoalEvaluation < Self :: Interner > > ,
155155 ) ;
156156
@@ -173,15 +173,10 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
173173 & self ,
174174 goal : Goal < Self :: Interner , <Self :: Interner as Interner >:: Predicate > ,
175175 generate_proof_tree : GenerateProofTree ,
176- cache_key : Option < CanonicalGoalCacheKey < Self :: Interner > > ,
176+ stalled_on : Option < GoalStalledOn < Self :: Interner > > ,
177177 ) -> (
178178 Result <
179- (
180- NestedNormalizationGoals < Self :: Interner > ,
181- HasChanged ,
182- Certainty ,
183- CanonicalGoalCacheKey < Self :: Interner > ,
184- ) ,
179+ ( NestedNormalizationGoals < Self :: Interner > , GoalEvaluation < Self :: Interner > ) ,
185180 NoSolution ,
186181 > ,
187182 Option < inspect:: GoalEvaluation < Self :: Interner > > ,
@@ -199,13 +194,10 @@ where
199194 goal : Goal < I , I :: Predicate > ,
200195 generate_proof_tree : GenerateProofTree ,
201196 span : I :: Span ,
202- cache_key : Option < CanonicalGoalCacheKey < I > > ,
203- ) -> (
204- Result < ( HasChanged , Certainty , CanonicalGoalCacheKey < I > ) , NoSolution > ,
205- Option < inspect:: GoalEvaluation < I > > ,
206- ) {
197+ stalled_on : Option < GoalStalledOn < I > > ,
198+ ) -> ( Result < GoalEvaluation < I > , NoSolution > , Option < inspect:: GoalEvaluation < I > > ) {
207199 EvalCtxt :: enter_root ( self , self . cx ( ) . recursion_limit ( ) , generate_proof_tree, span, |ecx| {
208- ecx. evaluate_goal ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal, cache_key )
200+ ecx. evaluate_goal ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal, stalled_on )
209201 } )
210202 }
211203
@@ -228,12 +220,9 @@ where
228220 & self ,
229221 goal : Goal < I , I :: Predicate > ,
230222 generate_proof_tree : GenerateProofTree ,
231- cache_key : Option < CanonicalGoalCacheKey < I > > ,
223+ stalled_on : Option < GoalStalledOn < I > > ,
232224 ) -> (
233- Result <
234- ( NestedNormalizationGoals < I > , HasChanged , Certainty , CanonicalGoalCacheKey < I > ) ,
235- NoSolution ,
236- > ,
225+ Result < ( NestedNormalizationGoals < I > , GoalEvaluation < I > ) , NoSolution > ,
237226 Option < inspect:: GoalEvaluation < I > > ,
238227 ) {
239228 EvalCtxt :: enter_root (
@@ -242,7 +231,7 @@ where
242231 generate_proof_tree,
243232 I :: Span :: dummy ( ) ,
244233 |ecx| {
245- ecx. evaluate_goal_raw ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal, cache_key )
234+ ecx. evaluate_goal_raw ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal, stalled_on )
246235 } ,
247236 )
248237 }
@@ -468,12 +457,12 @@ where
468457 goal_evaluation_kind : GoalEvaluationKind ,
469458 source : GoalSource ,
470459 goal : Goal < I , I :: Predicate > ,
471- cache_key : Option < CanonicalGoalCacheKey < I > > ,
472- ) -> Result < ( HasChanged , Certainty , CanonicalGoalCacheKey < I > ) , NoSolution > {
473- let ( normalization_nested_goals, has_changed , certainty , cache_key ) =
474- self . evaluate_goal_raw ( goal_evaluation_kind, source, goal, cache_key ) ?;
460+ stalled_on : Option < GoalStalledOn < I > > ,
461+ ) -> Result < GoalEvaluation < I > , NoSolution > {
462+ let ( normalization_nested_goals, goal_evaluation ) =
463+ self . evaluate_goal_raw ( goal_evaluation_kind, source, goal, stalled_on ) ?;
475464 assert ! ( normalization_nested_goals. is_empty( ) ) ;
476- Ok ( ( has_changed , certainty , cache_key ) )
465+ Ok ( goal_evaluation )
477466 }
478467
479468 /// Recursively evaluates `goal`, returning the nested goals in case
@@ -488,23 +477,25 @@ where
488477 goal_evaluation_kind : GoalEvaluationKind ,
489478 source : GoalSource ,
490479 goal : Goal < I , I :: Predicate > ,
491- cache_key : Option < CanonicalGoalCacheKey < I > > ,
492- ) -> Result <
493- ( NestedNormalizationGoals < I > , HasChanged , Certainty , CanonicalGoalCacheKey < I > ) ,
494- NoSolution ,
495- > {
496- if let Some ( cache_key ) = cache_key {
497- if !cache_key . stalled_vars . iter ( ) . any ( |value| self . delegate . is_changed_arg ( * value) )
480+ stalled_on : Option < GoalStalledOn < I > > ,
481+ ) -> Result < ( NestedNormalizationGoals < I > , GoalEvaluation < I > ) , NoSolution > {
482+ // If we have run this goal before, and it was stalled, check that any of the goal's
483+ // args have changed. Otherwise, we don't need to re-run the goal because it'll remain
484+ // stalled, since it'll canonicalize the same way and evaluation is pure.
485+ if let Some ( stalled_on ) = stalled_on {
486+ if !stalled_on . stalled_vars . iter ( ) . any ( |value| self . delegate . is_changed_arg ( * value) )
498487 && !self
499488 . delegate
500489 . opaque_types_storage_num_entries ( )
501- . needs_reevaluation ( cache_key . num_opaques )
490+ . needs_reevaluation ( stalled_on . num_opaques )
502491 {
503492 return Ok ( (
504493 NestedNormalizationGoals :: empty ( ) ,
505- HasChanged :: No ,
506- cache_key. certainty ,
507- cache_key,
494+ GoalEvaluation {
495+ certainty : Certainty :: Maybe ( stalled_on. stalled_cause ) ,
496+ has_changed : HasChanged :: No ,
497+ stalled_on : Some ( stalled_on) ,
498+ } ,
508499 ) ) ;
509500 }
510501 }
@@ -544,33 +535,35 @@ where
544535 // Once we have decided on how to handle trait-system-refactor-initiative#75,
545536 // we should re-add an assert here.
546537
547- // Remove the unconstrained RHS arg, which is expected to have changed.
548- let mut stalled_vars = orig_values;
549- if let Some ( normalizes_to) = goal. predicate . as_normalizes_to ( ) {
550- let normalizes_to = normalizes_to. skip_binder ( ) ;
551- let rhs_arg: I :: GenericArg = normalizes_to. term . into ( ) ;
552- let idx = stalled_vars
553- . iter ( )
554- . rposition ( |arg| * arg == rhs_arg)
555- . expect ( "expected unconstrained arg" ) ;
556- stalled_vars. swap_remove ( idx) ;
557- }
538+ let stalled_on = match certainty {
539+ Certainty :: Yes => None ,
540+ Certainty :: Maybe ( stalled_cause) => {
541+ // Remove the unconstrained RHS arg, which is expected to have changed.
542+ let mut stalled_vars = orig_values;
543+ if let Some ( normalizes_to) = goal. predicate . as_normalizes_to ( ) {
544+ let normalizes_to = normalizes_to. skip_binder ( ) ;
545+ let rhs_arg: I :: GenericArg = normalizes_to. term . into ( ) ;
546+ let idx = stalled_vars
547+ . iter ( )
548+ . rposition ( |arg| * arg == rhs_arg)
549+ . expect ( "expected unconstrained arg" ) ;
550+ stalled_vars. swap_remove ( idx) ;
551+ }
558552
559- Ok ( (
560- normalization_nested_goals,
561- has_changed,
562- certainty,
563- CanonicalGoalCacheKey {
564- num_opaques : canonical_goal
565- . canonical
566- . value
567- . predefined_opaques_in_body
568- . opaque_types
569- . len ( ) ,
570- stalled_vars,
571- certainty,
572- } ,
573- ) )
553+ Some ( GoalStalledOn {
554+ num_opaques : canonical_goal
555+ . canonical
556+ . value
557+ . predefined_opaques_in_body
558+ . opaque_types
559+ . len ( ) ,
560+ stalled_vars,
561+ stalled_cause,
562+ } )
563+ }
564+ } ;
565+
566+ Ok ( ( normalization_nested_goals, GoalEvaluation { certainty, has_changed, stalled_on } ) )
574567 }
575568
576569 fn compute_goal ( & mut self , goal : Goal < I , I :: Predicate > ) -> QueryResult < I > {
@@ -670,7 +663,7 @@ where
670663 let cx = self . cx ( ) ;
671664 // If this loop did not result in any progress, what's our final certainty.
672665 let mut unchanged_certainty = Some ( Certainty :: Yes ) ;
673- for ( source, goal, cache_key ) in mem:: take ( & mut self . nested_goals ) {
666+ for ( source, goal, stalled_on ) in mem:: take ( & mut self . nested_goals ) {
674667 if let Some ( has_changed) = self . delegate . compute_goal_fast_path ( goal, self . origin_span )
675668 {
676669 if matches ! ( has_changed, HasChanged :: Yes ) {
@@ -698,13 +691,15 @@ where
698691 let unconstrained_goal =
699692 goal. with ( cx, ty:: NormalizesTo { alias : pred. alias , term : unconstrained_rhs } ) ;
700693
701- let ( NestedNormalizationGoals ( nested_goals) , _, certainty, cache_key) = self
702- . evaluate_goal_raw (
703- GoalEvaluationKind :: Nested ,
704- source,
705- unconstrained_goal,
706- cache_key,
707- ) ?;
694+ let (
695+ NestedNormalizationGoals ( nested_goals) ,
696+ GoalEvaluation { certainty, stalled_on, has_changed : _ } ,
697+ ) = self . evaluate_goal_raw (
698+ GoalEvaluationKind :: Nested ,
699+ source,
700+ unconstrained_goal,
701+ stalled_on,
702+ ) ?;
708703 // Add the nested goals from normalization to our own nested goals.
709704 trace ! ( ?nested_goals) ;
710705 self . nested_goals . extend ( nested_goals. into_iter ( ) . map ( |( s, g) | ( s, g, None ) ) ) ;
@@ -743,21 +738,21 @@ where
743738 match certainty {
744739 Certainty :: Yes => { }
745740 Certainty :: Maybe ( _) => {
746- self . nested_goals . push ( ( source, with_resolved_vars, Some ( cache_key ) ) ) ;
741+ self . nested_goals . push ( ( source, with_resolved_vars, stalled_on ) ) ;
747742 unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
748743 }
749744 }
750745 } else {
751- let ( has_changed , certainty, cache_key ) =
752- self . evaluate_goal ( GoalEvaluationKind :: Nested , source, goal, cache_key ) ?;
746+ let GoalEvaluation { certainty, has_changed , stalled_on } =
747+ self . evaluate_goal ( GoalEvaluationKind :: Nested , source, goal, stalled_on ) ?;
753748 if has_changed == HasChanged :: Yes {
754749 unchanged_certainty = None ;
755750 }
756751
757752 match certainty {
758753 Certainty :: Yes => { }
759754 Certainty :: Maybe ( _) => {
760- self . nested_goals . push ( ( source, goal, Some ( cache_key ) ) ) ;
755+ self . nested_goals . push ( ( source, goal, stalled_on ) ) ;
761756 unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
762757 }
763758 }
0 commit comments