@@ -34,6 +34,11 @@ use ty::codec::{self as ty_codec, TyDecoder};
34
34
use ty:: context:: TyCtxt ;
35
35
use ty:: subst:: Substs ;
36
36
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
+
37
42
/// `OnDiskCache` provides an interface to incr. comp. data cached from the
38
43
/// previous compilation session. This data will eventually include the results
39
44
/// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
@@ -91,15 +96,17 @@ impl<'sess> OnDiskCache<'sess> {
91
96
92
97
// Decode Diagnostics
93
98
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
+
97
104
diagnostics. into_iter ( ) . collect ( )
98
105
} ;
99
106
100
107
// Decode DefPathTables
101
108
let prev_def_path_tables: Vec < DefPathTable > =
102
- Decodable :: decode ( & mut decoder)
109
+ decode_tagged ( & mut decoder, DEF_PATH_TABLE_TAG )
103
110
. expect ( "Error while trying to decode cached DefPathTables" ) ;
104
111
105
112
( prev_diagnostics, prev_def_path_tables)
@@ -176,7 +183,7 @@ impl<'sess> OnDiskCache<'sess> {
176
183
. map ( |( k, v) | ( SerializedDepNodeIndex :: new ( k. index ( ) ) , v. clone ( ) ) )
177
184
. collect ( ) ;
178
185
179
- diagnostics . encode ( & mut encoder ) ?;
186
+ encoder . encode_tagged ( PREV_DIAGNOSTICS_TAG , & diagnostics ) ?;
180
187
181
188
182
189
// Encode all DefPathTables
@@ -192,7 +199,7 @@ impl<'sess> OnDiskCache<'sess> {
192
199
}
193
200
} ) . collect ( ) ;
194
201
195
- def_path_tables . encode ( & mut encoder ) ?;
202
+ encoder . encode_tagged ( DEF_PATH_TABLE_TAG , & def_path_tables ) ?;
196
203
197
204
return Ok ( ( ) ) ;
198
205
@@ -342,6 +349,30 @@ impl<'a, 'tcx, 'x> Decoder for CacheDecoder<'a, 'tcx, 'x> {
342
349
}
343
350
}
344
351
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
+
345
376
impl < ' a , ' tcx : ' a , ' x > ty_codec:: TyDecoder < ' a , ' tcx > for CacheDecoder < ' a , ' tcx , ' x > {
346
377
347
378
#[ inline]
@@ -565,6 +596,30 @@ struct CacheEncoder<'enc, 'tcx, E>
565
596
definitions : & ' enc Definitions ,
566
597
}
567
598
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
+
568
623
impl < ' enc , ' tcx , E > ty_codec:: TyEncoder for CacheEncoder < ' enc , ' tcx , E >
569
624
where E : ' enc + ty_codec:: TyEncoder
570
625
{
@@ -644,3 +699,4 @@ impl<'enc, 'tcx, E> Encoder for CacheEncoder<'enc, 'tcx, E>
644
699
emit_str( & str ) ;
645
700
}
646
701
}
702
+
0 commit comments