Skip to content

Commit 8ad7c8d

Browse files
committed
Implement compiletest --new-output-capture, in stable Rust
1 parent e29f129 commit 8ad7c8d

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

src/tools/compiletest/src/executor.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,17 @@ enum CaptureKind {
168168
/// Use the old output-capture implementation, which relies on the unstable
169169
/// library feature `#![feature(internal_output_capture)]`.
170170
Old { buf: Arc<Mutex<Vec<u8>>> },
171+
172+
/// Use the new output-capture implementation, which only uses stable Rust.
173+
New { buf: output_capture::CaptureBuf },
171174
}
172175

173176
impl CaptureKind {
174177
fn for_config(config: &Config) -> Self {
175178
if config.nocapture {
176179
Self::None
180+
} else if config.new_output_capture {
181+
Self::New { buf: output_capture::CaptureBuf::new() }
177182
} else {
178183
// Create a capure buffer for `io::set_output_capture`.
179184
Self::Old { buf: Default::default() }
@@ -184,21 +189,30 @@ impl CaptureKind {
184189
match self {
185190
Self::None => false,
186191
Self::Old { .. } => true,
192+
Self::New { .. } => true,
187193
}
188194
}
189195

190196
fn stdout(&self) -> &dyn ConsoleOut {
191-
&output_capture::Stdout
197+
self.capture_buf_or(&output_capture::Stdout)
192198
}
193199

194200
fn stderr(&self) -> &dyn ConsoleOut {
195-
&output_capture::Stderr
201+
self.capture_buf_or(&output_capture::Stderr)
202+
}
203+
204+
fn capture_buf_or<'a>(&'a self, fallback: &'a dyn ConsoleOut) -> &'a dyn ConsoleOut {
205+
match self {
206+
Self::None | Self::Old { .. } => fallback,
207+
Self::New { buf } => buf,
208+
}
196209
}
197210

198211
fn into_inner(self) -> Option<Vec<u8>> {
199212
match self {
200213
Self::None => None,
201214
Self::Old { buf } => Some(buf.lock().unwrap_or_else(|e| e.into_inner()).to_vec()),
215+
Self::New { buf } => Some(buf.into_inner().into()),
202216
}
203217
}
204218
}

src/tools/compiletest/src/output_capture.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::fmt;
22
use std::panic::RefUnwindSafe;
3+
use std::sync::Mutex;
34

45
pub trait ConsoleOut: fmt::Debug + RefUnwindSafe {
56
fn write_fmt(&self, args: fmt::Arguments<'_>);
@@ -22,3 +23,30 @@ impl ConsoleOut for Stderr {
2223
eprint!("{args}");
2324
}
2425
}
26+
27+
pub(crate) struct CaptureBuf {
28+
inner: Mutex<String>,
29+
}
30+
31+
impl CaptureBuf {
32+
pub(crate) fn new() -> Self {
33+
Self { inner: Mutex::new(String::new()) }
34+
}
35+
36+
pub(crate) fn into_inner(self) -> String {
37+
self.inner.into_inner().unwrap_or_else(|e| e.into_inner())
38+
}
39+
}
40+
41+
impl fmt::Debug for CaptureBuf {
42+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43+
f.debug_struct("CaptureBuf").finish_non_exhaustive()
44+
}
45+
}
46+
47+
impl ConsoleOut for CaptureBuf {
48+
fn write_fmt(&self, args: fmt::Arguments<'_>) {
49+
let mut s = self.inner.lock().unwrap_or_else(|e| e.into_inner());
50+
<String as fmt::Write>::write_fmt(&mut s, args).unwrap();
51+
}
52+
}

0 commit comments

Comments
 (0)