@@ -75,6 +75,10 @@ pub struct OnDiskCache<'sess> {
7575 // A map from dep-node to the position of any associated diagnostics in
7676 // `serialized_data`.
7777 prev_diagnostics_index : FxHashMap < SerializedDepNodeIndex , AbsoluteBytePos > ,
78+
79+ // A map from dep-node to the position of any associated constants in
80+ // `serialized_data`.
81+ prev_constants_index : FxHashMap < SerializedDepNodeIndex , AbsoluteBytePos > ,
7882}
7983
8084// This type is used only for (de-)serialization.
@@ -84,8 +88,10 @@ struct Footer {
8488 prev_cnums : Vec < ( u32 , String , CrateDisambiguator ) > ,
8589 query_result_index : EncodedQueryResultIndex ,
8690 diagnostics_index : EncodedQueryResultIndex ,
91+ constants_index : EncodedConstantsIndex ,
8792}
8893
94+ type EncodedConstantsIndex = Vec < ( SerializedDepNodeIndex , AbsoluteBytePos ) > ;
8995type EncodedQueryResultIndex = Vec < ( SerializedDepNodeIndex , AbsoluteBytePos ) > ;
9096type EncodedDiagnosticsIndex = Vec < ( SerializedDepNodeIndex , AbsoluteBytePos ) > ;
9197type EncodedDiagnostics = Vec < Diagnostic > ;
@@ -139,6 +145,7 @@ impl<'sess> OnDiskCache<'sess> {
139145 current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
140146 query_result_index : footer. query_result_index . into_iter ( ) . collect ( ) ,
141147 prev_diagnostics_index : footer. diagnostics_index . into_iter ( ) . collect ( ) ,
148+ prev_constants_index : footer. constants_index . into_iter ( ) . collect ( ) ,
142149 synthetic_expansion_infos : RefCell :: new ( FxHashMap ( ) ) ,
143150 }
144151 }
@@ -154,6 +161,7 @@ impl<'sess> OnDiskCache<'sess> {
154161 current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
155162 query_result_index : FxHashMap ( ) ,
156163 prev_diagnostics_index : FxHashMap ( ) ,
164+ prev_constants_index : FxHashMap ( ) ,
157165 synthetic_expansion_infos : RefCell :: new ( FxHashMap ( ) ) ,
158166 }
159167 }
@@ -223,6 +231,45 @@ impl<'sess> OnDiskCache<'sess> {
223231 encode_query_results :: < trans_fn_attrs , _ > ( tcx, enc, qri) ?;
224232 }
225233
234+ // encode successful constant evaluations
235+ let constants_index = {
236+ let mut constants_index = EncodedConstantsIndex :: new ( ) ;
237+ use ty:: maps:: queries:: const_eval;
238+ use ty:: maps:: plumbing:: GetCacheInternal ;
239+ use ty:: maps:: config:: QueryDescription ;
240+ for ( key, entry) in const_eval:: get_cache_internal ( tcx) . map . iter ( ) {
241+ if let Ok ( ref constant) = entry. value {
242+ if const_eval:: cache_on_disk ( key. clone ( ) ) {
243+ trace ! ( "caching constant {:?} with value {:#?}" , key, constant) ;
244+ let dep_node = SerializedDepNodeIndex :: new ( entry. index . index ( ) ) ;
245+
246+ // Record position of the cache entry
247+ constants_index. push ( (
248+ dep_node,
249+ AbsoluteBytePos :: new ( encoder. position ( ) ) ,
250+ ) ) ;
251+ let did = key. value . instance . def_id ( ) ;
252+ let constant = if key. value . promoted . is_none ( )
253+ && tcx. is_static ( did) . is_some ( ) {
254+ // memorize the allocation for the static, too, so
255+ // we can refer to the static, not just read its value
256+ // since we have had a successful query, the cached value must
257+ // exist, so we can unwrap it
258+ let cached = tcx. interpret_interner . get_cached ( did) . unwrap ( ) ;
259+ ( constant, Some ( cached) )
260+ } else {
261+ ( constant, None )
262+ } ;
263+
264+ // Encode the type check tables with the SerializedDepNodeIndex
265+ // as tag.
266+ encoder. encode_tagged ( dep_node, & constant) ?;
267+ }
268+ }
269+ }
270+ constants_index
271+ } ;
272+
226273 // Encode diagnostics
227274 let diagnostics_index = {
228275 let mut diagnostics_index = EncodedDiagnosticsIndex :: new ( ) ;
@@ -256,6 +303,7 @@ impl<'sess> OnDiskCache<'sess> {
256303 prev_cnums,
257304 query_result_index,
258305 diagnostics_index,
306+ constants_index,
259307 } ) ?;
260308
261309 // Encode the position of the footer as the last 8 bytes of the
@@ -278,6 +326,25 @@ impl<'sess> OnDiskCache<'sess> {
278326 } )
279327 }
280328
329+ /// Load a constant emitted during the previous compilation session.
330+ pub fn load_constant < ' a , ' tcx > ( & self ,
331+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
332+ dep_node_index : SerializedDepNodeIndex )
333+ -> Option < & ' tcx ty:: Const < ' tcx > > {
334+ type Encoded < ' tcx > = ( ty:: Const < ' tcx > , Option < interpret:: AllocId > ) ;
335+ let constant: Option < Encoded < ' tcx > > = self . load_indexed (
336+ tcx,
337+ dep_node_index,
338+ & self . prev_constants_index ,
339+ "constants" ) ;
340+
341+ constant. map ( |( c, _alloc_id) | {
342+ // the AllocId decoding already registers the AllocId to its DefId
343+ // so we don't need to take additional actions here
344+ tcx. mk_const ( c)
345+ } )
346+ }
347+
281348 /// Load a diagnostic emitted during the previous compilation session.
282349 pub fn load_diagnostics < ' a , ' tcx > ( & self ,
283350 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
@@ -563,6 +630,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<interpret::AllocId> for CacheDecoder<'a, '
563630 tcx. interpret_interner . intern_at_reserved ( alloc_id, allocation) ;
564631
565632 if let Some ( glob) = Option :: < DefId > :: decode ( self ) ? {
633+ trace ! ( "connecting alloc {:?} with {:?}" , alloc_id, glob) ;
566634 tcx. interpret_interner . cache ( glob, alloc_id) ;
567635 }
568636
0 commit comments