diff --git a/crates/red_knot_test/src/lib.rs b/crates/red_knot_test/src/lib.rs index 001bd2a70df4f..b234a64719122 100644 --- a/crates/red_knot_test/src/lib.rs +++ b/crates/red_knot_test/src/lib.rs @@ -141,10 +141,23 @@ fn run_test(db: &mut db::Db, test: &parser::MarkdownTest) -> Result<(), Failures Ok(type_diagnostics) => type_diagnostics, Err(info) => { let mut by_line = matcher::FailuresByLine::default(); - by_line.push( - OneIndexed::from_zero_indexed(0), - info.info.split('\n').map(String::from).collect(), - ); + let mut messages = vec![]; + match info.location { + Some(location) => messages.push(format!("panicked at {location}")), + None => messages.push("panicked at unknown location".to_string()), + }; + match info.payload { + Some(payload) => messages.push(payload), + // Mimic the default panic hook's rendering of the panic payload if it's + // not a string. + None => messages.push("Box".to_string()), + }; + if let Some(backtrace) = info.backtrace { + if std::env::var("RUST_BACKTRACE").is_ok() { + messages.extend(backtrace.to_string().split('\n').map(String::from)); + } + } + by_line.push(OneIndexed::from_zero_indexed(0), messages); return Some(FileFailures { backtick_offset: test_file.backtick_offset, by_line, diff --git a/crates/ruff_db/src/panic.rs b/crates/ruff_db/src/panic.rs index 744ab49cbefbc..576425a99e0fe 100644 --- a/crates/ruff_db/src/panic.rs +++ b/crates/ruff_db/src/panic.rs @@ -1,20 +1,27 @@ use std::cell::Cell; +use std::panic::Location; use std::sync::OnceLock; #[derive(Default, Debug)] pub struct PanicError { - pub info: String, + pub location: Option, + pub payload: Option, pub backtrace: Option, } impl std::fmt::Display for PanicError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "{}", self.info)?; + writeln!(f, "panicked at")?; + if let Some(location) = &self.location { + write!(f, " {location}")?; + } + if let Some(payload) = &self.payload { + write!(f, ":\n{payload}")?; + } if let Some(backtrace) = &self.backtrace { - writeln!(f, "Backtrace: {backtrace}") - } else { - Ok(()) + writeln!(f, "\nBacktrace: {backtrace}")?; } + Ok(()) } } @@ -34,11 +41,17 @@ fn install_hook() { if !should_capture { return (*prev)(info); } - let info = info.to_string(); + let payload = if let Some(s) = info.payload().downcast_ref::<&str>() { + Some(s.to_string()) + } else { + info.payload().downcast_ref::().cloned() + }; + let location = info.location().map(Location::to_string); let backtrace = std::backtrace::Backtrace::force_capture(); LAST_PANIC.with(|cell| { cell.set(Some(PanicError { - info, + payload, + location, backtrace: Some(backtrace), })); });