@@ -120,16 +120,15 @@ fn run_test_inner(
120120 runnable_test : RunnableTest ,
121121 completion_sender : mpsc:: Sender < TestCompletion > ,
122122) {
123- let is_capture = ! runnable_test. config . nocapture ;
123+ let capture = CaptureKind :: for_config ( & runnable_test. config ) ;
124124
125125 // Install a panic-capture buffer for use by the custom panic hook.
126- if is_capture {
126+ if capture . should_set_panic_hook ( ) {
127127 panic_hook:: set_capture_buf ( Default :: default ( ) ) ;
128128 }
129- let capture_buf = is_capture. then ( || Arc :: new ( Mutex :: new ( vec ! [ ] ) ) ) ;
130129
131- if let Some ( capture_buf ) = & capture_buf {
132- io:: set_output_capture ( Some ( Arc :: clone ( capture_buf ) ) ) ;
130+ if let CaptureKind :: Old { ref buf } = capture {
131+ io:: set_output_capture ( Some ( Arc :: clone ( buf ) ) ) ;
133132 }
134133
135134 let panic_payload = panic:: catch_unwind ( move || runnable_test. run ( ) ) . err ( ) ;
@@ -141,7 +140,7 @@ fn run_test_inner(
141140 // non-panic output, append the panic message to that buffer instead.
142141 eprint ! ( "{panic_buf}" ) ;
143142 }
144- if is_capture {
143+ if matches ! ( capture , CaptureKind :: Old { .. } ) {
145144 io:: set_output_capture ( None ) ;
146145 }
147146
@@ -152,11 +151,48 @@ fn run_test_inner(
152151 TestOutcome :: Failed { message : Some ( "test did not panic as expected" ) }
153152 }
154153 } ;
155- let stdout = capture_buf. map ( |mutex| mutex. lock ( ) . unwrap_or_else ( |e| e. into_inner ( ) ) . to_vec ( ) ) ;
156154
155+ let stdout = capture. into_inner ( ) ;
157156 completion_sender. send ( TestCompletion { id, outcome, stdout } ) . unwrap ( ) ;
158157}
159158
159+ enum CaptureKind {
160+ /// Do not capture test-runner output, for `--no-capture`.
161+ ///
162+ /// (This does not affect `rustc` and other subprocesses spawned by test
163+ /// runners, whose output is always captured.)
164+ None ,
165+
166+ /// Use the old output-capture implementation, which relies on the unstable
167+ /// library feature `#![feature(internal_output_capture)]`.
168+ Old { buf : Arc < Mutex < Vec < u8 > > > } ,
169+ }
170+
171+ impl CaptureKind {
172+ fn for_config ( config : & Config ) -> Self {
173+ if config. nocapture {
174+ Self :: None
175+ } else {
176+ // Create a capure buffer for `io::set_output_capture`.
177+ Self :: Old { buf : Default :: default ( ) }
178+ }
179+ }
180+
181+ fn should_set_panic_hook ( & self ) -> bool {
182+ match self {
183+ Self :: None => false ,
184+ Self :: Old { .. } => true ,
185+ }
186+ }
187+
188+ fn into_inner ( self ) -> Option < Vec < u8 > > {
189+ match self {
190+ Self :: None => None ,
191+ Self :: Old { buf } => Some ( buf. lock ( ) . unwrap_or_else ( |e| e. into_inner ( ) ) . to_vec ( ) ) ,
192+ }
193+ }
194+ }
195+
160196#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
161197struct TestId ( usize ) ;
162198
0 commit comments