@@ -13,14 +13,14 @@ use crate::thread::LocalKey;
1313
1414thread_local ! {
1515 /// 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 >>> = {
1717 RefCell :: new( None )
1818 }
1919}
2020
2121thread_local ! {
2222 /// 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 >>> = {
2424 RefCell :: new( None )
2525 }
2626}
@@ -903,6 +903,18 @@ impl fmt::Debug for StderrLock<'_> {
903903 }
904904}
905905
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+
906918/// Resets the thread-local stderr handle to the specified writer
907919///
908920/// This will replace the current thread's stderr handle, returning the old
@@ -918,7 +930,7 @@ impl fmt::Debug for StderrLock<'_> {
918930 issue = "none"
919931) ]
920932#[ 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 > > {
922934 use crate :: mem;
923935 LOCAL_STDERR . with ( move |slot| mem:: replace ( & mut * slot. borrow_mut ( ) , sink) ) . and_then ( |mut s| {
924936 let _ = s. flush ( ) ;
@@ -941,14 +953,25 @@ pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write +
941953 issue = "none"
942954) ]
943955#[ 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 > > {
945957 use crate :: mem;
946958 LOCAL_STDOUT . with ( move |slot| mem:: replace ( & mut * slot. borrow_mut ( ) , sink) ) . and_then ( |mut s| {
947959 let _ = s. flush ( ) ;
948960 Some ( s)
949961 } )
950962}
951963
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+
952975/// Write `args` to output stream `local_s` if possible, `global_s`
953976/// otherwise. `label` identifies the stream in a panic message.
954977///
@@ -961,7 +984,7 @@ pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write +
961984/// However, if the actual I/O causes an error, this function does panic.
962985fn print_to < T > (
963986 args : fmt:: Arguments < ' _ > ,
964- local_s : & ' static LocalKey < RefCell < Option < Box < dyn Write + Send > > > > ,
987+ local_s : & ' static LocalKey < RefCell < Option < Box < dyn LocalOutput > > > > ,
965988 global_s : fn ( ) -> T ,
966989 label : & str ,
967990) where
0 commit comments