use std::env;
use std::fs;
use std::io::{self, Read};
-use std::path::Path;
+use std::path::{Path, PathBuf};
use rustc_data_structures::memmap::Mmap;
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
use rustc_serialize::Encoder;
+use rustc_session::Session;
/// The first few bytes of files generated by incremental compilation.
const FILE_MAGIC: &[u8] = b"RSIC";
/// the Git commit hash.
const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION");
-pub fn write_file_header(stream: &mut FileEncoder, nightly_build: bool) -> FileEncodeResult {
+pub(crate) fn write_file_header(stream: &mut FileEncoder, nightly_build: bool) -> FileEncodeResult {
stream.emit_raw_bytes(FILE_MAGIC)?;
stream.emit_raw_bytes(&[
(HEADER_FORMAT_VERSION >> 0) as u8,
stream.emit_raw_bytes(rustc_version.as_bytes())
}
+pub(crate) fn save_in<F>(sess: &Session, path_buf: PathBuf, name: &str, encode: F)
+where
+ F: FnOnce(&mut FileEncoder) -> FileEncodeResult,
+{
+ debug!("save: storing data in {}", path_buf.display());
+
+ // Delete the old file, if any.
+ // Note: It's important that we actually delete the old file and not just
+ // truncate and overwrite it, since it might be a shared hard-link, the
+ // underlying data of which we don't want to modify
+ match fs::remove_file(&path_buf) {
+ Ok(()) => {
+ debug!("save: remove old file");
+ }
+ Err(err) if err.kind() == io::ErrorKind::NotFound => (),
+ Err(err) => {
+ sess.err(&format!(
+ "unable to delete old {} at `{}`: {}",
+ name,
+ path_buf.display(),
+ err
+ ));
+ return;
+ }
+ }
+
+ let mut encoder = match FileEncoder::new(&path_buf) {
+ Ok(encoder) => encoder,
+ Err(err) => {
+ sess.err(&format!("failed to create {} at `{}`: {}", name, path_buf.display(), err));
+ return;
+ }
+ };
+
+ if let Err(err) = write_file_header(&mut encoder, sess.is_nightly_build()) {
+ sess.err(&format!("failed to write {} header to `{}`: {}", name, path_buf.display(), err));
+ return;
+ }
+
+ if let Err(err) = encode(&mut encoder) {
+ sess.err(&format!("failed to write {} to `{}`: {}", name, path_buf.display(), err));
+ return;
+ }
+
+ if let Err(err) = encoder.flush() {
+ sess.err(&format!("failed to flush {} to `{}`: {}", name, path_buf.display(), err));
+ return;
+ }
+
+ debug!("save: data written to disk successfully");
+}
+
/// Reads the contents of a file with a file header as defined in this module.
///
/// - Returns `Ok(Some(data, pos))` if the file existed and was generated by a
use rustc_serialize::Encodable as RustcEncodable;
use rustc_session::Session;
use std::fs;
-use std::io;
-use std::path::PathBuf;
use super::data::*;
use super::dirty_clean;
join(
move || {
sess.time("incr_comp_persist_result_cache", || {
- save_in(sess, query_cache_path, "query cache", |e| encode_query_cache(tcx, e));
+ file_format::save_in(sess, query_cache_path, "query cache", |e| {
+ encode_query_cache(tcx, e)
+ });
});
},
move || {
debug!("save_work_product_index()");
dep_graph.assert_ignored();
let path = work_products_path(sess);
- save_in(sess, path, "work product index", |e| encode_work_product_index(&new_work_products, e));
+ file_format::save_in(sess, path, "work product index", |e| {
+ encode_work_product_index(&new_work_products, e)
+ });
// We also need to clean out old work-products, as not all of them are
// deleted during invalidation. Some object files don't change their
});
}
-pub(crate) fn save_in<F>(sess: &Session, path_buf: PathBuf, name: &str, encode: F)
-where
- F: FnOnce(&mut FileEncoder) -> FileEncodeResult,
-{
- debug!("save: storing data in {}", path_buf.display());
-
- // Delete the old file, if any.
- // Note: It's important that we actually delete the old file and not just
- // truncate and overwrite it, since it might be a shared hard-link, the
- // underlying data of which we don't want to modify
- match fs::remove_file(&path_buf) {
- Ok(()) => {
- debug!("save: remove old file");
- }
- Err(err) if err.kind() == io::ErrorKind::NotFound => (),
- Err(err) => {
- sess.err(&format!(
- "unable to delete old {} at `{}`: {}",
- name,
- path_buf.display(),
- err
- ));
- return;
- }
- }
-
- let mut encoder = match FileEncoder::new(&path_buf) {
- Ok(encoder) => encoder,
- Err(err) => {
- sess.err(&format!("failed to create {} at `{}`: {}", name, path_buf.display(), err));
- return;
- }
- };
-
- if let Err(err) = file_format::write_file_header(&mut encoder, sess.is_nightly_build()) {
- sess.err(&format!("failed to write {} header to `{}`: {}", name, path_buf.display(), err));
- return;
- }
-
- if let Err(err) = encode(&mut encoder) {
- sess.err(&format!("failed to write {} to `{}`: {}", name, path_buf.display(), err));
- return;
- }
-
- if let Err(err) = encoder.flush() {
- sess.err(&format!("failed to flush {} to `{}`: {}", name, path_buf.display(), err));
- return;
- }
-
- debug!("save: data written to disk successfully");
-}
-
fn encode_work_product_index(
work_products: &FxHashMap<WorkProductId, WorkProduct>,
encoder: &mut FileEncoder,