about summary refs log tree commit diff
path: root/compiler/rustc_query_system/src
diff options
context:
space:
mode:
authorAaron Hill <aa1ronham@gmail.com>2021-08-12 15:11:21 -0500
committerAaron Hill <aa1ronham@gmail.com>2021-08-12 15:11:39 -0500
commit77b02eed7b4d15e5395019d02e8c60fdfdf3ee9c (patch)
tree9aeab22760b343459620094603a28e829dd3ea2a /compiler/rustc_query_system/src
parent4498e300e41f47c75abe4e49ec91ae949aaeea5f (diff)
downloadrust-77b02eed7b4d15e5395019d02e8c60fdfdf3ee9c.tar.gz
rust-77b02eed7b4d15e5395019d02e8c60fdfdf3ee9c.zip
Prevent double panic when handling incremental fingerprint mismatch
When an incremental fingerprint mismatch occurs, we debug-print
our `DepNode` and query result. Unfortunately, the debug printing
process may cause us to run additional queries, which can result
in a re-entrant fingerprint mismatch error.

To avoid a double panic, this commit adds a thread-local variable
to detect re-entrant calls.
Diffstat (limited to 'compiler/rustc_query_system/src')
-rw-r--r--compiler/rustc_query_system/src/lib.rs1
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs33
2 files changed, 28 insertions, 6 deletions
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index 0d4fb34265c..c205f0fb531 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -3,6 +3,7 @@
 #![feature(hash_raw_entry)]
 #![feature(iter_zip)]
 #![feature(min_specialization)]
+#![feature(thread_local_const_init)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index a708631af0a..a7511846cad 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -20,6 +20,7 @@ use rustc_data_structures::thin_vec::ThinVec;
 use rustc_errors::DiagnosticBuilder;
 use rustc_errors::{Diagnostic, FatalError};
 use rustc_span::{Span, DUMMY_SP};
+use std::cell::Cell;
 use std::collections::hash_map::Entry;
 use std::fmt::Debug;
 use std::hash::{Hash, Hasher};
@@ -618,12 +619,32 @@ fn incremental_verify_ich<CTX, K, V: Debug>(
         } else {
             "`cargo clean`".to_string()
         };
-        tcx.sess().struct_err(&format!("internal compiler error: encountered incremental compilation error with {:?}", dep_node))
-            .help(&format!("This is a known issue with the compiler. Run {} to allow your project to compile", run_cmd))
-            .note(&"Please follow the instructions below to create a bug report with the provided information")
-            .note(&"See <https://github.com/rust-lang/rust/issues/84970> for more information")
-            .emit();
-        panic!("Found unstable fingerprints for {:?}: {:?}", dep_node, result);
+
+        // When we emit an error message and panic, we try to debug-print the `DepNode`
+        // and query result. Unforunately, this can cause us to run additional queries,
+        // which may result in another fingerprint mismatch while we're in the middle
+        // of processing this one. To avoid a double-panic (which kills the process
+        // before we can print out the query static), we print out a terse
+        // but 'safe' message if we detect a re-entrant call to this method.
+        thread_local! {
+            static INSIDE_VERIFY_PANIC: Cell<bool> = const { Cell::new(false) };
+        };
+
+        let old_in_panic = INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.replace(true));
+
+        if old_in_panic {
+            tcx.sess().struct_err("internal compiler error: re-entrant incremental verify failure, suppressing message")
+                .emit();
+        } else {
+            tcx.sess().struct_err(&format!("internal compiler error: encountered incremental compilation error with {:?}", dep_node))
+                .help(&format!("This is a known issue with the compiler. Run {} to allow your project to compile", run_cmd))
+                .note(&"Please follow the instructions below to create a bug report with the provided information")
+                .note(&"See <https://github.com/rust-lang/rust/issues/84970> for more information")
+                .emit();
+            panic!("Found unstable fingerprints for {:?}: {:?}", dep_node, result);
+        }
+
+        INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.set(old_in_panic));
     }
 }