Skip to content

Commit 54337fa

Browse files
committed
compiletest: support '--pass check' and '// ignore-pass'.
1 parent a56a6d7 commit 54337fa

File tree

4 files changed

+89
-22
lines changed

4 files changed

+89
-22
lines changed

src/tools/compiletest/src/common.rs

+33
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,36 @@ impl fmt::Display for Mode {
9999
}
100100
}
101101

102+
#[derive(Clone, Copy, PartialEq, Debug, Hash)]
103+
pub enum PassMode {
104+
Check,
105+
Build,
106+
Run,
107+
}
108+
109+
impl FromStr for PassMode {
110+
type Err = ();
111+
fn from_str(s: &str) -> Result<Self, ()> {
112+
match s {
113+
"check" => Ok(PassMode::Check),
114+
"build" => Ok(PassMode::Build),
115+
"run" => Ok(PassMode::Run),
116+
_ => Err(()),
117+
}
118+
}
119+
}
120+
121+
impl fmt::Display for PassMode {
122+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123+
let s = match *self {
124+
PassMode::Check => "check",
125+
PassMode::Build => "build",
126+
PassMode::Run => "run",
127+
};
128+
fmt::Display::fmt(s, f)
129+
}
130+
}
131+
102132
#[derive(Clone, Debug, PartialEq)]
103133
pub enum CompareMode {
104134
Nll,
@@ -184,6 +214,9 @@ pub struct Config {
184214
/// Exactly match the filter, rather than a substring
185215
pub filter_exact: bool,
186216

217+
/// Force the pass mode of a check/build/run-pass test to this mode.
218+
pub force_pass_mode: Option<PassMode>,
219+
187220
/// Write out a parseable log of tests that were run
188221
pub logfile: Option<PathBuf>,
189222

src/tools/compiletest/src/header.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
66

77
use log::*;
88

9-
use crate::common::{self, CompareMode, Config, Mode};
9+
use crate::common::{self, CompareMode, Config, Mode, PassMode};
1010
use crate::util;
1111

1212
use crate::extract_gdb_version;
@@ -290,13 +290,6 @@ impl EarlyProps {
290290
}
291291
}
292292

293-
#[derive(Clone, Copy, PartialEq, Debug)]
294-
pub enum PassMode {
295-
Check,
296-
Build,
297-
Run,
298-
}
299-
300293
#[derive(Clone, Debug)]
301294
pub struct TestProps {
302295
// Lines that should be expected, in order, on standard out
@@ -358,6 +351,8 @@ pub struct TestProps {
358351
pub incremental_dir: Option<PathBuf>,
359352
// How far should the test proceed while still passing.
360353
pub pass_mode: Option<PassMode>,
354+
// Ignore `--pass` overrides from the command line for this test.
355+
pub ignore_pass: bool,
361356
// rustdoc will test the output of the `--test` option
362357
pub check_test_line_numbers_match: bool,
363358
// Do not pass `-Z ui-testing` to UI tests
@@ -400,6 +395,7 @@ impl TestProps {
400395
forbid_output: vec![],
401396
incremental_dir: None,
402397
pass_mode: None,
398+
ignore_pass: false,
403399
check_test_line_numbers_match: false,
404400
disable_ui_testing_normalization: false,
405401
normalize_stdout: vec![],
@@ -528,6 +524,10 @@ impl TestProps {
528524

529525
self.update_pass_mode(ln, cfg, config);
530526

527+
if !self.ignore_pass {
528+
self.ignore_pass = config.parse_ignore_pass(ln);
529+
}
530+
531531
if !self.disable_ui_testing_normalization {
532532
self.disable_ui_testing_normalization =
533533
config.parse_disable_ui_testing_normalization(ln);
@@ -743,6 +743,10 @@ impl Config {
743743
self.parse_name_directive(line, "check-test-line-numbers-match")
744744
}
745745

746+
fn parse_ignore_pass(&self, line: &str) -> bool {
747+
self.parse_name_directive(line, "ignore-pass")
748+
}
749+
746750
fn parse_assembly_output(&self, line: &str) -> Option<String> {
747751
self.parse_name_value_directive(line, "assembly-output")
748752
.map(|r| r.trim().to_string())

src/tools/compiletest/src/main.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
extern crate test;
77

8-
use crate::common::CompareMode;
8+
use crate::common::{CompareMode, PassMode};
99
use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
1010
use crate::common::{Config, TestPaths};
1111
use crate::common::{DebugInfoCdb, DebugInfoGdbLldb, DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
@@ -128,6 +128,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
128128
"(compile-fail|run-fail|run-pass|\
129129
run-pass-valgrind|pretty|debug-info|incremental|mir-opt)",
130130
)
131+
.optopt(
132+
"",
133+
"pass",
134+
"force {check,build,run}-pass tests to this mode.",
135+
"check | build | run"
136+
)
131137
.optflag("", "ignored", "run tests marked as ignored")
132138
.optflag("", "exact", "filters match exactly")
133139
.optopt(
@@ -320,6 +326,10 @@ pub fn parse_config(args: Vec<String>) -> Config {
320326
run_ignored,
321327
filter: matches.free.first().cloned(),
322328
filter_exact: matches.opt_present("exact"),
329+
force_pass_mode: matches.opt_str("pass").map(|mode|
330+
mode.parse::<PassMode>()
331+
.unwrap_or_else(|_| panic!("unknown `--pass` option `{}` given.", mode))
332+
),
323333
logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)),
324334
runtool: matches.opt_str("runtool"),
325335
host_rustcflags: matches.opt_str("host-rustcflags"),
@@ -382,6 +392,10 @@ pub fn log_config(config: &Config) {
382392
),
383393
);
384394
logv(c, format!("filter_exact: {}", config.filter_exact));
395+
logv(c, format!(
396+
"force_pass_mode: {}",
397+
opt_str(&config.force_pass_mode.map(|m| format!("{}", m))),
398+
));
385399
logv(c, format!("runtool: {}", opt_str(&config.runtool)));
386400
logv(
387401
c,

src/tools/compiletest/src/runtest.rs

+29-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// ignore-tidy-filelength
22

3-
use crate::common::CompareMode;
3+
use crate::common::{CompareMode, PassMode};
44
use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
55
use crate::common::{output_base_dir, output_base_name, output_testname_unique};
66
use crate::common::{Codegen, CodegenUnits, Rustdoc};
@@ -10,7 +10,7 @@ use crate::common::{Config, TestPaths};
1010
use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly};
1111
use diff;
1212
use crate::errors::{self, Error, ErrorKind};
13-
use crate::header::{TestProps, PassMode};
13+
use crate::header::TestProps;
1414
use crate::json;
1515
use regex::{Captures, Regex};
1616
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
@@ -211,6 +211,7 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
211211
props: &props,
212212
testpaths,
213213
revision: revision,
214+
is_aux: false,
214215
};
215216
create_dir_all(&cx.output_base_dir()).unwrap();
216217

@@ -229,6 +230,7 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
229230
props: &revision_props,
230231
testpaths,
231232
revision: Some(revision),
233+
is_aux: false,
232234
};
233235
rev_cx.run_revision();
234236
}
@@ -260,6 +262,10 @@ pub fn compute_stamp_hash(config: &Config) -> String {
260262
env::var_os("PYTHONPATH").hash(&mut hash);
261263
}
262264

265+
if let Ui | RunPass = config.mode {
266+
config.force_pass_mode.hash(&mut hash);
267+
}
268+
263269
format!("{:x}", hash.finish())
264270
}
265271

@@ -268,6 +274,7 @@ struct TestCx<'test> {
268274
props: &'test TestProps,
269275
testpaths: &'test TestPaths,
270276
revision: Option<&'test str>,
277+
is_aux: bool,
271278
}
272279

273280
struct DebuggerCommands {
@@ -309,10 +316,18 @@ impl<'test> TestCx<'test> {
309316
}
310317
}
311318

319+
fn effective_pass_mode(&self) -> Option<PassMode> {
320+
if !self.props.ignore_pass {
321+
if let (mode @ Some(_), Some(_)) = (self.config.force_pass_mode, self.props.pass_mode) {
322+
return mode;
323+
}
324+
}
325+
self.props.pass_mode
326+
}
327+
312328
fn should_run_successfully(&self) -> bool {
313329
match self.config.mode {
314-
RunPass => true,
315-
Ui => self.props.pass_mode == Some(PassMode::Run),
330+
RunPass | Ui => self.effective_pass_mode() == Some(PassMode::Run),
316331
mode => panic!("unimplemented for mode {:?}", mode),
317332
}
318333
}
@@ -1563,6 +1578,7 @@ impl<'test> TestCx<'test> {
15631578
props: &aux_props,
15641579
testpaths: &aux_testpaths,
15651580
revision: self.revision,
1581+
is_aux: true,
15661582
};
15671583
// Create the directory for the stdout/stderr files.
15681584
create_dir_all(aux_cx.output_base_dir()).unwrap();
@@ -1732,6 +1748,7 @@ impl<'test> TestCx<'test> {
17321748
props: &aux_props,
17331749
testpaths: &aux_testpaths,
17341750
revision: self.revision,
1751+
is_aux: true,
17351752
};
17361753
// Create the directory for the stdout/stderr files.
17371754
create_dir_all(aux_cx.output_base_dir()).unwrap();
@@ -1871,7 +1888,11 @@ impl<'test> TestCx<'test> {
18711888
result
18721889
}
18731890

1874-
fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> Command {
1891+
fn make_compile_args(
1892+
&self,
1893+
input_file: &Path,
1894+
output_file: TargetLocation,
1895+
) -> Command {
18751896
let is_rustdoc = self.config.src_base.ends_with("rustdoc-ui") ||
18761897
self.config.src_base.ends_with("rustdoc-js");
18771898
let mut rustc = if !is_rustdoc {
@@ -1968,14 +1989,8 @@ impl<'test> TestCx<'test> {
19681989
}
19691990
}
19701991

1971-
if self.props.pass_mode == Some(PassMode::Check) {
1972-
assert!(
1973-
!self
1974-
.props
1975-
.compile_flags
1976-
.iter()
1977-
.any(|s| s.starts_with("--emit"))
1978-
);
1992+
let pass_mode = if self.is_aux { self.props.pass_mode } else { self.effective_pass_mode() };
1993+
if let Some(PassMode::Check) = pass_mode {
19791994
rustc.args(&["--emit", "metadata"]);
19801995
}
19811996

@@ -2713,6 +2728,7 @@ impl<'test> TestCx<'test> {
27132728
props: &revision_props,
27142729
testpaths: self.testpaths,
27152730
revision: self.revision,
2731+
is_aux: false,
27162732
};
27172733

27182734
if self.config.verbose {

0 commit comments

Comments
 (0)