@@ -129,16 +129,6 @@ impl<'tcx> SearchGraph<'tcx> {
129
129
self . mode
130
130
}
131
131
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
-
142
132
/// Pops the highest goal from the stack, lazily updating the
143
133
/// the next goal in the stack.
144
134
///
@@ -266,37 +256,7 @@ impl<'tcx> SearchGraph<'tcx> {
266
256
return Self :: response_no_constraints ( tcx, input, Certainty :: overflow ( true ) ) ;
267
257
} ;
268
258
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) {
300
260
return result;
301
261
}
302
262
@@ -378,7 +338,10 @@ impl<'tcx> SearchGraph<'tcx> {
378
338
379
339
// This is for global caching, so we properly track query dependencies.
380
340
// 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.
382
345
let ( ( final_entry, result) , dep_node) =
383
346
tcx. dep_graph . with_anon_task ( tcx, dep_kinds:: TraitSelect , || {
384
347
for _ in 0 ..FIXPOINT_STEP_LIMIT {
@@ -436,6 +399,45 @@ impl<'tcx> SearchGraph<'tcx> {
436
399
437
400
result
438
401
}
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
+ }
439
441
}
440
442
441
443
enum StepResult < ' tcx > {
0 commit comments