@@ -83,14 +83,16 @@ pub struct OnDiskCache<'sess> {
83
83
// `ExpnData` (e.g `ExpnData.krate` may not be `LOCAL_CRATE`). Alternatively,
84
84
// we could look up the `ExpnData` from the metadata of foreign crates,
85
85
// but it seemed easier to have `OnDiskCache` be independent of the `CStore`.
86
- expn_data : FxHashMap < u32 , AbsoluteBytePos > ,
86
+ expn_data : UnhashMap < ExpnHash , AbsoluteBytePos > ,
87
87
// Additional information used when decoding hygiene data.
88
88
hygiene_context : HygieneDecodeContext ,
89
89
// Maps `DefPathHash`es to their `RawDefId`s from the *previous*
90
90
// compilation session. This is used as an initial 'guess' when
91
91
// we try to map a `DefPathHash` to its `DefId` in the current compilation
92
92
// session.
93
93
foreign_def_path_hashes : UnhashMap < DefPathHash , RawDefId > ,
94
+ // Likewise for ExpnId.
95
+ foreign_expn_data : UnhashMap < ExpnHash , u32 > ,
94
96
95
97
// The *next* compilation sessison's `foreign_def_path_hashes` - at
96
98
// the end of our current compilation session, this will get written
@@ -118,8 +120,9 @@ struct Footer {
118
120
// See `OnDiskCache.syntax_contexts`
119
121
syntax_contexts : FxHashMap < u32 , AbsoluteBytePos > ,
120
122
// See `OnDiskCache.expn_data`
121
- expn_data : FxHashMap < u32 , AbsoluteBytePos > ,
123
+ expn_data : UnhashMap < ExpnHash , AbsoluteBytePos > ,
122
124
foreign_def_path_hashes : UnhashMap < DefPathHash , RawDefId > ,
125
+ foreign_expn_data : UnhashMap < ExpnHash , u32 > ,
123
126
}
124
127
125
128
pub type EncodedQueryResultIndex = Vec < ( SerializedDepNodeIndex , AbsoluteBytePos ) > ;
@@ -217,6 +220,7 @@ impl<'sess> OnDiskCache<'sess> {
217
220
alloc_decoding_state : AllocDecodingState :: new ( footer. interpret_alloc_index ) ,
218
221
syntax_contexts : footer. syntax_contexts ,
219
222
expn_data : footer. expn_data ,
223
+ foreign_expn_data : footer. foreign_expn_data ,
220
224
hygiene_context : Default :: default ( ) ,
221
225
foreign_def_path_hashes : footer. foreign_def_path_hashes ,
222
226
latest_foreign_def_path_hashes : Default :: default ( ) ,
@@ -236,7 +240,8 @@ impl<'sess> OnDiskCache<'sess> {
236
240
prev_diagnostics_index : Default :: default ( ) ,
237
241
alloc_decoding_state : AllocDecodingState :: new ( Vec :: new ( ) ) ,
238
242
syntax_contexts : FxHashMap :: default ( ) ,
239
- expn_data : FxHashMap :: default ( ) ,
243
+ expn_data : UnhashMap :: default ( ) ,
244
+ foreign_expn_data : UnhashMap :: default ( ) ,
240
245
hygiene_context : Default :: default ( ) ,
241
246
foreign_def_path_hashes : Default :: default ( ) ,
242
247
latest_foreign_def_path_hashes : Default :: default ( ) ,
@@ -350,7 +355,8 @@ impl<'sess> OnDiskCache<'sess> {
350
355
} ;
351
356
352
357
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 ( ) ;
354
360
355
361
// Encode all hygiene data (`SyntaxContextData` and `ExpnData`) from the current
356
362
// session.
@@ -363,13 +369,14 @@ impl<'sess> OnDiskCache<'sess> {
363
369
syntax_contexts. insert ( index, pos) ;
364
370
Ok ( ( ) )
365
371
} ,
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 {
368
374
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 ( ) ) ;
371
379
}
372
- // TODO Handle foreign expansions.
373
380
Ok ( ( ) )
374
381
} ,
375
382
) ?;
@@ -387,7 +394,8 @@ impl<'sess> OnDiskCache<'sess> {
387
394
diagnostics_index,
388
395
interpret_alloc_index,
389
396
syntax_contexts,
390
- expn_data : expn_ids,
397
+ expn_data,
398
+ foreign_expn_data,
391
399
foreign_def_path_hashes,
392
400
} ,
393
401
) ?;
@@ -549,6 +557,7 @@ impl<'sess> OnDiskCache<'sess> {
549
557
alloc_decoding_session : self . alloc_decoding_state . new_decoding_session ( ) ,
550
558
syntax_contexts : & self . syntax_contexts ,
551
559
expn_data : & self . expn_data ,
560
+ foreign_expn_data : & self . foreign_expn_data ,
552
561
hygiene_context : & self . hygiene_context ,
553
562
} ;
554
563
f ( & mut decoder)
@@ -643,7 +652,8 @@ pub struct CacheDecoder<'a, 'tcx> {
643
652
file_index_to_stable_id : & ' a FxHashMap < SourceFileIndex , EncodedSourceFileId > ,
644
653
alloc_decoding_session : AllocDecodingSession < ' a > ,
645
654
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 > ,
647
657
hygiene_context : & ' a HygieneDecodeContext ,
648
658
}
649
659
@@ -794,27 +804,43 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
794
804
795
805
impl < ' a , ' tcx > Decodable < CacheDecoder < ' a , ' tcx > > for ExpnId {
796
806
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)
818
844
}
819
845
}
820
846
@@ -990,8 +1016,7 @@ where
990
1016
{
991
1017
fn encode ( & self , s : & mut CacheEncoder < ' a , ' tcx , E > ) -> Result < ( ) , E :: Error > {
992
1018
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)
995
1020
}
996
1021
}
997
1022
0 commit comments