@@ -240,6 +240,7 @@ fn wait_for_query<'tcx, C: QueryCache>(
240240 tcx : TyCtxt < ' tcx > ,
241241 span : Span ,
242242 key : C :: Key ,
243+ key_hash : u64 ,
243244 latch : QueryLatch < ' tcx > ,
244245 current : Option < QueryJobId > ,
245246) -> ( C :: Value , Option < DepNodeIndex > ) {
@@ -248,8 +249,7 @@ fn wait_for_query<'tcx, C: QueryCache>(
248249 // self-profiler.
249250 let query_blocked_prof_timer = tcx. prof . query_blocked ( ) ;
250251
251- // With parallel queries we might just have to wait on some other
252- // thread.
252+ // With parallel queries we might just have to wait on some other thread.
253253 let result = latch. wait_on ( tcx, current, span) ;
254254
255255 match result {
@@ -258,7 +258,6 @@ fn wait_for_query<'tcx, C: QueryCache>(
258258 outline ( || {
259259 // We didn't find the query result in the query cache. Check if it was
260260 // poisoned due to a panic instead.
261- let key_hash = sharded:: make_hash ( & key) ;
262261 let shard = query. state . active . lock_shard_by_hash ( key_hash) ;
263262 match shard. find ( key_hash, equivalent_key ( key) ) {
264263 // The query we waited on panicked. Continue unwinding here.
@@ -311,16 +310,37 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
311310
312311 match state_lock. entry ( key_hash, equivalent_key ( key) , |( k, _) | sharded:: make_hash ( k) ) {
313312 Entry :: Vacant ( entry) => {
314- // Nothing has computed or is computing the query, so we start a new job and insert it in the
315- // state map.
313+ // Nothing has computed or is computing the query, so we start a new job and insert it
314+ // in the state map.
316315 let id = next_job_id ( tcx) ;
317316 let job = QueryJob :: new ( id, span, current_job_id) ;
318317 entry. insert ( ( key, ActiveKeyStatus :: Started ( job) ) ) ;
319318
320- // Drop the lock before we start executing the query
319+ // Drop the lock before we start executing the query.
321320 drop ( state_lock) ;
322321
323- execute_job :: < C , INCR > ( query, tcx, key, key_hash, id, dep_node)
322+ // Set up a guard object that will automatically poison the query if a
323+ // panic occurs while executing the query (or any intermediate plumbing).
324+ let job_guard = ActiveJobGuard { state : & query. state , key, key_hash } ;
325+
326+ debug_assert_eq ! ( tcx. dep_graph. is_fully_enabled( ) , INCR ) ;
327+
328+ // Delegate to another function to actually execute the query job.
329+ let ( value, dep_node_index) = if INCR {
330+ execute_job_incr ( query, tcx, key, dep_node, id)
331+ } else {
332+ execute_job_non_incr ( query, tcx, key, id)
333+ } ;
334+
335+ if query. feedable {
336+ check_feedable_consistency ( tcx, query, key, & value) ;
337+ }
338+
339+ // Tell the guard to insert `value` in the cache and remove the status entry from
340+ // `query.state`.
341+ job_guard. complete ( & query. cache , value, dep_node_index) ;
342+
343+ ( value, Some ( dep_node_index) )
324344 }
325345 Entry :: Occupied ( mut entry) => {
326346 match & mut entry. get_mut ( ) . 1 {
@@ -332,7 +352,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
332352
333353 // Only call `wait_for_query` if we're using a Rayon thread pool
334354 // as it will attempt to mark the worker thread as blocked.
335- wait_for_query ( query, tcx, span, key, latch, current_job_id)
355+ wait_for_query ( query, tcx, span, key, key_hash , latch, current_job_id)
336356 } else {
337357 let id = job. id ;
338358 drop ( state_lock) ;
@@ -349,67 +369,44 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
349369}
350370
351371#[ inline( always) ]
352- fn execute_job < ' tcx , C : QueryCache , const INCR : bool > (
353- query : & ' tcx QueryVTable < ' tcx , C > ,
372+ fn check_feedable_consistency < ' tcx , C : QueryCache > (
354373 tcx : TyCtxt < ' tcx > ,
374+ query : & ' tcx QueryVTable < ' tcx , C > ,
355375 key : C :: Key ,
356- key_hash : u64 ,
357- id : QueryJobId ,
358- dep_node : Option < DepNode > ,
359- ) -> ( C :: Value , Option < DepNodeIndex > ) {
360- // Set up a guard object that will automatically poison the query if a
361- // panic occurs while executing the query (or any intermediate plumbing) .
362- let job_guard = ActiveJobGuard { state : & query. state , key, key_hash } ;
363-
364- debug_assert_eq ! ( tcx . dep_graph . is_fully_enabled ( ) , INCR ) ;
365-
366- // Delegate to another function to actually execute the query job.
367- let ( value , dep_node_index ) = if INCR {
368- execute_job_incr ( query , tcx , key , dep_node , id )
369- } else {
370- execute_job_non_incr ( query , tcx , key , id )
376+ value : & C :: Value ,
377+ ) {
378+ // We should not compute queries that also got a value via feeding.
379+ // This can't happen, as query feeding adds the very dependencies to the fed query
380+ // as its feeding query had. So if the fed query is red, so is its feeder, which will
381+ // get evaluated first, and re-feed the query.
382+ let Some ( ( cached_value , _ ) ) = query. cache . lookup ( & key) else { return } ;
383+
384+ let Some ( hash_value_fn ) = query . hash_value_fn else {
385+ panic ! (
386+ "no_hash fed query later has its value computed. \n \
387+ Remove `no_hash` modifier to allow recomputation. \n \
388+ The already cached value: {}" ,
389+ ( query . format_value ) ( & cached_value )
390+ ) ;
371391 } ;
372392
373- let cache = & query. cache ;
374- if query. feedable {
375- // We should not compute queries that also got a value via feeding.
376- // This can't happen, as query feeding adds the very dependencies to the fed query
377- // as its feeding query had. So if the fed query is red, so is its feeder, which will
378- // get evaluated first, and re-feed the query.
379- if let Some ( ( cached_value, _) ) = cache. lookup ( & key) {
380- let Some ( hash_value_fn) = query. hash_value_fn else {
381- panic ! (
382- "no_hash fed query later has its value computed.\n \
383- Remove `no_hash` modifier to allow recomputation.\n \
384- The already cached value: {}",
385- ( query. format_value) ( & cached_value)
386- ) ;
387- } ;
388-
389- let ( old_hash, new_hash) = tcx. with_stable_hashing_context ( |mut hcx| {
390- ( hash_value_fn ( & mut hcx, & cached_value) , hash_value_fn ( & mut hcx, & value) )
391- } ) ;
392- let formatter = query. format_value ;
393- if old_hash != new_hash {
394- // We have an inconsistency. This can happen if one of the two
395- // results is tainted by errors.
396- assert ! (
397- tcx. dcx( ) . has_errors( ) . is_some( ) ,
398- "Computed query value for {:?}({:?}) is inconsistent with fed value,\n \
399- computed={:#?}\n fed={:#?}",
400- query. dep_kind,
401- key,
402- formatter( & value) ,
403- formatter( & cached_value) ,
404- ) ;
405- }
406- }
393+ let ( old_hash, new_hash) = tcx. with_stable_hashing_context ( |mut hcx| {
394+ ( hash_value_fn ( & mut hcx, & cached_value) , hash_value_fn ( & mut hcx, value) )
395+ } ) ;
396+ let formatter = query. format_value ;
397+ if old_hash != new_hash {
398+ // We have an inconsistency. This can happen if one of the two
399+ // results is tainted by errors.
400+ assert ! (
401+ tcx. dcx( ) . has_errors( ) . is_some( ) ,
402+ "Computed query value for {:?}({:?}) is inconsistent with fed value,\n \
403+ computed={:#?}\n fed={:#?}",
404+ query. dep_kind,
405+ key,
406+ formatter( value) ,
407+ formatter( & cached_value) ,
408+ ) ;
407409 }
408-
409- // Tell the guard to perform completion bookkeeping, and also to not poison the query.
410- job_guard. complete ( cache, value, dep_node_index) ;
411-
412- ( value, Some ( dep_node_index) )
413410}
414411
415412// Fast path for when incr. comp. is off.
0 commit comments