@@ -27,7 +27,8 @@ use std::collections::BTreeMap;
27
27
use std:: mem;
28
28
use syntax:: ast:: NodeId ;
29
29
use syntax:: codemap:: { CodeMap , StableFilemapId } ;
30
- use syntax_pos:: { BytePos , Span , NO_EXPANSION , DUMMY_SP } ;
30
+ use syntax_pos:: { BytePos , Span , DUMMY_SP } ;
31
+ use syntax_pos:: hygiene:: { Mark , SyntaxContext , ExpnInfo } ;
31
32
use ty;
32
33
use ty:: codec:: { self as ty_codec, TyDecoder , TyEncoder } ;
33
34
use ty:: context:: TyCtxt ;
@@ -40,6 +41,10 @@ const QUERY_RESULT_INDEX_TAG: u64 = 0x1234_5678_C3C3_C3C3;
40
41
const TAG_CLEAR_CROSS_CRATE_CLEAR : u8 = 0 ;
41
42
const TAG_CLEAR_CROSS_CRATE_SET : u8 = 1 ;
42
43
44
+ const TAG_NO_EXPANSION_INFO : u8 = 0 ;
45
+ const TAG_EXPANSION_INFO_SHORTHAND : u8 = 1 ;
46
+ const TAG_EXPANSION_INFO_INLINE : u8 = 2 ;
47
+
43
48
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
44
49
/// previous compilation session. This data will eventually include the results
45
50
/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
@@ -61,6 +66,7 @@ pub struct OnDiskCache<'sess> {
61
66
62
67
prev_filemap_starts : BTreeMap < BytePos , StableFilemapId > ,
63
68
codemap : & ' sess CodeMap ,
69
+ synthetic_expansion_infos : RefCell < FxHashMap < usize , SyntaxContext > > ,
64
70
65
71
// A map from dep-node to the position of the cached query result in
66
72
// `serialized_data`.
@@ -90,13 +96,16 @@ impl<'sess> OnDiskCache<'sess> {
90
96
( header, decoder. position ( ) )
91
97
} ;
92
98
99
+ let mut synthetic_expansion_infos = FxHashMap ( ) ;
100
+
93
101
let ( prev_diagnostics, query_result_index) = {
94
102
let mut decoder = CacheDecoder {
95
103
tcx : None ,
96
104
opaque : opaque:: Decoder :: new ( & data[ ..] , post_header_pos) ,
97
105
codemap : sess. codemap ( ) ,
98
106
prev_filemap_starts : & header. prev_filemap_starts ,
99
107
cnum_map : & IndexVec :: new ( ) ,
108
+ synthetic_expansion_infos : & mut synthetic_expansion_infos,
100
109
} ;
101
110
102
111
// Decode Diagnostics
@@ -135,6 +144,7 @@ impl<'sess> OnDiskCache<'sess> {
135
144
codemap : sess. codemap ( ) ,
136
145
current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
137
146
query_result_index : query_result_index. into_iter ( ) . collect ( ) ,
147
+ synthetic_expansion_infos : RefCell :: new ( synthetic_expansion_infos) ,
138
148
}
139
149
}
140
150
@@ -148,6 +158,7 @@ impl<'sess> OnDiskCache<'sess> {
148
158
codemap,
149
159
current_diagnostics : RefCell :: new ( FxHashMap ( ) ) ,
150
160
query_result_index : FxHashMap ( ) ,
161
+ synthetic_expansion_infos : RefCell :: new ( FxHashMap ( ) ) ,
151
162
}
152
163
}
153
164
@@ -166,6 +177,7 @@ impl<'sess> OnDiskCache<'sess> {
166
177
encoder,
167
178
type_shorthands : FxHashMap ( ) ,
168
179
predicate_shorthands : FxHashMap ( ) ,
180
+ expn_info_shorthands : FxHashMap ( ) ,
169
181
} ;
170
182
171
183
@@ -269,12 +281,15 @@ impl<'sess> OnDiskCache<'sess> {
269
281
* cnum_map = Some ( Self :: compute_cnum_map ( tcx, & self . prev_cnums [ ..] ) ) ;
270
282
}
271
283
284
+ let mut synthetic_expansion_infos = self . synthetic_expansion_infos . borrow_mut ( ) ;
285
+
272
286
let mut decoder = CacheDecoder {
273
287
tcx : Some ( tcx) ,
274
288
opaque : opaque:: Decoder :: new ( & self . serialized_data [ ..] , pos) ,
275
289
codemap : self . codemap ,
276
290
prev_filemap_starts : & self . prev_filemap_starts ,
277
291
cnum_map : cnum_map. as_ref ( ) . unwrap ( ) ,
292
+ synthetic_expansion_infos : & mut * synthetic_expansion_infos,
278
293
} ;
279
294
280
295
match decode_tagged ( & mut decoder, dep_node_index) {
@@ -350,6 +365,7 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
350
365
codemap : & ' x CodeMap ,
351
366
prev_filemap_starts : & ' x BTreeMap < BytePos , StableFilemapId > ,
352
367
cnum_map : & ' x IndexVec < CrateNum , Option < CrateNum > > ,
368
+ synthetic_expansion_infos : & ' x mut FxHashMap < usize , SyntaxContext > ,
353
369
}
354
370
355
371
impl < ' a , ' tcx , ' x > CacheDecoder < ' a , ' tcx , ' x > {
@@ -457,7 +473,39 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx, 'x> {
457
473
if let Some ( current_filemap) = self . codemap . filemap_by_stable_id ( filemap_id) {
458
474
let lo = ( lo + current_filemap. start_pos ) - prev_filemap_start;
459
475
let hi = ( hi + current_filemap. start_pos ) - prev_filemap_start;
460
- return Ok ( Span :: new ( lo, hi, NO_EXPANSION ) ) ;
476
+
477
+ let expn_info_tag = u8:: decode ( self ) ?;
478
+
479
+ let ctxt = match expn_info_tag {
480
+ TAG_NO_EXPANSION_INFO => {
481
+ SyntaxContext :: empty ( )
482
+ }
483
+ TAG_EXPANSION_INFO_INLINE => {
484
+ let pos = self . position ( ) ;
485
+ let expn_info: ExpnInfo = Decodable :: decode ( self ) ?;
486
+ let ctxt = SyntaxContext :: allocate_directly ( expn_info) ;
487
+ self . synthetic_expansion_infos . insert ( pos, ctxt) ;
488
+ ctxt
489
+ }
490
+ TAG_EXPANSION_INFO_SHORTHAND => {
491
+ let pos = usize:: decode ( self ) ?;
492
+ if let Some ( ctxt) = self . synthetic_expansion_infos . get ( & pos) . cloned ( ) {
493
+ ctxt
494
+ } else {
495
+ let expn_info = self . with_position ( pos, |this| {
496
+ ExpnInfo :: decode ( this)
497
+ } ) ?;
498
+ let ctxt = SyntaxContext :: allocate_directly ( expn_info) ;
499
+ self . synthetic_expansion_infos . insert ( pos, ctxt) ;
500
+ ctxt
501
+ }
502
+ }
503
+ _ => {
504
+ unreachable ! ( )
505
+ }
506
+ } ;
507
+
508
+ return Ok ( Span :: new ( lo, hi, ctxt) ) ;
461
509
}
462
510
}
463
511
@@ -479,6 +527,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx, 'x> {
479
527
// compilation sessions. We use the DefPathHash, which is stable across
480
528
// sessions, to map the old DefId to the new one.
481
529
impl < ' a , ' tcx , ' x > SpecializedDecoder < DefId > for CacheDecoder < ' a , ' tcx , ' x > {
530
+ #[ inline]
482
531
fn specialized_decode ( & mut self ) -> Result < DefId , Self :: Error > {
483
532
// Load the DefPathHash which is was we encoded the DefId as.
484
533
let def_path_hash = DefPathHash :: decode ( self ) ?;
@@ -489,6 +538,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx, 'x> {
489
538
}
490
539
491
540
impl < ' a , ' tcx , ' x > SpecializedDecoder < LocalDefId > for CacheDecoder < ' a , ' tcx , ' x > {
541
+ #[ inline]
492
542
fn specialized_decode ( & mut self ) -> Result < LocalDefId , Self :: Error > {
493
543
Ok ( LocalDefId :: from_def_id ( DefId :: decode ( self ) ?) )
494
544
}
@@ -558,6 +608,7 @@ struct CacheEncoder<'enc, 'a, 'tcx, E>
558
608
encoder : & ' enc mut E ,
559
609
type_shorthands : FxHashMap < ty:: Ty < ' tcx > , usize > ,
560
610
predicate_shorthands : FxHashMap < ty:: Predicate < ' tcx > , usize > ,
611
+ expn_info_shorthands : FxHashMap < Mark , usize > ,
561
612
}
562
613
563
614
impl < ' enc , ' a , ' tcx , E > CacheEncoder < ' enc , ' a , ' tcx , E >
@@ -584,6 +635,37 @@ impl<'enc, 'a, 'tcx, E> CacheEncoder<'enc, 'a, 'tcx, E>
584
635
}
585
636
}
586
637
638
+ impl < ' enc , ' a , ' tcx , E > SpecializedEncoder < Span > for CacheEncoder < ' enc , ' a , ' tcx , E >
639
+ where E : ' enc + ty_codec:: TyEncoder
640
+ {
641
+ fn specialized_encode ( & mut self , span : & Span ) -> Result < ( ) , Self :: Error > {
642
+ let span_data = span. data ( ) ;
643
+
644
+ span_data. lo . encode ( self ) ?;
645
+ span_data. hi . encode ( self ) ?;
646
+
647
+ if span_data. ctxt == SyntaxContext :: empty ( ) {
648
+ TAG_NO_EXPANSION_INFO . encode ( self )
649
+ } else {
650
+ let mark = span_data. ctxt . outer ( ) ;
651
+
652
+ if let Some ( expn_info) = mark. expn_info ( ) {
653
+ if let Some ( pos) = self . expn_info_shorthands . get ( & mark) . cloned ( ) {
654
+ TAG_EXPANSION_INFO_SHORTHAND . encode ( self ) ?;
655
+ pos. encode ( self )
656
+ } else {
657
+ TAG_EXPANSION_INFO_INLINE . encode ( self ) ?;
658
+ let pos = self . position ( ) ;
659
+ self . expn_info_shorthands . insert ( mark, pos) ;
660
+ expn_info. encode ( self )
661
+ }
662
+ } else {
663
+ TAG_NO_EXPANSION_INFO . encode ( self )
664
+ }
665
+ }
666
+ }
667
+ }
668
+
587
669
impl < ' enc , ' a , ' tcx , E > ty_codec:: TyEncoder for CacheEncoder < ' enc , ' a , ' tcx , E >
588
670
where E : ' enc + ty_codec:: TyEncoder
589
671
{
0 commit comments