@@ -18,14 +18,14 @@ use crate::thread::LocalKey;
1818
1919thread_local !  { 
2020    /// Used by the test crate to capture the output of the print! and println! macros. 
21-      static  LOCAL_STDOUT :  RefCell <Option <Box <dyn Write  +  Send >>> = { 
21+      static  LOCAL_STDOUT :  RefCell <Option <Box <dyn LocalOutput >>> = { 
2222        RefCell :: new( None ) 
2323    } 
2424} 
2525
2626thread_local !  { 
2727    /// Used by the test crate to capture the output of the eprint! and eprintln! macros, and panics. 
28-      static  LOCAL_STDERR :  RefCell <Option <Box <dyn Write  +  Send >>> = { 
28+      static  LOCAL_STDERR :  RefCell <Option <Box <dyn LocalOutput >>> = { 
2929        RefCell :: new( None ) 
3030    } 
3131} 
@@ -888,6 +888,18 @@ impl fmt::Debug for StderrLock<'_> {
888888    } 
889889} 
890890
891+ /// A writer than can be cloned to new threads. 
892+ #[ unstable(  
893+     feature = "set_stdio" ,  
894+     reason = "this trait may disappear completely or be replaced \   
895+                       with a more general mechanism", 
896+     issue = "none"  
897+ ) ] 
898+ #[ doc( hidden) ]  
899+ pub  trait  LocalOutput :  Write  + Send  { 
900+     fn  clone_box ( & self )  -> Box < dyn  LocalOutput > ; 
901+ } 
902+ 
891903/// Resets the thread-local stderr handle to the specified writer 
892904/// 
893905/// This will replace the current thread's stderr handle, returning the old 
@@ -903,7 +915,7 @@ impl fmt::Debug for StderrLock<'_> {
903915    issue = "none"  
904916) ] 
905917#[ doc( hidden) ]  
906- pub  fn  set_panic ( sink :  Option < Box < dyn  Write  +  Send > > )  -> Option < Box < dyn  Write  +  Send > >  { 
918+ pub  fn  set_panic ( sink :  Option < Box < dyn  LocalOutput > > )  -> Option < Box < dyn  LocalOutput > >  { 
907919    use  crate :: mem; 
908920    if  sink. is_none ( )  && !LOCAL_STREAMS . load ( Ordering :: Relaxed )  { 
909921        // LOCAL_STDERR is definitely None since LOCAL_STREAMS is false. 
@@ -934,7 +946,7 @@ pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write +
934946    issue = "none"  
935947) ] 
936948#[ doc( hidden) ]  
937- pub  fn  set_print ( sink :  Option < Box < dyn  Write  +  Send > > )  -> Option < Box < dyn  Write  +  Send > >  { 
949+ pub  fn  set_print ( sink :  Option < Box < dyn  LocalOutput > > )  -> Option < Box < dyn  LocalOutput > >  { 
938950    use  crate :: mem; 
939951    if  sink. is_none ( )  && !LOCAL_STREAMS . load ( Ordering :: Relaxed )  { 
940952        // LOCAL_STDOUT is definitely None since LOCAL_STREAMS is false. 
@@ -950,6 +962,22 @@ pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write +
950962    s
951963} 
952964
965+ pub ( crate )  fn  clone_io ( )  -> ( Option < Box < dyn  LocalOutput > > ,  Option < Box < dyn  LocalOutput > > )  { 
966+     // Don't waste time when LOCAL_{STDOUT,STDERR} are definitely None. 
967+     if  !LOCAL_STREAMS . load ( Ordering :: Relaxed )  { 
968+         return  ( None ,  None ) ; 
969+     } 
970+ 
971+     LOCAL_STDOUT . with ( |stdout| { 
972+         LOCAL_STDERR . with ( |stderr| { 
973+             ( 
974+                 stdout. borrow ( ) . as_ref ( ) . map ( |o| o. clone_box ( ) ) , 
975+                 stderr. borrow ( ) . as_ref ( ) . map ( |o| o. clone_box ( ) ) , 
976+             ) 
977+         } ) 
978+     } ) 
979+ } 
980+ 
953981/// Write `args` to output stream `local_s` if possible, `global_s` 
954982/// otherwise. `label` identifies the stream in a panic message. 
955983/// 
@@ -962,7 +990,7 @@ pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write +
962990/// However, if the actual I/O causes an error, this function does panic. 
963991fn  print_to < T > ( 
964992    args :  fmt:: Arguments < ' _ > , 
965-     local_s :  & ' static  LocalKey < RefCell < Option < Box < dyn  Write  +  Send > > > > , 
993+     local_s :  & ' static  LocalKey < RefCell < Option < Box < dyn  LocalOutput > > > > , 
966994    global_s :  fn ( )  -> T , 
967995    label :  & str , 
968996)  where 
0 commit comments