Rollup merge of #106321 - compiler-errors:delayed-bug-backtrace, r=Nilstrieb
Collect and emit proper backtraces for `delay_span_bug`s This is a follow-up to #106317, which addresses this comment (https://github.com/rust-lang/rust/issues/106267#issuecomment-1367507507) which notes that `delay_span_bug`s' backtraces are nonsense. Captures and emits the backtrace of the delayed span bug when it's *created*, rather than using the backtrace of the place where delayed bugs are flushed. --- To test, I delayed a span bug during HIR typeck, specifically in `typeck_with_fallback`... Before, note `flush_delayed` on frame 18. This is at the end of the compilation session, far from where the bug is being delayed. ``` error: internal compiler error: test --> /home/ubuntu/test.rs:1:1 | 1 | fn main() {} | ^^^^^^^^^ | = note: delayed at compiler/rustc_hir_typeck/src/lib.rs:196:14 thread 'rustc' panicked at 'Box<dyn Any>', compiler/rustc_errors/src/lib.rs:1634:13 stack backtrace: 0: 0x7f9c3ec69dd1 - std::backtrace_rs::backtrace::libunwind::trace::h26056f81198c6594 at /home/ubuntu/rust2/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5 1: 0x7f9c3ec69dd1 - std::backtrace_rs::backtrace::trace_unsynchronized::hacfb345a0c6d5bb1 at /home/ubuntu/rust2/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5 2: 0x7f9c3ec69dd1 - std::sys_common::backtrace::_print_fmt::h18ea6016ac8030f3 at /home/ubuntu/rust2/library/std/src/sys_common/backtrace.rs:65:5 3: 0x7f9c3ec69dd1 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::he35dde201d0c2d09 at /home/ubuntu/rust2/library/std/src/sys_common/backtrace.rs:44:22 4: 0x7f9c3ecee308 - core::fmt::write::h094ad263467a053c at /home/ubuntu/rust2/library/core/src/fmt/mod.rs:1208:17 5: 0x7f9c3ec8aaf1 - std::io::Write::write_fmt::hd47b4e2324b4d9b7 at /home/ubuntu/rust2/library/std/src/io/mod.rs:1682:15 6: 0x7f9c3ec69bfa - std::sys_common::backtrace::_print::h43044162653a17fc at /home/ubuntu/rust2/library/std/src/sys_common/backtrace.rs:47:5 7: 0x7f9c3ec69bfa - std::sys_common::backtrace::print::hc8605da258fa5aeb at /home/ubuntu/rust2/library/std/src/sys_common/backtrace.rs:34:9 8: 0x7f9c3ec4db87 - std::panicking::default_hook::{{closure}}::h9e37f23f75122a15 9: 0x7f9c3ec4d97b - std::panicking::default_hook::h602873a063f84da2 at /home/ubuntu/rust2/library/std/src/panicking.rs:286:9 10: 0x7f9c3f6672b2 - <alloc[48d7b30605060536]::boxed::Box<dyn for<'a, 'b> core[672e3947e150d6c6]::ops::function::Fn<(&'a core[672e3947e150d6c6]::panic::panic_info::PanicInfo<'b>,), Output = ()> + core[672e3947e150d6c6]::marker::Send + core[672e3947e150d6c6]::marker::Sync> as core[672e3947e150d6c6]::ops::function::Fn<(&core[672e3947e150d6c6]::panic::panic_info::PanicInfo,)>>::call at /home/ubuntu/rust2/library/alloc/src/boxed.rs:2002:9 11: 0x7f9c3f6672b2 - rustc_driver[f5b6d32d8905ecdd]::DEFAULT_HOOK::{closure#0}::{closure#0} at /home/ubuntu/rust2/compiler/rustc_driver/src/lib.rs:1204:17 12: 0x7f9c3ec4e0d3 - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::hfd13333ca953ae8e at /home/ubuntu/rust2/library/alloc/src/boxed.rs:2002:9 13: 0x7f9c3ec4e0d3 - std::panicking::rust_panic_with_hook::h45753e10264ebe7e at /home/ubuntu/rust2/library/std/src/panicking.rs:692:13 14: 0x7f9c422a1aa3 - std[3330b4673efabfce]::panicking::begin_panic::<rustc_errors[1b15f4e7e49d1fd5]::ExplicitBug>::{closure#0} at /home/ubuntu/rust2/library/std/src/panicking.rs:608:9 15: 0x7f9c422a1a46 - std[3330b4673efabfce]::sys_common::backtrace::__rust_end_short_backtrace::<std[3330b4673efabfce]::panicking::begin_panic<rustc_errors[1b15f4e7e49d1fd5]::ExplicitBug>::{closure#0}, !> at /home/ubuntu/rust2/library/std/src/sys_common/backtrace.rs:137:18 16: 0x7f9c3f63a996 - std[3330b4673efabfce]::panicking::begin_panic::<rustc_errors[1b15f4e7e49d1fd5]::ExplicitBug> at /home/ubuntu/rust2/library/std/src/panicking.rs:607:12 17: 0x7f9c4227a496 - std[3330b4673efabfce]::panic::panic_any::<rustc_errors[1b15f4e7e49d1fd5]::ExplicitBug> at /home/ubuntu/rust2/library/std/src/panic.rs:61:5 18: 0x7f9c4227cdf7 - <rustc_errors[1b15f4e7e49d1fd5]::HandlerInner>::flush_delayed::<alloc[48d7b30605060536]::vec::Vec<rustc_errors[1b15f4e7e49d1fd5]::diagnostic::Diagnostic>, &str, rustc_errors[1b15f4e7e49d1fd5]::ExplicitBug> at /home/ubuntu/rust2/compiler/rustc_errors/src/lib.rs:1634:13 19: 0x7f9c422498cf - <rustc_errors[1b15f4e7e49d1fd5]::Handler>::flush_delayed at /home/ubuntu/rust2/compiler/rustc_errors/src/lib.rs:1225:9 [ FRAMES INTENTIONALLY OMITTED ] 44: 0x7f9c3f6f3584 - <std[3330b4673efabfce]:🧵:Builder>::spawn_unchecked_::<rustc_interface[947706ead88047d0]::util::run_in_thread_pool_with_globals<rustc_interface[947706ead88047d0]::interface::run_compiler<core[672e3947e150d6c6]::result::Result<(), rustc_errors[1b15f4e7e49d1fd5]::ErrorGuaranteed>, rustc_driver[f5b6d32d8905ecdd]::run_compiler::{closure#1}>::{closure#0}, core[672e3947e150d6c6]::result::Result<(), rustc_errors[1b15f4e7e49d1fd5]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[672e3947e150d6c6]::result::Result<(), rustc_errors[1b15f4e7e49d1fd5]::ErrorGuaranteed>>::{closure#1} at /home/ubuntu/rust2/library/std/src/thread/mod.rs:549:30 45: 0x7f9c3f6f3584 - <<std[3330b4673efabfce]:🧵:Builder>::spawn_unchecked_<rustc_interface[947706ead88047d0]::util::run_in_thread_pool_with_globals<rustc_interface[947706ead88047d0]::interface::run_compiler<core[672e3947e150d6c6]::result::Result<(), rustc_errors[1b15f4e7e49d1fd5]::ErrorGuaranteed>, rustc_driver[f5b6d32d8905ecdd]::run_compiler::{closure#1}>::{closure#0}, core[672e3947e150d6c6]::result::Result<(), rustc_errors[1b15f4e7e49d1fd5]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[672e3947e150d6c6]::result::Result<(), rustc_errors[1b15f4e7e49d1fd5]::ErrorGuaranteed>>::{closure#1} as core[672e3947e150d6c6]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0} at /home/ubuntu/rust2/library/core/src/ops/function.rs:250:5 46: 0x7f9c3ec81968 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::he8b26fc22c6f51ec at /home/ubuntu/rust2/library/alloc/src/boxed.rs:1988:9 47: 0x7f9c3ec81968 - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h5cf9cbe75a8c3ddc at /home/ubuntu/rust2/library/alloc/src/boxed.rs:1988:9 48: 0x7f9c3ec5f99c - std::sys::unix:🧵:Thread:🆕:thread_start::h2d6dd4455e97d031 at /home/ubuntu/rust2/library/std/src/sys/unix/thread.rs:108:17 49: 0x7f9c37c69609 - start_thread 50: 0x7f9c3ead0133 - clone 51: 0x0 - <unknown> ``` After, note `typeck_with_fallback` on the 5th frame, that's where we *actually* need to be pointed to: ``` error: internal compiler error: no errors encountered even though `delay_span_bug` issued error: internal compiler error: test --> /home/ubuntu/test.rs:1:1 | 1 | fn main() {} | ^^^^^^^^^ | = note: delayed at 0: <rustc_errors::HandlerInner>::emit_diagnostic at ./compiler/rustc_errors/src/lib.rs:1279:29 1: <rustc_errors::HandlerInner>::delay_span_bug::<rustc_span::span_encoding::Span, &str> at ./compiler/rustc_errors/src/lib.rs:1553:9 2: <rustc_errors::Handler>::delay_span_bug::<rustc_span::span_encoding::Span, &str> at ./compiler/rustc_errors/src/lib.rs:995:9 3: <rustc_session::session::Session>::delay_span_bug::<rustc_span::span_encoding::Span, &str> at ./compiler/rustc_session/src/session.rs:600:9 4: rustc_hir_typeck::typeck_with_fallback::<rustc_hir_typeck::typeck::{closure#0}>::{closure#0} at ./compiler/rustc_hir_typeck/src/lib.rs:196:5 5: rustc_hir_typeck::typeck_with_fallback::<rustc_hir_typeck::typeck::{closure#0}> at ./compiler/rustc_hir_typeck/src/lib.rs:185:36 6: rustc_hir_typeck::typeck at ./compiler/rustc_hir_typeck/src/lib.rs:166:9 [ FRAMES INTENTIONALLY OMITTED ] 108: std::panicking::try::<core::result::Result<(), rustc_errors::ErrorGuaranteed>, core::panic::unwind_safe::AssertUnwindSafe<<std:🧵:Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#1}::{closure#0}>> at ./library/std/src/panicking.rs:447:19 109: std::panic::catch_unwind::<core::panic::unwind_safe::AssertUnwindSafe<<std:🧵:Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#1}::{closure#0}>, core::result::Result<(), rustc_errors::ErrorGuaranteed>> at ./library/std/src/panic.rs:140:14 110: <std:🧵:Builder>::spawn_unchecked_::<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#1} at ./library/std/src/thread/mod.rs:549:30 111: <<std:🧵:Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorGuaranteed>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorGuaranteed>>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0} at ./library/core/src/ops/function.rs:250:5 112: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once at ./library/alloc/src/boxed.rs:1988:9 113: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once at ./library/alloc/src/boxed.rs:1988:9 114: std::sys::unix:🧵:Thread:🆕:thread_start at ./library/std/src/sys/unix/thread.rs:108:17 115: start_thread 116: clone ```
This commit is contained in:
commit
0681a9652e
2 changed files with 18 additions and 26 deletions
|
@ -1196,8 +1196,8 @@ static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send +
|
|||
};
|
||||
|
||||
// Invoke the default handler, which prints the actual panic message and optionally a backtrace
|
||||
// Don't do this for `GoodPathBug`, which already emits its own more useful backtrace.
|
||||
if !info.payload().is::<rustc_errors::GoodPathBug>() {
|
||||
// Don't do this for delayed bugs, which already emit their own more useful backtrace.
|
||||
if !info.payload().is::<rustc_errors::DelayedBugPanic>() {
|
||||
(*DEFAULT_HOOK)(info);
|
||||
|
||||
// Separate the output with an empty line
|
||||
|
@ -1235,7 +1235,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
|
|||
// a .span_bug or .bug call has already printed what
|
||||
// it wants to print.
|
||||
if !info.payload().is::<rustc_errors::ExplicitBug>()
|
||||
&& !info.payload().is::<rustc_errors::GoodPathBug>()
|
||||
&& !info.payload().is::<rustc_errors::DelayedBugPanic>()
|
||||
{
|
||||
let mut d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic");
|
||||
handler.emit_diagnostic(&mut d);
|
||||
|
|
|
@ -40,7 +40,6 @@ use rustc_span::source_map::SourceMap;
|
|||
use rustc_span::HashStableContext;
|
||||
use rustc_span::{Loc, Span};
|
||||
|
||||
use std::any::Any;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
|
@ -364,9 +363,9 @@ pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
|
|||
/// or `.span_bug` rather than a failed assertion, etc.
|
||||
pub struct ExplicitBug;
|
||||
|
||||
/// Signifies that the compiler died with an explicit call to `.delay_good_path_bug`
|
||||
/// Signifies that the compiler died with an explicit call to `.delay_*_bug`
|
||||
/// rather than a failed assertion, etc.
|
||||
pub struct GoodPathBug;
|
||||
pub struct DelayedBugPanic;
|
||||
|
||||
pub use diagnostic::{
|
||||
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
|
||||
|
@ -399,7 +398,7 @@ struct HandlerInner {
|
|||
warn_count: usize,
|
||||
deduplicated_err_count: usize,
|
||||
emitter: Box<dyn Emitter + sync::Send>,
|
||||
delayed_span_bugs: Vec<Diagnostic>,
|
||||
delayed_span_bugs: Vec<DelayedDiagnostic>,
|
||||
delayed_good_path_bugs: Vec<DelayedDiagnostic>,
|
||||
/// This flag indicates that an expected diagnostic was emitted and suppressed.
|
||||
/// This is used for the `delayed_good_path_bugs` check.
|
||||
|
@ -505,11 +504,7 @@ impl Drop for HandlerInner {
|
|||
|
||||
if !self.has_errors() {
|
||||
let bugs = std::mem::replace(&mut self.delayed_span_bugs, Vec::new());
|
||||
self.flush_delayed(
|
||||
bugs,
|
||||
"no errors encountered even though `delay_span_bug` issued",
|
||||
ExplicitBug,
|
||||
);
|
||||
self.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued");
|
||||
}
|
||||
|
||||
// FIXME(eddyb) this explains what `delayed_good_path_bugs` are!
|
||||
|
@ -520,9 +515,8 @@ impl Drop for HandlerInner {
|
|||
if !self.has_any_message() && !self.suppressed_expected_diag {
|
||||
let bugs = std::mem::replace(&mut self.delayed_good_path_bugs, Vec::new());
|
||||
self.flush_delayed(
|
||||
bugs.into_iter().map(DelayedDiagnostic::decorate),
|
||||
bugs,
|
||||
"no warnings or errors encountered even though `delayed_good_path_bugs` issued",
|
||||
GoodPathBug,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1223,11 +1217,7 @@ impl Handler {
|
|||
pub fn flush_delayed(&self) {
|
||||
let mut inner = self.inner.lock();
|
||||
let bugs = std::mem::replace(&mut inner.delayed_span_bugs, Vec::new());
|
||||
inner.flush_delayed(
|
||||
bugs,
|
||||
"no errors encountered even though `delay_span_bug` issued",
|
||||
ExplicitBug,
|
||||
);
|
||||
inner.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1287,7 +1277,9 @@ impl HandlerInner {
|
|||
// once *any* errors were emitted (and truncate `delayed_span_bugs`
|
||||
// when an error is first emitted, also), but maybe there's a case
|
||||
// in which that's not sound? otherwise this is really inefficient.
|
||||
self.delayed_span_bugs.push(diagnostic.clone());
|
||||
let backtrace = std::backtrace::Backtrace::force_capture();
|
||||
self.delayed_span_bugs
|
||||
.push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
|
||||
|
||||
if !self.flags.report_delayed_bugs {
|
||||
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
|
||||
|
@ -1562,7 +1554,6 @@ impl HandlerInner {
|
|||
}
|
||||
let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
|
||||
diagnostic.set_span(sp.into());
|
||||
diagnostic.note(&format!("delayed at {}", std::panic::Location::caller()));
|
||||
self.emit_diagnostic(&mut diagnostic).unwrap()
|
||||
}
|
||||
|
||||
|
@ -1605,12 +1596,13 @@ impl HandlerInner {
|
|||
|
||||
fn flush_delayed(
|
||||
&mut self,
|
||||
bugs: impl IntoIterator<Item = Diagnostic>,
|
||||
bugs: impl IntoIterator<Item = DelayedDiagnostic>,
|
||||
explanation: impl Into<DiagnosticMessage> + Copy,
|
||||
panic_with: impl Any + Send + 'static,
|
||||
) {
|
||||
let mut no_bugs = true;
|
||||
for mut bug in bugs {
|
||||
for bug in bugs {
|
||||
let mut bug = bug.decorate();
|
||||
|
||||
if no_bugs {
|
||||
// Put the overall explanation before the `DelayedBug`s, to
|
||||
// frame them better (e.g. separate warnings from them).
|
||||
|
@ -1633,9 +1625,9 @@ impl HandlerInner {
|
|||
self.emit_diagnostic(&mut bug);
|
||||
}
|
||||
|
||||
// Panic with `ExplicitBug` to avoid "unexpected panic" messages.
|
||||
// Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
|
||||
if !no_bugs {
|
||||
panic::panic_any(panic_with);
|
||||
panic::panic_any(DelayedBugPanic);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue