From 77b02eed7b4d15e5395019d02e8c60fdfdf3ee9c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 12 Aug 2021 15:11:21 -0500 Subject: [PATCH] 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. --- compiler/rustc_query_system/src/lib.rs | 1 + .../rustc_query_system/src/query/plumbing.rs | 33 +++++++++++++++---- 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 0d4fb34265c55..c205f0fb531ae 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 a708631af0a7d..a7511846cadb6 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( } 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 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 = 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 for more information") + .emit(); + panic!("Found unstable fingerprints for {:?}: {:?}", dep_node, result); + } + + INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.set(old_in_panic)); } }