@@ -134,16 +134,6 @@ impl<I: Interner> SearchGraph<I> {
134
134
self . mode
135
135
}
136
136
137
- /// Update the stack and reached depths on cache hits.
138
- #[ instrument( level = "trace" , skip( self ) ) ]
139
- fn on_cache_hit ( & mut self , additional_depth : usize , encountered_overflow : bool ) {
140
- let reached_depth = self . stack . next_index ( ) . plus ( additional_depth) ;
141
- if let Some ( last) = self . stack . raw . last_mut ( ) {
142
- last. reached_depth = last. reached_depth . max ( reached_depth) ;
143
- last. encountered_overflow |= encountered_overflow;
144
- }
145
- }
146
-
147
137
/// Pops the highest goal from the stack, lazily updating the
148
138
/// the next goal in the stack.
149
139
///
@@ -276,37 +266,7 @@ impl<'tcx> SearchGraph<TyCtxt<'tcx>> {
276
266
return Self :: response_no_constraints ( tcx, input, Certainty :: overflow ( true ) ) ;
277
267
} ;
278
268
279
- // Try to fetch the goal from the global cache.
280
- ' global: {
281
- let Some ( CacheData { result, proof_tree, reached_depth, encountered_overflow } ) =
282
- self . global_cache ( tcx) . get (
283
- tcx,
284
- input,
285
- |cycle_participants| {
286
- self . stack . iter ( ) . any ( |entry| cycle_participants. contains ( & entry. input ) )
287
- } ,
288
- available_depth,
289
- )
290
- else {
291
- break ' global;
292
- } ;
293
-
294
- // If we're building a proof tree and the current cache entry does not
295
- // contain a proof tree, we do not use the entry but instead recompute
296
- // the goal. We simply overwrite the existing entry once we're done,
297
- // caching the proof tree.
298
- if !inspect. is_noop ( ) {
299
- if let Some ( revisions) = proof_tree {
300
- inspect. goal_evaluation_kind (
301
- inspect:: WipCanonicalGoalEvaluationKind :: Interned { revisions } ,
302
- ) ;
303
- } else {
304
- break ' global;
305
- }
306
- }
307
-
308
- self . on_cache_hit ( reached_depth, encountered_overflow) ;
309
- debug ! ( "global cache hit" ) ;
269
+ if let Some ( result) = self . lookup_global_cache ( tcx, input, available_depth, inspect) {
310
270
return result;
311
271
}
312
272
@@ -388,7 +348,10 @@ impl<'tcx> SearchGraph<TyCtxt<'tcx>> {
388
348
389
349
// This is for global caching, so we properly track query dependencies.
390
350
// Everything that affects the `result` should be performed within this
391
- // `with_anon_task` closure.
351
+ // `with_anon_task` closure. If computing this goal depends on something
352
+ // not tracked by the cache key and from outside of this anon task, it
353
+ // must not be added to the global cache. Notably, this is the case for
354
+ // trait solver cycles participants.
392
355
let ( ( final_entry, result) , dep_node) =
393
356
tcx. dep_graph . with_anon_task ( tcx, dep_kinds:: TraitSelect , || {
394
357
for _ in 0 ..FIXPOINT_STEP_LIMIT {
@@ -446,6 +409,45 @@ impl<'tcx> SearchGraph<TyCtxt<'tcx>> {
446
409
447
410
result
448
411
}
412
+
413
+ /// Try to fetch a previously computed result from the global cache,
414
+ /// making sure to only do so if it would match the result of reevaluating
415
+ /// this goal.
416
+ fn lookup_global_cache (
417
+ & mut self ,
418
+ tcx : TyCtxt < ' tcx > ,
419
+ input : CanonicalInput < ' tcx > ,
420
+ available_depth : Limit ,
421
+ inspect : & mut ProofTreeBuilder < TyCtxt < ' tcx > > ,
422
+ ) -> Option < QueryResult < ' tcx > > {
423
+ let CacheData { result, proof_tree, additional_depth, encountered_overflow } = self
424
+ . global_cache ( tcx)
425
+ . get ( tcx, input, self . stack . iter ( ) . map ( |e| e. input ) , available_depth) ?;
426
+
427
+ // If we're building a proof tree and the current cache entry does not
428
+ // contain a proof tree, we do not use the entry but instead recompute
429
+ // the goal. We simply overwrite the existing entry once we're done,
430
+ // caching the proof tree.
431
+ if !inspect. is_noop ( ) {
432
+ if let Some ( revisions) = proof_tree {
433
+ let kind = inspect:: WipCanonicalGoalEvaluationKind :: Interned { revisions } ;
434
+ inspect. goal_evaluation_kind ( kind) ;
435
+ } else {
436
+ return None ;
437
+ }
438
+ }
439
+
440
+ // Update the reached depth of the current goal to make sure
441
+ // its state is the same regardless of whether we've used the
442
+ // global cache or not.
443
+ let reached_depth = self . stack . next_index ( ) . plus ( additional_depth) ;
444
+ if let Some ( last) = self . stack . raw . last_mut ( ) {
445
+ last. reached_depth = last. reached_depth . max ( reached_depth) ;
446
+ last. encountered_overflow |= encountered_overflow;
447
+ }
448
+
449
+ Some ( result)
450
+ }
449
451
}
450
452
451
453
enum StepResult < ' tcx > {
0 commit comments