@@ -238,6 +238,7 @@ fn wait_for_query<'tcx, C: QueryCache>(
238238 tcx : TyCtxt < ' tcx > ,
239239 span : Span ,
240240 key : C :: Key ,
241+ key_hash : u64 ,
241242 latch : QueryLatch < ' tcx > ,
242243 current : Option < QueryJobId > ,
243244) -> ( C :: Value , Option < DepNodeIndex > ) {
@@ -246,8 +247,7 @@ fn wait_for_query<'tcx, C: QueryCache>(
246247 // self-profiler.
247248 let query_blocked_prof_timer = tcx. prof . query_blocked ( ) ;
248249
249- // With parallel queries we might just have to wait on some other
250- // thread.
250+ // With parallel queries we might just have to wait on some other thread.
251251 let result = latch. wait_on ( tcx, current, span) ;
252252
253253 match result {
@@ -256,7 +256,6 @@ fn wait_for_query<'tcx, C: QueryCache>(
256256 outline ( || {
257257 // We didn't find the query result in the query cache. Check if it was
258258 // poisoned due to a panic instead.
259- let key_hash = sharded:: make_hash ( & key) ;
260259 let shard = query. state . active . lock_shard_by_hash ( key_hash) ;
261260 match shard. find ( key_hash, equivalent_key ( key) ) {
262261 // The query we waited on panicked. Continue unwinding here.
@@ -309,16 +308,37 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
309308
310309 match state_lock. entry ( key_hash, equivalent_key ( key) , |( k, _) | sharded:: make_hash ( k) ) {
311310 Entry :: Vacant ( entry) => {
312- // Nothing has computed or is computing the query, so we start a new job and insert it in the
313- // state map.
311+ // Nothing has computed or is computing the query, so we start a new job and insert it
312+ // in the state map.
314313 let id = next_job_id ( tcx) ;
315314 let job = QueryJob :: new ( id, span, current_job_id) ;
316315 entry. insert ( ( key, ActiveKeyStatus :: Started ( job) ) ) ;
317316
318- // Drop the lock before we start executing the query
317+ // Drop the lock before we start executing the query.
319318 drop ( state_lock) ;
320319
321- execute_job :: < C , INCR > ( query, tcx, key, key_hash, id, dep_node)
320+ // Set up a guard object that will automatically poison the query if a
321+ // panic occurs while executing the query (or any intermediate plumbing).
322+ let job_guard = ActiveJobGuard { state : & query. state , key, key_hash } ;
323+
324+ debug_assert_eq ! ( tcx. dep_graph. is_fully_enabled( ) , INCR ) ;
325+
326+ // Delegate to another function to actually execute the query job.
327+ let ( value, dep_node_index) = if INCR {
328+ execute_job_incr ( query, tcx, key, dep_node, id)
329+ } else {
330+ execute_job_non_incr ( query, tcx, key, id)
331+ } ;
332+
333+ if query. feedable {
334+ check_feedable ( tcx, query, key, & value) ;
335+ }
336+
337+ // Tell the guard to insert `value` in the cache and remove the status entry from
338+ // `query.state`.
339+ job_guard. complete ( & query. cache , value, dep_node_index) ;
340+
341+ ( value, Some ( dep_node_index) )
322342 }
323343 Entry :: Occupied ( mut entry) => {
324344 match & mut entry. get_mut ( ) . 1 {
@@ -330,7 +350,7 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
330350
331351 // Only call `wait_for_query` if we're using a Rayon thread pool
332352 // as it will attempt to mark the worker thread as blocked.
333- wait_for_query ( query, tcx, span, key, latch, current_job_id)
353+ wait_for_query ( query, tcx, span, key, key_hash , latch, current_job_id)
334354 } else {
335355 let id = job. id ;
336356 drop ( state_lock) ;
@@ -347,67 +367,44 @@ fn try_execute_query<'tcx, C: QueryCache, const INCR: bool>(
347367}
348368
349369#[ inline( always) ]
350- fn execute_job < ' tcx , C : QueryCache , const INCR : bool > (
351- query : & ' tcx QueryVTable < ' tcx , C > ,
370+ fn check_feedable < ' tcx , C : QueryCache > (
352371 tcx : TyCtxt < ' tcx > ,
372+ query : & ' tcx QueryVTable < ' tcx , C > ,
353373 key : C :: Key ,
354- key_hash : u64 ,
355- id : QueryJobId ,
356- dep_node : Option < DepNode > ,
357- ) -> ( C :: Value , Option < DepNodeIndex > ) {
358- // Set up a guard object that will automatically poison the query if a
359- // panic occurs while executing the query (or any intermediate plumbing).
360- let job_guard = ActiveJobGuard { state : & query. state , key, key_hash } ;
361-
362- debug_assert_eq ! ( tcx. dep_graph. is_fully_enabled( ) , INCR ) ;
363-
364- // Delegate to another function to actually execute the query job.
365- let ( value, dep_node_index) = if INCR {
366- execute_job_incr ( query, tcx, key, dep_node, id)
367- } else {
368- execute_job_non_incr ( query, tcx, key, id)
369- } ;
370-
371- let cache = & query. cache ;
372- if query. feedable {
373- // We should not compute queries that also got a value via feeding.
374- // This can't happen, as query feeding adds the very dependencies to the fed query
375- // as its feeding query had. So if the fed query is red, so is its feeder, which will
376- // get evaluated first, and re-feed the query.
377- if let Some ( ( cached_value, _) ) = cache. lookup ( & key) {
378- let Some ( hash_value_fn) = query. hash_value_fn else {
379- panic ! (
380- "no_hash fed query later has its value computed.\n \
381- Remove `no_hash` modifier to allow recomputation.\n \
382- The already cached value: {}",
383- ( query. format_value) ( & cached_value)
384- ) ;
385- } ;
374+ value : & C :: Value ,
375+ ) {
376+ // We should not compute queries that also got a value via feeding.
377+ // This can't happen, as query feeding adds the very dependencies to the fed query
378+ // as its feeding query had. So if the fed query is red, so is its feeder, which will
379+ // get evaluated first, and re-feed the query.
380+ if let Some ( ( cached_value, _) ) = query. cache . lookup ( & key) {
381+ let Some ( hash_value_fn) = query. hash_value_fn else {
382+ panic ! (
383+ "no_hash fed query later has its value computed.\n \
384+ Remove `no_hash` modifier to allow recomputation.\n \
385+ The already cached value: {}",
386+ ( query. format_value) ( & cached_value)
387+ ) ;
388+ } ;
386389
387- let ( old_hash, new_hash) = tcx. with_stable_hashing_context ( |mut hcx| {
388- ( hash_value_fn ( & mut hcx, & cached_value) , hash_value_fn ( & mut hcx, & value) )
389- } ) ;
390- let formatter = query. format_value ;
391- if old_hash != new_hash {
392- // We have an inconsistency. This can happen if one of the two
393- // results is tainted by errors.
394- assert ! (
395- tcx. dcx( ) . has_errors( ) . is_some( ) ,
396- "Computed query value for {:?}({:?}) is inconsistent with fed value,\n \
397- computed={:#?}\n fed={:#?}",
398- query. dep_kind,
399- key,
400- formatter( & value) ,
401- formatter( & cached_value) ,
402- ) ;
403- }
390+ let ( old_hash, new_hash) = tcx. with_stable_hashing_context ( |mut hcx| {
391+ ( hash_value_fn ( & mut hcx, & cached_value) , hash_value_fn ( & mut hcx, value) )
392+ } ) ;
393+ let formatter = query. format_value ;
394+ if old_hash != new_hash {
395+ // We have an inconsistency. This can happen if one of the two
396+ // results is tainted by errors.
397+ assert ! (
398+ tcx. dcx( ) . has_errors( ) . is_some( ) ,
399+ "Computed query value for {:?}({:?}) is inconsistent with fed value,\n \
400+ computed={:#?}\n fed={:#?}",
401+ query. dep_kind,
402+ key,
403+ formatter( value) ,
404+ formatter( & cached_value) ,
405+ ) ;
404406 }
405407 }
406-
407- // Tell the guard to perform completion bookkeeping, and also to not poison the query.
408- job_guard. complete ( cache, value, dep_node_index) ;
409-
410- ( value, Some ( dep_node_index) )
411408}
412409
413410// Fast path for when incr. comp. is off.
0 commit comments