Collect backtraces for delayed span-bugs too
This commit is contained in:
parent
3020239de9
commit
05c1ac0215
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
|
// 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.
|
// Don't do this for delayed bugs, which already emit their own more useful backtrace.
|
||||||
if !info.payload().is::<rustc_errors::GoodPathBug>() {
|
if !info.payload().is::<rustc_errors::DelayedBugPanic>() {
|
||||||
(*DEFAULT_HOOK)(info);
|
(*DEFAULT_HOOK)(info);
|
||||||
|
|
||||||
// Separate the output with an empty line
|
// 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
|
// a .span_bug or .bug call has already printed what
|
||||||
// it wants to print.
|
// it wants to print.
|
||||||
if !info.payload().is::<rustc_errors::ExplicitBug>()
|
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");
|
let mut d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic");
|
||||||
handler.emit_diagnostic(&mut d);
|
handler.emit_diagnostic(&mut d);
|
||||||
|
|
|
@ -40,7 +40,6 @@ use rustc_span::source_map::SourceMap;
|
||||||
use rustc_span::HashStableContext;
|
use rustc_span::HashStableContext;
|
||||||
use rustc_span::{Loc, Span};
|
use rustc_span::{Loc, Span};
|
||||||
|
|
||||||
use std::any::Any;
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::Hash;
|
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.
|
/// or `.span_bug` rather than a failed assertion, etc.
|
||||||
pub struct ExplicitBug;
|
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.
|
/// rather than a failed assertion, etc.
|
||||||
pub struct GoodPathBug;
|
pub struct DelayedBugPanic;
|
||||||
|
|
||||||
pub use diagnostic::{
|
pub use diagnostic::{
|
||||||
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
|
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
|
||||||
|
@ -399,7 +398,7 @@ struct HandlerInner {
|
||||||
warn_count: usize,
|
warn_count: usize,
|
||||||
deduplicated_err_count: usize,
|
deduplicated_err_count: usize,
|
||||||
emitter: Box<dyn Emitter + sync::Send>,
|
emitter: Box<dyn Emitter + sync::Send>,
|
||||||
delayed_span_bugs: Vec<Diagnostic>,
|
delayed_span_bugs: Vec<DelayedDiagnostic>,
|
||||||
delayed_good_path_bugs: Vec<DelayedDiagnostic>,
|
delayed_good_path_bugs: Vec<DelayedDiagnostic>,
|
||||||
/// This flag indicates that an expected diagnostic was emitted and suppressed.
|
/// This flag indicates that an expected diagnostic was emitted and suppressed.
|
||||||
/// This is used for the `delayed_good_path_bugs` check.
|
/// This is used for the `delayed_good_path_bugs` check.
|
||||||
|
@ -505,11 +504,7 @@ impl Drop for HandlerInner {
|
||||||
|
|
||||||
if !self.has_errors() {
|
if !self.has_errors() {
|
||||||
let bugs = std::mem::replace(&mut self.delayed_span_bugs, Vec::new());
|
let bugs = std::mem::replace(&mut self.delayed_span_bugs, Vec::new());
|
||||||
self.flush_delayed(
|
self.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued");
|
||||||
bugs,
|
|
||||||
"no errors encountered even though `delay_span_bug` issued",
|
|
||||||
ExplicitBug,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(eddyb) this explains what `delayed_good_path_bugs` are!
|
// 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 {
|
if !self.has_any_message() && !self.suppressed_expected_diag {
|
||||||
let bugs = std::mem::replace(&mut self.delayed_good_path_bugs, Vec::new());
|
let bugs = std::mem::replace(&mut self.delayed_good_path_bugs, Vec::new());
|
||||||
self.flush_delayed(
|
self.flush_delayed(
|
||||||
bugs.into_iter().map(DelayedDiagnostic::decorate),
|
bugs,
|
||||||
"no warnings or errors encountered even though `delayed_good_path_bugs` issued",
|
"no warnings or errors encountered even though `delayed_good_path_bugs` issued",
|
||||||
GoodPathBug,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,11 +1217,7 @@ impl Handler {
|
||||||
pub fn flush_delayed(&self) {
|
pub fn flush_delayed(&self) {
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
let bugs = std::mem::replace(&mut inner.delayed_span_bugs, Vec::new());
|
let bugs = std::mem::replace(&mut inner.delayed_span_bugs, Vec::new());
|
||||||
inner.flush_delayed(
|
inner.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued");
|
||||||
bugs,
|
|
||||||
"no errors encountered even though `delay_span_bug` issued",
|
|
||||||
ExplicitBug,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1287,7 +1277,9 @@ impl HandlerInner {
|
||||||
// once *any* errors were emitted (and truncate `delayed_span_bugs`
|
// once *any* errors were emitted (and truncate `delayed_span_bugs`
|
||||||
// when an error is first emitted, also), but maybe there's a case
|
// when an error is first emitted, also), but maybe there's a case
|
||||||
// in which that's not sound? otherwise this is really inefficient.
|
// 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 {
|
if !self.flags.report_delayed_bugs {
|
||||||
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
|
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
|
||||||
|
@ -1562,7 +1554,6 @@ impl HandlerInner {
|
||||||
}
|
}
|
||||||
let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
|
let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg);
|
||||||
diagnostic.set_span(sp.into());
|
diagnostic.set_span(sp.into());
|
||||||
diagnostic.note(&format!("delayed at {}", std::panic::Location::caller()));
|
|
||||||
self.emit_diagnostic(&mut diagnostic).unwrap()
|
self.emit_diagnostic(&mut diagnostic).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1605,12 +1596,13 @@ impl HandlerInner {
|
||||||
|
|
||||||
fn flush_delayed(
|
fn flush_delayed(
|
||||||
&mut self,
|
&mut self,
|
||||||
bugs: impl IntoIterator<Item = Diagnostic>,
|
bugs: impl IntoIterator<Item = DelayedDiagnostic>,
|
||||||
explanation: impl Into<DiagnosticMessage> + Copy,
|
explanation: impl Into<DiagnosticMessage> + Copy,
|
||||||
panic_with: impl Any + Send + 'static,
|
|
||||||
) {
|
) {
|
||||||
let mut no_bugs = true;
|
let mut no_bugs = true;
|
||||||
for mut bug in bugs {
|
for bug in bugs {
|
||||||
|
let mut bug = bug.decorate();
|
||||||
|
|
||||||
if no_bugs {
|
if no_bugs {
|
||||||
// Put the overall explanation before the `DelayedBug`s, to
|
// Put the overall explanation before the `DelayedBug`s, to
|
||||||
// frame them better (e.g. separate warnings from them).
|
// frame them better (e.g. separate warnings from them).
|
||||||
|
@ -1633,9 +1625,9 @@ impl HandlerInner {
|
||||||
self.emit_diagnostic(&mut bug);
|
self.emit_diagnostic(&mut bug);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Panic with `ExplicitBug` to avoid "unexpected panic" messages.
|
// Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
|
||||||
if !no_bugs {
|
if !no_bugs {
|
||||||
panic::panic_any(panic_with);
|
panic::panic_any(DelayedBugPanic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue