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+ old value: {old:?}\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+ old value: {old:?}\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- old value: {old:?}\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- old value: {old:?}\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