11use std:: num:: NonZero ;
22
3+ use rustc_data_structures:: stack:: ensure_sufficient_stack;
34use rustc_data_structures:: unord:: UnordMap ;
45use rustc_hir:: limit:: Limit ;
56use rustc_middle:: bug;
67#[ expect( unused_imports, reason = "used by doc comments" ) ]
78use rustc_middle:: dep_graph:: DepKindVTable ;
8- use rustc_middle:: dep_graph:: { DepNode , DepNodeKey , SerializedDepNodeIndex } ;
9+ use rustc_middle:: dep_graph:: { DepNode , DepNodeIndex , DepNodeKey , SerializedDepNodeIndex } ;
910use rustc_middle:: query:: erase:: { Erasable , Erased } ;
1011use rustc_middle:: query:: on_disk_cache:: { CacheDecoder , CacheEncoder } ;
1112use rustc_middle:: query:: { QueryCache , QueryJobId , QueryMode , QueryVTable , erase} ;
1213use rustc_middle:: ty:: TyCtxt ;
1314use rustc_middle:: ty:: tls:: { self , ImplicitCtxt } ;
15+ use rustc_middle:: verify_ich:: incremental_verify_ich;
1416use rustc_serialize:: { Decodable , Encodable } ;
1517use rustc_span:: DUMMY_SP ;
1618use rustc_span:: def_id:: LOCAL_CRATE ;
1719
1820use crate :: error:: { QueryOverflow , QueryOverflowNote } ;
19- use crate :: execution:: all_inactive;
21+ use crate :: execution:: { all_inactive, should_verify_loaded_value } ;
2022use crate :: job:: find_dep_kind_root;
2123use crate :: query_impl:: for_each_query_vtable;
2224use crate :: { CollectActiveJobsKind , collect_active_query_jobs} ;
@@ -140,6 +142,8 @@ pub(crate) fn promote_from_disk_inner<'tcx, C: QueryCache>(
140142 tcx : TyCtxt < ' tcx > ,
141143 query : & ' tcx QueryVTable < ' tcx , C > ,
142144 dep_node : DepNode ,
145+ prev_index : SerializedDepNodeIndex ,
146+ dep_node_index : DepNodeIndex ,
143147) {
144148 debug_assert ! ( tcx. dep_graph. is_green( & dep_node) ) ;
145149
@@ -156,17 +160,41 @@ pub(crate) fn promote_from_disk_inner<'tcx, C: QueryCache>(
156160 return ;
157161 }
158162
159- match query. cache . lookup ( & key) {
160- // If the value is already in memory, then promotion isn't needed.
161- Some ( _) => { }
162-
163- // "Execute" the query to load its disk-cached value into memory.
164- //
165- // We know that the key is cache-on-disk and its node is green,
166- // so there _must_ be a value on disk to load.
167- //
168- // FIXME(Zalathar): Is there a reasonable way to skip more of the
169- // query bookkeeping when doing this?
163+ // If the value is already in memory, then promotion isn't needed.
164+ if query. cache . lookup ( & key) . is_some ( ) {
165+ return ;
166+ }
167+
168+ // Load the disk-cached value into memory.
169+ let dep_graph_data =
170+ tcx. dep_graph . data ( ) . expect ( "should always be present in incremental mode" ) ;
171+
172+ let prof_timer = tcx. prof . incr_cache_loading ( ) ;
173+ let value = ensure_sufficient_stack ( || ( query. try_load_from_disk_fn ) ( tcx, prev_index) ) ;
174+ prof_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
175+
176+ match value {
177+ Some ( value) => {
178+ // Verify the fingerprints of the same subset of loaded values as
179+ // `load_from_disk_or_invoke_provider_green` does.
180+ let prev_fingerprint = dep_graph_data. prev_value_fingerprint_of ( prev_index) ;
181+ if should_verify_loaded_value ( tcx, prev_fingerprint) {
182+ incremental_verify_ich (
183+ tcx,
184+ dep_graph_data,
185+ & value,
186+ prev_index,
187+ query. hash_value_fn ,
188+ query. format_value ,
189+ ) ;
190+ }
191+
192+ query. cache . complete ( key, value, dep_node_index) ;
193+ }
194+
195+ // There was no value on disk, despite the key being cache-on-disk and
196+ // its node being green. "Execute" the query through the normal
197+ // machinery, which will recompute the value and put it in memory.
170198 None => {
171199 ( query. execute_query_fn ) ( tcx, DUMMY_SP , key, QueryMode :: Get ) ;
172200 }
0 commit comments