about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tools/compiletest/src/executor.rs24
-rw-r--r--src/tools/compiletest/src/lib.rs1
-rw-r--r--src/tools/compiletest/src/output_capture.rs24
-rw-r--r--src/tools/compiletest/src/runtest.rs19
4 files changed, 60 insertions, 8 deletions
diff --git a/src/tools/compiletest/src/executor.rs b/src/tools/compiletest/src/executor.rs
index 383a0aaefb9..818d1719885 100644
--- a/src/tools/compiletest/src/executor.rs
+++ b/src/tools/compiletest/src/executor.rs
@@ -13,6 +13,7 @@ use std::sync::{Arc, Mutex, mpsc};
 use std::{env, hint, io, mem, panic, thread};
 
 use crate::common::{Config, TestPaths};
+use crate::output_capture::{self, ConsoleOut};
 use crate::panic_hook;
 
 mod deadline;
@@ -131,14 +132,15 @@ fn run_test_inner(
         io::set_output_capture(Some(Arc::clone(buf)));
     }
 
-    let panic_payload = panic::catch_unwind(move || runnable_test.run()).err();
+    let stdout = capture.stdout();
+    let stderr = capture.stderr();
+
+    let panic_payload = panic::catch_unwind(move || runnable_test.run(stdout, stderr)).err();
 
     if let Some(panic_buf) = panic_hook::take_capture_buf() {
         let panic_buf = panic_buf.lock().unwrap_or_else(|e| e.into_inner());
-        // For now, forward any captured panic message to (captured) stderr.
-        // FIXME(Zalathar): Once we have our own output-capture buffer for
-        // non-panic output, append the panic message to that buffer instead.
-        eprint!("{panic_buf}");
+        // Forward any captured panic message to (captured) stderr.
+        write!(stderr, "{panic_buf}");
     }
     if matches!(capture, CaptureKind::Old { .. }) {
         io::set_output_capture(None);
@@ -185,6 +187,14 @@ impl CaptureKind {
         }
     }
 
+    fn stdout(&self) -> &dyn ConsoleOut {
+        &output_capture::Stdout
+    }
+
+    fn stderr(&self) -> &dyn ConsoleOut {
+        &output_capture::Stderr
+    }
+
     fn into_inner(self) -> Option<Vec<u8>> {
         match self {
             Self::None => None,
@@ -210,10 +220,12 @@ impl RunnableTest {
         Self { config, testpaths, revision }
     }
 
-    fn run(&self) {
+    fn run(&self, stdout: &dyn ConsoleOut, stderr: &dyn ConsoleOut) {
         __rust_begin_short_backtrace(|| {
             crate::runtest::run(
                 Arc::clone(&self.config),
+                stdout,
+                stderr,
                 &self.testpaths,
                 self.revision.as_deref(),
             );
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index fa84691a46f..875d497af1a 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -15,6 +15,7 @@ pub mod directives;
 pub mod errors;
 mod executor;
 mod json;
+mod output_capture;
 mod panic_hook;
 mod raise_fd_limit;
 mod read2;
diff --git a/src/tools/compiletest/src/output_capture.rs b/src/tools/compiletest/src/output_capture.rs
new file mode 100644
index 00000000000..e5e3e14f288
--- /dev/null
+++ b/src/tools/compiletest/src/output_capture.rs
@@ -0,0 +1,24 @@
+use std::fmt;
+use std::panic::RefUnwindSafe;
+
+pub trait ConsoleOut: fmt::Debug + RefUnwindSafe {
+    fn write_fmt(&self, args: fmt::Arguments<'_>);
+}
+
+#[derive(Debug)]
+pub(crate) struct Stdout;
+
+impl ConsoleOut for Stdout {
+    fn write_fmt(&self, args: fmt::Arguments<'_>) {
+        print!("{args}");
+    }
+}
+
+#[derive(Debug)]
+pub(crate) struct Stderr;
+
+impl ConsoleOut for Stderr {
+    fn write_fmt(&self, args: fmt::Arguments<'_>) {
+        eprint!("{args}");
+    }
+}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 867624cc8fa..4b23e569af3 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -23,6 +23,7 @@ use crate::common::{
 };
 use crate::directives::TestProps;
 use crate::errors::{Error, ErrorKind, load_errors};
+use crate::output_capture::ConsoleOut;
 use crate::read2::{Truncated, read2_abbreviated};
 use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff};
 use crate::util::{Utf8PathBufExt, add_dylib_path, static_regex};
@@ -108,7 +109,13 @@ fn dylib_name(name: &str) -> String {
     format!("{}{name}.{}", std::env::consts::DLL_PREFIX, std::env::consts::DLL_EXTENSION)
 }
 
-pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
+pub fn run(
+    config: Arc<Config>,
+    stdout: &dyn ConsoleOut,
+    stderr: &dyn ConsoleOut,
+    testpaths: &TestPaths,
+    revision: Option<&str>,
+) {
     match &*config.target {
         "arm-linux-androideabi"
         | "armv7-linux-androideabi"
@@ -143,7 +150,7 @@ pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
         props.incremental_dir = Some(incremental_dir(&config, testpaths, revision));
     }
 
-    let cx = TestCx { config: &config, props: &props, testpaths, revision };
+    let cx = TestCx { config: &config, stdout, stderr, props: &props, testpaths, revision };
 
     if let Err(e) = create_dir_all(&cx.output_base_dir()) {
         panic!("failed to create output base directory {}: {e}", cx.output_base_dir());
@@ -162,6 +169,8 @@ pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
             revision_props.incremental_dir = props.incremental_dir.clone();
             let rev_cx = TestCx {
                 config: &config,
+                stdout,
+                stderr,
                 props: &revision_props,
                 testpaths,
                 revision: Some(revision),
@@ -212,6 +221,8 @@ pub fn compute_stamp_hash(config: &Config) -> String {
 #[derive(Copy, Clone, Debug)]
 struct TestCx<'test> {
     config: &'test Config,
+    stdout: &'test dyn ConsoleOut,
+    stderr: &'test dyn ConsoleOut,
     props: &'test TestProps,
     testpaths: &'test TestPaths,
     revision: Option<&'test str>,
@@ -978,6 +989,8 @@ impl<'test> TestCx<'test> {
                     self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config);
                 let aux_cx = TestCx {
                     config: self.config,
+                    stdout: self.stdout,
+                    stderr: self.stderr,
                     props: &props_for_aux,
                     testpaths: &aux_testpaths,
                     revision: self.revision,
@@ -1343,6 +1356,8 @@ impl<'test> TestCx<'test> {
         let aux_output = TargetLocation::ThisDirectory(aux_dir.clone());
         let aux_cx = TestCx {
             config: self.config,
+            stdout: self.stdout,
+            stderr: self.stderr,
             props: &aux_props,
             testpaths: &aux_testpaths,
             revision: self.revision,