@@ -9,7 +9,7 @@ use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, OnceCell};
99use rustc_data_structures:: thin_vec:: ThinVec ;
1010use rustc_data_structures:: unhash:: UnhashMap ;
1111use rustc_errors:: Diagnostic ;
12- use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , LOCAL_CRATE } ;
12+ use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , StableCrateId , LOCAL_CRATE } ;
1313use rustc_hir:: definitions:: DefPathHash ;
1414use rustc_index:: vec:: { Idx , IndexVec } ;
1515use rustc_query_system:: dep_graph:: DepContext ;
@@ -18,7 +18,7 @@ use rustc_serialize::{
1818 opaque:: { self , FileEncodeResult , FileEncoder , IntEncodedWithFixedSize } ,
1919 Decodable , Decoder , Encodable , Encoder ,
2020} ;
21- use rustc_session:: { CrateDisambiguator , Session } ;
21+ use rustc_session:: Session ;
2222use rustc_span:: hygiene:: {
2323 ExpnDataDecodeMode , ExpnDataEncodeMode , ExpnId , HygieneDecodeContext , HygieneEncodeContext ,
2424 SyntaxContext , SyntaxContextData ,
@@ -51,11 +51,10 @@ pub struct OnDiskCache<'sess> {
5151 // session.
5252 current_diagnostics : Lock < FxHashMap < DepNodeIndex , Vec < Diagnostic > > > ,
5353
54- prev_cnums : Vec < ( u32 , String , CrateDisambiguator ) > ,
55- cnum_map : OnceCell < IndexVec < CrateNum , Option < CrateNum > > > ,
54+ cnum_map : OnceCell < UnhashMap < StableCrateId , CrateNum > > ,
5655
5756 source_map : & ' sess SourceMap ,
58- file_index_to_stable_id : FxHashMap < SourceFileIndex , StableSourceFileId > ,
57+ file_index_to_stable_id : FxHashMap < SourceFileIndex , EncodedSourceFileId > ,
5958
6059 // Caches that are populated lazily during decoding.
6160 file_index_to_file : Lock < FxHashMap < SourceFileIndex , Lrc < SourceFile > > > ,
@@ -112,8 +111,7 @@ pub struct OnDiskCache<'sess> {
112111// This type is used only for serialization and deserialization.
113112#[ derive( Encodable , Decodable ) ]
114113struct Footer {
115- file_index_to_stable_id : FxHashMap < SourceFileIndex , StableSourceFileId > ,
116- prev_cnums : Vec < ( u32 , String , CrateDisambiguator ) > ,
114+ file_index_to_stable_id : FxHashMap < SourceFileIndex , EncodedSourceFileId > ,
117115 query_result_index : EncodedQueryResultIndex ,
118116 diagnostics_index : EncodedQueryResultIndex ,
119117 // The location of all allocations.
@@ -159,6 +157,32 @@ crate struct RawDefId {
159157 pub index : u32 ,
160158}
161159
160+ /// An `EncodedSourceFileId` is the same as a `StableSourceFileId` except that
161+ /// the source crate is represented as a [StableCrateId] instead of as a
162+ /// `CrateNum`. This way `EncodedSourceFileId` can be encoded and decoded
163+ /// without any additional context, i.e. with a simple `opaque::Decoder` (which
164+ /// is the only thing available when decoding the cache's [Footer].
165+ #[ derive( Encodable , Decodable , Clone , Debug ) ]
166+ struct EncodedSourceFileId {
167+ file_name_hash : u64 ,
168+ stable_crate_id : StableCrateId ,
169+ }
170+
171+ impl EncodedSourceFileId {
172+ fn translate ( & self , cnum_map : & UnhashMap < StableCrateId , CrateNum > ) -> StableSourceFileId {
173+ let cnum = cnum_map[ & self . stable_crate_id ] ;
174+ StableSourceFileId { file_name_hash : self . file_name_hash , cnum }
175+ }
176+
177+ fn new ( tcx : TyCtxt < ' _ > , file : & SourceFile ) -> EncodedSourceFileId {
178+ let source_file_id = StableSourceFileId :: new ( file) ;
179+ EncodedSourceFileId {
180+ file_name_hash : source_file_id. file_name_hash ,
181+ stable_crate_id : tcx. stable_crate_id ( source_file_id. cnum ) ,
182+ }
183+ }
184+ }
185+
162186impl < ' sess > OnDiskCache < ' sess > {
163187 /// Creates a new `OnDiskCache` instance from the serialized data in `data`.
164188 pub fn new ( sess : & ' sess Session , data : Vec < u8 > , start_pos : usize ) -> Self {
@@ -186,7 +210,6 @@ impl<'sess> OnDiskCache<'sess> {
186210 serialized_data : data,
187211 file_index_to_stable_id : footer. file_index_to_stable_id ,
188212 file_index_to_file : Default :: default ( ) ,
189- prev_cnums : footer. prev_cnums ,
190213 cnum_map : OnceCell :: new ( ) ,
191214 source_map : sess. source_map ( ) ,
192215 current_diagnostics : Default :: default ( ) ,
@@ -207,7 +230,6 @@ impl<'sess> OnDiskCache<'sess> {
207230 serialized_data : Vec :: new ( ) ,
208231 file_index_to_stable_id : Default :: default ( ) ,
209232 file_index_to_file : Default :: default ( ) ,
210- prev_cnums : vec ! [ ] ,
211233 cnum_map : OnceCell :: new ( ) ,
212234 source_map,
213235 current_diagnostics : Default :: default ( ) ,
@@ -242,7 +264,8 @@ impl<'sess> OnDiskCache<'sess> {
242264 let index = SourceFileIndex ( index as u32 ) ;
243265 let file_ptr: * const SourceFile = & * * file as * const _ ;
244266 file_to_file_index. insert ( file_ptr, index) ;
245- file_index_to_stable_id. insert ( index, StableSourceFileId :: new ( & file) ) ;
267+ let source_file_id = EncodedSourceFileId :: new ( tcx, & file) ;
268+ file_index_to_stable_id. insert ( index, source_file_id) ;
246269 }
247270
248271 ( file_to_file_index, file_index_to_stable_id)
@@ -327,16 +350,6 @@ impl<'sess> OnDiskCache<'sess> {
327350 interpret_alloc_index
328351 } ;
329352
330- let sorted_cnums = sorted_cnums_including_local_crate ( tcx) ;
331- let prev_cnums: Vec < _ > = sorted_cnums
332- . iter ( )
333- . map ( |& cnum| {
334- let crate_name = tcx. crate_name ( cnum) . to_string ( ) ;
335- let crate_disambiguator = tcx. crate_disambiguator ( cnum) ;
336- ( cnum. as_u32 ( ) , crate_name, crate_disambiguator)
337- } )
338- . collect ( ) ;
339-
340353 let mut syntax_contexts = FxHashMap :: default ( ) ;
341354 let mut expn_ids = FxHashMap :: default ( ) ;
342355
@@ -368,7 +381,6 @@ impl<'sess> OnDiskCache<'sess> {
368381 TAG_FILE_FOOTER ,
369382 & Footer {
370383 file_index_to_stable_id,
371- prev_cnums,
372384 query_result_index,
373385 diagnostics_index,
374386 interpret_alloc_index,
@@ -385,16 +397,7 @@ impl<'sess> OnDiskCache<'sess> {
385397 // DO NOT WRITE ANYTHING TO THE ENCODER AFTER THIS POINT! The address
386398 // of the footer must be the last thing in the data stream.
387399
388- return Ok ( ( ) ) ;
389-
390- fn sorted_cnums_including_local_crate ( tcx : TyCtxt < ' _ > ) -> Vec < CrateNum > {
391- let mut cnums = vec ! [ LOCAL_CRATE ] ;
392- cnums. extend_from_slice ( tcx. crates ( ) ) ;
393- cnums. sort_unstable ( ) ;
394- // Just to be sure...
395- cnums. dedup ( ) ;
396- cnums
397- }
400+ Ok ( ( ) )
398401 } )
399402 }
400403
@@ -429,12 +432,11 @@ impl<'sess> OnDiskCache<'sess> {
429432 self . foreign_def_path_hashes . get ( hash) . copied ( )
430433 }
431434
432- fn try_remap_cnum ( & self , tcx : TyCtxt < ' _ > , cnum : u32 ) -> Option < CrateNum > {
433- let cnum_map =
434- self . cnum_map . get_or_init ( || Self :: compute_cnum_map ( tcx, & self . prev_cnums [ ..] ) ) ;
435- debug ! ( "try_remap_cnum({}): cnum_map={:?}" , cnum, cnum_map) ;
435+ fn try_remap_cnum ( & self , tcx : TyCtxt < ' _ > , stable_crate_id : StableCrateId ) -> Option < CrateNum > {
436+ let cnum_map = self . cnum_map . get_or_init ( || Self :: compute_cnum_map ( tcx) ) ;
437+ debug ! ( "try_remap_cnum({:?}): cnum_map={:?}" , stable_crate_id, cnum_map) ;
436438
437- cnum_map[ CrateNum :: from_u32 ( cnum ) ]
439+ cnum_map. get ( & stable_crate_id ) . copied ( )
438440 }
439441
440442 pub ( crate ) fn store_foreign_def_id_hash ( & self , def_id : DefId , hash : DefPathHash ) {
@@ -533,8 +535,7 @@ impl<'sess> OnDiskCache<'sess> {
533535 where
534536 T : Decodable < CacheDecoder < ' a , ' tcx > > ,
535537 {
536- let cnum_map =
537- self . cnum_map . get_or_init ( || Self :: compute_cnum_map ( tcx, & self . prev_cnums [ ..] ) ) ;
538+ let cnum_map = self . cnum_map . get_or_init ( || Self :: compute_cnum_map ( tcx) ) ;
538539
539540 let mut decoder = CacheDecoder {
540541 tcx,
@@ -555,31 +556,16 @@ impl<'sess> OnDiskCache<'sess> {
555556 // current-session-`CrateNum`. There might be `CrateNum`s from the previous
556557 // `Session` that don't occur in the current one. For these, the mapping
557558 // maps to None.
558- fn compute_cnum_map (
559- tcx : TyCtxt < ' _ > ,
560- prev_cnums : & [ ( u32 , String , CrateDisambiguator ) ] ,
561- ) -> IndexVec < CrateNum , Option < CrateNum > > {
559+ fn compute_cnum_map ( tcx : TyCtxt < ' _ > ) -> UnhashMap < StableCrateId , CrateNum > {
562560 tcx. dep_graph . with_ignore ( || {
563- let current_cnums = tcx
564- . all_crate_nums ( ( ) )
561+ tcx. all_crate_nums ( ( ) )
565562 . iter ( )
563+ . chain ( std:: iter:: once ( & LOCAL_CRATE ) )
566564 . map ( |& cnum| {
567- let crate_name = tcx. crate_name ( cnum) . to_string ( ) ;
568- let crate_disambiguator = tcx. crate_disambiguator ( cnum) ;
569- ( ( crate_name, crate_disambiguator) , cnum)
565+ let hash = tcx. def_path_hash ( cnum. as_def_id ( ) ) . stable_crate_id ( ) ;
566+ ( hash, cnum)
570567 } )
571- . collect :: < FxHashMap < _ , _ > > ( ) ;
572-
573- let map_size = prev_cnums. iter ( ) . map ( |& ( cnum, ..) | cnum) . max ( ) . unwrap_or ( 0 ) + 1 ;
574- let mut map = IndexVec :: from_elem_n ( None , map_size as usize ) ;
575-
576- for & ( prev_cnum, ref crate_name, crate_disambiguator) in prev_cnums {
577- let key = ( crate_name. clone ( ) , crate_disambiguator) ;
578- map[ CrateNum :: from_u32 ( prev_cnum) ] = current_cnums. get ( & key) . cloned ( ) ;
579- }
580-
581- map[ LOCAL_CRATE ] = Some ( LOCAL_CRATE ) ;
582- map
568+ . collect ( )
583569 } )
584570 }
585571
@@ -612,7 +598,7 @@ impl<'sess> OnDiskCache<'sess> {
612598 debug ! ( "def_path_hash_to_def_id({:?}): raw_def_id = {:?}" , hash, raw_def_id) ;
613599 // If the owning crate no longer exists, the corresponding definition definitely
614600 // no longer exists.
615- let krate = self . try_remap_cnum ( tcx, raw_def_id . krate ) ?;
601+ let krate = self . try_remap_cnum ( tcx, hash . stable_crate_id ( ) ) ?;
616602 debug ! ( "def_path_hash_to_def_id({:?}): krate = {:?}" , hash, krate) ;
617603 // If our `DefPathHash` corresponded to a definition in the local crate,
618604 // we should have either found it in `local_def_path_hash_to_def_id`, or
@@ -644,9 +630,9 @@ pub struct CacheDecoder<'a, 'tcx> {
644630 tcx : TyCtxt < ' tcx > ,
645631 opaque : opaque:: Decoder < ' a > ,
646632 source_map : & ' a SourceMap ,
647- cnum_map : & ' a IndexVec < CrateNum , Option < CrateNum > > ,
633+ cnum_map : & ' a UnhashMap < StableCrateId , CrateNum > ,
648634 file_index_to_file : & ' a Lock < FxHashMap < SourceFileIndex , Lrc < SourceFile > > > ,
649- file_index_to_stable_id : & ' a FxHashMap < SourceFileIndex , StableSourceFileId > ,
635+ file_index_to_stable_id : & ' a FxHashMap < SourceFileIndex , EncodedSourceFileId > ,
650636 alloc_decoding_session : AllocDecodingSession < ' a > ,
651637 syntax_contexts : & ' a FxHashMap < u32 , AbsoluteBytePos > ,
652638 expn_data : & ' a FxHashMap < u32 , AbsoluteBytePos > ,
@@ -659,14 +645,15 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
659645 ref file_index_to_file,
660646 ref file_index_to_stable_id,
661647 ref source_map,
648+ ref cnum_map,
662649 ..
663650 } = * self ;
664651
665652 file_index_to_file
666653 . borrow_mut ( )
667654 . entry ( index)
668655 . or_insert_with ( || {
669- let stable_id = file_index_to_stable_id[ & index] ;
656+ let stable_id = file_index_to_stable_id[ & index] . translate ( cnum_map ) ;
670657 source_map
671658 . source_file_by_stable_id ( stable_id)
672659 . expect ( "failed to lookup `SourceFile` in new context" )
@@ -765,10 +752,6 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
765752 r
766753 }
767754
768- fn map_encoded_cnum_to_current ( & self , cnum : CrateNum ) -> CrateNum {
769- self . cnum_map [ cnum] . unwrap_or_else ( || bug ! ( "could not find new `CrateNum` for {:?}" , cnum) )
770- }
771-
772755 fn decode_alloc_id ( & mut self ) -> Result < interpret:: AllocId , Self :: Error > {
773756 let alloc_decoding_session = self . alloc_decoding_session ;
774757 alloc_decoding_session. decode_alloc_id ( self )
@@ -850,8 +833,9 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
850833
851834impl < ' a , ' tcx > Decodable < CacheDecoder < ' a , ' tcx > > for CrateNum {
852835 fn decode ( d : & mut CacheDecoder < ' a , ' tcx > ) -> Result < Self , String > {
853- let cnum = CrateNum :: from_u32 ( u32:: decode ( d) ?) ;
854- Ok ( d. map_encoded_cnum_to_current ( cnum) )
836+ let stable_id = StableCrateId :: decode ( d) ?;
837+ let cnum = d. cnum_map [ & stable_id] ;
838+ Ok ( cnum)
855839 }
856840}
857841
@@ -1061,6 +1045,15 @@ where
10611045 }
10621046}
10631047
1048+ impl < ' a , ' tcx , E > Encodable < CacheEncoder < ' a , ' tcx , E > > for CrateNum
1049+ where
1050+ E : ' a + OpaqueEncoder ,
1051+ {
1052+ fn encode ( & self , s : & mut CacheEncoder < ' a , ' tcx , E > ) -> Result < ( ) , E :: Error > {
1053+ s. tcx . stable_crate_id ( * self ) . encode ( s)
1054+ }
1055+ }
1056+
10641057impl < ' a , ' tcx , E > Encodable < CacheEncoder < ' a , ' tcx , E > > for DefId
10651058where
10661059 E : ' a + OpaqueEncoder ,
0 commit comments