Skip to content

Commit f534b75

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 ccbce1d commit f534b75

File tree

5 files changed

+29
-79
lines changed

5 files changed

+29
-79
lines changed

compiler/rustc_interface/src/util.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
148148

149149
let main_handler = move || {
150150
rustc_span::with_session_globals(edition, || {
151-
if let Some(stderr) = stderr {
152-
io::set_panic(Some(stderr.clone()));
153-
}
151+
io::set_panic(stderr.clone());
154152
f()
155153
})
156154
};
@@ -188,9 +186,7 @@ pub fn setup_callbacks_and_run_in_thread_pool_with_globals<F: FnOnce() -> R + Se
188186
// on the new threads.
189187
let main_handler = move |thread: rayon::ThreadBuilder| {
190188
rustc_span::SESSION_GLOBALS.set(session_globals, || {
191-
if let Some(stderr) = stderr {
192-
io::set_panic(Some(stderr.clone()));
193-
}
189+
io::set_panic(stderr.clone());
194190
thread.run()
195191
})
196192
};

library/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
}

library/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)]

library/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);

src/test/ui/panic-while-printing.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
use std::fmt;
77
use std::fmt::{Display, Formatter};
8-
use std::io::{self, set_panic, Write};
8+
use std::io::set_panic;
99
use std::sync::{Arc, Mutex};
1010

1111
pub struct A;
@@ -16,19 +16,8 @@ impl Display for A {
1616
}
1717
}
1818

19-
struct Sink;
20-
21-
impl Write for Sink {
22-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
23-
Ok(buf.len())
24-
}
25-
fn flush(&mut self) -> io::Result<()> {
26-
Ok(())
27-
}
28-
}
29-
3019
fn main() {
31-
set_panic(Some(Arc::new(Mutex::new(Sink))));
20+
set_panic(Some(Arc::new(Mutex::new(Vec::new()))));
3221
assert!(std::panic::catch_unwind(|| {
3322
eprintln!("{}", A);
3423
})

0 commit comments

Comments
 (0)