99// except according to those terms.
1010
1111use dep_graph:: { DepNodeIndex , SerializedDepNodeIndex } ;
12- use rustc_data_structures:: fx:: FxHashMap ;
13- use rustc_data_structures:: indexed_vec:: Idx ;
1412use errors:: Diagnostic ;
13+ use hir;
14+ use hir:: def_id:: { CrateNum , DefIndex , DefId , RESERVED_FOR_INCR_COMP_CACHE ,
15+ LOCAL_CRATE } ;
16+ use hir:: map:: definitions:: { Definitions , DefPathTable } ;
17+ use middle:: const_val:: ByteArray ;
18+ use rustc_data_structures:: fx:: FxHashMap ;
19+ use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
1520use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder , opaque,
16- SpecializedDecoder , SpecializedEncoder } ;
21+ SpecializedDecoder , SpecializedEncoder ,
22+ UseSpecializedDecodable } ;
1723use session:: Session ;
1824use std:: borrow:: Cow ;
1925use std:: cell:: RefCell ;
2026use std:: collections:: BTreeMap ;
2127use std:: mem;
28+ use syntax:: ast:: NodeId ;
2229use syntax:: codemap:: { CodeMap , StableFilemapId } ;
2330use syntax_pos:: { BytePos , Span , NO_EXPANSION , DUMMY_SP } ;
2431use ty;
25- use ty:: codec:: { self as ty_codec} ;
32+ use ty:: codec:: { self as ty_codec, TyDecoder } ;
2633use ty:: context:: TyCtxt ;
34+ use ty:: subst:: Substs ;
2735
2836/// `OnDiskCache` provides an interface to incr. comp. data cached from the
2937/// previous compilation session. This data will eventually include the results
@@ -65,9 +73,12 @@ impl<'sess> OnDiskCache<'sess> {
6573
6674 let prev_diagnostics = {
6775 let mut decoder = CacheDecoder {
76+ tcx : None ,
6877 opaque : decoder,
6978 codemap : sess. codemap ( ) ,
7079 prev_filemap_starts : & header. prev_filemap_starts ,
80+ cnum_map : & IndexVec :: new ( ) ,
81+ prev_def_path_tables : & Vec :: new ( ) ,
7182 } ;
7283
7384 let prev_diagnostics: FxHashMap < _ , _ > = {
@@ -110,6 +121,7 @@ impl<'sess> OnDiskCache<'sess> {
110121 encoder,
111122 type_shorthands : FxHashMap ( ) ,
112123 predicate_shorthands : FxHashMap ( ) ,
124+ definitions : tcx. hir . definitions ( ) ,
113125 } ;
114126
115127 let prev_filemap_starts: BTreeMap < _ , _ > = self
@@ -174,13 +186,16 @@ impl<'sess> OnDiskCache<'sess> {
174186/// A decoder that can read the incr. comp. cache. It is similar to the one
175187/// we use for crate metadata decoding in that it can rebase spans and
176188/// eventually will also handle things that contain `Ty` instances.
177- struct CacheDecoder < ' a > {
178- opaque : opaque:: Decoder < ' a > ,
179- codemap : & ' a CodeMap ,
180- prev_filemap_starts : & ' a BTreeMap < BytePos , StableFilemapId > ,
189+ struct CacheDecoder < ' a , ' tcx : ' a , ' x > {
190+ tcx : Option < TyCtxt < ' a , ' tcx , ' tcx > > ,
191+ opaque : opaque:: Decoder < ' x > ,
192+ codemap : & ' x CodeMap ,
193+ prev_filemap_starts : & ' x BTreeMap < BytePos , StableFilemapId > ,
194+ cnum_map : & ' x IndexVec < CrateNum , Option < CrateNum > > ,
195+ prev_def_path_tables : & ' x Vec < DefPathTable > ,
181196}
182197
183- impl < ' a > CacheDecoder < ' a > {
198+ impl < ' a , ' tcx , ' x > CacheDecoder < ' a , ' tcx , ' x > {
184199 fn find_filemap_prev_bytepos ( & self ,
185200 prev_bytepos : BytePos )
186201 -> Option < ( BytePos , StableFilemapId ) > {
@@ -200,7 +215,7 @@ macro_rules! decoder_methods {
200215 }
201216}
202217
203- impl < ' sess > Decoder for CacheDecoder < ' sess > {
218+ impl < ' a , ' tcx , ' x > Decoder for CacheDecoder < ' a , ' tcx , ' x > {
204219 type Error = String ;
205220
206221 decoder_methods ! {
@@ -232,7 +247,65 @@ impl<'sess> Decoder for CacheDecoder<'sess> {
232247 }
233248}
234249
235- impl < ' a > SpecializedDecoder < Span > for CacheDecoder < ' a > {
250+ impl < ' a , ' tcx : ' a , ' x > ty_codec:: TyDecoder < ' a , ' tcx > for CacheDecoder < ' a , ' tcx , ' x > {
251+
252+ #[ inline]
253+ fn tcx ( & self ) -> TyCtxt < ' a , ' tcx , ' tcx > {
254+ self . tcx . expect ( "missing TyCtxt in CacheDecoder" )
255+ }
256+
257+ #[ inline]
258+ fn position ( & self ) -> usize {
259+ self . opaque . position ( )
260+ }
261+
262+ #[ inline]
263+ fn peek_byte ( & self ) -> u8 {
264+ self . opaque . data [ self . opaque . position ( ) ]
265+ }
266+
267+ fn cached_ty_for_shorthand < F > ( & mut self ,
268+ shorthand : usize ,
269+ or_insert_with : F )
270+ -> Result < ty:: Ty < ' tcx > , Self :: Error >
271+ where F : FnOnce ( & mut Self ) -> Result < ty:: Ty < ' tcx > , Self :: Error >
272+ {
273+ let tcx = self . tcx ( ) ;
274+
275+ let cache_key = ty:: CReaderCacheKey {
276+ cnum : RESERVED_FOR_INCR_COMP_CACHE ,
277+ pos : shorthand,
278+ } ;
279+
280+ if let Some ( & ty) = tcx. rcache . borrow ( ) . get ( & cache_key) {
281+ return Ok ( ty) ;
282+ }
283+
284+ let ty = or_insert_with ( self ) ?;
285+ tcx. rcache . borrow_mut ( ) . insert ( cache_key, ty) ;
286+ Ok ( ty)
287+ }
288+
289+ fn with_position < F , R > ( & mut self , pos : usize , f : F ) -> R
290+ where F : FnOnce ( & mut Self ) -> R
291+ {
292+ debug_assert ! ( pos < self . opaque. data. len( ) ) ;
293+
294+ let new_opaque = opaque:: Decoder :: new ( self . opaque . data , pos) ;
295+ let old_opaque = mem:: replace ( & mut self . opaque , new_opaque) ;
296+ let r = f ( self ) ;
297+ self . opaque = old_opaque;
298+ r
299+ }
300+
301+ fn map_encoded_cnum_to_current ( & self , cnum : CrateNum ) -> CrateNum {
302+ self . cnum_map [ cnum] . unwrap_or_else ( || {
303+ bug ! ( "Could not find new CrateNum for {:?}" , cnum)
304+ } )
305+ }
306+ }
307+
308+ impl < ' a , ' tcx , ' x > SpecializedDecoder < Span > for CacheDecoder < ' a , ' tcx , ' x > {
236309 fn specialized_decode ( & mut self ) -> Result < Span , Self :: Error > {
237310 let lo = BytePos :: decode ( self ) ?;
238311 let hi = BytePos :: decode ( self ) ?;
@@ -249,6 +322,142 @@ impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> {
249322 }
250323}
251324
325+ impl < ' a , ' tcx , ' x > SpecializedDecoder < CrateNum > for CacheDecoder < ' a , ' tcx , ' x > {
326+ fn specialized_decode ( & mut self ) -> Result < CrateNum , Self :: Error > {
327+ let cnum = CrateNum :: from_u32 ( u32:: decode ( self ) ?) ;
328+ let mapped = self . map_encoded_cnum_to_current ( cnum) ;
329+ Ok ( mapped)
330+ }
331+ }
332+
333+ // This impl makes sure that we get a runtime error when we try decode a
334+ // DefIndex that is not contained in a DefId. Such a case would be problematic
335+ // because we would not know how to transform the DefIndex to the current
336+ // context.
337+ impl < ' a , ' tcx , ' x > SpecializedDecoder < DefIndex > for CacheDecoder < ' a , ' tcx , ' x > {
338+ fn specialized_decode ( & mut self ) -> Result < DefIndex , Self :: Error > {
339+ bug ! ( "Trying to decode DefIndex outside the context of a DefId" )
340+ }
341+ }
342+
343+ // Both the CrateNum and the DefIndex of a DefId can change in between two
344+ // compilation sessions. We use the DefPathHash, which is stable across
345+ // sessions, to map the old DefId to the new one.
346+ impl < ' a , ' tcx , ' x > SpecializedDecoder < DefId > for CacheDecoder < ' a , ' tcx , ' x > {
347+ fn specialized_decode ( & mut self ) -> Result < DefId , Self :: Error > {
348+ // Decode the unmapped CrateNum
349+ let prev_cnum = CrateNum :: default_decode ( self ) ?;
350+
351+ // Decode the unmapped DefIndex
352+ let def_index = DefIndex :: default_decode ( self ) ?;
353+
354+ // Unmapped CrateNum and DefIndex are valid keys for the *cached*
355+ // DefPathTables, so we use them to look up the DefPathHash.
356+ let def_path_hash = self . prev_def_path_tables [ prev_cnum. index ( ) ]
357+ . def_path_hash ( def_index) ;
358+
359+ // Using the DefPathHash, we can lookup the new DefId
360+ Ok ( self . tcx ( ) . def_path_hash_to_def_id . as_ref ( ) . unwrap ( ) [ & def_path_hash] )
361+ }
362+ }
363+
364+ impl < ' a , ' tcx , ' x > SpecializedDecoder < hir:: HirId > for CacheDecoder < ' a , ' tcx , ' x > {
365+ fn specialized_decode ( & mut self ) -> Result < hir:: HirId , Self :: Error > {
366+ // Decode the unmapped DefIndex of the HirId.
367+ let def_index = DefIndex :: default_decode ( self ) ?;
368+
369+ // Use the unmapped DefIndex to look up the DefPathHash in the cached
370+ // DefPathTable. For HirIds we know that we always have to look in the
371+ // *local* DefPathTable.
372+ let def_path_hash = self . prev_def_path_tables [ LOCAL_CRATE . index ( ) ]
373+ . def_path_hash ( def_index) ;
374+
375+ // Use the DefPathHash to map to the current DefId.
376+ let def_id = self . tcx ( )
377+ . def_path_hash_to_def_id
378+ . as_ref ( )
379+ . unwrap ( ) [ & def_path_hash] ;
380+
381+ // The ItemLocalId needs no remapping.
382+ let local_id = hir:: ItemLocalId :: decode ( self ) ?;
383+
384+ // Reconstruct the HirId and look up the corresponding NodeId in the
385+ // context of the current session.
386+ Ok ( hir:: HirId {
387+ owner : def_id. index ,
388+ local_id
389+ } )
390+ }
391+ }
392+
393+ // NodeIds are not stable across compilation sessions, so we store them in their
394+ // HirId representation. This allows use to map them to the current NodeId.
395+ impl < ' a , ' tcx , ' x > SpecializedDecoder < NodeId > for CacheDecoder < ' a , ' tcx , ' x > {
396+ fn specialized_decode ( & mut self ) -> Result < NodeId , Self :: Error > {
397+ let hir_id = hir:: HirId :: decode ( self ) ?;
398+ Ok ( self . tcx ( ) . hir . hir_to_node_id ( hir_id) )
399+ }
400+ }
401+
402+ impl < ' a , ' tcx , ' x > SpecializedDecoder < ty:: Ty < ' tcx > > for CacheDecoder < ' a , ' tcx , ' x > {
403+ fn specialized_decode ( & mut self ) -> Result < ty:: Ty < ' tcx > , Self :: Error > {
404+ ty_codec:: decode_ty ( self )
405+ }
406+ }
407+
408+ impl < ' a , ' tcx , ' x > SpecializedDecoder < ty:: GenericPredicates < ' tcx > >
409+ for CacheDecoder < ' a , ' tcx , ' x > {
410+ fn specialized_decode ( & mut self ) -> Result < ty:: GenericPredicates < ' tcx > , Self :: Error > {
411+ ty_codec:: decode_predicates ( self )
412+ }
413+ }
414+
415+ impl < ' a , ' tcx , ' x > SpecializedDecoder < & ' tcx Substs < ' tcx > > for CacheDecoder < ' a , ' tcx , ' x > {
416+ fn specialized_decode ( & mut self ) -> Result < & ' tcx Substs < ' tcx > , Self :: Error > {
417+ ty_codec:: decode_substs ( self )
418+ }
419+ }
420+
421+ impl < ' a , ' tcx , ' x > SpecializedDecoder < ty:: Region < ' tcx > > for CacheDecoder < ' a , ' tcx , ' x > {
422+ fn specialized_decode ( & mut self ) -> Result < ty:: Region < ' tcx > , Self :: Error > {
423+ ty_codec:: decode_region ( self )
424+ }
425+ }
426+
427+ impl < ' a , ' tcx , ' x > SpecializedDecoder < & ' tcx ty:: Slice < ty:: Ty < ' tcx > > >
428+ for CacheDecoder < ' a , ' tcx , ' x > {
429+ fn specialized_decode ( & mut self ) -> Result < & ' tcx ty:: Slice < ty:: Ty < ' tcx > > , Self :: Error > {
430+ ty_codec:: decode_ty_slice ( self )
431+ }
432+ }
433+
434+ impl < ' a , ' tcx , ' x > SpecializedDecoder < & ' tcx ty:: AdtDef > for CacheDecoder < ' a , ' tcx , ' x > {
435+ fn specialized_decode ( & mut self ) -> Result < & ' tcx ty:: AdtDef , Self :: Error > {
436+ ty_codec:: decode_adt_def ( self )
437+ }
438+ }
439+
440+ impl < ' a , ' tcx , ' x > SpecializedDecoder < & ' tcx ty:: Slice < ty:: ExistentialPredicate < ' tcx > > >
441+ for CacheDecoder < ' a , ' tcx , ' x > {
442+ fn specialized_decode ( & mut self )
443+ -> Result < & ' tcx ty:: Slice < ty:: ExistentialPredicate < ' tcx > > , Self :: Error > {
444+ ty_codec:: decode_existential_predicate_slice ( self )
445+ }
446+ }
447+
448+ impl < ' a , ' tcx , ' x > SpecializedDecoder < ByteArray < ' tcx > > for CacheDecoder < ' a , ' tcx , ' x > {
449+ fn specialized_decode ( & mut self ) -> Result < ByteArray < ' tcx > , Self :: Error > {
450+ ty_codec:: decode_byte_array ( self )
451+ }
452+ }
453+
454+ impl < ' a , ' tcx , ' x > SpecializedDecoder < & ' tcx ty:: Const < ' tcx > >
455+ for CacheDecoder < ' a , ' tcx , ' x > {
456+ fn specialized_decode ( & mut self ) -> Result < & ' tcx ty:: Const < ' tcx > , Self :: Error > {
457+ ty_codec:: decode_const ( self )
458+ }
459+ }
460+
252461
253462//- ENCODING -------------------------------------------------------------------
254463
@@ -258,6 +467,7 @@ struct CacheEncoder<'enc, 'tcx, E>
258467 encoder : & ' enc mut E ,
259468 type_shorthands : FxHashMap < ty:: Ty < ' tcx > , usize > ,
260469 predicate_shorthands : FxHashMap < ty:: Predicate < ' tcx > , usize > ,
470+ definitions : & ' enc Definitions ,
261471}
262472
263473impl < ' enc , ' tcx , E > ty_codec:: TyEncoder for CacheEncoder < ' enc , ' tcx , E >
@@ -289,6 +499,17 @@ impl<'enc, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>>
289499 }
290500}
291501
502+ // NodeIds are not stable across compilation sessions, so we store them in their
503+ // HirId representation. This allows use to map them to the current NodeId.
504+ impl < ' enc , ' tcx , E > SpecializedEncoder < NodeId > for CacheEncoder < ' enc , ' tcx , E >
505+ where E : ' enc + ty_codec:: TyEncoder
506+ {
507+ fn specialized_encode ( & mut self , node_id : & NodeId ) -> Result < ( ) , Self :: Error > {
508+ let hir_id = self . definitions . node_to_hir_id ( * node_id) ;
509+ hir_id. encode ( self )
510+ }
511+ }
512+
292513macro_rules! encoder_methods {
293514 ( $( $name: ident( $ty: ty) ; ) * ) => {
294515 $( fn $name( & mut self , value: $ty) -> Result <( ) , Self :: Error > {
0 commit comments