@@ -129,16 +129,6 @@ impl<'tcx> SearchGraph<'tcx> {
129129 self . mode
130130 }
131131
132- /// Update the stack and reached depths on cache hits.
133- #[ instrument( level = "trace" , skip( self ) ) ]
134- fn on_cache_hit ( & mut self , additional_depth : usize , encountered_overflow : bool ) {
135- let reached_depth = self . stack . next_index ( ) . plus ( additional_depth) ;
136- if let Some ( last) = self . stack . raw . last_mut ( ) {
137- last. reached_depth = last. reached_depth . max ( reached_depth) ;
138- last. encountered_overflow |= encountered_overflow;
139- }
140- }
141-
142132 /// Pops the highest goal from the stack, lazily updating the
143133 /// the next goal in the stack.
144134 ///
@@ -266,37 +256,7 @@ impl<'tcx> SearchGraph<'tcx> {
266256 return Self :: response_no_constraints ( tcx, input, Certainty :: overflow ( true ) ) ;
267257 } ;
268258
269- // Try to fetch the goal from the global cache.
270- ' global: {
271- let Some ( CacheData { result, proof_tree, reached_depth, encountered_overflow } ) =
272- self . global_cache ( tcx) . get (
273- tcx,
274- input,
275- |cycle_participants| {
276- self . stack . iter ( ) . any ( |entry| cycle_participants. contains ( & entry. input ) )
277- } ,
278- available_depth,
279- )
280- else {
281- break ' global;
282- } ;
283-
284- // If we're building a proof tree and the current cache entry does not
285- // contain a proof tree, we do not use the entry but instead recompute
286- // the goal. We simply overwrite the existing entry once we're done,
287- // caching the proof tree.
288- if !inspect. is_noop ( ) {
289- if let Some ( revisions) = proof_tree {
290- inspect. goal_evaluation_kind (
291- inspect:: WipCanonicalGoalEvaluationKind :: Interned { revisions } ,
292- ) ;
293- } else {
294- break ' global;
295- }
296- }
297-
298- self . on_cache_hit ( reached_depth, encountered_overflow) ;
299- debug ! ( "global cache hit" ) ;
259+ if let Some ( result) = self . lookup_global_cache ( tcx, input, available_depth, inspect) {
300260 return result;
301261 }
302262
@@ -378,7 +338,10 @@ impl<'tcx> SearchGraph<'tcx> {
378338
379339 // This is for global caching, so we properly track query dependencies.
380340 // Everything that affects the `result` should be performed within this
381- // `with_anon_task` closure.
341+ // `with_anon_task` closure. If computing this goal depends on something
342+ // not tracked by the cache key and from outside of this anon task, it
343+ // must not be added to the global cache. Notably, this is the case for
344+ // trait solver cycles participants.
382345 let ( ( final_entry, result) , dep_node) =
383346 tcx. dep_graph . with_anon_task ( tcx, dep_kinds:: TraitSelect , || {
384347 for _ in 0 ..FIXPOINT_STEP_LIMIT {
@@ -436,6 +399,45 @@ impl<'tcx> SearchGraph<'tcx> {
436399
437400 result
438401 }
402+
403+ /// Try to fetch a previously computed result from the global cache,
404+ /// making sure to only do so if it would match the result of reevaluating
405+ /// this goal.
406+ fn lookup_global_cache (
407+ & mut self ,
408+ tcx : TyCtxt < ' tcx > ,
409+ input : CanonicalInput < ' tcx > ,
410+ available_depth : Limit ,
411+ inspect : & mut ProofTreeBuilder < TyCtxt < ' tcx > > ,
412+ ) -> Option < QueryResult < ' tcx > > {
413+ let CacheData { result, proof_tree, additional_depth, encountered_overflow } = self
414+ . global_cache ( tcx)
415+ . get ( tcx, input, self . stack . iter ( ) . map ( |e| e. input ) , available_depth) ?;
416+
417+ // If we're building a proof tree and the current cache entry does not
418+ // contain a proof tree, we do not use the entry but instead recompute
419+ // the goal. We simply overwrite the existing entry once we're done,
420+ // caching the proof tree.
421+ if !inspect. is_noop ( ) {
422+ if let Some ( revisions) = proof_tree {
423+ let kind = inspect:: WipCanonicalGoalEvaluationKind :: Interned { revisions } ;
424+ inspect. goal_evaluation_kind ( kind) ;
425+ } else {
426+ return None ;
427+ }
428+ }
429+
430+ // Update the reached depth of the current goal to make sure
431+ // its state is the same regardless of whether we've used the
432+ // global cache or not.
433+ let reached_depth = self . stack . next_index ( ) . plus ( additional_depth) ;
434+ if let Some ( last) = self . stack . raw . last_mut ( ) {
435+ last. reached_depth = last. reached_depth . max ( reached_depth) ;
436+ last. encountered_overflow |= encountered_overflow;
437+ }
438+
439+ Some ( result)
440+ }
439441}
440442
441443enum StepResult < ' tcx > {
0 commit comments