1
Fork 0

Make tests capture the error printed by a Result return

This commit is contained in:
David Tolnay 2022-10-07 13:45:41 -07:00
parent 43c22af267
commit 293f662ca9
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82
3 changed files with 24 additions and 9 deletions

View file

@ -262,6 +262,7 @@ use crate::sys_common::memchr;
#[stable(feature = "bufwriter_into_parts", since = "1.56.0")] #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
pub use self::buffered::WriterPanicked; pub use self::buffered::WriterPanicked;
pub(crate) use self::stdio::attempt_print_to_stderr;
#[unstable(feature = "internal_output_capture", issue = "none")] #[unstable(feature = "internal_output_capture", issue = "none")]
#[doc(no_inline, hidden)] #[doc(no_inline, hidden)]
pub use self::stdio::set_output_capture; pub use self::stdio::set_output_capture;

View file

@ -999,7 +999,18 @@ fn print_to<T>(args: fmt::Arguments<'_>, global_s: fn() -> T, label: &str)
where where
T: Write, T: Write,
{ {
if OUTPUT_CAPTURE_USED.load(Ordering::Relaxed) if print_to_buffer_if_capture_used(args) {
// Successfully wrote to capture buffer.
return;
}
if let Err(e) = global_s().write_fmt(args) {
panic!("failed printing to {label}: {e}");
}
}
fn print_to_buffer_if_capture_used(args: fmt::Arguments<'_>) -> bool {
OUTPUT_CAPTURE_USED.load(Ordering::Relaxed)
&& OUTPUT_CAPTURE.try_with(|s| { && OUTPUT_CAPTURE.try_with(|s| {
// Note that we completely remove a local sink to write to in case // Note that we completely remove a local sink to write to in case
// our printing recursively panics/prints, so the recursive // our printing recursively panics/prints, so the recursive
@ -1009,14 +1020,19 @@ where
s.set(Some(w)); s.set(Some(w));
}) })
}) == Ok(Some(())) }) == Ok(Some(()))
{ }
// Successfully wrote to capture buffer.
/// Used by impl Termination for Result to print error after `main` or a test
/// has returned. Should avoid panicking, although we can't help it if one of
/// the Display impls inside args decides to.
pub(crate) fn attempt_print_to_stderr(args: fmt::Arguments<'_>) {
if print_to_buffer_if_capture_used(args) {
return; return;
} }
if let Err(e) = global_s().write_fmt(args) { // Ignore error if the write fails, for example because stderr is already
panic!("failed printing to {label}: {e}"); // closed. There is not much point panicking at this point.
} let _ = stderr().write_fmt(args);
} }
#[unstable( #[unstable(

View file

@ -2200,9 +2200,7 @@ impl<T: Termination, E: fmt::Debug> Termination for Result<T, E> {
match self { match self {
Ok(val) => val.report(), Ok(val) => val.report(),
Err(err) => { Err(err) => {
// Ignore error if the write fails, for example because stderr is io::attempt_print_to_stderr(format_args_nl!("Error: {err:?}"));
// already closed. There is not much point panicking at this point.
let _ = writeln!(io::stderr(), "Error: {err:?}");
ExitCode::FAILURE ExitCode::FAILURE
} }
} }