@@ -17,7 +17,8 @@ use rustc_session::Session;
1717use std:: borrow:: Cow ;
1818use std:: env;
1919use std:: fs;
20- use std:: io:: { self , Read } ;
20+ use std:: io:: { self , Read , Write } ;
21+ use std:: io:: { Seek , SeekFrom } ;
2122use std:: path:: { Path , PathBuf } ;
2223
2324/// The first few bytes of files generated by incremental compilation.
@@ -35,6 +36,8 @@ pub(crate) fn write_file_header(stream: &mut FileEncoder, sess: &Session) {
3536 assert_eq ! ( rustc_version. len( ) , ( rustc_version. len( ) as u8 ) as usize ) ;
3637 stream. emit_raw_bytes ( & [ rustc_version. len ( ) as u8 ] ) ;
3738 stream. emit_raw_bytes ( rustc_version. as_bytes ( ) ) ;
39+ // Reserve space for the u64 where we will later write in the expected total size of this file.
40+ stream. emit_raw_bytes ( & 0u64 . to_le_bytes ( ) ) ;
3841}
3942
4043pub ( crate ) fn save_in < F > ( sess : & Session , path_buf : PathBuf , name : & str , encode : F )
6568
6669 write_file_header ( & mut encoder, sess) ;
6770
71+ let len_offset = encoder. position ( ) - 8 ;
72+
6873 match encode ( encoder) {
6974 Ok ( position) => {
7075 sess. prof . artifact_size (
7681 }
7782 Err ( ( path, err) ) => sess. dcx ( ) . emit_fatal ( errors:: WriteNew { name, path, err } ) ,
7883 }
84+
85+ if let Err ( err) = write_file_len ( & path_buf, len_offset as u64 ) {
86+ sess. dcx ( ) . emit_fatal ( errors:: WriteNew { name, path : path_buf, err } ) ;
87+ }
88+ }
89+
90+ fn write_file_len ( path : & Path , offset : u64 ) -> Result < ( ) , std:: io:: Error > {
91+ let mut file = fs:: File :: options ( ) . write ( true ) . create ( false ) . open ( path) ?;
92+ let len = file. metadata ( ) ?. len ( ) ;
93+ file. seek ( SeekFrom :: Start ( offset) ) ?;
94+ file. write_all ( & len. to_le_bytes ( ) )
7995}
8096
8197/// Reads the contents of a file with a file header as defined in this module.
@@ -147,6 +163,14 @@ pub fn read_file(
147163 }
148164 }
149165
166+ // Check FILE_LEN
167+ {
168+ let mut len = [ 0u8 ; 8 ] ;
169+ file. read_exact ( & mut len) ?;
170+ let len_in_header = u64:: from_le_bytes ( len) ;
171+ assert_eq ! ( len_in_header, fs:: metadata( path) ?. len( ) ) ;
172+ }
173+
150174 let post_header_start_pos = file. position ( ) as usize ;
151175 Ok ( Some ( ( mmap, post_header_start_pos) ) )
152176}
0 commit comments