Use Vec<u8> for LOCAL_STD{OUT,ERR} instead of dyn Write.
It was only ever used with Vec<u8> anyway. This simplifies some things. - It no longer needs to be flushed, because that's a no-op anyway for a Vec<u8>. - Writing to a Vec<u8> never fails. - No #[cfg(test)] code is needed anymore to use `realstd` instead of `std`, because Vec comes from alloc, not std (like Write).
This commit is contained in:
parent
ccbce1d3b2
commit
f534b75f05
@ -148,9 +148,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
|
||||
|
||||
let main_handler = move || {
|
||||
rustc_span::with_session_globals(edition, || {
|
||||
if let Some(stderr) = stderr {
|
||||
io::set_panic(Some(stderr.clone()));
|
||||
}
|
||||
io::set_panic(stderr.clone());
|
||||
f()
|
||||
})
|
||||
};
|
||||
@ -188,9 +186,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
|
||||
// on the new threads.
|
||||
let main_handler = move |thread: rayon::ThreadBuilder| {
|
||||
rustc_span::SESSION_GLOBALS.set(session_globals, || {
|
||||
if let Some(stderr) = stderr {
|
||||
io::set_panic(Some(stderr.clone()));
|
||||
}
|
||||
io::set_panic(stderr.clone());
|
||||
thread.run()
|
||||
})
|
||||
};
|
||||
|
@ -16,7 +16,7 @@
|
||||
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
|
||||
use crate::thread::LocalKey;
|
||||
|
||||
type LocalStream = Arc<Mutex<dyn Write + Send>>;
|
||||
type LocalStream = Arc<Mutex<Vec<u8>>>;
|
||||
|
||||
thread_local! {
|
||||
/// Used by the test crate to capture the output of the print! and println! macros.
|
||||
@ -911,13 +911,8 @@ pub fn set_panic(sink: Option<LocalStream>) -> Option<LocalStream> {
|
||||
// LOCAL_STDERR is definitely None since LOCAL_STREAMS is false.
|
||||
return None;
|
||||
}
|
||||
let s =
|
||||
LOCAL_STDERR.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(|s| {
|
||||
let _ = s.lock().unwrap_or_else(|e| e.into_inner()).flush();
|
||||
Some(s)
|
||||
});
|
||||
LOCAL_STREAMS.store(true, Ordering::Relaxed);
|
||||
s
|
||||
LOCAL_STDERR.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink))
|
||||
}
|
||||
|
||||
/// Resets the thread-local stdout handle to the specified writer
|
||||
@ -941,13 +936,8 @@ pub fn set_print(sink: Option<LocalStream>) -> Option<LocalStream> {
|
||||
// LOCAL_STDOUT is definitely None since LOCAL_STREAMS is false.
|
||||
return None;
|
||||
}
|
||||
let s =
|
||||
LOCAL_STDOUT.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(|s| {
|
||||
let _ = s.lock().unwrap_or_else(|e| e.into_inner()).flush();
|
||||
Some(s)
|
||||
});
|
||||
LOCAL_STREAMS.store(true, Ordering::Relaxed);
|
||||
s
|
||||
LOCAL_STDOUT.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink))
|
||||
}
|
||||
|
||||
pub(crate) fn clone_io() -> (Option<LocalStream>, Option<LocalStream>) {
|
||||
@ -956,9 +946,10 @@ pub(crate) fn clone_io() -> (Option<LocalStream>, Option<LocalStream>) {
|
||||
return (None, None);
|
||||
}
|
||||
|
||||
LOCAL_STDOUT.with(|stdout| {
|
||||
LOCAL_STDERR.with(|stderr| (stdout.borrow().clone(), stderr.borrow().clone()))
|
||||
})
|
||||
(
|
||||
LOCAL_STDOUT.with(|s| s.borrow().clone()),
|
||||
LOCAL_STDERR.with(|s| s.borrow().clone()),
|
||||
)
|
||||
}
|
||||
|
||||
/// Write `args` to output stream `local_s` if possible, `global_s`
|
||||
@ -979,28 +970,22 @@ fn print_to<T>(
|
||||
) where
|
||||
T: Write,
|
||||
{
|
||||
let result = LOCAL_STREAMS
|
||||
.load(Ordering::Relaxed)
|
||||
.then(|| {
|
||||
local_s
|
||||
.try_with(|s| {
|
||||
// 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(w) = prev {
|
||||
let result = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
|
||||
*s.borrow_mut() = Some(w);
|
||||
return result;
|
||||
}
|
||||
global_s().write_fmt(args)
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.flatten()
|
||||
.unwrap_or_else(|| global_s().write_fmt(args));
|
||||
if LOCAL_STREAMS.load(Ordering::Relaxed)
|
||||
&& local_s.try_with(|s| {
|
||||
// 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.
|
||||
s.take().map(|w| {
|
||||
let _ = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
|
||||
*s.borrow_mut() = Some(w);
|
||||
})
|
||||
}) == Ok(Some(()))
|
||||
{
|
||||
// Succesfully wrote to local stream.
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(e) = result {
|
||||
if let Err(e) = global_s().write_fmt(args) {
|
||||
panic!("failed printing to {}: {}", label, e);
|
||||
}
|
||||
}
|
||||
|
@ -297,6 +297,7 @@
|
||||
#![feature(raw)]
|
||||
#![feature(raw_ref_macros)]
|
||||
#![feature(ready_macro)]
|
||||
#![feature(refcell_take)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(shrink_to)]
|
||||
|
@ -219,28 +219,7 @@ fn default_hook(info: &PanicInfo<'_>) {
|
||||
};
|
||||
|
||||
if let Some(local) = set_panic(None) {
|
||||
let mut stream = local.lock().unwrap_or_else(|e| e.into_inner());
|
||||
|
||||
#[cfg(test)]
|
||||
{
|
||||
use crate::io;
|
||||
struct Wrapper<'a>(&'a mut (dyn ::realstd::io::Write + Send));
|
||||
impl io::Write for Wrapper<'_> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf).map_err(|_| io::ErrorKind::Other.into())
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.0.flush().map_err(|_| io::ErrorKind::Other.into())
|
||||
}
|
||||
}
|
||||
write(&mut Wrapper(&mut *stream));
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
write(&mut *stream);
|
||||
|
||||
drop(stream);
|
||||
|
||||
write(&mut *local.lock().unwrap_or_else(|e| e.into_inner()));
|
||||
set_panic(Some(local));
|
||||
} else if let Some(mut out) = panic_output() {
|
||||
write(&mut out);
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
use std::fmt;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::io::{self, set_panic, Write};
|
||||
use std::io::set_panic;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
pub struct A;
|
||||
@ -16,19 +16,8 @@ fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
struct Sink;
|
||||
|
||||
impl Write for Sink {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
Ok(buf.len())
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
set_panic(Some(Arc::new(Mutex::new(Sink))));
|
||||
set_panic(Some(Arc::new(Mutex::new(Vec::new()))));
|
||||
assert!(std::panic::catch_unwind(|| {
|
||||
eprintln!("{}", A);
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user