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 ,
@@ -567,54 +571,77 @@ macro_rules! define_feedable {
567571
568572 let tcx = self . tcx;
569573 let erased = queries:: $name:: provided_to_erased( tcx, value) ;
570- let value = restore:: <$V>( erased) ;
571574 let cache = & tcx. query_system. caches. $name;
572575
573576 let name: & ' static str = stringify!( $name) ;
574577 let dep_kind: dep_graph:: DepKind = dep_graph:: dep_kinds:: $name;
575578 let hasher: Option <fn ( & mut StableHashingContext <' _>, & _) -> _> = hash_result!( [ $( $modifiers) * ] ) ;
576- match try_get_cached( tcx, cache, & key) {
577- Some ( old) => {
578- let old = restore:: <$V>( old) ;
579- if let Some ( hasher) = hasher {
580- let ( value_hash, old_hash) : ( Fingerprint , Fingerprint ) = tcx. with_stable_hashing_context( |mut hcx|
581- ( hasher( & mut hcx, & value) , hasher( & mut hcx, & old) )
582- ) ;
583- if old_hash != value_hash {
584- // We have an inconsistency. This can happen if one of the two
585- // results is tainted by errors. In this case, delay a bug to
586- // ensure compilation is doomed, and keep the `old` value.
587- tcx. dcx( ) . delayed_bug( format!(
588- "Trying to feed an already recorded value for query {name} key={key:?}:\n \
589- old value: {old:?}\n new value: {value:?}",
590- ) ) ;
591- }
592- } else {
593- // The query is `no_hash`, so we have no way to perform a sanity check.
594- // If feeding the same value multiple times needs to be supported,
595- // the query should not be marked `no_hash`.
596- bug!(
597- "Trying to feed an already recorded value for query {name} key={key:?}:\n \
598- old value: {old:?}\n new value: {value:?}",
599- )
600- }
601- }
602- None => {
603- let dep_node = dep_graph:: DepNode :: construct( tcx, dep_kind, & key) ;
604- let dep_node_index = tcx. dep_graph. with_feed_task(
605- dep_node,
606- tcx,
607- & value,
608- hasher,
609- ) ;
610- cache. complete( key, erased, dep_node_index) ;
611- }
612- }
579+
580+ $crate:: query:: plumbing:: query_feed_inner(
581+ tcx,
582+ name,
583+ dep_kind,
584+ hasher,
585+ cache,
586+ key,
587+ erased,
588+ ) ;
613589 }
614590 } ) *
615591 }
616592}
617593
594+ /// Common implementation of query feeding, used by `define_feedable!`.
595+ pub ( crate ) fn query_feed_inner < ' tcx , Cache , Value > (
596+ tcx : TyCtxt < ' tcx > ,
597+ name : & ' static str ,
598+ dep_kind : DepKind ,
599+ hasher : Option < fn ( & mut StableHashingContext < ' _ > , & Value ) -> Fingerprint > ,
600+ cache : & Cache ,
601+ key : Cache :: Key ,
602+ erased : Erase < Value > ,
603+ ) where
604+ Cache : QueryCache < Value = Erase < Value > > ,
605+ Cache :: Key : DepNodeParams < TyCtxt < ' tcx > > ,
606+ Value : EraseType + Debug ,
607+ {
608+ let value = restore :: < Value > ( erased) ;
609+
610+ match try_get_cached ( tcx, cache, & key) {
611+ Some ( old) => {
612+ let old = restore :: < Value > ( old) ;
613+ if let Some ( hasher) = hasher {
614+ let ( value_hash, old_hash) : ( Fingerprint , Fingerprint ) = tcx
615+ . with_stable_hashing_context ( |mut hcx| {
616+ ( hasher ( & mut hcx, & value) , hasher ( & mut hcx, & old) )
617+ } ) ;
618+ if old_hash != value_hash {
619+ // We have an inconsistency. This can happen if one of the two
620+ // results is tainted by errors. In this case, delay a bug to
621+ // ensure compilation is doomed, and keep the `old` value.
622+ tcx. dcx ( ) . delayed_bug ( format ! (
623+ "Trying to feed an already recorded value for query {name} key={key:?}:\n \
624+ old value: {old:?}\n new value: {value:?}",
625+ ) ) ;
626+ }
627+ } else {
628+ // The query is `no_hash`, so we have no way to perform a sanity check.
629+ // If feeding the same value multiple times needs to be supported,
630+ // the query should not be marked `no_hash`.
631+ bug ! (
632+ "Trying to feed an already recorded value for query {name} key={key:?}:\n \
633+ old value: {old:?}\n new value: {value:?}",
634+ )
635+ }
636+ }
637+ None => {
638+ let dep_node = dep_graph:: DepNode :: construct ( tcx, dep_kind, & key) ;
639+ let dep_node_index = tcx. dep_graph . with_feed_task ( dep_node, tcx, & value, hasher) ;
640+ cache. complete ( key, erased, dep_node_index) ;
641+ }
642+ }
643+ }
644+
618645// Each of these queries corresponds to a function pointer field in the
619646// `Providers` struct for requesting a value of that type, and a method
620647// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
0 commit comments