Skip to content

Commit 08b7cb7

Browse files
committed
Use Cell instead of RefCell for LOCAL_{STDOUT,STDERR}.
1 parent f534b75 commit 08b7cb7

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

library/std/src/io/stdio.rs

+16-15
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mod tests;
55

66
use crate::io::prelude::*;
77

8-
use crate::cell::RefCell;
8+
use crate::cell::{Cell, RefCell};
99
use crate::fmt;
1010
use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter};
1111
use crate::lazy::SyncOnceCell;
@@ -20,15 +20,15 @@ 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.
23-
static LOCAL_STDOUT: RefCell<Option<LocalStream>> = {
24-
RefCell::new(None)
23+
static LOCAL_STDOUT: Cell<Option<LocalStream>> = {
24+
Cell::new(None)
2525
}
2626
}
2727

2828
thread_local! {
2929
/// Used by the test crate to capture the output of the eprint! and eprintln! macros, and panics.
30-
static LOCAL_STDERR: RefCell<Option<LocalStream>> = {
31-
RefCell::new(None)
30+
static LOCAL_STDERR: Cell<Option<LocalStream>> = {
31+
Cell::new(None)
3232
}
3333
}
3434

@@ -906,13 +906,12 @@ impl fmt::Debug for StderrLock<'_> {
906906
)]
907907
#[doc(hidden)]
908908
pub fn set_panic(sink: Option<LocalStream>) -> Option<LocalStream> {
909-
use crate::mem;
910909
if sink.is_none() && !LOCAL_STREAMS.load(Ordering::Relaxed) {
911910
// LOCAL_STDERR is definitely None since LOCAL_STREAMS is false.
912911
return None;
913912
}
914913
LOCAL_STREAMS.store(true, Ordering::Relaxed);
915-
LOCAL_STDERR.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink))
914+
LOCAL_STDERR.with(move |slot| slot.replace(sink))
916915
}
917916

918917
/// Resets the thread-local stdout handle to the specified writer
@@ -931,13 +930,12 @@ pub fn set_panic(sink: Option<LocalStream>) -> Option<LocalStream> {
931930
)]
932931
#[doc(hidden)]
933932
pub fn set_print(sink: Option<LocalStream>) -> Option<LocalStream> {
934-
use crate::mem;
935933
if sink.is_none() && !LOCAL_STREAMS.load(Ordering::Relaxed) {
936934
// LOCAL_STDOUT is definitely None since LOCAL_STREAMS is false.
937935
return None;
938936
}
939937
LOCAL_STREAMS.store(true, Ordering::Relaxed);
940-
LOCAL_STDOUT.with(move |slot| mem::replace(&mut *slot.borrow_mut(), sink))
938+
LOCAL_STDOUT.with(move |slot| slot.replace(sink))
941939
}
942940

943941
pub(crate) fn clone_io() -> (Option<LocalStream>, Option<LocalStream>) {
@@ -946,10 +944,13 @@ pub(crate) fn clone_io() -> (Option<LocalStream>, Option<LocalStream>) {
946944
return (None, None);
947945
}
948946

949-
(
950-
LOCAL_STDOUT.with(|s| s.borrow().clone()),
951-
LOCAL_STDERR.with(|s| s.borrow().clone()),
952-
)
947+
let clone = |cell: &Cell<Option<LocalStream>>| {
948+
let s = cell.take();
949+
cell.set(s.clone());
950+
s
951+
};
952+
953+
(LOCAL_STDOUT.with(clone), LOCAL_STDERR.with(clone))
953954
}
954955

955956
/// Write `args` to output stream `local_s` if possible, `global_s`
@@ -964,7 +965,7 @@ pub(crate) fn clone_io() -> (Option<LocalStream>, Option<LocalStream>) {
964965
/// However, if the actual I/O causes an error, this function does panic.
965966
fn print_to<T>(
966967
args: fmt::Arguments<'_>,
967-
local_s: &'static LocalKey<RefCell<Option<LocalStream>>>,
968+
local_s: &'static LocalKey<Cell<Option<LocalStream>>>,
968969
global_s: fn() -> T,
969970
label: &str,
970971
) where
@@ -977,7 +978,7 @@ fn print_to<T>(
977978
// panic/print goes to the global sink instead of our local sink.
978979
s.take().map(|w| {
979980
let _ = w.lock().unwrap_or_else(|e| e.into_inner()).write_fmt(args);
980-
*s.borrow_mut() = Some(w);
981+
s.set(Some(w));
981982
})
982983
}) == Ok(Some(()))
983984
{

0 commit comments

Comments
 (0)