@@ -120,16 +120,15 @@ fn run_test_inner(
120
120
runnable_test : RunnableTest ,
121
121
completion_sender : mpsc:: Sender < TestCompletion > ,
122
122
) {
123
- let is_capture = ! runnable_test. config . nocapture ;
123
+ let capture = CaptureKind :: for_config ( & runnable_test. config ) ;
124
124
125
125
// Install a panic-capture buffer for use by the custom panic hook.
126
- if is_capture {
126
+ if capture . should_set_panic_hook ( ) {
127
127
panic_hook:: set_capture_buf ( Default :: default ( ) ) ;
128
128
}
129
- let capture_buf = is_capture. then ( || Arc :: new ( Mutex :: new ( vec ! [ ] ) ) ) ;
130
129
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 ) ) ) ;
133
132
}
134
133
135
134
let panic_payload = panic:: catch_unwind ( move || runnable_test. run ( ) ) . err ( ) ;
@@ -141,7 +140,7 @@ fn run_test_inner(
141
140
// non-panic output, append the panic message to that buffer instead.
142
141
eprint ! ( "{panic_buf}" ) ;
143
142
}
144
- if is_capture {
143
+ if matches ! ( capture , CaptureKind :: Old { .. } ) {
145
144
io:: set_output_capture ( None ) ;
146
145
}
147
146
@@ -152,11 +151,48 @@ fn run_test_inner(
152
151
TestOutcome :: Failed { message : Some ( "test did not panic as expected" ) }
153
152
}
154
153
} ;
155
- let stdout = capture_buf. map ( |mutex| mutex. lock ( ) . unwrap_or_else ( |e| e. into_inner ( ) ) . to_vec ( ) ) ;
156
154
155
+ let stdout = capture. into_inner ( ) ;
157
156
completion_sender. send ( TestCompletion { id, outcome, stdout } ) . unwrap ( ) ;
158
157
}
159
158
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
+
160
196
#[ derive( Clone , Copy , Debug , PartialEq , Eq , Hash ) ]
161
197
struct TestId ( usize ) ;
162
198
0 commit comments