@@ -34,6 +34,11 @@ use ty::codec::{self as ty_codec, TyDecoder};
3434use ty:: context:: TyCtxt ;
3535use ty:: subst:: Substs ;
3636
37+ // Some magic values used for verifying that encoding and decoding. These are
38+ // basically random numbers.
39+ const PREV_DIAGNOSTICS_TAG : u64 = 0x1234_5678_A1A1_A1A1 ;
40+ const DEF_PATH_TABLE_TAG : u64 = 0x1234_5678_B2B2_B2B2 ;
41+
3742/// `OnDiskCache` provides an interface to incr. comp. data cached from the
3843/// previous compilation session. This data will eventually include the results
3944/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
@@ -91,15 +96,17 @@ impl<'sess> OnDiskCache<'sess> {
9196
9297 // Decode Diagnostics
9398 let prev_diagnostics: FxHashMap < _ , _ > = {
94- let diagnostics = EncodedPrevDiagnostics :: decode ( & mut decoder)
95- . expect ( "Error while trying to decode prev. diagnostics \
96- from incr. comp. cache.") ;
99+ let diagnostics: EncodedPrevDiagnostics =
100+ decode_tagged ( & mut decoder, PREV_DIAGNOSTICS_TAG )
101+ . expect ( "Error while trying to decode previous session \
102+ diagnostics from incr. comp. cache.") ;
103+
97104 diagnostics. into_iter ( ) . collect ( )
98105 } ;
99106
100107 // Decode DefPathTables
101108 let prev_def_path_tables: Vec < DefPathTable > =
102- Decodable :: decode ( & mut decoder)
109+ decode_tagged ( & mut decoder, DEF_PATH_TABLE_TAG )
103110 . expect ( "Error while trying to decode cached DefPathTables" ) ;
104111
105112 ( prev_diagnostics, prev_def_path_tables)
@@ -176,7 +183,7 @@ impl<'sess> OnDiskCache<'sess> {
176183 . map ( |( k, v) | ( SerializedDepNodeIndex :: new ( k. index ( ) ) , v. clone ( ) ) )
177184 . collect ( ) ;
178185
179- diagnostics . encode ( & mut encoder ) ?;
186+ encoder . encode_tagged ( PREV_DIAGNOSTICS_TAG , & diagnostics ) ?;
180187
181188
182189 // Encode all DefPathTables
@@ -192,7 +199,7 @@ impl<'sess> OnDiskCache<'sess> {
192199 }
193200 } ) . collect ( ) ;
194201
195- def_path_tables . encode ( & mut encoder ) ?;
202+ encoder . encode_tagged ( DEF_PATH_TABLE_TAG , & def_path_tables ) ?;
196203
197204 return Ok ( ( ) ) ;
198205
@@ -342,6 +349,30 @@ impl<'a, 'tcx, 'x> Decoder for CacheDecoder<'a, 'tcx, 'x> {
342349 }
343350}
344351
352+ // Decode something that was encoded with encode_tagged() and verify that the
353+ // tag matches and the correct amount of bytes was read.
354+ fn decode_tagged < ' a , ' tcx , D , T , V > ( decoder : & mut D ,
355+ expected_tag : T )
356+ -> Result < V , D :: Error >
357+ where T : Decodable + Eq + :: std:: fmt:: Debug ,
358+ V : Decodable ,
359+ D : Decoder + ty_codec:: TyDecoder < ' a , ' tcx > ,
360+ ' tcx : ' a ,
361+ {
362+ let start_pos = decoder. position ( ) ;
363+
364+ let actual_tag = T :: decode ( decoder) ?;
365+ assert_eq ! ( actual_tag, expected_tag) ;
366+ let value = V :: decode ( decoder) ?;
367+ let end_pos = decoder. position ( ) ;
368+
369+ let expected_len: u64 = Decodable :: decode ( decoder) ?;
370+ assert_eq ! ( ( end_pos - start_pos) as u64 , expected_len) ;
371+
372+ Ok ( value)
373+ }
374+
375+
345376impl < ' a , ' tcx : ' a , ' x > ty_codec:: TyDecoder < ' a , ' tcx > for CacheDecoder < ' a , ' tcx , ' x > {
346377
347378 #[ inline]
@@ -565,6 +596,30 @@ struct CacheEncoder<'enc, 'tcx, E>
565596 definitions : & ' enc Definitions ,
566597}
567598
599+ impl < ' enc , ' tcx , E > CacheEncoder < ' enc , ' tcx , E >
600+ where E : ' enc + ty_codec:: TyEncoder
601+ {
602+ /// Encode something with additional information that allows to do some
603+ /// sanity checks when decoding the data again. This method will first
604+ /// encode the specified tag, then the given value, then the number of
605+ /// bytes taken up by tag and value. On decoding, we can then verify that
606+ /// we get the expected tag and read the expected number of bytes.
607+ fn encode_tagged < T : Encodable , V : Encodable > ( & mut self ,
608+ tag : T ,
609+ value : & V )
610+ -> Result < ( ) , E :: Error >
611+ {
612+ use ty:: codec:: TyEncoder ;
613+ let start_pos = self . position ( ) ;
614+
615+ tag. encode ( self ) ?;
616+ value. encode ( self ) ?;
617+
618+ let end_pos = self . position ( ) ;
619+ ( ( end_pos - start_pos) as u64 ) . encode ( self )
620+ }
621+ }
622+
568623impl < ' enc , ' tcx , E > ty_codec:: TyEncoder for CacheEncoder < ' enc , ' tcx , E >
569624 where E : ' enc + ty_codec:: TyEncoder
570625{
@@ -644,3 +699,4 @@ impl<'enc, 'tcx, E> Encoder for CacheEncoder<'enc, 'tcx, E>
644699 emit_str( & str ) ;
645700 }
646701}
702+
0 commit comments