@@ -83,14 +83,16 @@ pub struct OnDiskCache<'sess> {
8383 // `ExpnData` (e.g `ExpnData.krate` may not be `LOCAL_CRATE`). Alternatively,
8484 // we could look up the `ExpnData` from the metadata of foreign crates,
8585 // but it seemed easier to have `OnDiskCache` be independent of the `CStore`.
86- expn_data : FxHashMap < u32 , AbsoluteBytePos > ,
86+ expn_data : UnhashMap < ExpnHash , AbsoluteBytePos > ,
8787 // Additional information used when decoding hygiene data.
8888 hygiene_context : HygieneDecodeContext ,
8989 // Maps `DefPathHash`es to their `RawDefId`s from the *previous*
9090 // compilation session. This is used as an initial 'guess' when
9191 // we try to map a `DefPathHash` to its `DefId` in the current compilation
9292 // session.
9393 foreign_def_path_hashes : UnhashMap < DefPathHash , RawDefId > ,
94+ // Likewise for ExpnId.
95+ foreign_expn_data : UnhashMap < ExpnHash , u32 > ,
9496
9597 // The *next* compilation sessison's `foreign_def_path_hashes` - at
9698 // the end of our current compilation session, this will get written
@@ -118,8 +120,9 @@ struct Footer {
118120 // See `OnDiskCache.syntax_contexts`
119121 syntax_contexts : FxHashMap < u32 , AbsoluteBytePos > ,
120122 // See `OnDiskCache.expn_data`
121- expn_data : FxHashMap < u32 , AbsoluteBytePos > ,
123+ expn_data : UnhashMap < ExpnHash , AbsoluteBytePos > ,
122124 foreign_def_path_hashes : UnhashMap < DefPathHash , RawDefId > ,
125+ foreign_expn_data : UnhashMap < ExpnHash , u32 > ,
123126}
124127
125128pub type EncodedQueryResultIndex = Vec < ( SerializedDepNodeIndex , AbsoluteBytePos ) > ;
@@ -217,6 +220,7 @@ impl<'sess> OnDiskCache<'sess> {
217220 alloc_decoding_state : AllocDecodingState :: new ( footer. interpret_alloc_index ) ,
218221 syntax_contexts : footer. syntax_contexts ,
219222 expn_data : footer. expn_data ,
223+ foreign_expn_data : footer. foreign_expn_data ,
220224 hygiene_context : Default :: default ( ) ,
221225 foreign_def_path_hashes : footer. foreign_def_path_hashes ,
222226 latest_foreign_def_path_hashes : Default :: default ( ) ,
@@ -236,7 +240,8 @@ impl<'sess> OnDiskCache<'sess> {
236240 prev_diagnostics_index : Default :: default ( ) ,
237241 alloc_decoding_state : AllocDecodingState :: new ( Vec :: new ( ) ) ,
238242 syntax_contexts : FxHashMap :: default ( ) ,
239- expn_data : FxHashMap :: default ( ) ,
243+ expn_data : UnhashMap :: default ( ) ,
244+ foreign_expn_data : UnhashMap :: default ( ) ,
240245 hygiene_context : Default :: default ( ) ,
241246 foreign_def_path_hashes : Default :: default ( ) ,
242247 latest_foreign_def_path_hashes : Default :: default ( ) ,
@@ -350,7 +355,8 @@ impl<'sess> OnDiskCache<'sess> {
350355 } ;
351356
352357 let mut syntax_contexts = FxHashMap :: default ( ) ;
353- let mut expn_ids = FxHashMap :: default ( ) ;
358+ let mut expn_data = UnhashMap :: default ( ) ;
359+ let mut foreign_expn_data = UnhashMap :: default ( ) ;
354360
355361 // Encode all hygiene data (`SyntaxContextData` and `ExpnData`) from the current
356362 // session.
@@ -363,13 +369,14 @@ impl<'sess> OnDiskCache<'sess> {
363369 syntax_contexts. insert ( index, pos) ;
364370 Ok ( ( ) )
365371 } ,
366- |encoder, index , expn_data , hash| -> FileEncodeResult {
367- if index . krate == LOCAL_CRATE {
372+ |encoder, expn_id , data , hash| -> FileEncodeResult {
373+ if expn_id . krate == LOCAL_CRATE {
368374 let pos = AbsoluteBytePos :: new ( encoder. position ( ) ) ;
369- encoder. encode_tagged ( TAG_EXPN_DATA , & ( expn_data, hash) ) ?;
370- expn_ids. insert ( index. local_id . as_u32 ( ) , pos) ;
375+ encoder. encode_tagged ( TAG_EXPN_DATA , & data) ?;
376+ expn_data. insert ( hash, pos) ;
377+ } else {
378+ foreign_expn_data. insert ( hash, expn_id. local_id . as_u32 ( ) ) ;
371379 }
372- // TODO Handle foreign expansions.
373380 Ok ( ( ) )
374381 } ,
375382 ) ?;
@@ -387,7 +394,8 @@ impl<'sess> OnDiskCache<'sess> {
387394 diagnostics_index,
388395 interpret_alloc_index,
389396 syntax_contexts,
390- expn_data : expn_ids,
397+ expn_data,
398+ foreign_expn_data,
391399 foreign_def_path_hashes,
392400 } ,
393401 ) ?;
@@ -549,6 +557,7 @@ impl<'sess> OnDiskCache<'sess> {
549557 alloc_decoding_session : self . alloc_decoding_state . new_decoding_session ( ) ,
550558 syntax_contexts : & self . syntax_contexts ,
551559 expn_data : & self . expn_data ,
560+ foreign_expn_data : & self . foreign_expn_data ,
552561 hygiene_context : & self . hygiene_context ,
553562 } ;
554563 f ( & mut decoder)
@@ -643,7 +652,8 @@ pub struct CacheDecoder<'a, 'tcx> {
643652 file_index_to_stable_id : & ' a FxHashMap < SourceFileIndex , EncodedSourceFileId > ,
644653 alloc_decoding_session : AllocDecodingSession < ' a > ,
645654 syntax_contexts : & ' a FxHashMap < u32 , AbsoluteBytePos > ,
646- expn_data : & ' a FxHashMap < u32 , AbsoluteBytePos > ,
655+ expn_data : & ' a UnhashMap < ExpnHash , AbsoluteBytePos > ,
656+ foreign_expn_data : & ' a UnhashMap < ExpnHash , u32 > ,
647657 hygiene_context : & ' a HygieneDecodeContext ,
648658}
649659
@@ -794,27 +804,43 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
794804
795805impl < ' a , ' tcx > Decodable < CacheDecoder < ' a , ' tcx > > for ExpnId {
796806 fn decode ( decoder : & mut CacheDecoder < ' a , ' tcx > ) -> Result < Self , String > {
797- let krate = CrateNum :: decode ( decoder) ?;
798- let index = u32:: decode ( decoder) ?;
799-
800- let expn_data = decoder. expn_data ;
801- let tcx = decoder. tcx ;
802- rustc_span:: hygiene:: decode_expn_id_incrcomp (
803- krate,
804- index,
805- decoder. hygiene_context ,
806- |index| -> Result < ( ExpnData , ExpnHash ) , _ > {
807- // This closure is invoked if we haven't already decoded the data for the `ExpnId` we are deserializing.
808- // We look up the position of the associated `ExpnData` and decode it.
809- let pos = expn_data
810- . get ( & index)
811- . unwrap_or_else ( || panic ! ( "Bad index {:?} (map {:?})" , index, expn_data) ) ;
812-
813- decoder
814- . with_position ( pos. to_usize ( ) , |decoder| decode_tagged ( decoder, TAG_EXPN_DATA ) )
815- } ,
816- |expn_id| tcx. untracked_resolutions . cstore . decode_expn_data ( tcx. sess , expn_id) ,
817- )
807+ let hash = ExpnHash :: decode ( decoder) ?;
808+ if hash. is_root ( ) {
809+ return Ok ( ExpnId :: root ( ) ) ;
810+ }
811+
812+ if let Some ( expn_id) = ExpnId :: from_hash ( hash) {
813+ return Ok ( expn_id) ;
814+ }
815+
816+ let krate = decoder. cnum_map [ & hash. stable_crate_id ( ) ] ;
817+
818+ let expn_id = if krate == LOCAL_CRATE {
819+ // We look up the position of the associated `ExpnData` and decode it.
820+ let pos = decoder
821+ . expn_data
822+ . get ( & hash)
823+ . unwrap_or_else ( || panic ! ( "Bad hash {:?} (map {:?})" , hash, decoder. expn_data) ) ;
824+
825+ let data: ExpnData = decoder
826+ . with_position ( pos. to_usize ( ) , |decoder| decode_tagged ( decoder, TAG_EXPN_DATA ) ) ?;
827+ rustc_span:: hygiene:: register_local_expn_id ( data, hash)
828+ } else {
829+ let index_guess = decoder. foreign_expn_data [ & hash] ;
830+ decoder. tcx . untracked_resolutions . cstore . expn_hash_to_expn_id ( krate, index_guess, hash)
831+ } ;
832+
833+ #[ cfg( debug_assertions) ]
834+ {
835+ use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
836+ let mut hcx = decoder. tcx . create_stable_hashing_context ( ) ;
837+ let mut hasher = StableHasher :: new ( ) ;
838+ expn_id. expn_data ( ) . hash_stable ( & mut hcx, & mut hasher) ;
839+ let local_hash: u64 = hasher. finish ( ) ;
840+ debug_assert_eq ! ( hash. local_hash( ) , local_hash) ;
841+ }
842+
843+ Ok ( expn_id)
818844 }
819845}
820846
@@ -990,8 +1016,7 @@ where
9901016{
9911017 fn encode ( & self , s : & mut CacheEncoder < ' a , ' tcx , E > ) -> Result < ( ) , E :: Error > {
9921018 s. hygiene_context . schedule_expn_data_for_encoding ( * self ) ;
993- self . krate . encode ( s) ?;
994- self . local_id . as_u32 ( ) . encode ( s)
1019+ self . expn_hash ( ) . encode ( s)
9951020 }
9961021}
9971022
0 commit comments