From c0e8cf94103289c424c62ca48e1e3f56e352a84a Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Thu, 14 Feb 2019 18:06:01 +0530 Subject: [PATCH] Use the correct stderr when testing libstd --- src/libstd/io/impls.rs | 14 ++++++++++++++ src/libstd/io/stdio.rs | 16 ++++++++++++++-- src/libstd/lib.rs | 2 +- src/libstd/panicking.rs | 28 ++++++++++++---------------- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs index bd3d0a41638..b286e4016da 100644 --- a/src/libstd/io/impls.rs +++ b/src/libstd/io/impls.rs @@ -165,6 +165,20 @@ fn read_line(&mut self, buf: &mut String) -> io::Result { } } +// Used by panicking::default_hook +#[cfg(test)] +/// This impl is only used by printing logic, so any error returned is always +/// of kind `Other`, and should be ignored. +impl Write for Box { + fn write(&mut self, buf: &[u8]) -> io::Result { + (**self).write(buf).map_err(|_| ErrorKind::Other.into()) + } + + fn flush(&mut self) -> io::Result<()> { + (**self).flush().map_err(|_| ErrorKind::Other.into()) + } +} + // ============================================================================= // In-memory buffer implementations diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 13bf357e2eb..589fb455a19 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -1,3 +1,5 @@ +#![cfg_attr(test, allow(unused))] + use crate::io::prelude::*; use crate::cell::RefCell; @@ -16,6 +18,13 @@ } } +/// Stderr used by eprint! and eprintln! macros, and panics +thread_local! { + static LOCAL_STDERR: RefCell>> = { + RefCell::new(None) + } +} + /// A handle to a raw instance of the standard input stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via @@ -668,7 +677,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { issue = "0")] #[doc(hidden)] pub fn set_panic(sink: Option>) -> Option> { - use crate::panicking::LOCAL_STDERR; use crate::mem; LOCAL_STDERR.with(move |slot| { mem::replace(&mut *slot.borrow_mut(), sink) @@ -740,6 +748,7 @@ fn print_to( reason = "implementation detail which may disappear or be replaced at any time", issue = "0")] #[doc(hidden)] +#[cfg(not(test))] pub fn _print(args: fmt::Arguments) { print_to(args, &LOCAL_STDOUT, stdout, "stdout"); } @@ -748,11 +757,14 @@ pub fn _print(args: fmt::Arguments) { reason = "implementation detail which may disappear or be replaced at any time", issue = "0")] #[doc(hidden)] +#[cfg(not(test))] pub fn _eprint(args: fmt::Arguments) { - use crate::panicking::LOCAL_STDERR; print_to(args, &LOCAL_STDERR, stderr, "stderr"); } +#[cfg(test)] +pub use realstd::io::{_eprint, _print}; + #[cfg(test)] mod tests { use crate::panic::{UnwindSafe, RefUnwindSafe}; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 32a168619df..e31680f23f1 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -219,7 +219,7 @@ // std may use features in a platform-specific way #![allow(unused_features)] -#![cfg_attr(test, feature(test, update_panic_count))] +#![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))] #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), feature(global_asm, range_contains, slice_index_methods, decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 868b309686c..eae885602d3 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -7,13 +7,9 @@ //! * Executing a panic up to doing the actual implementation //! * Shims around "try" -use core::panic::BoxMeUp; -use core::panic::{PanicInfo, Location}; - -use crate::io::prelude::*; +use core::panic::{BoxMeUp, PanicInfo, Location}; use crate::any::Any; -use crate::cell::RefCell; use crate::fmt; use crate::intrinsics; use crate::mem; @@ -25,11 +21,12 @@ use crate::sys_common::util; use crate::thread; -thread_local! { - pub static LOCAL_STDERR: RefCell>> = { - RefCell::new(None) - } -} +#[cfg(not(test))] +use crate::io::set_panic; +// make sure to use the stderr output configured +// by libtest in the real copy of std +#[cfg(test)] +use realstd::io::set_panic; // Binary interface to the panic runtime that the standard library depends on. // @@ -205,12 +202,11 @@ fn default_hook(info: &PanicInfo) { } }; - if let Some(mut local) = LOCAL_STDERR.with(|s| s.borrow_mut().take()) { - write(&mut *local); - let mut s = Some(local); - LOCAL_STDERR.with(|slot| { - *slot.borrow_mut() = s.take(); - }); + if let Some(mut local) = set_panic(None) { + // NB. In `cfg(test)` this uses the forwarding impl + // for `Box`. + write(&mut local); + set_panic(Some(local)); } else if let Some(mut out) = panic_output() { write(&mut out); } -- 2.44.0