Skip to content

Commit

Permalink
Prevent double panic when handling incremental fingerprint mismatch
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Aaron1011 committed Aug 12, 2021
1 parent 4498e30 commit 77b02ee
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_query_system/src/lib.rs
Expand Up @@ -3,6 +3,7 @@
#![feature(hash_raw_entry)]
#![feature(iter_zip)]
#![feature(min_specialization)]
#![feature(thread_local_const_init)]

#[macro_use]
extern crate tracing;
Expand Down
33 changes: 27 additions & 6 deletions compiler/rustc_query_system/src/query/plumbing.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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));
}
}

Expand Down

0 comments on commit 77b02ee

Please sign in to comment.