1+ use  std:: fmt:: Debug ; 
12use  std:: ops:: Deref ; 
23
4+ use  rustc_data_structures:: fingerprint:: Fingerprint ; 
35use  rustc_data_structures:: sync:: { AtomicU64 ,  WorkerLocal } ; 
46use  rustc_hir:: def_id:: { DefId ,  LocalDefId } ; 
57use  rustc_hir:: hir_id:: OwnerId ; 
68use  rustc_macros:: HashStable ; 
79use  rustc_query_system:: HandleCycleError ; 
8- use  rustc_query_system:: dep_graph:: { DepNodeIndex ,  SerializedDepNodeIndex } ; 
10+ use  rustc_query_system:: dep_graph:: { DepNodeIndex ,  DepNodeParams ,  SerializedDepNodeIndex } ; 
11+ use  rustc_query_system:: ich:: StableHashingContext ; 
912pub ( crate )  use  rustc_query_system:: query:: QueryJobId ; 
1013use  rustc_query_system:: query:: * ; 
1114use  rustc_span:: { DUMMY_SP ,  ErrorGuaranteed ,  Span } ; 
@@ -14,6 +17,7 @@ pub use sealed::IntoQueryParam;
1417use  super :: erase:: EraseType ; 
1518use  crate :: dep_graph; 
1619use  crate :: dep_graph:: DepKind ; 
20+ use  crate :: query:: erase:: { Erase ,  restore} ; 
1721use  crate :: query:: on_disk_cache:: { CacheEncoder ,  EncodedDepNodeIndex ,  OnDiskCache } ; 
1822use  crate :: query:: { 
1923    DynamicQueries ,  ExternProviders ,  Providers ,  QueryArenas ,  QueryCaches ,  QueryEngine ,  QueryStates , 
@@ -230,6 +234,56 @@ where
230234    } 
231235} 
232236
237+ /// Common implementation of query feeding, used by `define_feedable!`. 
238+ pub ( crate )  fn  query_feed_inner < ' tcx ,  Cache ,  Value > ( 
239+     tcx :  TyCtxt < ' tcx > , 
240+     dep_kind :  DepKind , 
241+     hasher :  Option < fn ( & mut  StableHashingContext < ' _ > ,  & Value )  -> Fingerprint > , 
242+     cache :  & Cache , 
243+     key :  Cache :: Key , 
244+     erased :  Erase < Value > , 
245+ )  where 
246+     Cache :  QueryCache < Value  = Erase < Value > > , 
247+     Cache :: Key :  DepNodeParams < TyCtxt < ' tcx > > , 
248+     Value :  EraseType  + Debug , 
249+ { 
250+     let  value = restore :: < Value > ( erased) ; 
251+ 
252+     match  try_get_cached ( tcx,  cache,  & key)  { 
253+         Some ( old)  => { 
254+             let  old = restore :: < Value > ( old) ; 
255+             if  let  Some ( hasher)  = hasher { 
256+                 let  ( value_hash,  old_hash) :  ( Fingerprint ,  Fingerprint )  = tcx
257+                     . with_stable_hashing_context ( |mut  hcx| { 
258+                         ( hasher ( & mut  hcx,  & value) ,  hasher ( & mut  hcx,  & old) ) 
259+                     } ) ; 
260+                 if  old_hash != value_hash { 
261+                     // We have an inconsistency. This can happen if one of the two 
262+                     // results is tainted by errors. In this case, delay a bug to 
263+                     // ensure compilation is doomed, and keep the `old` value. 
264+                     tcx. dcx ( ) . delayed_bug ( format ! ( 
265+                         "Trying to feed an already recorded value for query {dep_kind:?} key={key:?}:\n \  
266+ \n new value: {value:?}", 
267+                     ) ) ; 
268+                 } 
269+             }  else  { 
270+                 // The query is `no_hash`, so we have no way to perform a sanity check. 
271+                 // If feeding the same value multiple times needs to be supported, 
272+                 // the query should not be marked `no_hash`. 
273+                 bug ! ( 
274+                     "Trying to feed an already recorded value for query {dep_kind:?} key={key:?}:\n \  
275+ \n new value: {value:?}", 
276+                 ) 
277+             } 
278+         } 
279+         None  => { 
280+             let  dep_node = dep_graph:: DepNode :: construct ( tcx,  dep_kind,  & key) ; 
281+             let  dep_node_index = tcx. dep_graph . with_feed_task ( dep_node,  tcx,  & value,  hasher) ; 
282+             cache. complete ( key,  erased,  dep_node_index) ; 
283+         } 
284+     } 
285+ } 
286+ 
233287macro_rules!  query_ensure { 
234288    ( [ ] $( $args: tt) * )  => { 
235289        query_ensure( $( $args) * ) 
@@ -567,48 +621,19 @@ macro_rules! define_feedable {
567621
568622                let  tcx = self . tcx; 
569623                let  erased = queries:: $name:: provided_to_erased( tcx,  value) ; 
570-                 let  value = restore:: <$V>( erased) ; 
571624                let  cache = & tcx. query_system. caches. $name; 
572625
573626                let  dep_kind:  dep_graph:: DepKind  = dep_graph:: dep_kinds:: $name; 
574627                let  hasher:  Option <fn ( & mut  StableHashingContext <' _>,  & _)  -> _> = hash_result!( [ $( $modifiers) * ] ) ; 
575-                 match  try_get_cached( tcx,  cache,  & key)  { 
576-                     Some ( old)  => { 
577-                         let  old = restore:: <$V>( old) ; 
578-                         if  let  Some ( hasher)  = hasher { 
579-                             let  ( value_hash,  old_hash) :  ( Fingerprint ,  Fingerprint )  = tcx. with_stable_hashing_context( |mut  hcx|
580-                                 ( hasher( & mut  hcx,  & value) ,  hasher( & mut  hcx,  & old) ) 
581-                             ) ; 
582-                             if  old_hash != value_hash { 
583-                                 // We have an inconsistency. This can happen if one of the two 
584-                                 // results is tainted by errors. In this case, delay a bug to 
585-                                 // ensure compilation is doomed, and keep the `old` value. 
586-                                 tcx. dcx( ) . delayed_bug( format!( 
587-                                     "Trying to feed an already recorded value for query {dep_kind:?} key={key:?}:\n \  
588- \n new value: {value:?}", 
589-                                 ) ) ; 
590-                             } 
591-                         }  else { 
592-                             // The query is `no_hash`, so we have no way to perform a sanity check. 
593-                             // If feeding the same value multiple times needs to be supported, 
594-                             // the query should not be marked `no_hash`. 
595-                             bug!( 
596-                                 "Trying to feed an already recorded value for query {dep_kind:?} key={key:?}:\n \  
597- \n new value: {value:?}", 
598-                             ) 
599-                         } 
600-                     } 
601-                     None  => { 
602-                         let  dep_node = dep_graph:: DepNode :: construct( tcx,  dep_kind,  & key) ; 
603-                         let  dep_node_index = tcx. dep_graph. with_feed_task( 
604-                             dep_node, 
605-                             tcx, 
606-                             & value, 
607-                             hasher, 
608-                         ) ; 
609-                         cache. complete( key,  erased,  dep_node_index) ; 
610-                     } 
611-                 } 
628+ 
629+                 $crate:: query:: plumbing:: query_feed_inner( 
630+                     tcx, 
631+                     dep_kind, 
632+                     hasher, 
633+                     cache, 
634+                     key, 
635+                     erased, 
636+                 ) ; 
612637            } 
613638        } ) * 
614639    } 
0 commit comments