Skip to content

Add compiletest --compare-mode nll option #49293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,26 @@ impl fmt::Display for Mode {
}
}

#[derive(Clone)]
pub enum CompareMode {
Nll
}

impl CompareMode {
fn to_str(&self) -> &'static str {
match *self {
CompareMode::Nll => "nll"
}
}

pub fn parse(s: String) -> CompareMode {
match s.as_str() {
"nll" => CompareMode::Nll,
x => panic!("unknown --compare-mode option: {}", x),
}
}
}

#[derive(Clone)]
pub struct Config {
/// The library paths required for running the compiler
Expand Down Expand Up @@ -210,6 +230,9 @@ pub struct Config {
/// where to find the remote test client process, if we're using it
pub remote_test_client: Option<PathBuf>,

/// mode describing what file the actual ui output will be compared to
pub compare_mode: Option<CompareMode>,

// Configuration for various run-make tests frobbing things like C compilers
// or querying about various LLVM component information.
pub cc: String,
Expand All @@ -230,12 +253,19 @@ pub struct TestPaths {
}

/// Used by `ui` tests to generate things like `foo.stderr` from `foo.rs`.
pub fn expected_output_path(testpaths: &TestPaths, revision: Option<&str>, kind: &str) -> PathBuf {
pub fn expected_output_path(testpaths: &TestPaths,
revision: Option<&str>,
compare_mode: &Option<CompareMode>,
kind: &str) -> PathBuf {

assert!(UI_EXTENSIONS.contains(&kind));
let extension = match revision {
Some(r) => format!("{}.{}", r, kind),
None => kind.to_string(),
};
let mut parts = Vec::new();

if let Some(x) = revision { parts.push(x); }
if let Some(ref x) = *compare_mode { parts.push(x.to_str()); }
parts.push(kind);

let extension = parts.join(".");
testpaths.file.with_extension(extension)
}

Expand Down
18 changes: 15 additions & 3 deletions src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use getopts::Options;
use common::{Config, TestPaths};
use common::{DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
use common::{expected_output_path, UI_EXTENSIONS};
use common::CompareMode;
use test::ColorConfig;
use util::logv;

Expand Down Expand Up @@ -227,6 +228,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
"path to the remote test client",
"PATH",
)
.optopt(
"",
"compare-mode",
"mode describing what file the actual ui output will be compared to",
"COMPARE MODE"
)
.optflag("h", "help", "show this message");

let (argv0, args_) = args.split_first().unwrap();
Expand Down Expand Up @@ -320,6 +327,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
quiet: matches.opt_present("quiet"),
color,
remote_test_client: matches.opt_str("remote-test-client").map(PathBuf::from),
compare_mode: matches.opt_str("compare-mode").map(CompareMode::parse),

cc: matches.opt_str("cc").unwrap(),
cxx: matches.opt_str("cxx").unwrap(),
Expand Down Expand Up @@ -615,7 +623,8 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn
};

// Debugging emscripten code doesn't make sense today
let ignore = early_props.ignore || !up_to_date(config, testpaths, &early_props)
let ignore = early_props.ignore
|| (!up_to_date(config, testpaths, &early_props) && config.compare_mode.is_none())
|| (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
&& config.target.contains("emscripten");

Expand Down Expand Up @@ -688,12 +697,15 @@ fn up_to_date(config: &Config, testpaths: &TestPaths, props: &EarlyProps) -> boo
// UI test files.
for extension in UI_EXTENSIONS {
for revision in &props.revisions {
let path = &expected_output_path(testpaths, Some(revision), extension);
let path = &expected_output_path(testpaths,
Some(revision),
&config.compare_mode,
extension);
inputs.push(mtime(path));
}

if props.revisions.is_empty() {
let path = &expected_output_path(testpaths, None, extension);
let path = &expected_output_path(testpaths, None, &config.compare_mode, extension);
inputs.push(mtime(path));
}
}
Expand Down
46 changes: 32 additions & 14 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc};
use common::{Incremental, MirOpt, RunMake, Ui};
use common::{expected_output_path, UI_STDERR, UI_STDOUT};
use common::CompareMode;
use diff;
use errors::{self, Error, ErrorKind};
use filetime::FileTime;
Expand Down Expand Up @@ -1681,6 +1682,13 @@ impl<'test> TestCx<'test> {
}
}

match self.config.compare_mode {
Some(CompareMode::Nll) => {
rustc.args(&["-Znll", "-Zborrowck=mir", "-Ztwo-phase-borrows"]);
},
None => {},
}

if self.props.force_host {
rustc.args(self.split_maybe_args(&self.config.host_rustcflags));
} else {
Expand Down Expand Up @@ -2507,11 +2515,8 @@ impl<'test> TestCx<'test> {
let proc_res = self.compile_test();
self.check_if_test_should_compile(&proc_res);

let expected_stderr_path = self.expected_output_path(UI_STDERR);
let expected_stderr = self.load_expected_output(&expected_stderr_path);

let expected_stdout_path = self.expected_output_path(UI_STDOUT);
let expected_stdout = self.load_expected_output(&expected_stdout_path);
let expected_stderr = self.load_expected_output(UI_STDERR);
let expected_stdout = self.load_expected_output(UI_STDOUT);

let normalized_stdout =
self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout);
Expand Down Expand Up @@ -2554,7 +2559,7 @@ impl<'test> TestCx<'test> {
self.fatal_proc_rec("test run failed!", &proc_res);
}
}
if !explicit {
if !explicit && self.config.compare_mode.is_none() {
if !expected_errors.is_empty() || !proc_res.status.success() {
// "// error-pattern" comments
self.check_expected_errors(expected_errors, &proc_res);
Expand Down Expand Up @@ -2797,19 +2802,32 @@ impl<'test> TestCx<'test> {
normalized
}

fn expected_output_path(&self, kind: &str) -> PathBuf {
expected_output_path(&self.testpaths, self.revision, kind)
}
fn load_expected_output(&self, kind: &str) -> String {
let mut path = expected_output_path(&self.testpaths,
self.revision,
&self.config.compare_mode,
kind);

fn load_expected_output(&self, path: &Path) -> String {
if !path.exists() {
return String::new();
if !path.exists() && self.config.compare_mode.is_some() {
// fallback!
path = expected_output_path(&self.testpaths, self.revision, &None, kind);
}

if path.exists() {
match self.load_expected_output_from_path(&path) {
Ok(x) => x,
Err(x) => self.fatal(&x),
}
} else {
String::new()
}
}

fn load_expected_output_from_path(&self, path: &Path) -> Result<String, String> {
let mut result = String::new();
match File::open(path).and_then(|mut f| f.read_to_string(&mut result)) {
Ok(_) => result,
Err(e) => self.fatal(&format!(
Ok(_) => Ok(result),
Err(e) => Err(format!(
"failed to load expected output from `{}`: {}",
path.display(),
e
Expand Down