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- \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- \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+ \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+ \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