9
9
// except according to those terms.
10
10
11
11
use dep_graph:: { DepNodeIndex , SerializedDepNodeIndex } ;
12
- use rustc_data_structures:: fx:: FxHashMap ;
13
- use rustc_data_structures:: indexed_vec:: Idx ;
14
12
use 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 } ;
15
20
use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder , opaque,
16
- SpecializedDecoder , SpecializedEncoder } ;
21
+ SpecializedDecoder , SpecializedEncoder ,
22
+ UseSpecializedDecodable } ;
17
23
use session:: Session ;
18
24
use std:: borrow:: Cow ;
19
25
use std:: cell:: RefCell ;
20
26
use std:: collections:: BTreeMap ;
21
27
use std:: mem;
28
+ use syntax:: ast:: NodeId ;
22
29
use syntax:: codemap:: { CodeMap , StableFilemapId } ;
23
30
use syntax_pos:: { BytePos , Span , NO_EXPANSION , DUMMY_SP } ;
24
31
use ty;
25
- use ty:: codec:: { self as ty_codec} ;
32
+ use ty:: codec:: { self as ty_codec, TyDecoder } ;
26
33
use ty:: context:: TyCtxt ;
34
+ use ty:: subst:: Substs ;
27
35
28
36
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
29
37
/// previous compilation session. This data will eventually include the results
@@ -65,9 +73,12 @@ impl<'sess> OnDiskCache<'sess> {
65
73
66
74
let prev_diagnostics = {
67
75
let mut decoder = CacheDecoder {
76
+ tcx : None ,
68
77
opaque : decoder,
69
78
codemap : sess. codemap ( ) ,
70
79
prev_filemap_starts : & header. prev_filemap_starts ,
80
+ cnum_map : & IndexVec :: new ( ) ,
81
+ prev_def_path_tables : & Vec :: new ( ) ,
71
82
} ;
72
83
73
84
let prev_diagnostics: FxHashMap < _ , _ > = {
@@ -110,6 +121,7 @@ impl<'sess> OnDiskCache<'sess> {
110
121
encoder,
111
122
type_shorthands : FxHashMap ( ) ,
112
123
predicate_shorthands : FxHashMap ( ) ,
124
+ definitions : tcx. hir . definitions ( ) ,
113
125
} ;
114
126
115
127
let prev_filemap_starts: BTreeMap < _ , _ > = self
@@ -174,13 +186,16 @@ impl<'sess> OnDiskCache<'sess> {
174
186
/// A decoder that can read the incr. comp. cache. It is similar to the one
175
187
/// we use for crate metadata decoding in that it can rebase spans and
176
188
/// 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 > ,
181
196
}
182
197
183
- impl < ' a > CacheDecoder < ' a > {
198
+ impl < ' a , ' tcx , ' x > CacheDecoder < ' a , ' tcx , ' x > {
184
199
fn find_filemap_prev_bytepos ( & self ,
185
200
prev_bytepos : BytePos )
186
201
-> Option < ( BytePos , StableFilemapId ) > {
@@ -200,7 +215,7 @@ macro_rules! decoder_methods {
200
215
}
201
216
}
202
217
203
- impl < ' sess > Decoder for CacheDecoder < ' sess > {
218
+ impl < ' a , ' tcx , ' x > Decoder for CacheDecoder < ' a , ' tcx , ' x > {
204
219
type Error = String ;
205
220
206
221
decoder_methods ! {
@@ -232,7 +247,65 @@ impl<'sess> Decoder for CacheDecoder<'sess> {
232
247
}
233
248
}
234
249
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 > {
236
309
fn specialized_decode ( & mut self ) -> Result < Span , Self :: Error > {
237
310
let lo = BytePos :: decode ( self ) ?;
238
311
let hi = BytePos :: decode ( self ) ?;
@@ -249,6 +322,142 @@ impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> {
249
322
}
250
323
}
251
324
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
+
252
461
253
462
//- ENCODING -------------------------------------------------------------------
254
463
@@ -258,6 +467,7 @@ struct CacheEncoder<'enc, 'tcx, E>
258
467
encoder : & ' enc mut E ,
259
468
type_shorthands : FxHashMap < ty:: Ty < ' tcx > , usize > ,
260
469
predicate_shorthands : FxHashMap < ty:: Predicate < ' tcx > , usize > ,
470
+ definitions : & ' enc Definitions ,
261
471
}
262
472
263
473
impl < ' enc , ' tcx , E > ty_codec:: TyEncoder for CacheEncoder < ' enc , ' tcx , E >
@@ -289,6 +499,17 @@ impl<'enc, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>>
289
499
}
290
500
}
291
501
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
+
292
513
macro_rules! encoder_methods {
293
514
( $( $name: ident( $ty: ty) ; ) * ) => {
294
515
$( fn $name( & mut self , value: $ty) -> Result <( ) , Self :: Error > {
0 commit comments