@@ -13,14 +13,14 @@ use crate::thread::LocalKey;
13
13
14
14
thread_local ! {
15
15
/// Stdout used by print! and println! macros
16
- static LOCAL_STDOUT : RefCell <Option <Box <dyn Write + Send >>> = {
16
+ static LOCAL_STDOUT : RefCell <Option <Box <dyn LocalOutput >>> = {
17
17
RefCell :: new( None )
18
18
}
19
19
}
20
20
21
21
thread_local ! {
22
22
/// Stderr used by eprint! and eprintln! macros, and panics
23
- static LOCAL_STDERR : RefCell <Option <Box <dyn Write + Send >>> = {
23
+ static LOCAL_STDERR : RefCell <Option <Box <dyn LocalOutput >>> = {
24
24
RefCell :: new( None )
25
25
}
26
26
}
@@ -903,6 +903,18 @@ impl fmt::Debug for StderrLock<'_> {
903
903
}
904
904
}
905
905
906
+ /// A writer than can be cloned to new threads.
907
+ #[ unstable(
908
+ feature = "set_stdio" ,
909
+ reason = "this trait may disappear completely or be replaced \
910
+ with a more general mechanism",
911
+ issue = "none"
912
+ ) ]
913
+ #[ doc( hidden) ]
914
+ pub trait LocalOutput : Write + Send {
915
+ fn clone_box ( & self ) -> Box < dyn LocalOutput > ;
916
+ }
917
+
906
918
/// Resets the thread-local stderr handle to the specified writer
907
919
///
908
920
/// This will replace the current thread's stderr handle, returning the old
@@ -918,7 +930,7 @@ impl fmt::Debug for StderrLock<'_> {
918
930
issue = "none"
919
931
) ]
920
932
#[ doc( hidden) ]
921
- pub fn set_panic ( sink : Option < Box < dyn Write + Send > > ) -> Option < Box < dyn Write + Send > > {
933
+ pub fn set_panic ( sink : Option < Box < dyn LocalOutput > > ) -> Option < Box < dyn LocalOutput > > {
922
934
use crate :: mem;
923
935
LOCAL_STDERR . with ( move |slot| mem:: replace ( & mut * slot. borrow_mut ( ) , sink) ) . and_then ( |mut s| {
924
936
let _ = s. flush ( ) ;
@@ -941,14 +953,25 @@ pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write +
941
953
issue = "none"
942
954
) ]
943
955
#[ doc( hidden) ]
944
- pub fn set_print ( sink : Option < Box < dyn Write + Send > > ) -> Option < Box < dyn Write + Send > > {
956
+ pub fn set_print ( sink : Option < Box < dyn LocalOutput > > ) -> Option < Box < dyn LocalOutput > > {
945
957
use crate :: mem;
946
958
LOCAL_STDOUT . with ( move |slot| mem:: replace ( & mut * slot. borrow_mut ( ) , sink) ) . and_then ( |mut s| {
947
959
let _ = s. flush ( ) ;
948
960
Some ( s)
949
961
} )
950
962
}
951
963
964
+ pub ( crate ) fn clone_io ( ) -> ( Option < Box < dyn LocalOutput > > , Option < Box < dyn LocalOutput > > ) {
965
+ LOCAL_STDOUT . with ( |stdout| {
966
+ LOCAL_STDERR . with ( |stderr| {
967
+ (
968
+ stdout. borrow ( ) . as_ref ( ) . map ( |o| o. clone_box ( ) ) ,
969
+ stderr. borrow ( ) . as_ref ( ) . map ( |o| o. clone_box ( ) ) ,
970
+ )
971
+ } )
972
+ } )
973
+ }
974
+
952
975
/// Write `args` to output stream `local_s` if possible, `global_s`
953
976
/// otherwise. `label` identifies the stream in a panic message.
954
977
///
@@ -961,7 +984,7 @@ pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write +
961
984
/// However, if the actual I/O causes an error, this function does panic.
962
985
fn print_to < T > (
963
986
args : fmt:: Arguments < ' _ > ,
964
- local_s : & ' static LocalKey < RefCell < Option < Box < dyn Write + Send > > > > ,
987
+ local_s : & ' static LocalKey < RefCell < Option < Box < dyn LocalOutput > > > > ,
965
988
global_s : fn ( ) -> T ,
966
989
label : & str ,
967
990
) where
0 commit comments