Skip to content

Commit 4f9f35b

Browse files
committed
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).
1 parent 5996a9c commit 4f9f35b

File tree

3 files changed

+25
-60
lines changed

3 files changed

+25
-60
lines changed

std/src/io/stdio.rs

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::sys_common;
1616
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
1717
use crate::thread::LocalKey;
1818

19-
type LocalStream = Arc<Mutex<dyn Write + Send>>;
19+
type LocalStream = Arc<Mutex<Vec<u8>>>;
2020

2121
thread_local! {
2222
/// 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> {
911911
// LOCAL_STDERR is definitely None since LOCAL_STREAMS is false.
912912
return None;
913913
}
914-
let s =
915-
LOCAL_STDERR.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(|s| {
916-
let _ = s.lock().unwrap_or_else(|e| e.into_inner()).flush();
917-
Some(s)
918-
});
919914
LOCAL_STREAMS.store(true, Ordering::Relaxed);
920-
s
915+
LOCAL_STDERR.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink))
921916
}
922917

923918
/// Resets the thread-local stdout handle to the specified writer
@@ -941,13 +936,8 @@ pub fn set_print(sink: Option<LocalStream>) -> Option<LocalStream> {
941936
// LOCAL_STDOUT is definitely None since LOCAL_STREAMS is false.
942937
return None;
943938
}
944-
let s =
945-
LOCAL_STDOUT.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink)).and_then(|s| {
946-
let _ = s.lock().unwrap_or_else(|e| e.into_inner()).flush();
947-
Some(s)
948-
});
949939
LOCAL_STREAMS.store(true, Ordering::Relaxed);
950-
s
940+
LOCAL_STDOUT.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink))
951941
}
952942

953943
pub(crate) fn clone_io() -> (Option<LocalStream>, Option<LocalStream>) {
@@ -956,9 +946,10 @@ pub(crate) fn clone_io() -> (Option<LocalStream>, Option<LocalStream>) {
956946
return (None, None);
957947
}
958948

959-
LOCAL_STDOUT.with(|stdout| {
960-
LOCAL_STDERR.with(|stderr| (stdout.borrow().clone(), stderr.borrow().clone()))
961-
})
949+
(
950+
LOCAL_STDOUT.with(|s| s.borrow().clone()),
951+
LOCAL_STDERR.with(|s| s.borrow().clone()),
952+
)
962953
}
963954

964955
/// Write `args` to output stream `local_s` if possible, `global_s`
@@ -979,28 +970,22 @@ fn print_to<T>(
979970
) where
980971
T: Write,
981972
{
982-
let result = LOCAL_STREAMS
983-
.load(Ordering::Relaxed)
984-
.then(|| {
985-
local_s
986-
.try_with(|s| {
987-
// Note that we completely remove a local sink to write to in case
988-
// our printing recursively panics/prints, so the recursive
989-
// panic/print goes to the global sink instead of our local sink.
990-
let prev = s.borrow_mut().take();
991-
if let Some(w) = prev {
992-
let result = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
993-
*s.borrow_mut() = Some(w);
994-
return result;
995-
}
996-
global_s().write_fmt(args)
997-
})
998-
.ok()
999-
})
1000-
.flatten()
1001-
.unwrap_or_else(|| global_s().write_fmt(args));
1002-
1003-
if let Err(e) = result {
973+
if LOCAL_STREAMS.load(Ordering::Relaxed)
974+
&& local_s.try_with(|s| {
975+
// Note that we completely remove a local sink to write to in case
976+
// our printing recursively panics/prints, so the recursive
977+
// panic/print goes to the global sink instead of our local sink.
978+
s.take().map(|w| {
979+
let _ = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
980+
*s.borrow_mut() = Some(w);
981+
})
982+
}) == Ok(Some(()))
983+
{
984+
// Succesfully wrote to local stream.
985+
return;
986+
}
987+
988+
if let Err(e) = global_s().write_fmt(args) {
1004989
panic!("failed printing to {}: {}", label, e);
1005990
}
1006991
}

std/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@
297297
#![feature(raw)]
298298
#![feature(raw_ref_macros)]
299299
#![feature(ready_macro)]
300+
#![feature(refcell_take)]
300301
#![feature(rustc_attrs)]
301302
#![feature(rustc_private)]
302303
#![feature(shrink_to)]

std/src/panicking.rs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -219,28 +219,7 @@ fn default_hook(info: &PanicInfo<'_>) {
219219
};
220220

221221
if let Some(local) = set_panic(None) {
222-
let mut stream = local.lock().unwrap_or_else(|e| e.into_inner());
223-
224-
#[cfg(test)]
225-
{
226-
use crate::io;
227-
struct Wrapper<'a>(&'a mut (dyn ::realstd::io::Write + Send));
228-
impl io::Write for Wrapper<'_> {
229-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
230-
self.0.write(buf).map_err(|_| io::ErrorKind::Other.into())
231-
}
232-
fn flush(&mut self) -> io::Result<()> {
233-
self.0.flush().map_err(|_| io::ErrorKind::Other.into())
234-
}
235-
}
236-
write(&mut Wrapper(&mut *stream));
237-
}
238-
239-
#[cfg(not(test))]
240-
write(&mut *stream);
241-
242-
drop(stream);
243-
222+
write(&mut *local.lock().unwrap_or_else(|e| e.into_inner()));
244223
set_panic(Some(local));
245224
} else if let Some(mut out) = panic_output() {
246225
write(&mut out);

0 commit comments

Comments
 (0)