@@ -26,7 +26,8 @@ use std::collections::BTreeMap;
26
26
use std:: mem;
27
27
use syntax:: ast:: NodeId ;
28
28
use syntax:: codemap:: { CodeMap , StableFilemapId } ;
29
- use syntax_pos:: { BytePos , Span , NO_EXPANSION , DUMMY_SP } ;
29
+ use syntax_pos:: { BytePos , Span , DUMMY_SP } ;
30
+ use syntax_pos:: hygiene:: { Mark , SyntaxContext , ExpnInfo } ;
30
31
use ty;
31
32
use ty:: codec:: { self as ty_codec, TyDecoder , TyEncoder } ;
32
33
use ty:: context:: TyCtxt ;
@@ -36,6 +37,10 @@ use ty::context::TyCtxt;
36
37
const PREV_DIAGNOSTICS_TAG : u64 = 0x1234_5678_A1A1_A1A1 ;
37
38
const QUERY_RESULT_INDEX_TAG : u64 = 0x1234_5678_C3C3_C3C3 ;
38
39
40
+ const TAG_NO_EXPANSION_INFO : u8 = 0 ;
41
+ const TAG_EXPANSION_INFO_SHORTHAND : u8 = 1 ;
42
+ const TAG_EXPANSION_INFO_INLINE : u8 = 2 ;
43
+
39
44
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
40
45
/// previous compilation session. This data will eventually include the results
41
46
/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
@@ -57,6 +62,7 @@ pub struct OnDiskCache<'sess> {
57
62
58
63
prev_filemap_starts : BTreeMap < BytePos , StableFilemapId > ,
59
64
codemap : & ' sess CodeMap ,
65
+ synthetic_expansion_infos : RefCell < FxHashMap < usize , SyntaxContext > > ,
60
66
61
67
// A map from dep-node to the position of the cached query result in
62
68
// `serialized_data`.
@@ -86,13 +92,16 @@ impl<'sess> OnDiskCache<'sess> {
86
92
( header, decoder. position ( ) )
87
93
} ;
88
94
95
+ let mut synthetic_expansion_infos = FxHashMap ( ) ;
96
+
89
97
let ( prev_diagnostics, query_result_index) = {
90
98
let mut decoder = CacheDecoder {
91
99
tcx : None ,
92
100
opaque : opaque:: Decoder :: new ( & data[ ..] , post_header_pos) ,
93
101
codemap : sess. codemap ( ) ,
94
102
prev_filemap_starts : & header. prev_filemap_starts ,
95
103
cnum_map : & IndexVec :: new ( ) ,
104
+ synthetic_expansion_infos : & mut synthetic_expansion_infos,
96
105
} ;
97
106
98
107
// Decode Diagnostics
@@ -131,6 +140,7 @@ impl<'sess> OnDiskCache<'sess> {
131
140
codemap : sess. codemap ( ) ,
132
141
current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
133
142
query_result_index : query_result_index. into_iter ( ) . collect ( ) ,
143
+ synthetic_expansion_infos : RefCell :: new ( synthetic_expansion_infos) ,
134
144
}
135
145
}
136
146
@@ -144,6 +154,7 @@ impl<'sess> OnDiskCache<'sess> {
144
154
codemap,
145
155
current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
146
156
query_result_index : FxHashMap ( ) ,
157
+ synthetic_expansion_infos : RefCell :: new ( FxHashMap ( ) ) ,
147
158
}
148
159
}
149
160
@@ -162,6 +173,7 @@ impl<'sess> OnDiskCache<'sess> {
162
173
encoder,
163
174
type_shorthands : FxHashMap ( ) ,
164
175
predicate_shorthands : FxHashMap ( ) ,
176
+ expn_info_shorthands : FxHashMap ( ) ,
165
177
} ;
166
178
167
179
@@ -265,12 +277,15 @@ impl<'sess> OnDiskCache<'sess> {
265
277
* cnum_map = Some ( Self :: compute_cnum_map ( tcx, & self . prev_cnums [ ..] ) ) ;
266
278
}
267
279
280
+ let mut synthetic_expansion_infos = self . synthetic_expansion_infos . borrow_mut ( ) ;
281
+
268
282
let mut decoder = CacheDecoder {
269
283
tcx : Some ( tcx) ,
270
284
opaque : opaque:: Decoder :: new ( & self . serialized_data [ ..] , pos) ,
271
285
codemap : self . codemap ,
272
286
prev_filemap_starts : & self . prev_filemap_starts ,
273
287
cnum_map : cnum_map. as_ref ( ) . unwrap ( ) ,
288
+ synthetic_expansion_infos : & mut * synthetic_expansion_infos,
274
289
} ;
275
290
276
291
match decode_tagged ( & mut decoder, dep_node_index) {
@@ -346,6 +361,7 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
346
361
codemap : & ' x CodeMap ,
347
362
prev_filemap_starts : & ' x BTreeMap < BytePos , StableFilemapId > ,
348
363
cnum_map : & ' x IndexVec < CrateNum , Option < CrateNum > > ,
364
+ synthetic_expansion_infos : & ' x mut FxHashMap < usize , SyntaxContext > ,
349
365
}
350
366
351
367
impl < ' a , ' tcx , ' x > CacheDecoder < ' a , ' tcx , ' x > {
@@ -453,7 +469,39 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx, 'x> {
453
469
if let Some ( current_filemap) = self . codemap . filemap_by_stable_id ( filemap_id) {
454
470
let lo = ( lo + current_filemap. start_pos ) - prev_filemap_start;
455
471
let hi = ( hi + current_filemap. start_pos ) - prev_filemap_start;
456
- return Ok ( Span :: new ( lo, hi, NO_EXPANSION ) ) ;
472
+
473
+ let expn_info_tag = u8:: decode ( self ) ?;
474
+
475
+ let ctxt = match expn_info_tag {
476
+ TAG_NO_EXPANSION_INFO => {
477
+ SyntaxContext :: empty ( )
478
+ }
479
+ TAG_EXPANSION_INFO_INLINE => {
480
+ let pos = self . position ( ) ;
481
+ let expn_info: ExpnInfo = Decodable :: decode ( self ) ?;
482
+ let ctxt = SyntaxContext :: allocate_directly ( expn_info) ;
483
+ self . synthetic_expansion_infos . insert ( pos, ctxt) ;
484
+ ctxt
485
+ }
486
+ TAG_EXPANSION_INFO_SHORTHAND => {
487
+ let pos = usize:: decode ( self ) ?;
488
+ if let Some ( ctxt) = self . synthetic_expansion_infos . get ( & pos) . cloned ( ) {
489
+ ctxt
490
+ } else {
491
+ let expn_info = self . with_position ( pos, |this| {
492
+ ExpnInfo :: decode ( this)
493
+ } ) ?;
494
+ let ctxt = SyntaxContext :: allocate_directly ( expn_info) ;
495
+ self . synthetic_expansion_infos . insert ( pos, ctxt) ;
496
+ ctxt
497
+ }
498
+ }
499
+ _ => {
500
+ unreachable ! ( )
501
+ }
502
+ } ;
503
+
504
+ return Ok ( Span :: new ( lo, hi, ctxt) ) ;
457
505
}
458
506
}
459
507
@@ -475,6 +523,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx, 'x> {
475
523
// compilation sessions. We use the DefPathHash, which is stable across
476
524
// sessions, to map the old DefId to the new one.
477
525
impl < ' a , ' tcx , ' x > SpecializedDecoder < DefId > for CacheDecoder < ' a , ' tcx , ' x > {
526
+ #[ inline]
478
527
fn specialized_decode ( & mut self ) -> Result < DefId , Self :: Error > {
479
528
// Load the DefPathHash which is was we encoded the DefId as.
480
529
let def_path_hash = DefPathHash :: decode ( self ) ?;
@@ -485,6 +534,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx, 'x> {
485
534
}
486
535
487
536
impl < ' a , ' tcx , ' x > SpecializedDecoder < LocalDefId > for CacheDecoder < ' a , ' tcx , ' x > {
537
+ #[ inline]
488
538
fn specialized_decode ( & mut self ) -> Result < LocalDefId , Self :: Error > {
489
539
Ok ( LocalDefId :: from_def_id ( DefId :: decode ( self ) ?) )
490
540
}
@@ -534,6 +584,7 @@ struct CacheEncoder<'enc, 'a, 'tcx, E>
534
584
encoder : & ' enc mut E ,
535
585
type_shorthands : FxHashMap < ty:: Ty < ' tcx > , usize > ,
536
586
predicate_shorthands : FxHashMap < ty:: Predicate < ' tcx > , usize > ,
587
+ expn_info_shorthands : FxHashMap < Mark , usize > ,
537
588
}
538
589
539
590
impl < ' enc , ' a , ' tcx , E > CacheEncoder < ' enc , ' a , ' tcx , E >
@@ -560,6 +611,37 @@ impl<'enc, 'a, 'tcx, E> CacheEncoder<'enc, 'a, 'tcx, E>
560
611
}
561
612
}
562
613
614
+ impl < ' enc , ' a , ' tcx , E > SpecializedEncoder < Span > for CacheEncoder < ' enc , ' a , ' tcx , E >
615
+ where E : ' enc + ty_codec:: TyEncoder
616
+ {
617
+ fn specialized_encode ( & mut self , span : & Span ) -> Result < ( ) , Self :: Error > {
618
+ let span_data = span. data ( ) ;
619
+
620
+ span_data. lo . encode ( self ) ?;
621
+ span_data. hi . encode ( self ) ?;
622
+
623
+ if span_data. ctxt == SyntaxContext :: empty ( ) {
624
+ TAG_NO_EXPANSION_INFO . encode ( self )
625
+ } else {
626
+ let mark = span_data. ctxt . outer ( ) ;
627
+
628
+ if let Some ( expn_info) = mark. expn_info ( ) {
629
+ if let Some ( pos) = self . expn_info_shorthands . get ( & mark) . cloned ( ) {
630
+ TAG_EXPANSION_INFO_SHORTHAND . encode ( self ) ?;
631
+ pos. encode ( self )
632
+ } else {
633
+ TAG_EXPANSION_INFO_INLINE . encode ( self ) ?;
634
+ let pos = self . position ( ) ;
635
+ self . expn_info_shorthands . insert ( mark, pos) ;
636
+ expn_info. encode ( self )
637
+ }
638
+ } else {
639
+ TAG_NO_EXPANSION_INFO . encode ( self )
640
+ }
641
+ }
642
+ }
643
+ }
644
+
563
645
impl < ' enc , ' a , ' tcx , E > ty_codec:: TyEncoder for CacheEncoder < ' enc , ' a , ' tcx , E >
564
646
where E : ' enc + ty_codec:: TyEncoder
565
647
{
0 commit comments