about summary refs log tree commit diff
path: root/compiler/rustc_incremental
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_incremental')
-rw-r--r--compiler/rustc_incremental/messages.ftl2
-rw-r--r--compiler/rustc_incremental/src/errors.rs6
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs21
3 files changed, 25 insertions, 4 deletions
diff --git a/compiler/rustc_incremental/messages.ftl b/compiler/rustc_incremental/messages.ftl
index e74173b24a9..de2177ebb6e 100644
--- a/compiler/rustc_incremental/messages.ftl
+++ b/compiler/rustc_incremental/messages.ftl
@@ -21,6 +21,8 @@ incremental_cargo_help_2 =
 incremental_copy_workproduct_to_cache =
     error copying object file `{$from}` to incremental directory as `{$to}`: {$err}
 
+incremental_corrupt_file = corrupt incremental compilation artifact found at `{$path}`. This file will automatically be ignored and deleted. If you see this message repeatedly or can provoke it without manually manipulating the compiler's artifacts, please file an issue. The incremental compilation system relies on hardlinks and filesystem locks behaving correctly, and may not deal well with OS crashes, so whatever information you can provide about your filesystem or other state may be very relevant.
+
 incremental_create_dep_graph = failed to create dependency graph at `{$path}`: {$err}
 
 incremental_create_incr_comp_dir =
diff --git a/compiler/rustc_incremental/src/errors.rs b/compiler/rustc_incremental/src/errors.rs
index 61bb0353a9f..e94a7fb876b 100644
--- a/compiler/rustc_incremental/src/errors.rs
+++ b/compiler/rustc_incremental/src/errors.rs
@@ -306,3 +306,9 @@ pub struct DeleteWorkProduct<'a> {
     pub path: &'a Path,
     pub err: std::io::Error,
 }
+
+#[derive(Diagnostic)]
+#[diag(incremental_corrupt_file)]
+pub struct CorruptFile<'a> {
+    pub path: &'a Path,
+}
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 26aaa24771f..9e6ce066785 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -115,7 +115,12 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkPr
 
         if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result {
             // Decode the list of work_products
-            let mut work_product_decoder = MemDecoder::new(&work_products_data[..], start_pos);
+            let Ok(mut work_product_decoder) =
+                MemDecoder::new(&work_products_data[..], start_pos)
+            else {
+                sess.dcx().emit_warn(errors::CorruptFile { path: &work_products_path });
+                return LoadResult::DataOutOfDate;
+            };
             let work_products: Vec<SerializedWorkProduct> =
                 Decodable::decode(&mut work_product_decoder);
 
@@ -145,7 +150,10 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkPr
         LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
         LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
         LoadResult::Ok { data: (bytes, start_pos) } => {
-            let mut decoder = MemDecoder::new(&bytes, start_pos);
+            let Ok(mut decoder) = MemDecoder::new(&bytes, start_pos) else {
+                sess.dcx().emit_warn(errors::CorruptFile { path: &path });
+                return LoadResult::DataOutOfDate;
+            };
             let prev_commandline_args_hash = u64::decode(&mut decoder);
 
             if prev_commandline_args_hash != expected_hash {
@@ -181,9 +189,14 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache<'_>> {
 
     let _prof_timer = sess.prof.generic_activity("incr_comp_load_query_result_cache");
 
-    match load_data(&query_cache_path(sess), sess) {
+    let path = query_cache_path(sess);
+    match load_data(&path, sess) {
         LoadResult::Ok { data: (bytes, start_pos) } => {
-            Some(OnDiskCache::new(sess, bytes, start_pos))
+            let cache = OnDiskCache::new(sess, bytes, start_pos).unwrap_or_else(|()| {
+                sess.dcx().emit_warn(errors::CorruptFile { path: &path });
+                OnDiskCache::new_empty(sess.source_map())
+            });
+            Some(cache)
         }
         _ => Some(OnDiskCache::new_empty(sess.source_map())),
     }