diff options
| author | bors <bors@rust-lang.org> | 2018-04-07 02:51:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-07 02:51:17 +0000 |
| commit | ee1014e50570e4572980e2496634cbb0eac768dd (patch) | |
| tree | 20af1439556617699e663f7452560acbfed30a30 | |
| parent | 5911314efd39cabd7ee262da31cf0cb3faea4d7b (diff) | |
| parent | 4fd188e5f31f14625eb8b1feec38da5ad538e3c9 (diff) | |
Auto merge of #49222 - Zoxc:print-query-stack, r=nikomatsakis
Print query stack on ICEs
ICE output is now:
```
thread 'rustc' panicked at 'no borrowck', librustc_borrowck\borrowck\mod.rs:95:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
query stack during panic:
#0 [borrowck] processing `main`
--> no-std.rs:10:1
|
10 | fn main() {}
| ^^^^^^^^^
end of query stack
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.26.0-dev running on x86_64-pc-windows-msvc
```
Fixes #42529.
r? @eddyb
| -rw-r--r-- | src/librustc/ty/maps/plumbing.rs | 35 | ||||
| -rw-r--r-- | src/librustc/util/common.rs | 10 | ||||
| -rw-r--r-- | src/librustc_errors/lib.rs | 5 |
3 files changed, 49 insertions, 1 deletions
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 65571aa6a69..232b300e754 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -14,6 +14,8 @@ use dep_graph::{DepNodeIndex, DepNode, DepKind, DepNodeColor}; use errors::DiagnosticBuilder; +use errors::Level; +use ty::tls; use ty::{TyCtxt}; use ty::maps::config::QueryDescription; use ty::maps::job::{QueryResult, QueryInfo}; @@ -108,6 +110,33 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }) } + pub fn try_print_query_stack() { + eprintln!("query stack during panic:"); + + tls::with_context_opt(|icx| { + if let Some(icx) = icx { + let mut current_query = icx.query.clone(); + let mut i = 0; + + while let Some(query) = current_query { + let mut db = DiagnosticBuilder::new(icx.tcx.sess.diagnostic(), + Level::FailureNote, + &format!("#{} [{}] {}", + i, + query.info.query.name(), + query.info.query.describe(icx.tcx))); + db.set_span(icx.tcx.sess.codemap().def_span(query.info.span)); + icx.tcx.sess.diagnostic().force_print_db(db); + + current_query = query.parent.clone(); + i += 1; + } + } + }); + + eprintln!("end of query stack"); + } + /// Try to read a node index for the node dep_node. /// A node will have an index, when it's already been marked green, or when we can mark it /// green. This function will mark the current task as a reader of the specified node, when @@ -219,6 +248,12 @@ macro_rules! define_maps { } impl<$tcx> Query<$tcx> { + pub fn name(&self) -> &'static str { + match *self { + $(Query::$name(_) => stringify!($name),)* + } + } + pub fn describe(&self, tcx: TyCtxt) -> String { let (r, name) = match *self { $(Query::$name(key) => { diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 6b896a889e3..32ec837f031 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -17,12 +17,14 @@ use std::fmt::Debug; use std::hash::{Hash, BuildHasher}; use std::iter::repeat; use std::panic; +use std::env; use std::path::Path; use std::time::{Duration, Instant}; use std::sync::mpsc::{Sender}; use syntax_pos::{SpanData}; use ty::maps::{QueryMsg}; +use ty::TyCtxt; use dep_graph::{DepNode}; use proc_macro; use lazy_static; @@ -48,7 +50,13 @@ lazy_static! { fn panic_hook(info: &panic::PanicInfo) { if !proc_macro::__internal::in_sess() { - (*DEFAULT_HOOK)(info) + (*DEFAULT_HOOK)(info); + + let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false); + + if backtrace { + TyCtxt::try_print_query_stack(); + } } } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 990ae2fc544..43fe812a6ce 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -641,6 +641,11 @@ impl Handler { self.tracked_diagnostic_codes.borrow().contains(code) } + pub fn force_print_db(&self, mut db: DiagnosticBuilder) { + self.emitter.borrow_mut().emit(&db); + db.cancel(); + } + fn emit_db(&self, db: &DiagnosticBuilder) { let diagnostic = &**db; |
