@@ -13,14 +13,17 @@ use rustc_data_structures::fx::FxHashMap;
13
13
use rustc_data_structures:: indexed_vec:: Idx ;
14
14
use errors:: Diagnostic ;
15
15
use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder , opaque,
16
- SpecializedDecoder } ;
16
+ SpecializedDecoder , SpecializedEncoder } ;
17
17
use session:: Session ;
18
18
use std:: borrow:: Cow ;
19
19
use std:: cell:: RefCell ;
20
20
use std:: collections:: BTreeMap ;
21
21
use std:: mem;
22
22
use syntax:: codemap:: { CodeMap , StableFilemapId } ;
23
23
use syntax_pos:: { BytePos , Span , NO_EXPANSION , DUMMY_SP } ;
24
+ use ty;
25
+ use ty:: codec:: { self as ty_codec} ;
26
+ use ty:: context:: TyCtxt ;
24
27
25
28
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
26
29
/// previous compilation session. This data will eventually include the results
@@ -46,11 +49,7 @@ struct Header {
46
49
prev_filemap_starts : BTreeMap < BytePos , StableFilemapId > ,
47
50
}
48
51
49
- // This type is used only for (de-)serialization.
50
- #[ derive( RustcEncodable , RustcDecodable ) ]
51
- struct Body {
52
- diagnostics : Vec < ( SerializedDepNodeIndex , Vec < Diagnostic > ) > ,
53
- }
52
+ type EncodedPrevDiagnostics = Vec < ( SerializedDepNodeIndex , Vec < Diagnostic > ) > ;
54
53
55
54
impl < ' sess > OnDiskCache < ' sess > {
56
55
/// Create a new OnDiskCache instance from the serialized data in `data`.
@@ -64,14 +63,21 @@ impl<'sess> OnDiskCache<'sess> {
64
63
let mut decoder = opaque:: Decoder :: new ( & data[ ..] , start_pos) ;
65
64
let header = Header :: decode ( & mut decoder) . unwrap ( ) ;
66
65
67
- let prev_diagnostics: FxHashMap < _ , _ > = {
66
+ let prev_diagnostics = {
68
67
let mut decoder = CacheDecoder {
69
68
opaque : decoder,
70
69
codemap : sess. codemap ( ) ,
71
70
prev_filemap_starts : & header. prev_filemap_starts ,
72
71
} ;
73
- let body = Body :: decode ( & mut decoder) . unwrap ( ) ;
74
- body. diagnostics . into_iter ( ) . collect ( )
72
+
73
+ let prev_diagnostics: FxHashMap < _ , _ > = {
74
+ let diagnostics = EncodedPrevDiagnostics :: decode ( & mut decoder)
75
+ . expect ( "Error while trying to decode prev. diagnostics \
76
+ from incr. comp. cache.") ;
77
+ diagnostics. into_iter ( ) . collect ( )
78
+ } ;
79
+
80
+ prev_diagnostics
75
81
} ;
76
82
77
83
OnDiskCache {
@@ -91,28 +97,38 @@ impl<'sess> OnDiskCache<'sess> {
91
97
}
92
98
}
93
99
94
- pub fn serialize < ' a , ' tcx , E > ( & self ,
95
- encoder : & mut E )
96
- -> Result < ( ) , E :: Error >
97
- where E : Encoder
98
- {
100
+ pub fn serialize < ' a , ' gcx , ' lcx , E > ( & self ,
101
+ tcx : TyCtxt < ' a , ' gcx , ' lcx > ,
102
+ encoder : & mut E )
103
+ -> Result < ( ) , E :: Error >
104
+ where E : ty_codec:: TyEncoder
105
+ {
106
+ // Serializing the DepGraph should not modify it:
107
+ let _in_ignore = tcx. dep_graph . in_ignore ( ) ;
108
+
109
+ let mut encoder = CacheEncoder {
110
+ encoder,
111
+ type_shorthands : FxHashMap ( ) ,
112
+ predicate_shorthands : FxHashMap ( ) ,
113
+ } ;
114
+
99
115
let prev_filemap_starts: BTreeMap < _ , _ > = self
100
116
. codemap
101
117
. files ( )
102
118
. iter ( )
103
119
. map ( |fm| ( fm. start_pos , StableFilemapId :: new ( fm) ) )
104
120
. collect ( ) ;
105
121
106
- Header { prev_filemap_starts } . encode ( encoder) ?;
122
+ Header { prev_filemap_starts } . encode ( & mut encoder) ?;
107
123
108
- let diagnostics: Vec < ( SerializedDepNodeIndex , Vec < Diagnostic > ) > =
124
+ let diagnostics: EncodedPrevDiagnostics =
109
125
self . current_diagnostics
110
126
. borrow ( )
111
127
. iter ( )
112
128
. map ( |( k, v) | ( SerializedDepNodeIndex :: new ( k. index ( ) ) , v. clone ( ) ) )
113
129
. collect ( ) ;
114
130
115
- Body { diagnostics } . encode ( encoder) ?;
131
+ diagnostics. encode ( & mut encoder) ?;
116
132
117
133
Ok ( ( ) )
118
134
}
@@ -152,6 +168,9 @@ impl<'sess> OnDiskCache<'sess> {
152
168
}
153
169
}
154
170
171
+
172
+ //- DECODING -------------------------------------------------------------------
173
+
155
174
/// A decoder that can read the incr. comp. cache. It is similar to the one
156
175
/// we use for crate metadata decoding in that it can rebase spans and
157
176
/// eventually will also handle things that contain `Ty` instances.
@@ -229,3 +248,83 @@ impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> {
229
248
Ok ( DUMMY_SP )
230
249
}
231
250
}
251
+
252
+
253
+ //- ENCODING -------------------------------------------------------------------
254
+
255
+ struct CacheEncoder < ' enc , ' tcx , E >
256
+ where E : ' enc + ty_codec:: TyEncoder
257
+ {
258
+ encoder : & ' enc mut E ,
259
+ type_shorthands : FxHashMap < ty:: Ty < ' tcx > , usize > ,
260
+ predicate_shorthands : FxHashMap < ty:: Predicate < ' tcx > , usize > ,
261
+ }
262
+
263
+ impl < ' enc , ' tcx , E > ty_codec:: TyEncoder for CacheEncoder < ' enc , ' tcx , E >
264
+ where E : ' enc + ty_codec:: TyEncoder
265
+ {
266
+ fn position ( & self ) -> usize {
267
+ self . encoder . position ( )
268
+ }
269
+ }
270
+
271
+ impl < ' enc , ' tcx , E > SpecializedEncoder < ty:: Ty < ' tcx > > for CacheEncoder < ' enc , ' tcx , E >
272
+ where E : ' enc + ty_codec:: TyEncoder
273
+ {
274
+ fn specialized_encode ( & mut self , ty : & ty:: Ty < ' tcx > ) -> Result < ( ) , Self :: Error > {
275
+ ty_codec:: encode_with_shorthand ( self , ty,
276
+ |encoder| & mut encoder. type_shorthands )
277
+ }
278
+ }
279
+
280
+ impl < ' enc , ' tcx , E > SpecializedEncoder < ty:: GenericPredicates < ' tcx > >
281
+ for CacheEncoder < ' enc , ' tcx , E >
282
+ where E : ' enc + ty_codec:: TyEncoder
283
+ {
284
+ fn specialized_encode ( & mut self ,
285
+ predicates : & ty:: GenericPredicates < ' tcx > )
286
+ -> Result < ( ) , Self :: Error > {
287
+ ty_codec:: encode_predicates ( self , predicates,
288
+ |encoder| & mut encoder. predicate_shorthands )
289
+ }
290
+ }
291
+
292
+ macro_rules! encoder_methods {
293
+ ( $( $name: ident( $ty: ty) ; ) * ) => {
294
+ $( fn $name( & mut self , value: $ty) -> Result <( ) , Self :: Error > {
295
+ self . encoder. $name( value)
296
+ } ) *
297
+ }
298
+ }
299
+
300
+ impl < ' enc , ' tcx , E > Encoder for CacheEncoder < ' enc , ' tcx , E >
301
+ where E : ' enc + ty_codec:: TyEncoder
302
+ {
303
+ type Error = E :: Error ;
304
+
305
+ fn emit_nil ( & mut self ) -> Result < ( ) , Self :: Error > {
306
+ Ok ( ( ) )
307
+ }
308
+
309
+ encoder_methods ! {
310
+ emit_usize( usize ) ;
311
+ emit_u128( u128 ) ;
312
+ emit_u64( u64 ) ;
313
+ emit_u32( u32 ) ;
314
+ emit_u16( u16 ) ;
315
+ emit_u8( u8 ) ;
316
+
317
+ emit_isize( isize ) ;
318
+ emit_i128( i128 ) ;
319
+ emit_i64( i64 ) ;
320
+ emit_i32( i32 ) ;
321
+ emit_i16( i16 ) ;
322
+ emit_i8( i8 ) ;
323
+
324
+ emit_bool( bool ) ;
325
+ emit_f64( f64 ) ;
326
+ emit_f32( f32 ) ;
327
+ emit_char( char ) ;
328
+ emit_str( & str ) ;
329
+ }
330
+ }
0 commit comments