1
+ use std:: fmt:: Debug ;
1
2
use std:: ops:: Deref ;
2
3
4
+ use rustc_data_structures:: fingerprint:: Fingerprint ;
3
5
use rustc_data_structures:: sync:: { AtomicU64 , WorkerLocal } ;
4
6
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
5
7
use rustc_hir:: hir_id:: OwnerId ;
6
8
use rustc_macros:: HashStable ;
7
9
use 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 ;
9
12
pub ( crate ) use rustc_query_system:: query:: QueryJobId ;
10
13
use rustc_query_system:: query:: * ;
11
14
use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Span } ;
@@ -14,6 +17,7 @@ pub use sealed::IntoQueryParam;
14
17
use super :: erase:: EraseType ;
15
18
use crate :: dep_graph;
16
19
use crate :: dep_graph:: DepKind ;
20
+ use crate :: query:: erase:: { Erase , restore} ;
17
21
use crate :: query:: on_disk_cache:: { CacheEncoder , EncodedDepNodeIndex , OnDiskCache } ;
18
22
use crate :: query:: {
19
23
DynamicQueries , ExternProviders , Providers , QueryArenas , QueryCaches , QueryEngine , QueryStates ,
@@ -567,54 +571,77 @@ macro_rules! define_feedable {
567
571
568
572
let tcx = self . tcx;
569
573
let erased = queries:: $name:: provided_to_erased( tcx, value) ;
570
- let value = restore:: <$V>( erased) ;
571
574
let cache = & tcx. query_system. caches. $name;
572
575
573
576
let name: & ' static str = stringify!( $name) ;
574
577
let dep_kind: dep_graph:: DepKind = dep_graph:: dep_kinds:: $name;
575
578
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
+ ) ;
613
589
}
614
590
} ) *
615
591
}
616
592
}
617
593
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
+
618
645
// Each of these queries corresponds to a function pointer field in the
619
646
// `Providers` struct for requesting a value of that type, and a method
620
647
// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
0 commit comments