@@ -13,14 +13,17 @@ use rustc_data_structures::fx::FxHashMap;
1313use rustc_data_structures:: indexed_vec:: Idx ;
1414use errors:: Diagnostic ;
1515use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder , opaque,
16- SpecializedDecoder } ;
16+ SpecializedDecoder , SpecializedEncoder } ;
1717use session:: Session ;
1818use std:: borrow:: Cow ;
1919use std:: cell:: RefCell ;
2020use std:: collections:: BTreeMap ;
2121use std:: mem;
2222use syntax:: codemap:: { CodeMap , StableFilemapId } ;
2323use syntax_pos:: { BytePos , Span , NO_EXPANSION , DUMMY_SP } ;
24+ use ty;
25+ use ty:: codec:: { self as ty_codec} ;
26+ use ty:: context:: TyCtxt ;
2427
2528/// `OnDiskCache` provides an interface to incr. comp. data cached from the
2629/// previous compilation session. This data will eventually include the results
@@ -46,11 +49,7 @@ struct Header {
4649 prev_filemap_starts : BTreeMap < BytePos , StableFilemapId > ,
4750}
4851
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 > ) > ;
5453
5554impl < ' sess > OnDiskCache < ' sess > {
5655 /// Create a new OnDiskCache instance from the serialized data in `data`.
@@ -64,14 +63,21 @@ impl<'sess> OnDiskCache<'sess> {
6463 let mut decoder = opaque:: Decoder :: new ( & data[ ..] , start_pos) ;
6564 let header = Header :: decode ( & mut decoder) . unwrap ( ) ;
6665
67- let prev_diagnostics: FxHashMap < _ , _ > = {
66+ let prev_diagnostics = {
6867 let mut decoder = CacheDecoder {
6968 opaque : decoder,
7069 codemap : sess. codemap ( ) ,
7170 prev_filemap_starts : & header. prev_filemap_starts ,
7271 } ;
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
7581 } ;
7682
7783 OnDiskCache {
@@ -91,28 +97,38 @@ impl<'sess> OnDiskCache<'sess> {
9197 }
9298 }
9399
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+
99115 let prev_filemap_starts: BTreeMap < _ , _ > = self
100116 . codemap
101117 . files ( )
102118 . iter ( )
103119 . map ( |fm| ( fm. start_pos , StableFilemapId :: new ( fm) ) )
104120 . collect ( ) ;
105121
106- Header { prev_filemap_starts } . encode ( encoder) ?;
122+ Header { prev_filemap_starts } . encode ( & mut encoder) ?;
107123
108- let diagnostics: Vec < ( SerializedDepNodeIndex , Vec < Diagnostic > ) > =
124+ let diagnostics: EncodedPrevDiagnostics =
109125 self . current_diagnostics
110126 . borrow ( )
111127 . iter ( )
112128 . map ( |( k, v) | ( SerializedDepNodeIndex :: new ( k. index ( ) ) , v. clone ( ) ) )
113129 . collect ( ) ;
114130
115- Body { diagnostics } . encode ( encoder) ?;
131+ diagnostics. encode ( & mut encoder) ?;
116132
117133 Ok ( ( ) )
118134 }
@@ -152,6 +168,9 @@ impl<'sess> OnDiskCache<'sess> {
152168 }
153169}
154170
171+
172+ //- DECODING -------------------------------------------------------------------
173+
155174/// A decoder that can read the incr. comp. cache. It is similar to the one
156175/// we use for crate metadata decoding in that it can rebase spans and
157176/// eventually will also handle things that contain `Ty` instances.
@@ -229,3 +248,83 @@ impl<'a> SpecializedDecoder<Span> for CacheDecoder<'a> {
229248 Ok ( DUMMY_SP )
230249 }
231250}
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