about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/compiletest/src/common.rs33
-rw-r--r--src/tools/compiletest/src/header.rs20
-rw-r--r--src/tools/compiletest/src/main.rs16
-rw-r--r--src/tools/compiletest/src/runtest.rs42
4 files changed, 89 insertions, 22 deletions
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 722979c3c14..a75d9f0b0bb 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -99,6 +99,36 @@ impl fmt::Display for Mode {
     }
 }
 
+#[derive(Clone, Copy, PartialEq, Debug, Hash)]
+pub enum PassMode {
+    Check,
+    Build,
+    Run,
+}
+
+impl FromStr for PassMode {
+    type Err = ();
+    fn from_str(s: &str) -> Result<Self, ()> {
+        match s {
+            "check" => Ok(PassMode::Check),
+            "build" => Ok(PassMode::Build),
+            "run" => Ok(PassMode::Run),
+            _ => Err(()),
+        }
+    }
+}
+
+impl fmt::Display for PassMode {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let s = match *self {
+            PassMode::Check => "check",
+            PassMode::Build => "build",
+            PassMode::Run => "run",
+        };
+        fmt::Display::fmt(s, f)
+    }
+}
+
 #[derive(Clone, Debug, PartialEq)]
 pub enum CompareMode {
     Nll,
@@ -184,6 +214,9 @@ pub struct Config {
     /// Exactly match the filter, rather than a substring
     pub filter_exact: bool,
 
+    /// Force the pass mode of a check/build/run-pass test to this mode.
+    pub force_pass_mode: Option<PassMode>,
+
     /// Write out a parseable log of tests that were run
     pub logfile: Option<PathBuf>,
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 6ce7461f759..8202218f7d1 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
 
 use log::*;
 
-use crate::common::{self, CompareMode, Config, Mode};
+use crate::common::{self, CompareMode, Config, Mode, PassMode};
 use crate::util;
 
 use crate::extract_gdb_version;
@@ -290,13 +290,6 @@ impl EarlyProps {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub enum PassMode {
-    Check,
-    Build,
-    Run,
-}
-
 #[derive(Clone, Debug)]
 pub struct TestProps {
     // Lines that should be expected, in order, on standard out
@@ -358,6 +351,8 @@ pub struct TestProps {
     pub incremental_dir: Option<PathBuf>,
     // How far should the test proceed while still passing.
     pub pass_mode: Option<PassMode>,
+    // Ignore `--pass` overrides from the command line for this test.
+    pub ignore_pass: bool,
     // rustdoc will test the output of the `--test` option
     pub check_test_line_numbers_match: bool,
     // Do not pass `-Z ui-testing` to UI tests
@@ -400,6 +395,7 @@ impl TestProps {
             forbid_output: vec![],
             incremental_dir: None,
             pass_mode: None,
+            ignore_pass: false,
             check_test_line_numbers_match: false,
             disable_ui_testing_normalization: false,
             normalize_stdout: vec![],
@@ -528,6 +524,10 @@ impl TestProps {
 
             self.update_pass_mode(ln, cfg, config);
 
+            if !self.ignore_pass {
+                self.ignore_pass = config.parse_ignore_pass(ln);
+            }
+
             if !self.disable_ui_testing_normalization {
                 self.disable_ui_testing_normalization =
                     config.parse_disable_ui_testing_normalization(ln);
@@ -743,6 +743,10 @@ impl Config {
         self.parse_name_directive(line, "check-test-line-numbers-match")
     }
 
+    fn parse_ignore_pass(&self, line: &str) -> bool {
+        self.parse_name_directive(line, "ignore-pass")
+    }
+
     fn parse_assembly_output(&self, line: &str) -> Option<String> {
         self.parse_name_value_directive(line, "assembly-output")
             .map(|r| r.trim().to_string())
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index d0dc9d11d39..288853d5e18 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -5,7 +5,7 @@
 
 extern crate test;
 
-use crate::common::CompareMode;
+use crate::common::{CompareMode, PassMode};
 use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
 use crate::common::{Config, TestPaths};
 use crate::common::{DebugInfoCdb, DebugInfoGdbLldb, DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
@@ -128,6 +128,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "(compile-fail|run-fail|run-pass|\
              run-pass-valgrind|pretty|debug-info|incremental|mir-opt)",
         )
+        .optopt(
+            "",
+            "pass",
+            "force {check,build,run}-pass tests to this mode.",
+            "check | build | run"
+        )
         .optflag("", "ignored", "run tests marked as ignored")
         .optflag("", "exact", "filters match exactly")
         .optopt(
@@ -320,6 +326,10 @@ pub fn parse_config(args: Vec<String>) -> Config {
         run_ignored,
         filter: matches.free.first().cloned(),
         filter_exact: matches.opt_present("exact"),
+        force_pass_mode: matches.opt_str("pass").map(|mode|
+            mode.parse::<PassMode>()
+                .unwrap_or_else(|_| panic!("unknown `--pass` option `{}` given.", mode))
+        ),
         logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)),
         runtool: matches.opt_str("runtool"),
         host_rustcflags: matches.opt_str("host-rustcflags"),
@@ -382,6 +392,10 @@ pub fn log_config(config: &Config) {
         ),
     );
     logv(c, format!("filter_exact: {}", config.filter_exact));
+    logv(c, format!(
+        "force_pass_mode: {}",
+        opt_str(&config.force_pass_mode.map(|m| format!("{}", m))),
+    ));
     logv(c, format!("runtool: {}", opt_str(&config.runtool)));
     logv(
         c,
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 8b52a529d44..270420991e9 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-filelength
 
-use crate::common::CompareMode;
+use crate::common::{CompareMode, PassMode};
 use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
 use crate::common::{output_base_dir, output_base_name, output_testname_unique};
 use crate::common::{Codegen, CodegenUnits, Rustdoc};
@@ -10,7 +10,7 @@ use crate::common::{Config, TestPaths};
 use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly};
 use diff;
 use crate::errors::{self, Error, ErrorKind};
-use crate::header::{TestProps, PassMode};
+use crate::header::TestProps;
 use crate::json;
 use regex::{Captures, Regex};
 use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
@@ -211,6 +211,7 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
         props: &props,
         testpaths,
         revision: revision,
+        is_aux: false,
     };
     create_dir_all(&cx.output_base_dir()).unwrap();
 
@@ -229,6 +230,7 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
                 props: &revision_props,
                 testpaths,
                 revision: Some(revision),
+                is_aux: false,
             };
             rev_cx.run_revision();
         }
@@ -260,6 +262,10 @@ pub fn compute_stamp_hash(config: &Config) -> String {
         env::var_os("PYTHONPATH").hash(&mut hash);
     }
 
+    if let Ui | RunPass = config.mode {
+        config.force_pass_mode.hash(&mut hash);
+    }
+
     format!("{:x}", hash.finish())
 }
 
@@ -268,6 +274,7 @@ struct TestCx<'test> {
     props: &'test TestProps,
     testpaths: &'test TestPaths,
     revision: Option<&'test str>,
+    is_aux: bool,
 }
 
 struct DebuggerCommands {
@@ -309,10 +316,18 @@ impl<'test> TestCx<'test> {
         }
     }
 
+    fn effective_pass_mode(&self) -> Option<PassMode> {
+        if !self.props.ignore_pass {
+            if let (mode @ Some(_), Some(_)) = (self.config.force_pass_mode, self.props.pass_mode) {
+                return mode;
+            }
+        }
+        self.props.pass_mode
+    }
+
     fn should_run_successfully(&self) -> bool {
         match self.config.mode {
-            RunPass => true,
-            Ui => self.props.pass_mode == Some(PassMode::Run),
+            RunPass | Ui => self.effective_pass_mode() == Some(PassMode::Run),
             mode => panic!("unimplemented for mode {:?}", mode),
         }
     }
@@ -1563,6 +1578,7 @@ impl<'test> TestCx<'test> {
                     props: &aux_props,
                     testpaths: &aux_testpaths,
                     revision: self.revision,
+                    is_aux: true,
                 };
                 // Create the directory for the stdout/stderr files.
                 create_dir_all(aux_cx.output_base_dir()).unwrap();
@@ -1732,6 +1748,7 @@ impl<'test> TestCx<'test> {
                 props: &aux_props,
                 testpaths: &aux_testpaths,
                 revision: self.revision,
+                is_aux: true,
             };
             // Create the directory for the stdout/stderr files.
             create_dir_all(aux_cx.output_base_dir()).unwrap();
@@ -1871,7 +1888,11 @@ impl<'test> TestCx<'test> {
         result
     }
 
-    fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> Command {
+    fn make_compile_args(
+        &self,
+        input_file: &Path,
+        output_file: TargetLocation,
+    ) -> Command {
         let is_rustdoc = self.config.src_base.ends_with("rustdoc-ui") ||
                          self.config.src_base.ends_with("rustdoc-js");
         let mut rustc = if !is_rustdoc {
@@ -1968,14 +1989,8 @@ impl<'test> TestCx<'test> {
             }
         }
 
-        if self.props.pass_mode == Some(PassMode::Check) {
-            assert!(
-                !self
-                    .props
-                    .compile_flags
-                    .iter()
-                    .any(|s| s.starts_with("--emit"))
-            );
+        let pass_mode = if self.is_aux { self.props.pass_mode } else { self.effective_pass_mode() };
+        if let Some(PassMode::Check) = pass_mode {
             rustc.args(&["--emit", "metadata"]);
         }
 
@@ -2713,6 +2728,7 @@ impl<'test> TestCx<'test> {
             props: &revision_props,
             testpaths: self.testpaths,
             revision: self.revision,
+            is_aux: false,
         };
 
         if self.config.verbose {