|
1 |
| -use crate::errors::{FailCreateFileEncoder, FailSeekFile, FailWriteFile}; |
| 1 | +use crate::errors::{FailCreateFileEncoder, FailWriteFile}; |
2 | 2 | use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
|
3 | 3 | use crate::rmeta::table::TableBuilder;
|
4 | 4 | use crate::rmeta::*;
|
@@ -42,6 +42,7 @@ use rustc_span::symbol::{sym, Symbol};
|
42 | 42 | use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SpanData, SyntaxContext};
|
43 | 43 | use std::borrow::Borrow;
|
44 | 44 | use std::collections::hash_map::Entry;
|
| 45 | +use std::fs::File; |
45 | 46 | use std::hash::Hash;
|
46 | 47 | use std::io::{Read, Seek, Write};
|
47 | 48 | use std::num::NonZeroUsize;
|
@@ -2255,25 +2256,34 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>, path: &Path) {
|
2255 | 2256 | // culminating in the `CrateRoot` which points to all of it.
|
2256 | 2257 | let root = ecx.encode_crate_root();
|
2257 | 2258 |
|
2258 |
| - ecx.opaque.flush(); |
| 2259 | + // Make sure we report any errors from writing to the file. |
| 2260 | + // If we forget this, compilation can succeed with an incomplete rmeta file, |
| 2261 | + // causing an ICE when the rmeta file is read by another compilation. |
| 2262 | + if let Err((path, err)) = ecx.opaque.finish() { |
| 2263 | + tcx.sess.emit_err(FailWriteFile { path: &path, err }); |
| 2264 | + } |
| 2265 | + |
| 2266 | + let file = ecx.opaque.file(); |
| 2267 | + if let Err(err) = encode_root_position(file, root.position.get()) { |
| 2268 | + tcx.sess.emit_err(FailWriteFile { path: ecx.opaque.path(), err }); |
| 2269 | + } |
| 2270 | + |
| 2271 | + // Record metadata size for self-profiling |
| 2272 | + tcx.prof.artifact_size("crate_metadata", "crate_metadata", file.metadata().unwrap().len()); |
| 2273 | +} |
2259 | 2274 |
|
2260 |
| - let mut file = ecx.opaque.file(); |
| 2275 | +fn encode_root_position(mut file: &File, pos: usize) -> Result<(), std::io::Error> { |
2261 | 2276 | // We will return to this position after writing the root position.
|
2262 | 2277 | let pos_before_seek = file.stream_position().unwrap();
|
2263 | 2278 |
|
2264 | 2279 | // Encode the root position.
|
2265 | 2280 | let header = METADATA_HEADER.len();
|
2266 |
| - file.seek(std::io::SeekFrom::Start(header as u64)) |
2267 |
| - .unwrap_or_else(|err| tcx.sess.emit_fatal(FailSeekFile { err })); |
2268 |
| - let pos = root.position.get(); |
2269 |
| - file.write_all(&[(pos >> 24) as u8, (pos >> 16) as u8, (pos >> 8) as u8, (pos >> 0) as u8]) |
2270 |
| - .unwrap_or_else(|err| tcx.sess.emit_fatal(FailWriteFile { err })); |
| 2281 | + file.seek(std::io::SeekFrom::Start(header as u64))?; |
| 2282 | + file.write_all(&[(pos >> 24) as u8, (pos >> 16) as u8, (pos >> 8) as u8, (pos >> 0) as u8])?; |
2271 | 2283 |
|
2272 | 2284 | // Return to the position where we are before writing the root position.
|
2273 |
| - file.seek(std::io::SeekFrom::Start(pos_before_seek)).unwrap(); |
2274 |
| - |
2275 |
| - // Record metadata size for self-profiling |
2276 |
| - tcx.prof.artifact_size("crate_metadata", "crate_metadata", file.metadata().unwrap().len()); |
| 2285 | + file.seek(std::io::SeekFrom::Start(pos_before_seek))?; |
| 2286 | + Ok(()) |
2277 | 2287 | }
|
2278 | 2288 |
|
2279 | 2289 | pub fn provide(providers: &mut Providers) {
|
|
0 commit comments