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 ,
@@ -230,6 +234,56 @@ where
230
234
}
231
235
}
232
236
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
+
233
287
macro_rules! query_ensure {
234
288
( [ ] $( $args: tt) * ) => {
235
289
query_ensure( $( $args) * )
@@ -567,48 +621,19 @@ macro_rules! define_feedable {
567
621
568
622
let tcx = self . tcx;
569
623
let erased = queries:: $name:: provided_to_erased( tcx, value) ;
570
- let value = restore:: <$V>( erased) ;
571
624
let cache = & tcx. query_system. caches. $name;
572
625
573
626
let dep_kind: dep_graph:: DepKind = dep_graph:: dep_kinds:: $name;
574
627
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
+ ) ;
612
637
}
613
638
} ) *
614
639
}
0 commit comments