@@ -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 = "debug" , 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,36 +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) ;
259+ if let Some ( result) = self . lookup_global_cache ( tcx, input, available_depth, inspect) {
299260 return result;
300261 }
301262
@@ -376,7 +337,10 @@ impl<'tcx> SearchGraph<'tcx> {
376337
377338 // This is for global caching, so we properly track query dependencies.
378339 // Everything that affects the `result` should be performed within this
379- // `with_anon_task` closure.
340+ // `with_anon_task` closure. If computing this goal depends on something
341+ // not tracked by the cache key and from outside of this anon task, it
342+ // must not be added to the global cache. Notably, this is the case for
343+ // trait solver cycles participants.
380344 let ( ( final_entry, result) , dep_node) =
381345 tcx. dep_graph . with_anon_task ( tcx, dep_kinds:: TraitSelect , || {
382346 for _ in 0 ..FIXPOINT_STEP_LIMIT {
@@ -434,6 +398,45 @@ impl<'tcx> SearchGraph<'tcx> {
434398
435399 result
436400 }
401+
402+ /// Try to fetch a previously computed result from the global cache,
403+ /// making sure to only do so if it would match the result of reevaluating
404+ /// this goal.
405+ fn lookup_global_cache (
406+ & mut self ,
407+ tcx : TyCtxt < ' tcx > ,
408+ input : CanonicalInput < ' tcx > ,
409+ available_depth : Limit ,
410+ inspect : & mut ProofTreeBuilder < ' tcx > ,
411+ ) -> Option < QueryResult < ' tcx > > {
412+ let CacheData { result, proof_tree, additional_depth, encountered_overflow } = self
413+ . global_cache ( tcx)
414+ . get ( tcx, input, self . stack . iter ( ) . map ( |e| e. input ) , available_depth) ?;
415+
416+ // If we're building a proof tree and the current cache entry does not
417+ // contain a proof tree, we do not use the entry but instead recompute
418+ // the goal. We simply overwrite the existing entry once we're done,
419+ // caching the proof tree.
420+ if !inspect. is_noop ( ) {
421+ if let Some ( revisions) = proof_tree {
422+ let kind = inspect:: WipCanonicalGoalEvaluationKind :: Interned { revisions } ;
423+ inspect. goal_evaluation_kind ( kind) ;
424+ } else {
425+ return None ;
426+ }
427+ }
428+
429+ // Update the reached depth of the current goal to make sure
430+ // its state is the same regardless of whether we've used the
431+ // global cache or not.
432+ let reached_depth = self . stack . next_index ( ) . plus ( additional_depth) ;
433+ if let Some ( last) = self . stack . raw . last_mut ( ) {
434+ last. reached_depth = last. reached_depth . max ( reached_depth) ;
435+ last. encountered_overflow |= encountered_overflow;
436+ }
437+
438+ Some ( result)
439+ }
437440}
438441
439442enum StepResult < ' tcx > {
0 commit comments