@@ -22,8 +22,9 @@ use crate::delegate::SolverDelegate;
2222use crate :: solve:: inspect:: { self , ProofTreeBuilder } ;
2323use crate :: solve:: search_graph:: SearchGraph ;
2424use crate :: solve:: {
25- CanonicalInput , Certainty , FIXPOINT_STEP_LIMIT , Goal , GoalEvaluationKind , GoalSource ,
26- HasChanged , NestedNormalizationGoals , NoSolution , QueryInput , QueryResult ,
25+ CanonicalGoalCacheKey , CanonicalInput , Certainty , FIXPOINT_STEP_LIMIT , Goal ,
26+ GoalEvaluationKind , GoalSource , HasChanged , NestedNormalizationGoals , NoSolution , QueryInput ,
27+ QueryResult ,
2728} ;
2829
2930pub ( super ) mod canonical;
@@ -115,7 +116,7 @@ where
115116
116117 pub ( super ) search_graph : & ' a mut SearchGraph < D > ,
117118
118- nested_goals : Vec < ( GoalSource , Goal < I , I :: Predicate > ) > ,
119+ nested_goals : Vec < ( GoalSource , Goal < I , I :: Predicate > , Option < CanonicalGoalCacheKey < I > > ) > ,
119120
120121 pub ( super ) origin_span : I :: Span ,
121122
@@ -147,8 +148,9 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
147148 goal : Goal < Self :: Interner , <Self :: Interner as Interner >:: Predicate > ,
148149 generate_proof_tree : GenerateProofTree ,
149150 span : <Self :: Interner as Interner >:: Span ,
151+ cache_key : Option < CanonicalGoalCacheKey < Self :: Interner > > ,
150152 ) -> (
151- Result < ( HasChanged , Certainty ) , NoSolution > ,
153+ Result < ( HasChanged , Certainty , CanonicalGoalCacheKey < Self :: Interner > ) , NoSolution > ,
152154 Option < inspect:: GoalEvaluation < Self :: Interner > > ,
153155 ) ;
154156
@@ -171,8 +173,17 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
171173 & self ,
172174 goal : Goal < Self :: Interner , <Self :: Interner as Interner >:: Predicate > ,
173175 generate_proof_tree : GenerateProofTree ,
176+ cache_key : Option < CanonicalGoalCacheKey < Self :: Interner > > ,
174177 ) -> (
175- Result < ( NestedNormalizationGoals < Self :: Interner > , HasChanged , Certainty ) , NoSolution > ,
178+ Result <
179+ (
180+ NestedNormalizationGoals < Self :: Interner > ,
181+ HasChanged ,
182+ Certainty ,
183+ CanonicalGoalCacheKey < Self :: Interner > ,
184+ ) ,
185+ NoSolution ,
186+ > ,
176187 Option < inspect:: GoalEvaluation < Self :: Interner > > ,
177188 ) ;
178189}
@@ -188,9 +199,13 @@ where
188199 goal : Goal < I , I :: Predicate > ,
189200 generate_proof_tree : GenerateProofTree ,
190201 span : I :: Span ,
191- ) -> ( Result < ( HasChanged , Certainty ) , NoSolution > , Option < inspect:: GoalEvaluation < I > > ) {
202+ cache_key : Option < CanonicalGoalCacheKey < I > > ,
203+ ) -> (
204+ Result < ( HasChanged , Certainty , CanonicalGoalCacheKey < I > ) , NoSolution > ,
205+ Option < inspect:: GoalEvaluation < I > > ,
206+ ) {
192207 EvalCtxt :: enter_root ( self , self . cx ( ) . recursion_limit ( ) , generate_proof_tree, span, |ecx| {
193- ecx. evaluate_goal ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal)
208+ ecx. evaluate_goal ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal, cache_key )
194209 } )
195210 }
196211
@@ -201,7 +216,7 @@ where
201216 ) -> bool {
202217 self . probe ( || {
203218 EvalCtxt :: enter_root ( self , root_depth, GenerateProofTree :: No , I :: Span :: dummy ( ) , |ecx| {
204- ecx. evaluate_goal ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal)
219+ ecx. evaluate_goal ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal, None )
205220 } )
206221 . 0
207222 } )
@@ -213,16 +228,22 @@ where
213228 & self ,
214229 goal : Goal < I , I :: Predicate > ,
215230 generate_proof_tree : GenerateProofTree ,
231+ cache_key : Option < CanonicalGoalCacheKey < I > > ,
216232 ) -> (
217- Result < ( NestedNormalizationGoals < I > , HasChanged , Certainty ) , NoSolution > ,
233+ Result <
234+ ( NestedNormalizationGoals < I > , HasChanged , Certainty , CanonicalGoalCacheKey < I > ) ,
235+ NoSolution ,
236+ > ,
218237 Option < inspect:: GoalEvaluation < I > > ,
219238 ) {
220239 EvalCtxt :: enter_root (
221240 self ,
222241 self . cx ( ) . recursion_limit ( ) ,
223242 generate_proof_tree,
224243 I :: Span :: dummy ( ) ,
225- |ecx| ecx. evaluate_goal_raw ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal) ,
244+ |ecx| {
245+ ecx. evaluate_goal_raw ( GoalEvaluationKind :: Root , GoalSource :: Misc , goal, cache_key)
246+ } ,
226247 )
227248 }
228249}
@@ -447,11 +468,12 @@ where
447468 goal_evaluation_kind : GoalEvaluationKind ,
448469 source : GoalSource ,
449470 goal : Goal < I , I :: Predicate > ,
450- ) -> Result < ( HasChanged , Certainty ) , NoSolution > {
451- let ( normalization_nested_goals, has_changed, certainty) =
452- self . evaluate_goal_raw ( goal_evaluation_kind, source, goal) ?;
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) ?;
453475 assert ! ( normalization_nested_goals. is_empty( ) ) ;
454- Ok ( ( has_changed, certainty) )
476+ Ok ( ( has_changed, certainty, cache_key ) )
455477 }
456478
457479 /// Recursively evaluates `goal`, returning the nested goals in case
@@ -466,7 +488,26 @@ where
466488 goal_evaluation_kind : GoalEvaluationKind ,
467489 source : GoalSource ,
468490 goal : Goal < I , I :: Predicate > ,
469- ) -> Result < ( NestedNormalizationGoals < I > , HasChanged , Certainty ) , NoSolution > {
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. orig_values . iter ( ) . any ( |value| {
498+ cache_key. unconstrained_rhs == Some ( value) || self . delegate . is_changed_arg ( value)
499+ } ) && self . delegate . opaque_types_storage_num_unique_entries_raw ( )
500+ == cache_key. num_opaques
501+ {
502+ return Ok ( (
503+ NestedNormalizationGoals :: empty ( ) ,
504+ HasChanged :: No ,
505+ cache_key. certainty ,
506+ cache_key,
507+ ) ) ;
508+ }
509+ }
510+
470511 let ( orig_values, canonical_goal) = self . canonicalize_goal ( goal) ;
471512 let mut goal_evaluation =
472513 self . inspect . new_goal_evaluation ( goal, & orig_values, goal_evaluation_kind) ;
@@ -489,7 +530,7 @@ where
489530 if !has_only_region_constraints ( response) { HasChanged :: Yes } else { HasChanged :: No } ;
490531
491532 let ( normalization_nested_goals, certainty) =
492- self . instantiate_and_apply_query_response ( goal. param_env , orig_values, response) ;
533+ self . instantiate_and_apply_query_response ( goal. param_env , & orig_values, response) ;
493534 self . inspect . goal_evaluation ( goal_evaluation) ;
494535
495536 // FIXME: We previously had an assert here that checked that recomputing
@@ -502,7 +543,22 @@ where
502543 // Once we have decided on how to handle trait-system-refactor-initiative#75,
503544 // we should re-add an assert here.
504545
505- Ok ( ( normalization_nested_goals, has_changed, certainty) )
546+ Ok ( (
547+ normalization_nested_goals,
548+ has_changed,
549+ certainty,
550+ CanonicalGoalCacheKey {
551+ num_opaques : canonical_goal
552+ . canonical
553+ . value
554+ . predefined_opaques_in_body
555+ . opaque_types
556+ . len ( ) ,
557+ unconstrained_rhs : None ,
558+ orig_values : self . cx ( ) . mk_args ( & orig_values) ,
559+ certainty,
560+ } ,
561+ ) )
506562 }
507563
508564 fn compute_goal ( & mut self , goal : Goal < I , I :: Predicate > ) -> QueryResult < I > {
@@ -602,7 +658,7 @@ where
602658 let cx = self . cx ( ) ;
603659 // If this loop did not result in any progress, what's our final certainty.
604660 let mut unchanged_certainty = Some ( Certainty :: Yes ) ;
605- for ( source, goal) in mem:: take ( & mut self . nested_goals ) {
661+ for ( source, goal, cache_key ) in mem:: take ( & mut self . nested_goals ) {
606662 if let Some ( has_changed) = self . delegate . compute_goal_fast_path ( goal, self . origin_span )
607663 {
608664 if matches ! ( has_changed, HasChanged :: Yes ) {
@@ -630,11 +686,16 @@ where
630686 let unconstrained_goal =
631687 goal. with ( cx, ty:: NormalizesTo { alias : pred. alias , term : unconstrained_rhs } ) ;
632688
633- let ( NestedNormalizationGoals ( nested_goals) , _, certainty) =
634- self . evaluate_goal_raw ( GoalEvaluationKind :: Nested , source, unconstrained_goal) ?;
689+ let ( NestedNormalizationGoals ( nested_goals) , _, certainty, cache_key) = self
690+ . evaluate_goal_raw (
691+ GoalEvaluationKind :: Nested ,
692+ source,
693+ unconstrained_goal,
694+ cache_key,
695+ ) ?;
635696 // Add the nested goals from normalization to our own nested goals.
636697 trace ! ( ?nested_goals) ;
637- self . nested_goals . extend ( nested_goals) ;
698+ self . nested_goals . extend ( nested_goals. into_iter ( ) . map ( | ( s , g ) | ( s , g , None ) ) ) ;
638699
639700 // Finally, equate the goal's RHS with the unconstrained var.
640701 //
@@ -660,6 +721,8 @@ where
660721 // looking at the "has changed" return from evaluate_goal,
661722 // because we expect the `unconstrained_rhs` part of the predicate
662723 // to have changed -- that means we actually normalized successfully!
724+ // FIXME: Do we need to eagerly resolve here? Or should we check
725+ // if the cache key has any changed vars?
663726 let with_resolved_vars = self . resolve_vars_if_possible ( goal) ;
664727 if pred. alias != goal. predicate . as_normalizes_to ( ) . unwrap ( ) . skip_binder ( ) . alias {
665728 unchanged_certainty = None ;
@@ -668,21 +731,24 @@ where
668731 match certainty {
669732 Certainty :: Yes => { }
670733 Certainty :: Maybe ( _) => {
671- self . nested_goals . push ( ( source, with_resolved_vars) ) ;
734+ let mut cache_key = cache_key;
735+ // FIXME: lmao
736+ cache_key. unconstrained_rhs = Some ( unconstrained_rhs. into ( ) ) ;
737+ self . nested_goals . push ( ( source, with_resolved_vars, Some ( cache_key) ) ) ;
672738 unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
673739 }
674740 }
675741 } else {
676- let ( has_changed, certainty) =
677- self . evaluate_goal ( GoalEvaluationKind :: Nested , source, goal) ?;
742+ let ( has_changed, certainty, cache_key ) =
743+ self . evaluate_goal ( GoalEvaluationKind :: Nested , source, goal, cache_key ) ?;
678744 if has_changed == HasChanged :: Yes {
679745 unchanged_certainty = None ;
680746 }
681747
682748 match certainty {
683749 Certainty :: Yes => { }
684750 Certainty :: Maybe ( _) => {
685- self . nested_goals . push ( ( source, goal) ) ;
751+ self . nested_goals . push ( ( source, goal, Some ( cache_key ) ) ) ;
686752 unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
687753 }
688754 }
@@ -706,7 +772,7 @@ where
706772 goal. predicate =
707773 goal. predicate . fold_with ( & mut ReplaceAliasWithInfer :: new ( self , source, goal. param_env ) ) ;
708774 self . inspect . add_goal ( self . delegate , self . max_input_universe , source, goal) ;
709- self . nested_goals . push ( ( source, goal) ) ;
775+ self . nested_goals . push ( ( source, goal, None ) ) ;
710776 }
711777
712778 #[ instrument( level = "trace" , skip( self , goals) ) ]
0 commit comments