@@ -22,8 +22,9 @@ use crate::delegate::SolverDelegate;
22
22
use crate :: solve:: inspect:: { self , ProofTreeBuilder } ;
23
23
use crate :: solve:: search_graph:: SearchGraph ;
24
24
use 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 ,
27
28
} ;
28
29
29
30
pub ( super ) mod canonical;
@@ -115,7 +116,7 @@ where
115
116
116
117
pub ( super ) search_graph : & ' a mut SearchGraph < D > ,
117
118
118
- nested_goals : Vec < ( GoalSource , Goal < I , I :: Predicate > ) > ,
119
+ nested_goals : Vec < ( GoalSource , Goal < I , I :: Predicate > , Option < CanonicalGoalCacheKey < I > > ) > ,
119
120
120
121
pub ( super ) origin_span : I :: Span ,
121
122
@@ -147,8 +148,9 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
147
148
goal : Goal < Self :: Interner , <Self :: Interner as Interner >:: Predicate > ,
148
149
generate_proof_tree : GenerateProofTree ,
149
150
span : <Self :: Interner as Interner >:: Span ,
151
+ cache_key : Option < CanonicalGoalCacheKey < Self :: Interner > > ,
150
152
) -> (
151
- Result < ( HasChanged , Certainty ) , NoSolution > ,
153
+ Result < ( HasChanged , Certainty , CanonicalGoalCacheKey < Self :: Interner > ) , NoSolution > ,
152
154
Option < inspect:: GoalEvaluation < Self :: Interner > > ,
153
155
) ;
154
156
@@ -171,8 +173,17 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
171
173
& self ,
172
174
goal : Goal < Self :: Interner , <Self :: Interner as Interner >:: Predicate > ,
173
175
generate_proof_tree : GenerateProofTree ,
176
+ cache_key : Option < CanonicalGoalCacheKey < Self :: Interner > > ,
174
177
) -> (
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
+ > ,
176
187
Option < inspect:: GoalEvaluation < Self :: Interner > > ,
177
188
) ;
178
189
}
@@ -188,9 +199,13 @@ where
188
199
goal : Goal < I , I :: Predicate > ,
189
200
generate_proof_tree : GenerateProofTree ,
190
201
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
+ ) {
192
207
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 )
194
209
} )
195
210
}
196
211
@@ -201,7 +216,7 @@ where
201
216
) -> bool {
202
217
self . probe ( || {
203
218
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 )
205
220
} )
206
221
. 0
207
222
} )
@@ -213,16 +228,22 @@ where
213
228
& self ,
214
229
goal : Goal < I , I :: Predicate > ,
215
230
generate_proof_tree : GenerateProofTree ,
231
+ cache_key : Option < CanonicalGoalCacheKey < I > > ,
216
232
) -> (
217
- Result < ( NestedNormalizationGoals < I > , HasChanged , Certainty ) , NoSolution > ,
233
+ Result <
234
+ ( NestedNormalizationGoals < I > , HasChanged , Certainty , CanonicalGoalCacheKey < I > ) ,
235
+ NoSolution ,
236
+ > ,
218
237
Option < inspect:: GoalEvaluation < I > > ,
219
238
) {
220
239
EvalCtxt :: enter_root (
221
240
self ,
222
241
self . cx ( ) . recursion_limit ( ) ,
223
242
generate_proof_tree,
224
243
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
+ } ,
226
247
)
227
248
}
228
249
}
@@ -447,11 +468,12 @@ where
447
468
goal_evaluation_kind : GoalEvaluationKind ,
448
469
source : GoalSource ,
449
470
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) ?;
453
475
assert ! ( normalization_nested_goals. is_empty( ) ) ;
454
- Ok ( ( has_changed, certainty) )
476
+ Ok ( ( has_changed, certainty, cache_key ) )
455
477
}
456
478
457
479
/// Recursively evaluates `goal`, returning the nested goals in case
@@ -466,7 +488,26 @@ where
466
488
goal_evaluation_kind : GoalEvaluationKind ,
467
489
source : GoalSource ,
468
490
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
+
470
511
let ( orig_values, canonical_goal) = self . canonicalize_goal ( goal) ;
471
512
let mut goal_evaluation =
472
513
self . inspect . new_goal_evaluation ( goal, & orig_values, goal_evaluation_kind) ;
@@ -489,7 +530,7 @@ where
489
530
if !has_only_region_constraints ( response) { HasChanged :: Yes } else { HasChanged :: No } ;
490
531
491
532
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) ;
493
534
self . inspect . goal_evaluation ( goal_evaluation) ;
494
535
495
536
// FIXME: We previously had an assert here that checked that recomputing
@@ -502,7 +543,22 @@ where
502
543
// Once we have decided on how to handle trait-system-refactor-initiative#75,
503
544
// we should re-add an assert here.
504
545
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
+ ) )
506
562
}
507
563
508
564
fn compute_goal ( & mut self , goal : Goal < I , I :: Predicate > ) -> QueryResult < I > {
@@ -602,7 +658,7 @@ where
602
658
let cx = self . cx ( ) ;
603
659
// If this loop did not result in any progress, what's our final certainty.
604
660
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 ) {
606
662
if let Some ( has_changed) = self . delegate . compute_goal_fast_path ( goal, self . origin_span )
607
663
{
608
664
if matches ! ( has_changed, HasChanged :: Yes ) {
@@ -630,11 +686,16 @@ where
630
686
let unconstrained_goal =
631
687
goal. with ( cx, ty:: NormalizesTo { alias : pred. alias , term : unconstrained_rhs } ) ;
632
688
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
+ ) ?;
635
696
// Add the nested goals from normalization to our own nested goals.
636
697
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 ) ) ) ;
638
699
639
700
// Finally, equate the goal's RHS with the unconstrained var.
640
701
//
@@ -660,6 +721,8 @@ where
660
721
// looking at the "has changed" return from evaluate_goal,
661
722
// because we expect the `unconstrained_rhs` part of the predicate
662
723
// 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?
663
726
let with_resolved_vars = self . resolve_vars_if_possible ( goal) ;
664
727
if pred. alias != goal. predicate . as_normalizes_to ( ) . unwrap ( ) . skip_binder ( ) . alias {
665
728
unchanged_certainty = None ;
@@ -668,21 +731,24 @@ where
668
731
match certainty {
669
732
Certainty :: Yes => { }
670
733
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) ) ) ;
672
738
unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
673
739
}
674
740
}
675
741
} 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 ) ?;
678
744
if has_changed == HasChanged :: Yes {
679
745
unchanged_certainty = None ;
680
746
}
681
747
682
748
match certainty {
683
749
Certainty :: Yes => { }
684
750
Certainty :: Maybe ( _) => {
685
- self . nested_goals . push ( ( source, goal) ) ;
751
+ self . nested_goals . push ( ( source, goal, Some ( cache_key ) ) ) ;
686
752
unchanged_certainty = unchanged_certainty. map ( |c| c. and ( certainty) ) ;
687
753
}
688
754
}
@@ -706,7 +772,7 @@ where
706
772
goal. predicate =
707
773
goal. predicate . fold_with ( & mut ReplaceAliasWithInfer :: new ( self , source, goal. param_env ) ) ;
708
774
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 ) ) ;
710
776
}
711
777
712
778
#[ instrument( level = "trace" , skip( self , goals) ) ]
0 commit comments