about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2020-03-12 13:03:48 -0700
committerAlex Crichton <alex@alexcrichton.com>2020-03-18 07:06:13 -0700
commitd5b6a20557743911ff9f90af5d8ad24c699570d3 (patch)
treea157c7372ba995c00b667f297d5917714c5fa9ec /src/libstd
parent23de8275c9b5e5812dc54a12bdba6d80870d9dc8 (diff)
downloadrust-d5b6a20557743911ff9f90af5d8ad24c699570d3.tar.gz
rust-d5b6a20557743911ff9f90af5d8ad24c699570d3.zip
std: Don't abort process when printing panics in tests
This commit fixes an issue when using `set_print` and friends, notably
used by libtest, to avoid aborting the process if printing panics. This
previously panicked due to borrowing a mutable `RefCell` twice, and this
is worked around by borrowing these cells for less time, instead
taking out and removing contents temporarily.

Closes #69558
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/io/stdio.rs12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index d410faca30d..0fb0757792e 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -792,10 +792,14 @@ fn print_to<T>(
 {
     let result = local_s
         .try_with(|s| {
-            if let Ok(mut borrowed) = s.try_borrow_mut() {
-                if let Some(w) = borrowed.as_mut() {
-                    return w.write_fmt(args);
-                }
+            // Note that we completely remove a local sink to write to in case
+            // our printing recursively panics/prints, so the recursive
+            // panic/print goes to the global sink instead of our local sink.
+            let prev = s.borrow_mut().take();
+            if let Some(mut w) = prev {
+                let result = w.write_fmt(args);
+                *s.borrow_mut() = Some(w);
+                return result;
             }
             global_s().write_fmt(args)
         })