From a4cafe46c2f82d8c465dce0276197a630cb91127 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 6 Dec 2017 06:06:04 -0500 Subject: [PATCH 1/3] runtest: rustfmt --- src/tools/compiletest/src/main.rs | 455 +++++--- src/tools/compiletest/src/runtest.rs | 1435 +++++++++++++++----------- 2 files changed, 1136 insertions(+), 754 deletions(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 6da37df19279a..d8ccb285cc513 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -9,22 +9,20 @@ // except according to those terms. #![crate_name = "compiletest"] - #![feature(test)] #![feature(slice_rotate)] - #![deny(warnings)] +extern crate diff; +extern crate env_logger; +extern crate filetime; +extern crate getopts; #[cfg(unix)] extern crate libc; -extern crate test; -extern crate getopts; -extern crate rustc_serialize; #[macro_use] extern crate log; -extern crate env_logger; -extern crate filetime; -extern crate diff; +extern crate rustc_serialize; +extern crate test; use std::env; use std::ffi::OsString; @@ -35,8 +33,8 @@ use std::process::Command; use filetime::FileTime; use getopts::Options; use common::Config; -use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Mode}; -use test::{TestPaths, ColorConfig}; +use common::{DebugInfoGdb, DebugInfoLldb, Mode, Pretty}; +use test::{ColorConfig, TestPaths}; use util::logv; use self::header::EarlyProps; @@ -63,53 +61,168 @@ fn main() { run_tests(&config); } -pub fn parse_config(args: Vec ) -> Config { - +pub fn parse_config(args: Vec) -> Config { let mut opts = Options::new(); - opts.reqopt("", "compile-lib-path", "path to host shared libraries", "PATH") - .reqopt("", "run-lib-path", "path to target shared libraries", "PATH") - .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH") - .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH") - .reqopt("", "lldb-python", "path to python to use for doc tests", "PATH") - .reqopt("", "docck-python", "path to python to use for doc tests", "PATH") - .optopt("", "valgrind-path", "path to Valgrind executable for Valgrind tests", "PROGRAM") - .optflag("", "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind") - .optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR") + opts.reqopt( + "", + "compile-lib-path", + "path to host shared libraries", + "PATH", + ).reqopt( + "", + "run-lib-path", + "path to target shared libraries", + "PATH", + ) + .reqopt( + "", + "rustc-path", + "path to rustc to use for compiling", + "PATH", + ) + .optopt( + "", + "rustdoc-path", + "path to rustdoc to use for compiling", + "PATH", + ) + .reqopt( + "", + "lldb-python", + "path to python to use for doc tests", + "PATH", + ) + .reqopt( + "", + "docck-python", + "path to python to use for doc tests", + "PATH", + ) + .optopt( + "", + "valgrind-path", + "path to Valgrind executable for Valgrind tests", + "PROGRAM", + ) + .optflag( + "", + "force-valgrind", + "fail if Valgrind tests cannot be run under Valgrind", + ) + .optopt( + "", + "llvm-filecheck", + "path to LLVM's FileCheck binary", + "DIR", + ) .reqopt("", "src-base", "directory to scan for test files", "PATH") - .reqopt("", "build-base", "directory to deposit test outputs", "PATH") - .reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET") - .reqopt("", "mode", "which sort of compile tests to run", - "(compile-fail|parse-fail|run-fail|run-pass|\ - run-pass-valgrind|pretty|debug-info|incremental|mir-opt)") + .reqopt( + "", + "build-base", + "directory to deposit test outputs", + "PATH", + ) + .reqopt( + "", + "stage-id", + "the target-stage identifier", + "stageN-TARGET", + ) + .reqopt( + "", + "mode", + "which sort of compile tests to run", + "(compile-fail|parse-fail|run-fail|run-pass|\ + run-pass-valgrind|pretty|debug-info|incremental|mir-opt)", + ) .optflag("", "ignored", "run tests marked as ignored") .optflag("", "exact", "filters match exactly") - .optopt("", "runtool", "supervisor program to run tests under \ - (eg. emulator, valgrind)", "PROGRAM") - .optopt("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS") - .optopt("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS") + .optopt( + "", + "runtool", + "supervisor program to run tests under \ + (eg. emulator, valgrind)", + "PROGRAM", + ) + .optopt( + "", + "host-rustcflags", + "flags to pass to rustc for host", + "FLAGS", + ) + .optopt( + "", + "target-rustcflags", + "flags to pass to rustc for target", + "FLAGS", + ) .optflag("", "verbose", "run tests verbosely, showing all output") - .optflag("", "quiet", "print one character per test instead of one line") + .optflag( + "", + "quiet", + "print one character per test instead of one line", + ) .optopt("", "color", "coloring: auto, always, never", "WHEN") .optopt("", "logfile", "file to log test execution to", "FILE") .optopt("", "target", "the target to build for", "TARGET") .optopt("", "host", "the host to build for", "HOST") - .optopt("", "gdb", "path to GDB to use for GDB debuginfo tests", "PATH") - .optopt("", "lldb-version", "the version of LLDB used", "VERSION STRING") - .optopt("", "llvm-version", "the version of LLVM used", "VERSION STRING") + .optopt( + "", + "gdb", + "path to GDB to use for GDB debuginfo tests", + "PATH", + ) + .optopt( + "", + "lldb-version", + "the version of LLDB used", + "VERSION STRING", + ) + .optopt( + "", + "llvm-version", + "the version of LLVM used", + "VERSION STRING", + ) .optflag("", "system-llvm", "is LLVM the system LLVM") - .optopt("", "android-cross-path", "Android NDK standalone path", "PATH") + .optopt( + "", + "android-cross-path", + "Android NDK standalone path", + "PATH", + ) .optopt("", "adb-path", "path to the android debugger", "PATH") - .optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH") - .optopt("", "lldb-python-dir", "directory containing LLDB's python module", "PATH") + .optopt( + "", + "adb-test-dir", + "path to tests for the android debugger", + "PATH", + ) + .optopt( + "", + "lldb-python-dir", + "directory containing LLDB's python module", + "PATH", + ) .reqopt("", "cc", "path to a C compiler", "PATH") .reqopt("", "cxx", "path to a C++ compiler", "PATH") .reqopt("", "cflags", "flags for the C compiler", "FLAGS") .optopt("", "ar", "path to an archiver", "PATH") .optopt("", "linker", "path to a linker", "PATH") - .reqopt("", "llvm-components", "list of LLVM components built in", "LIST") + .reqopt( + "", + "llvm-components", + "list of LLVM components built in", + "LIST", + ) .reqopt("", "llvm-cxxflags", "C++ flags for LLVM", "FLAGS") .optopt("", "nodejs", "the name of nodejs", "PATH") - .optopt("", "remote-test-client", "path to the remote test client", "PATH") + .optopt( + "", + "remote-test-client", + "path to the remote test client", + "PATH", + ) .optflag("h", "help", "show this message"); let (argv0, args_) = args.split_first().unwrap(); @@ -120,11 +233,10 @@ pub fn parse_config(args: Vec ) -> Config { panic!() } - let matches = - &match opts.parse(args_) { - Ok(m) => m, - Err(f) => panic!("{:?}", f) - }; + let matches = &match opts.parse(args_) { + Ok(m) => m, + Err(f) => panic!("{:?}", f), + }; if matches.opt_present("h") || matches.opt_present("help") { let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0); @@ -154,7 +266,10 @@ pub fn parse_config(args: Vec ) -> Config { Some("auto") | None => ColorConfig::AutoColor, Some("always") => ColorConfig::AlwaysColor, Some("never") => ColorConfig::NeverColor, - Some(x) => panic!("argument for --color must be auto, always, or never, but found `{}`", x), + Some(x) => panic!( + "argument for --color must be auto, always, or never, but found `{}`", + x + ), }; Config { @@ -170,7 +285,11 @@ pub fn parse_config(args: Vec ) -> Config { src_base: opt_path(matches, "src-base"), build_base: opt_path(matches, "build-base"), stage_id: matches.opt_str("stage-id").unwrap(), - mode: matches.opt_str("mode").unwrap().parse().expect("invalid mode"), + mode: matches + .opt_str("mode") + .unwrap() + .parse() + .expect("invalid mode"), run_ignored: matches.opt_present("ignored"), filter: matches.free.first().cloned(), filter_exact: matches.opt_present("exact"), @@ -189,10 +308,9 @@ pub fn parse_config(args: Vec ) -> Config { android_cross_path: opt_path(matches, "android-cross-path"), adb_path: opt_str2(matches.opt_str("adb-path")), adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")), - adb_device_status: - opt_str2(matches.opt_str("target")).contains("android") && - "(none)" != opt_str2(matches.opt_str("adb-test-dir")) && - !opt_str2(matches.opt_str("adb-test-dir")).is_empty(), + adb_device_status: opt_str2(matches.opt_str("target")).contains("android") + && "(none)" != opt_str2(matches.opt_str("adb-test-dir")) + && !opt_str2(matches.opt_str("adb-test-dir")).is_empty(), lldb_python_dir: matches.opt_str("lldb-python-dir"), verbose: matches.opt_present("verbose"), quiet: matches.opt_present("quiet"), @@ -213,7 +331,10 @@ pub fn parse_config(args: Vec ) -> Config { pub fn log_config(config: &Config) { let c = config; logv(c, "configuration:".to_string()); - logv(c, format!("compile_lib_path: {:?}", config.compile_lib_path)); + logv( + c, + format!("compile_lib_path: {:?}", config.compile_lib_path), + ); logv(c, format!("run_lib_path: {:?}", config.run_lib_path)); logv(c, format!("rustc_path: {:?}", config.rustc_path.display())); logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path)); @@ -222,24 +343,38 @@ pub fn log_config(config: &Config) { logv(c, format!("stage_id: {}", config.stage_id)); logv(c, format!("mode: {}", config.mode)); logv(c, format!("run_ignored: {}", config.run_ignored)); - logv(c, format!("filter: {}", - opt_str(&config.filter - .as_ref() - .map(|re| re.to_owned())))); + logv( + c, + format!( + "filter: {}", + opt_str(&config.filter.as_ref().map(|re| re.to_owned())) + ), + ); logv(c, format!("filter_exact: {}", config.filter_exact)); logv(c, format!("runtool: {}", opt_str(&config.runtool))); - logv(c, format!("host-rustcflags: {}", - opt_str(&config.host_rustcflags))); - logv(c, format!("target-rustcflags: {}", - opt_str(&config.target_rustcflags))); + logv( + c, + format!("host-rustcflags: {}", opt_str(&config.host_rustcflags)), + ); + logv( + c, + format!("target-rustcflags: {}", opt_str(&config.target_rustcflags)), + ); logv(c, format!("target: {}", config.target)); logv(c, format!("host: {}", config.host)); - logv(c, format!("android-cross-path: {:?}", - config.android_cross_path.display())); + logv( + c, + format!( + "android-cross-path: {:?}", + config.android_cross_path.display() + ), + ); logv(c, format!("adb_path: {:?}", config.adb_path)); logv(c, format!("adb_test_dir: {:?}", config.adb_test_dir)); - logv(c, format!("adb_device_status: {}", - config.adb_device_status)); + logv( + c, + format!("adb_device_status: {}", config.adb_device_status), + ); logv(c, format!("ar: {}", config.ar)); logv(c, format!("linker: {:?}", config.linker)); logv(c, format!("verbose: {}", config.verbose)); @@ -264,8 +399,11 @@ pub fn opt_str2(maybestr: Option) -> String { pub fn run_tests(config: &Config) { if config.target.contains("android") { if let DebugInfoGdb = config.mode { - println!("{} debug-info test uses tcp 5039 port.\ - please reserve it", config.target); + println!( + "{} debug-info test uses tcp 5039 port.\ + please reserve it", + config.target + ); // android debug-info test uses remote debugger so, we test 1 thread // at once as they're all sharing the same TCP port to communicate @@ -281,12 +419,14 @@ pub fn run_tests(config: &Config) { DebugInfoLldb => { if let Some(lldb_version) = config.lldb_version.as_ref() { if is_blacklisted_lldb_version(&lldb_version[..]) { - println!("WARNING: The used version of LLDB ({}) has a \ - known issue that breaks debuginfo tests. See \ - issue #32520 for more information. Skipping all \ - LLDB-based tests!", - lldb_version); - return + println!( + "WARNING: The used version of LLDB ({}) has a \ + known issue that breaks debuginfo tests. See \ + issue #32520 for more information. Skipping all \ + LLDB-based tests!", + lldb_version + ); + return; } } @@ -297,11 +437,12 @@ pub fn run_tests(config: &Config) { } DebugInfoGdb => { - if config.remote_test_client.is_some() && - !config.target.contains("android"){ - println!("WARNING: debuginfo tests are not available when \ - testing with remote"); - return + if config.remote_test_client.is_some() && !config.target.contains("android") { + println!( + "WARNING: debuginfo tests are not available when \ + testing with remote" + ); + return; } } _ => { /* proceed */ } @@ -317,7 +458,9 @@ pub fn run_tests(config: &Config) { // sadly osx needs some file descriptor limits raised for running tests in // parallel (especially when we have lots and lots of child processes). // For context, see #8904 - unsafe { raise_fd_limit::raise_fd_limit(); } + unsafe { + raise_fd_limit::raise_fd_limit(); + } // Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows // If #11207 is resolved (adding manifest to .exe) this becomes unnecessary env::set_var("__COMPAT_LAYER", "RunAsInvoker"); @@ -346,7 +489,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts { bench_benchmarks: true, nocapture: match env::var("RUST_TEST_NOCAPTURE") { Ok(val) => &val != "0", - Err(_) => false + Err(_) => false, }, color: config.color, test_threads: None, @@ -357,24 +500,25 @@ pub fn test_opts(config: &Config) -> test::TestOpts { } pub fn make_tests(config: &Config) -> Vec { - debug!("making tests from {:?}", - config.src_base.display()); + debug!("making tests from {:?}", config.src_base.display()); let mut tests = Vec::new(); - collect_tests_from_dir(config, - &config.src_base, - &config.src_base, - &PathBuf::new(), - &mut tests) - .unwrap(); + collect_tests_from_dir( + config, + &config.src_base, + &config.src_base, + &PathBuf::new(), + &mut tests, + ).unwrap(); tests } -fn collect_tests_from_dir(config: &Config, - base: &Path, - dir: &Path, - relative_dir_path: &Path, - tests: &mut Vec) - -> io::Result<()> { +fn collect_tests_from_dir( + config: &Config, + base: &Path, + dir: &Path, + relative_dir_path: &Path, + tests: &mut Vec, +) -> io::Result<()> { // Ignore directories that contain a file // `compiletest-ignore-dir`. for file in fs::read_dir(dir)? { @@ -390,7 +534,7 @@ fn collect_tests_from_dir(config: &Config, relative_dir: relative_dir_path.parent().unwrap().to_path_buf(), }; tests.push(make_test(config, &paths)); - return Ok(()) + return Ok(()); } } @@ -430,11 +574,7 @@ fn collect_tests_from_dir(config: &Config, fs::create_dir_all(&build_dir).unwrap(); } else { debug!("found directory: {:?}", file_path.display()); - collect_tests_from_dir(config, - base, - &file_path, - &relative_file_path, - tests)?; + collect_tests_from_dir(config, base, &file_path, &relative_file_path, tests)?; } } else { debug!("found other file/directory: {:?}", file_path.display()); @@ -467,13 +607,13 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn test::ShouldPanic::Yes } else { test::ShouldPanic::No - } + }, }; // Debugging emscripten code doesn't make sense today - let ignore = early_props.ignore || !up_to_date(config, testpaths, &early_props) || - (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb) && - config.target.contains("emscripten"); + let ignore = early_props.ignore || !up_to_date(config, testpaths, &early_props) + || (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb) + && config.target.contains("emscripten"); test::TestDescAndFn { desc: test::TestDesc { @@ -487,28 +627,32 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn } fn stamp(config: &Config, testpaths: &TestPaths) -> PathBuf { - let stamp_name = format!("{}-{}.stamp", - testpaths.file.file_name().unwrap() - .to_str().unwrap(), - config.stage_id); - config.build_base.canonicalize() - .unwrap_or_else(|_| config.build_base.clone()) - .join(&testpaths.relative_dir) - .join(stamp_name) + let stamp_name = format!( + "{}-{}.stamp", + testpaths.file.file_name().unwrap().to_str().unwrap(), + config.stage_id + ); + config + .build_base + .canonicalize() + .unwrap_or_else(|_| config.build_base.clone()) + .join(&testpaths.relative_dir) + .join(stamp_name) } fn up_to_date(config: &Config, testpaths: &TestPaths, props: &EarlyProps) -> bool { - let rust_src_dir = config.find_rust_src_root().expect( - "Could not find Rust source root", - ); + let rust_src_dir = config + .find_rust_src_root() + .expect("Could not find Rust source root"); let stamp = mtime(&stamp(config, testpaths)); let mut inputs = vec![mtime(&testpaths.file), mtime(&config.rustc_path)]; for aux in props.aux.iter() { - inputs.push(mtime( - &testpaths.file.parent().unwrap().join("auxiliary").join( - aux, - ), - )); + inputs.push(mtime(&testpaths + .file + .parent() + .unwrap() + .join("auxiliary") + .join(aux))); } // Relevant pretty printer files let pretty_printer_files = [ @@ -533,17 +677,16 @@ fn up_to_date(config: &Config, testpaths: &TestPaths, props: &EarlyProps) -> boo } fn mtime(path: &Path) -> FileTime { - fs::metadata(path).map(|f| { - FileTime::from_last_modification_time(&f) - }).unwrap_or_else(|_| FileTime::zero()) + fs::metadata(path) + .map(|f| FileTime::from_last_modification_time(&f)) + .unwrap_or_else(|_| FileTime::zero()) } pub fn make_test_name(config: &Config, testpaths: &TestPaths) -> test::TestName { // Convert a complete path to something like // // run-pass/foo/bar/baz.rs - let path = - PathBuf::from(config.src_base.file_name().unwrap()) + let path = PathBuf::from(config.src_base.file_name().unwrap()) .join(&testpaths.relative_dir) .join(&testpaths.file.file_name().unwrap()); test::DynTestName(format!("[{}] {}", config.mode, path.display())) @@ -552,9 +695,7 @@ pub fn make_test_name(config: &Config, testpaths: &TestPaths) -> test::TestName pub fn make_test_closure(config: &Config, testpaths: &TestPaths) -> test::TestFn { let config = config.clone(); let testpaths = testpaths.clone(); - test::DynTestFn(Box::new(move |()| { - runtest::run(config, &testpaths) - })) + test::DynTestFn(Box::new(move |()| runtest::run(config, &testpaths))) } /// Returns (Path to GDB, GDB Version, GDB has Rust Support) @@ -572,9 +713,17 @@ fn analyze_gdb(gdb: Option) -> (Option, Option, bool) { Some(ref s) => s, }; - let version_line = Command::new(gdb).arg("--version").output().map(|output| { - String::from_utf8_lossy(&output.stdout).lines().next().unwrap().to_string() - }).ok(); + let version_line = Command::new(gdb) + .arg("--version") + .output() + .map(|output| { + String::from_utf8_lossy(&output.stdout) + .lines() + .next() + .unwrap() + .to_string() + }) + .ok(); let version = match version_line { Some(line) => extract_gdb_version(&line), @@ -600,7 +749,7 @@ fn extract_gdb_version(full_version_line: &str) -> Option { for (pos, c) in full_version_line.char_indices() { if prev_was_digit || !c.is_digit(10) { prev_was_digit = c.is_digit(10); - continue + continue; } prev_was_digit = true; @@ -623,10 +772,15 @@ fn extract_gdb_version(full_version_line: &str) -> Option { Some(idx) => if line.as_bytes()[idx] == b'.' { let patch = &line[idx + 1..]; - let patch_len = patch.find(|c: char| !c.is_digit(10)) - .unwrap_or_else(|| patch.len()); + let patch_len = patch + .find(|c: char| !c.is_digit(10)) + .unwrap_or_else(|| patch.len()); let patch = &patch[..patch_len]; - let patch = if patch_len > 3 || patch_len == 0 { None } else { Some(patch) }; + let patch = if patch_len > 3 || patch_len == 0 { + None + } else { + Some(patch) + }; (&line[..idx], patch) } else { @@ -666,21 +820,36 @@ fn extract_lldb_version(full_version_line: Option) -> Option { let full_version_line = full_version_line.trim(); for (pos, l) in full_version_line.char_indices() { - if l != 'l' && l != 'L' { continue } - if pos + 5 >= full_version_line.len() { continue } + if l != 'l' && l != 'L' { + continue; + } + if pos + 5 >= full_version_line.len() { + continue; + } let l = full_version_line[pos + 1..].chars().next().unwrap(); - if l != 'l' && l != 'L' { continue } + if l != 'l' && l != 'L' { + continue; + } let d = full_version_line[pos + 2..].chars().next().unwrap(); - if d != 'd' && d != 'D' { continue } + if d != 'd' && d != 'D' { + continue; + } let b = full_version_line[pos + 3..].chars().next().unwrap(); - if b != 'b' && b != 'B' { continue } + if b != 'b' && b != 'B' { + continue; + } let dash = full_version_line[pos + 4..].chars().next().unwrap(); - if dash != '-' { continue } + if dash != '-' { + continue; + } - let vers = full_version_line[pos + 5..].chars().take_while(|c| { - c.is_digit(10) - }).collect::(); - if !vers.is_empty() { return Some(vers) } + let vers = full_version_line[pos + 5..] + .chars() + .take_while(|c| c.is_digit(10)) + .collect::(); + if !vers.is_empty() { + return Some(vers); + } } } } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7d20bb74c7aeb..d89dc855cb03c 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -10,10 +10,10 @@ use common::Config; use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind}; -use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits}; -use common::{Incremental, RunMake, Ui, MirOpt}; +use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc}; +use common::{Incremental, MirOpt, RunMake, Ui}; use diff; -use errors::{self, ErrorKind, Error}; +use errors::{self, Error, ErrorKind}; use filetime::FileTime; use json; use header::TestProps; @@ -24,12 +24,12 @@ use std::collections::HashMap; use std::collections::HashSet; use std::env; use std::ffi::OsString; -use std::fs::{self, File, create_dir_all}; +use std::fs::{self, create_dir_all, File}; use std::fmt; use std::io::prelude::*; use std::io::{self, BufReader}; use std::path::{Path, PathBuf}; -use std::process::{Command, Output, ExitStatus, Stdio, Child}; +use std::process::{Child, Command, ExitStatus, Output, Stdio}; use std::str; use extract_gdb_version; @@ -49,7 +49,6 @@ pub fn dylib_env_var() -> &'static str { pub fn run(config: Config, testpaths: &TestPaths) { match &*config.target { - "arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => { if !config.adb_device_status { panic!("android device not available"); @@ -71,24 +70,24 @@ pub fn run(config: Config, testpaths: &TestPaths) { debug!("running {:?}", testpaths.file.display()); let base_props = TestProps::from_file(&testpaths.file, None, &config); - let base_cx = TestCx { config: &config, - props: &base_props, - testpaths, - revision: None }; + let base_cx = TestCx { + config: &config, + props: &base_props, + testpaths, + revision: None, + }; base_cx.init_all(); if base_props.revisions.is_empty() { base_cx.run_revision() } else { for revision in &base_props.revisions { - let revision_props = TestProps::from_file(&testpaths.file, - Some(revision), - &config); + let revision_props = TestProps::from_file(&testpaths.file, Some(revision), &config); let rev_cx = TestCx { config: &config, props: &revision_props, testpaths, - revision: Some(revision) + revision: Some(revision), }; rev_cx.run_revision(); } @@ -103,7 +102,7 @@ struct TestCx<'test> { config: &'test Config, props: &'test TestProps, testpaths: &'test TestPaths, - revision: Option<&'test str> + revision: Option<&'test str>, } struct DebuggerCommands { @@ -125,8 +124,7 @@ impl<'test> TestCx<'test> { /// revisions, exactly once, with revision == None). fn run_revision(&self) { match self.config.mode { - CompileFail | - ParseFail => self.run_cfail_test(), + CompileFail | ParseFail => self.run_cfail_test(), RunFail => self.run_rfail_test(), RunPass => self.run_rpass_test(), RunPassValgrind => self.run_valgrind_test(), @@ -153,15 +151,14 @@ impl<'test> TestCx<'test> { if self.props.must_compile_successfully { if !proc_res.status.success() { - self.fatal_proc_rec( - "test compilation failed although it shouldn't!", - &proc_res); + self.fatal_proc_rec("test compilation failed although it shouldn't!", &proc_res); } } else { if proc_res.status.success() { self.fatal_proc_rec( &format!("{} test compiled successfully!", self.config.mode)[..], - &proc_res); + &proc_res, + ); } self.check_correct_failure_status(&proc_res); @@ -215,9 +212,9 @@ impl<'test> TestCx<'test> { const RUST_ERR: i32 = 101; if proc_res.status.code() != Some(RUST_ERR) { self.fatal_proc_rec( - &format!("failure produced the wrong error: {}", - proc_res.status), - proc_res); + &format!("failure produced the wrong error: {}", proc_res.status), + proc_res, + ); } } @@ -230,8 +227,10 @@ impl<'test> TestCx<'test> { // FIXME(#41968): Move this check to tidy? let expected_errors = errors::load_errors(&self.testpaths.file, self.revision); - assert!(expected_errors.is_empty(), - "run-pass tests with expected warnings should be moved to ui/"); + assert!( + expected_errors.is_empty(), + "run-pass tests with expected warnings should be moved to ui/" + ); let proc_res = self.exec_compiled_test(); @@ -256,7 +255,10 @@ impl<'test> TestCx<'test> { let mut new_config = self.config.clone(); new_config.runtool = new_config.valgrind_path.clone(); - let new_cx = TestCx { config: &new_config, ..*self }; + let new_cx = TestCx { + config: &new_config, + ..*self + }; proc_res = new_cx.exec_compiled_test(); if !proc_res.status.success() { @@ -268,28 +270,48 @@ impl<'test> TestCx<'test> { if self.props.pp_exact.is_some() { logv(self.config, "testing for exact pretty-printing".to_owned()); } else { - logv(self.config, "testing for converging pretty-printing".to_owned()); + logv( + self.config, + "testing for converging pretty-printing".to_owned(), + ); } - let rounds = match self.props.pp_exact { Some(_) => 1, None => 2 }; + let rounds = match self.props.pp_exact { + Some(_) => 1, + None => 2, + }; let mut src = String::new(); - File::open(&self.testpaths.file).unwrap().read_to_string(&mut src).unwrap(); + File::open(&self.testpaths.file) + .unwrap() + .read_to_string(&mut src) + .unwrap(); let mut srcs = vec![src]; let mut round = 0; while round < rounds { - logv(self.config, format!("pretty-printing round {} revision {:?}", - round, self.revision)); + logv( + self.config, + format!( + "pretty-printing round {} revision {:?}", + round, + self.revision + ), + ); let proc_res = self.print_source(srcs[round].to_owned(), &self.props.pretty_mode); if !proc_res.status.success() { - self.fatal_proc_rec(&format!("pretty-printing failed in round {} revision {:?}", - round, self.revision), - &proc_res); + self.fatal_proc_rec( + &format!( + "pretty-printing failed in round {} revision {:?}", + round, + self.revision + ), + &proc_res, + ); } - let ProcRes{ stdout, .. } = proc_res; + let ProcRes { stdout, .. } = proc_res; srcs.push(stdout); round += 1; } @@ -298,10 +320,13 @@ impl<'test> TestCx<'test> { Some(ref file) => { let filepath = self.testpaths.file.parent().unwrap().join(file); let mut s = String::new(); - File::open(&filepath).unwrap().read_to_string(&mut s).unwrap(); + File::open(&filepath) + .unwrap() + .read_to_string(&mut s) + .unwrap(); s } - None => { srcs[srcs.len() - 2].clone() } + None => srcs[srcs.len() - 2].clone(), }; let mut actual = srcs[srcs.len() - 1].clone(); @@ -315,7 +340,9 @@ impl<'test> TestCx<'test> { self.compare_source(&expected, &actual); // If we're only making sure that the output matches then just stop here - if self.props.pretty_compare_only { return; } + if self.props.pretty_compare_only { + return; + } // Finally, let's make sure it actually appears to remain valid code let proc_res = self.typecheck_source(actual); @@ -323,7 +350,9 @@ impl<'test> TestCx<'test> { self.fatal_proc_rec("pretty-printed source does not typecheck", &proc_res); } - if !self.props.pretty_expanded { return } + if !self.props.pretty_expanded { + return; + } // additionally, run `--pretty expanded` and try to build it. let proc_res = self.print_source(srcs[round].clone(), "expanded"); @@ -331,12 +360,16 @@ impl<'test> TestCx<'test> { self.fatal_proc_rec("pretty-printing (expanded) failed", &proc_res); } - let ProcRes{ stdout: expanded_src, .. } = proc_res; + let ProcRes { + stdout: expanded_src, + .. + } = proc_res; let proc_res = self.typecheck_source(expanded_src); if !proc_res.status.success() { self.fatal_proc_rec( "pretty-printed source (expanded) does not typecheck", - &proc_res); + &proc_res, + ); } } @@ -344,37 +377,42 @@ impl<'test> TestCx<'test> { let aux_dir = self.aux_output_dir_name(); let mut rustc = Command::new(&self.config.rustc_path); - rustc.arg("-") + rustc + .arg("-") .arg("-Zunstable-options") .args(&["--unpretty", &pretty_type]) .args(&["--target", &self.config.target]) - .arg("-L").arg(&aux_dir) + .arg("-L") + .arg(&aux_dir) .args(self.split_maybe_args(&self.config.target_rustcflags)) .args(&self.props.compile_flags) .envs(self.props.exec_env.clone()); - self.compose_and_run(rustc, - self.config.compile_lib_path.to_str().unwrap(), - Some(aux_dir.to_str().unwrap()), - Some(src)) + self.compose_and_run( + rustc, + self.config.compile_lib_path.to_str().unwrap(), + Some(aux_dir.to_str().unwrap()), + Some(src), + ) } - fn compare_source(&self, - expected: &str, - actual: &str) { + fn compare_source(&self, expected: &str, actual: &str) { if expected != actual { self.error("pretty-printed source does not match expected source"); - println!("\n\ -expected:\n\ -------------------------------------------\n\ -{}\n\ -------------------------------------------\n\ -actual:\n\ -------------------------------------------\n\ -{}\n\ -------------------------------------------\n\ -\n", - expected, actual); + println!( + "\n\ + expected:\n\ + ------------------------------------------\n\ + {}\n\ + ------------------------------------------\n\ + actual:\n\ + ------------------------------------------\n\ + {}\n\ + ------------------------------------------\n\ + \n", + expected, + actual + ); panic!(); } } @@ -394,12 +432,16 @@ actual:\n\ let aux_dir = self.aux_output_dir_name(); - rustc.arg("-") + rustc + .arg("-") .arg("-Zno-trans") - .arg("--out-dir").arg(&out_dir) + .arg("--out-dir") + .arg(&out_dir) .arg(&format!("--target={}", target)) - .arg("-L").arg(&self.config.build_base) - .arg("-L").arg(aux_dir); + .arg("-L") + .arg(&self.config.build_base) + .arg("-L") + .arg(aux_dir); if let Some(revision) = self.revision { rustc.args(&["--cfg", revision]); @@ -417,7 +459,7 @@ actual:\n\ let config = Config { target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - .. self.config.clone() + ..self.config.clone() }; let test_cx = TestCx { @@ -444,7 +486,7 @@ actual:\n\ let DebuggerCommands { commands, check_lines, - breakpoint_lines + breakpoint_lines, } = self.parse_debugger_commands(prefixes); let mut cmds = commands.join("\n"); @@ -458,15 +500,12 @@ actual:\n\ let debugger_run_result; match &*self.config.target { - "arm-linux-androideabi" | - "armv7-linux-androideabi" | - "aarch64-linux-android" => { - + "arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => { cmds = cmds.replace("run", "continue"); let tool_path = match self.config.android_cross_path.to_str() { Some(x) => x.to_owned(), - None => self.fatal("cannot find android cross path") + None => self.fatal("cannot find android cross path"), }; // write debugger script @@ -475,15 +514,20 @@ actual:\n\ script_str.push_str(&format!("set sysroot {}\n", tool_path)); script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap())); script_str.push_str("target remote :5039\n"); - script_str.push_str(&format!("set solib-search-path \ - ./{}/stage2/lib/rustlib/{}/lib/\n", - self.config.host, self.config.target)); + script_str.push_str(&format!( + "set solib-search-path \ + ./{}/stage2/lib/rustlib/{}/lib/\n", + self.config.host, + self.config.target + )); for line in &breakpoint_lines { - script_str.push_str(&format!("break {:?}:{}\n", - self.testpaths.file.file_name() - .unwrap() - .to_string_lossy(), - *line)[..]); + script_str.push_str( + &format!( + "break {:?}:{}\n", + self.testpaths.file.file_name().unwrap().to_string_lossy(), + *line + )[..], + ); } script_str.push_str(&cmds); script_str.push_str("\nquit\n"); @@ -505,14 +549,18 @@ actual:\n\ .status() .expect(&format!("failed to exec `{:?}`", adb_path)); - let adb_arg = format!("export LD_LIBRARY_PATH={}; \ - gdbserver{} :5039 {}/{}", - self.config.adb_test_dir.clone(), - if self.config.target.contains("aarch64") - {"64"} else {""}, - self.config.adb_test_dir.clone(), - exe_file.file_name().unwrap().to_str() - .unwrap()); + let adb_arg = format!( + "export LD_LIBRARY_PATH={}; \ + gdbserver{} :5039 {}/{}", + self.config.adb_test_dir.clone(), + if self.config.target.contains("aarch64") { + "64" + } else { + "" + }, + self.config.adb_test_dir.clone(), + exe_file.file_name().unwrap().to_str().unwrap() + ); debug!("adb arg: {}", adb_arg); let mut adb = Command::new(adb_path) @@ -531,25 +579,26 @@ actual:\n\ line.truncate(0); stdout.read_line(&mut line).unwrap(); if line.starts_with("Listening on port 5039") { - break + break; } } drop(stdout); let debugger_script = self.make_out_name("debugger.script"); // FIXME (#9639): This needs to handle non-utf8 paths - let debugger_opts = - vec!["-quiet".to_owned(), - "-batch".to_owned(), - "-nx".to_owned(), - format!("-command={}", debugger_script.to_str().unwrap())]; + let debugger_opts = vec![ + "-quiet".to_owned(), + "-batch".to_owned(), + "-nx".to_owned(), + format!("-command={}", debugger_script.to_str().unwrap()), + ]; let mut gdb_path = tool_path; gdb_path.push_str("/bin/gdb"); let Output { status, stdout, - stderr + stderr, } = Command::new(&gdb_path) .args(&debugger_opts) .output() @@ -574,14 +623,15 @@ actual:\n\ } _ => { - let rust_src_root = self.config.find_rust_src_root().expect( - "Could not find Rust source root", - ); + let rust_src_root = self.config + .find_rust_src_root() + .expect("Could not find Rust source root"); let rust_pp_module_rel_path = Path::new("./src/etc"); - let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path) - .to_str() - .unwrap() - .to_owned(); + let rust_pp_module_abs_path = rust_src_root + .join(rust_pp_module_rel_path) + .to_str() + .unwrap() + .to_owned(); // write debugger script let mut script_str = String::with_capacity(2048); script_str.push_str(&format!("set charset {}\n", Self::charset())); @@ -589,21 +639,25 @@ actual:\n\ match self.config.gdb_version { Some(version) => { - println!("NOTE: compiletest thinks it is using GDB version {}", - version); + println!( + "NOTE: compiletest thinks it is using GDB version {}", + version + ); if version > extract_gdb_version("7.4").unwrap() { // Add the directory containing the pretty printers to // GDB's script auto loading safe path - script_str.push_str( - &format!("add-auto-load-safe-path {}\n", - rust_pp_module_abs_path.replace(r"\", r"\\")) - ); + script_str.push_str(&format!( + "add-auto-load-safe-path {}\n", + rust_pp_module_abs_path.replace(r"\", r"\\") + )); } } _ => { - println!("NOTE: compiletest does not know which version of \ - GDB it is using"); + println!( + "NOTE: compiletest does not know which version of \ + GDB it is using" + ); } } @@ -612,13 +666,13 @@ actual:\n\ script_str.push_str("set print pretty off\n"); // Add the pretty printer directory to GDB's source-file search path - script_str.push_str(&format!("directory {}\n", - rust_pp_module_abs_path)); + script_str.push_str(&format!("directory {}\n", rust_pp_module_abs_path)); // Load the target executable - script_str.push_str(&format!("file {}\n", - exe_file.to_str().unwrap() - .replace(r"\", r"\\"))); + script_str.push_str(&format!( + "file {}\n", + exe_file.to_str().unwrap().replace(r"\", r"\\") + )); // Force GDB to print values in the Rust format. if self.config.gdb_native_rust { @@ -627,10 +681,11 @@ actual:\n\ // Add line breakpoints for line in &breakpoint_lines { - script_str.push_str(&format!("break '{}':{}\n", - self.testpaths.file.file_name().unwrap() - .to_string_lossy(), - *line)); + script_str.push_str(&format!( + "break '{}':{}\n", + self.testpaths.file.file_name().unwrap().to_string_lossy(), + *line + )); } script_str.push_str(&cmds); @@ -642,21 +697,23 @@ actual:\n\ let debugger_script = self.make_out_name("debugger.script"); // FIXME (#9639): This needs to handle non-utf8 paths - let debugger_opts = - vec!["-quiet".to_owned(), - "-batch".to_owned(), - "-nx".to_owned(), - format!("-command={}", debugger_script.to_str().unwrap())]; + let debugger_opts = vec![ + "-quiet".to_owned(), + "-batch".to_owned(), + "-nx".to_owned(), + format!("-command={}", debugger_script.to_str().unwrap()), + ]; let mut gdb = Command::new(self.config.gdb.as_ref().unwrap()); gdb.args(&debugger_opts) .env("PYTHONPATH", rust_pp_module_abs_path); - debugger_run_result = - self.compose_and_run(gdb, - self.config.run_lib_path.to_str().unwrap(), - None, - None); + debugger_run_result = self.compose_and_run( + gdb, + self.config.run_lib_path.to_str().unwrap(), + None, + None, + ); } } @@ -677,7 +734,7 @@ actual:\n\ let config = Config { target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags), host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags), - .. self.config.clone() + ..self.config.clone() }; @@ -700,12 +757,16 @@ actual:\n\ match self.config.lldb_version { Some(ref version) => { - println!("NOTE: compiletest thinks it is using LLDB version {}", - version); + println!( + "NOTE: compiletest thinks it is using LLDB version {}", + version + ); } _ => { - println!("NOTE: compiletest does not know which version of \ - LLDB it is using"); + println!( + "NOTE: compiletest does not know which version of \ + LLDB it is using" + ); } } @@ -725,17 +786,18 @@ actual:\n\ script_str.push_str("version\n"); // Switch LLDB into "Rust mode" - let rust_src_root = self.config.find_rust_src_root().expect( - "Could not find Rust source root", - ); + let rust_src_root = self.config + .find_rust_src_root() + .expect("Could not find Rust source root"); let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py"); - let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path) - .to_str() - .unwrap() - .to_owned(); - - script_str.push_str(&format!("command script import {}\n", - &rust_pp_module_abs_path[..])[..]); + let rust_pp_module_abs_path = rust_src_root + .join(rust_pp_module_rel_path) + .to_str() + .unwrap() + .to_owned(); + + script_str + .push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[..]); script_str.push_str("type summary add --no-value "); script_str.push_str("--python-function lldb_rust_formatters.print_val "); script_str.push_str("-x \".*\" --category Rust\n"); @@ -744,9 +806,11 @@ actual:\n\ // Set breakpoints on every line that contains the string "#break" let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy(); for line in &breakpoint_lines { - script_str.push_str(&format!("breakpoint set --file '{}' --line {}\n", - source_file_name, - line)); + script_str.push_str(&format!( + "breakpoint set --file '{}' --line {}\n", + source_file_name, + line + )); } // Append the other commands @@ -764,9 +828,7 @@ actual:\n\ let debugger_script = self.make_out_name("debugger.script"); // Let LLDB execute the script via lldb_batchmode.py - let debugger_run_result = self.run_lldb(&exe_file, - &debugger_script, - &rust_src_root); + let debugger_run_result = self.run_lldb(&exe_file, &debugger_script, &rust_src_root); if !debugger_run_result.status.success() { self.fatal_proc_rec("Error while running LLDB", &debugger_run_result); @@ -775,32 +837,39 @@ actual:\n\ self.check_debugger_output(&debugger_run_result, &check_lines); } - fn run_lldb(&self, - test_executable: &Path, - debugger_script: &Path, - rust_src_root: &Path) - -> ProcRes { + fn run_lldb( + &self, + test_executable: &Path, + debugger_script: &Path, + rust_src_root: &Path, + ) -> ProcRes { // Prepare the lldb_batchmode which executes the debugger script let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py"); - self.cmd2procres(Command::new(&self.config.lldb_python) - .arg(&lldb_script_path) - .arg(test_executable) - .arg(debugger_script) - .env("PYTHONPATH", - self.config.lldb_python_dir.as_ref().unwrap())) + self.cmd2procres( + Command::new(&self.config.lldb_python) + .arg(&lldb_script_path) + .arg(test_executable) + .arg(debugger_script) + .env("PYTHONPATH", self.config.lldb_python_dir.as_ref().unwrap()), + ) } fn cmd2procres(&self, cmd: &mut Command) -> ProcRes { let (status, out, err) = match cmd.output() { - Ok(Output { status, stdout, stderr }) => { - (status, - String::from_utf8(stdout).unwrap(), - String::from_utf8(stderr).unwrap()) - }, - Err(e) => { - self.fatal(&format!("Failed to setup Python process for \ - LLDB script: {}", e)) - } + Ok(Output { + status, + stdout, + stderr, + }) => ( + status, + String::from_utf8(stdout).unwrap(), + String::from_utf8(stderr).unwrap(), + ), + Err(e) => self.fatal(&format!( + "Failed to setup Python process for \ + LLDB script: {}", + e + )), }; self.dump_output(&out, &err); @@ -808,15 +877,17 @@ actual:\n\ status, stdout: out, stderr: err, - cmdline: format!("{:?}", cmd) + cmdline: format!("{:?}", cmd), } } fn parse_debugger_commands(&self, debugger_prefixes: &[&str]) -> DebuggerCommands { - let directives = debugger_prefixes.iter().map(|prefix| ( - format!("{}-command", prefix), - format!("{}-check", prefix), - )).collect::>(); + let directives = debugger_prefixes + .iter() + .map(|prefix| { + (format!("{}-command", prefix), format!("{}-check", prefix)) + }) + .collect::>(); let mut breakpoint_lines = vec![]; let mut commands = vec![]; @@ -831,22 +902,16 @@ actual:\n\ } for &(ref command_directive, ref check_directive) in &directives { - self.config.parse_name_value_directive( - &line, - command_directive).map(|cmd| { - commands.push(cmd) - }); - - self.config.parse_name_value_directive( - &line, - check_directive).map(|cmd| { - check_lines.push(cmd) - }); + self.config + .parse_name_value_directive(&line, command_directive) + .map(|cmd| commands.push(cmd)); + + self.config + .parse_name_value_directive(&line, check_directive) + .map(|cmd| check_lines.push(cmd)); } } - Err(e) => { - self.fatal(&format!("Error while parsing debugger commands: {}", e)) - } + Err(e) => self.fatal(&format!("Error while parsing debugger commands: {}", e)), } counter += 1; } @@ -864,15 +929,11 @@ actual:\n\ } // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS. - let options_to_remove = [ - "-O".to_owned(), - "-g".to_owned(), - "--debuginfo".to_owned() - ]; - let new_options = - self.split_maybe_args(options).into_iter() - .filter(|x| !options_to_remove.contains(x)) - .collect::>(); + let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()]; + let new_options = self.split_maybe_args(options) + .into_iter() + .filter(|x| !options_to_remove.contains(x)) + .collect::>(); Some(new_options.join(" ")) } @@ -891,9 +952,13 @@ actual:\n\ } } if check_line_index != num_check_lines && num_check_lines > 0 { - self.fatal_proc_rec(&format!("line not found in debugger output: {}", - check_lines[check_line_index]), - debugger_run_result); + self.fatal_proc_rec( + &format!( + "line not found in debugger output: {}", + check_lines[check_line_index] + ), + debugger_run_result, + ); } fn check_single_line(line: &str, check_line: &str) -> bool { @@ -904,17 +969,18 @@ actual:\n\ let can_start_anywhere = check_line.starts_with("[...]"); let can_end_anywhere = check_line.ends_with("[...]"); - let check_fragments: Vec<&str> = check_line.split("[...]") - .filter(|frag| !frag.is_empty()) - .collect(); + let check_fragments: Vec<&str> = check_line + .split("[...]") + .filter(|frag| !frag.is_empty()) + .collect(); if check_fragments.is_empty() { return true; } let (mut rest, first_fragment) = if can_start_anywhere { match line.find(check_fragments[0]) { - Some(pos) => (&line[pos + check_fragments[0].len() ..], 1), - None => return false + Some(pos) => (&line[pos + check_fragments[0].len()..], 1), + None => return false, } } else { (line, 0) @@ -923,9 +989,9 @@ actual:\n\ for current_fragment in &check_fragments[first_fragment..] { match rest.find(current_fragment) { Some(pos) => { - rest = &rest[pos + current_fragment.len() .. ]; + rest = &rest[pos + current_fragment.len()..]; } - None => return false + None => return false, } } @@ -937,15 +1003,15 @@ actual:\n\ } } - fn check_error_patterns(&self, - output_to_check: &str, - proc_res: &ProcRes) { + fn check_error_patterns(&self, output_to_check: &str, proc_res: &ProcRes) { if self.props.error_patterns.is_empty() { if self.props.must_compile_successfully { - return + return; } else { - self.fatal(&format!("no error pattern specified in {:?}", - self.testpaths.file.display())); + self.fatal(&format!( + "no error pattern specified in {:?}", + self.testpaths.file.display() + )); } } let mut next_err_idx = 0; @@ -963,13 +1029,16 @@ actual:\n\ next_err_pat = self.props.error_patterns[next_err_idx].trim(); } } - if done { return; } + if done { + return; + } let missing_patterns = &self.props.error_patterns[next_err_idx..]; if missing_patterns.len() == 1 { self.fatal_proc_rec( &format!("error pattern '{}' not found!", missing_patterns[0]), - proc_res); + proc_res, + ); } else { for pattern in missing_patterns { self.error(&format!("error pattern '{}' not found!", *pattern)); @@ -986,9 +1055,7 @@ actual:\n\ } } - fn check_forbid_output(&self, - output_to_check: &str, - proc_res: &ProcRes) { + fn check_forbid_output(&self, output_to_check: &str, proc_res: &ProcRes) { for pat in &self.props.forbid_output { if output_to_check.contains(pat) { self.fatal_proc_rec("forbidden pattern found in compiler output", proc_res); @@ -996,41 +1063,41 @@ actual:\n\ } } - fn check_expected_errors(&self, - expected_errors: Vec, - proc_res: &ProcRes) { - if proc_res.status.success() && - expected_errors.iter().any(|x| x.kind == Some(ErrorKind::Error)) { + fn check_expected_errors(&self, expected_errors: Vec, proc_res: &ProcRes) { + if proc_res.status.success() + && expected_errors + .iter() + .any(|x| x.kind == Some(ErrorKind::Error)) + { self.fatal_proc_rec("process did not return an error status", proc_res); } - let file_name = - format!("{}", self.testpaths.file.display()) - .replace(r"\", "/"); // on windows, translate all '\' path separators to '/' + let file_name = format!("{}", self.testpaths.file.display()).replace(r"\", "/"); // on windows, translate all '\' path separators to '/' // If the testcase being checked contains at least one expected "help" // message, then we'll ensure that all "help" messages are expected. // Otherwise, all "help" messages reported by the compiler will be ignored. // This logic also applies to "note" messages. - let expect_help = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Help)); - let expect_note = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Note)); + let expect_help = expected_errors + .iter() + .any(|ee| ee.kind == Some(ErrorKind::Help)); + let expect_note = expected_errors + .iter() + .any(|ee| ee.kind == Some(ErrorKind::Note)); // Parse the JSON output from the compiler and extract out the messages. let actual_errors = json::parse_output(&file_name, &proc_res.stderr, proc_res); let mut unexpected = Vec::new(); let mut found = vec![false; expected_errors.len()]; for actual_error in &actual_errors { - let opt_index = - expected_errors - .iter() - .enumerate() - .position(|(index, expected_error)| { - !found[index] && - actual_error.line_num == expected_error.line_num && - (expected_error.kind.is_none() || - actual_error.kind == expected_error.kind) && - actual_error.msg.contains(&expected_error.msg) - }); + let opt_index = expected_errors.iter().enumerate().position( + |(index, expected_error)| { + !found[index] && actual_error.line_num == expected_error.line_num + && (expected_error.kind.is_none() + || actual_error.kind == expected_error.kind) + && actual_error.msg.contains(&expected_error.msg) + }, + ); match opt_index { Some(index) => { @@ -1041,14 +1108,16 @@ actual:\n\ None => { if self.is_unexpected_compiler_message(actual_error, expect_help, expect_note) { - self.error( - &format!("{}:{}: unexpected {}: '{}'", - file_name, - actual_error.line_num, - actual_error.kind.as_ref() - .map_or(String::from("message"), - |k| k.to_string()), - actual_error.msg)); + self.error(&format!( + "{}:{}: unexpected {}: '{}'", + file_name, + actual_error.line_num, + actual_error + .kind + .as_ref() + .map_or(String::from("message"), |k| k.to_string()), + actual_error.msg + )); unexpected.push(actual_error); } } @@ -1059,24 +1128,27 @@ actual:\n\ // anything not yet found is a problem for (index, expected_error) in expected_errors.iter().enumerate() { if !found[index] { - self.error( - &format!("{}:{}: expected {} not found: {}", - file_name, - expected_error.line_num, - expected_error.kind.as_ref() - .map_or("message".into(), - |k| k.to_string()), - expected_error.msg)); + self.error(&format!( + "{}:{}: expected {} not found: {}", + file_name, + expected_error.line_num, + expected_error + .kind + .as_ref() + .map_or("message".into(), |k| k.to_string()), + expected_error.msg + )); not_found.push(expected_error); } } if !unexpected.is_empty() || !not_found.is_empty() { - self.error( - &format!("{} unexpected errors found, {} expected errors not found", - unexpected.len(), not_found.len())); - println!("status: {}\ncommand: {}", - proc_res.status, proc_res.cmdline); + self.error(&format!( + "{} unexpected errors found, {} expected errors not found", + unexpected.len(), + not_found.len() + )); + println!("status: {}\ncommand: {}", proc_res.status, proc_res.cmdline); if !unexpected.is_empty() { println!("unexpected errors (from JSON output): {:#?}\n", unexpected); } @@ -1091,24 +1163,25 @@ actual:\n\ /// which did not match any of the expected error. We always require /// errors/warnings to be explicitly listed, but only require /// helps/notes if there are explicit helps/notes given. - fn is_unexpected_compiler_message(&self, - actual_error: &Error, - expect_help: bool, - expect_note: bool) - -> bool { + fn is_unexpected_compiler_message( + &self, + actual_error: &Error, + expect_help: bool, + expect_note: bool, + ) -> bool { match actual_error.kind { Some(ErrorKind::Help) => expect_help, Some(ErrorKind::Note) => expect_note, - Some(ErrorKind::Error) | - Some(ErrorKind::Warning) => true, - Some(ErrorKind::Suggestion) | - None => false + Some(ErrorKind::Error) | Some(ErrorKind::Warning) => true, + Some(ErrorKind::Suggestion) | None => false, } } fn compile_test(&self) -> ProcRes { let mut rustc = self.make_compile_args( - &self.testpaths.file, TargetLocation::ThisFile(self.make_exe_name())); + &self.testpaths.file, + TargetLocation::ThisFile(self.make_exe_name()), + ); rustc.arg("-L").arg(&self.aux_output_dir_name()); @@ -1131,14 +1204,14 @@ actual:\n\ if self.props.build_aux_docs { for rel_ab in &self.props.aux_builds { let aux_testpaths = self.compute_aux_test_paths(rel_ab); - let aux_props = self.props.from_aux_file(&aux_testpaths.file, - self.revision, - self.config); + let aux_props = + self.props + .from_aux_file(&aux_testpaths.file, self.revision, self.config); let aux_cx = TestCx { config: self.config, props: &aux_props, testpaths: &aux_testpaths, - revision: self.revision + revision: self.revision, }; let auxres = aux_cx.document(out_dir); if !auxres.status.success() { @@ -1149,15 +1222,25 @@ actual:\n\ let aux_dir = self.aux_output_dir_name(); - let rustdoc_path = self.config.rustdoc_path.as_ref().expect("--rustdoc-path passed"); + let rustdoc_path = self.config + .rustdoc_path + .as_ref() + .expect("--rustdoc-path passed"); let mut rustdoc = Command::new(rustdoc_path); - rustdoc.arg("-L").arg(aux_dir) - .arg("-o").arg(out_dir) + rustdoc + .arg("-L") + .arg(aux_dir) + .arg("-o") + .arg(out_dir) .arg(&self.testpaths.file) .args(&self.props.compile_flags); if let Some(ref linker) = self.config.linker { - rustdoc.arg("--linker").arg(linker).arg("-Z").arg("unstable-options"); + rustdoc + .arg("--linker") + .arg(linker) + .arg("-Z") + .arg("unstable-options"); } self.compose_and_run_compiler(rustdoc, None) @@ -1187,34 +1270,39 @@ actual:\n\ for entry in entries { let entry = entry.unwrap(); if !entry.path().is_file() { - continue + continue; } prog.push_str(":"); prog.push_str(entry.path().to_str().unwrap()); } } - let mut test_client = Command::new( - self.config.remote_test_client.as_ref().unwrap()); + let mut test_client = + Command::new(self.config.remote_test_client.as_ref().unwrap()); test_client .args(&["run", &prog]) .args(args) .envs(env.clone()); - self.compose_and_run(test_client, - self.config.run_lib_path.to_str().unwrap(), - Some(aux_dir.to_str().unwrap()), - None) + self.compose_and_run( + test_client, + self.config.run_lib_path.to_str().unwrap(), + Some(aux_dir.to_str().unwrap()), + None, + ) } _ => { let aux_dir = self.aux_output_dir_name(); let ProcArgs { prog, args } = self.make_run_args(); let mut program = Command::new(&prog); - program.args(args) + program + .args(args) .current_dir(&self.output_base_name().parent().unwrap()) .envs(env.clone()); - self.compose_and_run(program, - self.config.run_lib_path.to_str().unwrap(), - Some(aux_dir.to_str().unwrap()), - None) + self.compose_and_run( + program, + self.config.run_lib_path.to_str().unwrap(), + Some(aux_dir.to_str().unwrap()), + None, + ) } } } @@ -1222,24 +1310,29 @@ actual:\n\ /// For each `aux-build: foo/bar` annotation, we check to find the /// file in a `aux` directory relative to the test itself. fn compute_aux_test_paths(&self, rel_ab: &str) -> TestPaths { - let test_ab = self.testpaths.file - .parent() - .expect("test file path has no parent") - .join("auxiliary") - .join(rel_ab); + let test_ab = self.testpaths + .file + .parent() + .expect("test file path has no parent") + .join("auxiliary") + .join(rel_ab); if !test_ab.exists() { - self.fatal(&format!("aux-build `{}` source not found", test_ab.display())) + self.fatal(&format!( + "aux-build `{}` source not found", + test_ab.display() + )) } TestPaths { file: test_ab, base: self.testpaths.base.clone(), - relative_dir: self.testpaths.relative_dir - .join("auxiliary") - .join(rel_ab) - .parent() - .expect("aux-build path has no parent") - .to_path_buf() + relative_dir: self.testpaths + .relative_dir + .join("auxiliary") + .join(rel_ab) + .parent() + .expect("aux-build path has no parent") + .to_path_buf(), } } @@ -1252,9 +1345,9 @@ actual:\n\ for rel_ab in &self.props.aux_builds { let aux_testpaths = self.compute_aux_test_paths(rel_ab); - let aux_props = self.props.from_aux_file(&aux_testpaths.file, - self.revision, - self.config); + let aux_props = + self.props + .from_aux_file(&aux_testpaths.file, self.revision, self.config); let aux_output = { let f = self.make_lib_name(&self.testpaths.file); let parent = f.parent().unwrap(); @@ -1264,15 +1357,16 @@ actual:\n\ config: self.config, props: &aux_props, testpaths: &aux_testpaths, - revision: self.revision + revision: self.revision, }; let mut aux_rustc = aux_cx.make_compile_args(&aux_testpaths.file, aux_output); let crate_type = if aux_props.no_prefer_dynamic { None - } else if (self.config.target.contains("musl") && !aux_props.force_host) || - self.config.target.contains("wasm32") || - self.config.target.contains("emscripten") { + } else if (self.config.target.contains("musl") && !aux_props.force_host) + || self.config.target.contains("wasm32") + || self.config.target.contains("emscripten") + { // We primarily compile all auxiliary libraries as dynamic libraries // to avoid code size bloat and large binaries as much as possible // for the test suite (otherwise including libstd statically in all @@ -1293,32 +1387,40 @@ actual:\n\ aux_rustc.arg("-L").arg(&aux_dir); - let auxres = aux_cx.compose_and_run(aux_rustc, - aux_cx.config.compile_lib_path.to_str().unwrap(), - Some(aux_dir.to_str().unwrap()), - None); + let auxres = aux_cx.compose_and_run( + aux_rustc, + aux_cx.config.compile_lib_path.to_str().unwrap(), + Some(aux_dir.to_str().unwrap()), + None, + ); if !auxres.status.success() { self.fatal_proc_rec( - &format!("auxiliary build of {:?} failed to compile: ", - aux_testpaths.file.display()), - &auxres); + &format!( + "auxiliary build of {:?} failed to compile: ", + aux_testpaths.file.display() + ), + &auxres, + ); } } rustc.envs(self.props.rustc_env.clone()); - self.compose_and_run(rustc, - self.config.compile_lib_path.to_str().unwrap(), - Some(aux_dir.to_str().unwrap()), - input) - } - - fn compose_and_run(&self, - mut command: Command, - lib_path: &str, - aux_path: Option<&str>, - input: Option) -> ProcRes { - let cmdline = - { + self.compose_and_run( + rustc, + self.config.compile_lib_path.to_str().unwrap(), + Some(aux_dir.to_str().unwrap()), + input, + ) + } + + fn compose_and_run( + &self, + mut command: Command, + lib_path: &str, + aux_path: Option<&str>, + input: Option, + ) -> ProcRes { + let cmdline = { let cmdline = self.make_cmdline(&command, lib_path); logv(self.config, format!("executing {}", cmdline)); cmdline @@ -1342,13 +1444,23 @@ actual:\n\ let newpath = env::join_paths(&path).unwrap(); command.env(dylib_env_var(), newpath); - let mut child = command.spawn().expect(&format!("failed to exec `{:?}`", &command)); + let mut child = command + .spawn() + .expect(&format!("failed to exec `{:?}`", &command)); if let Some(input) = input { - child.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap(); + child + .stdin + .as_mut() + .unwrap() + .write_all(input.as_bytes()) + .unwrap(); } - let Output { status, stdout, stderr } = read2_abbreviated(child) - .expect("failed to read output"); + let Output { + status, + stdout, + stderr, + } = read2_abbreviated(child).expect("failed to read output"); let result = ProcRes { status, @@ -1364,11 +1476,11 @@ actual:\n\ fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> Command { let mut rustc = Command::new(&self.config.rustc_path); - rustc.arg(input_file) - .arg("-L").arg(&self.config.build_base); + rustc.arg(input_file).arg("-L").arg(&self.config.build_base); // Optionally prevent default --target if specified in test compile-flags. - let custom_target = self.props.compile_flags + let custom_target = self.props + .compile_flags .iter() .any(|x| x.starts_with("--target")); @@ -1387,15 +1499,16 @@ actual:\n\ } if let Some(ref incremental_dir) = self.props.incremental_dir { - rustc.args(&["-Z", &format!("incremental={}", incremental_dir.display())]); + rustc.args(&[ + "-Z", + &format!("incremental={}", incremental_dir.display()), + ]); rustc.args(&["-Z", "incremental-verify-ich"]); rustc.args(&["-Z", "incremental-queries"]); } match self.config.mode { - CompileFail | - ParseFail | - Incremental => { + CompileFail | ParseFail | Incremental => { // If we are extracting and matching errors in the new // fashion, then you want JSON mode. Old-skool error // patterns still match the raw compiler output. @@ -1403,16 +1516,19 @@ actual:\n\ rustc.args(&["--error-format", "json"]); } } - Ui => { - if !self.props.compile_flags.iter().any(|s| s.starts_with("--error-format")) { - rustc.args(&["--error-format", "json"]); - } - } + Ui => if !self.props + .compile_flags + .iter() + .any(|s| s.starts_with("--error-format")) + { + rustc.args(&["--error-format", "json"]); + }, MirOpt => { rustc.args(&[ "-Zdump-mir=all", "-Zmir-opt-level=3", - "-Zdump-mir-exclude-pass-number"]); + "-Zdump-mir-exclude-pass-number", + ]); let mir_dump_dir = self.get_mir_dump_dir(); let _ = fs::remove_dir_all(&mir_dump_dir); @@ -1532,26 +1648,21 @@ actual:\n\ args.extend(self.split_maybe_args(&self.props.run_flags)); let prog = args.remove(0); - ProcArgs { - prog, - args, - } + ProcArgs { prog, args } } fn split_maybe_args(&self, argstr: &Option) -> Vec { match *argstr { - Some(ref s) => { - s - .split(' ') - .filter_map(|s| { - if s.chars().all(|c| c.is_whitespace()) { - None - } else { - Some(s.to_owned()) - } - }).collect() - } - None => Vec::new() + Some(ref s) => s.split(' ') + .filter_map(|s| { + if s.chars().all(|c| c.is_whitespace()) { + None + } else { + Some(s.to_owned()) + } + }) + .collect(), + None => Vec::new(), } } @@ -1565,7 +1676,11 @@ actual:\n\ // Build the LD_LIBRARY_PATH variable as it would be seen on the command line // for diagnostic purposes fn lib_path_cmd_prefix(path: &str) -> String { - format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path)) + format!( + "{}=\"{}\"", + util::lib_path_env_var(), + util::make_new_path(path) + ) } format!("{} {:?}", lib_path_cmd_prefix(libpath), command) @@ -1584,11 +1699,12 @@ actual:\n\ self.maybe_dump_to_stdout(out, err); } - fn dump_output_file(&self, - out: &str, - extension: &str) { + fn dump_output_file(&self, out: &str, extension: &str) { let outfile = self.make_out_name(extension); - File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap(); + File::create(&outfile) + .unwrap() + .write_all(out.as_bytes()) + .unwrap(); } fn make_out_name(&self, extension: &str) -> PathBuf { @@ -1613,8 +1729,7 @@ actual:\n\ let dir = self.config.build_base.join(&self.testpaths.relative_dir); // Note: The directory `dir` is created during `collect_tests_from_dir` - dir - .join(&self.output_testname(&self.testpaths.file)) + dir.join(&self.output_testname(&self.testpaths.file)) .with_extension(&self.config.stage_id) } @@ -1631,12 +1746,13 @@ actual:\n\ fn error(&self, err: &str) { match self.revision { Some(rev) => println!("\nerror in revision `{}`: {}", rev, err), - None => println!("\nerror: {}", err) + None => println!("\nerror: {}", err), } } fn fatal(&self, err: &str) -> ! { - self.error(err); panic!(); + self.error(err); + panic!(); } fn fatal_proc_rec(&self, err: &str, proc_res: &ProcRes) -> ! { @@ -1652,10 +1768,10 @@ actual:\n\ // errors here. fn try_print_open_handles(&self) { if !cfg!(windows) { - return + return; } if self.config.mode != Incremental { - return + return; } let filename = match self.testpaths.file.file_stem() { @@ -1689,11 +1805,10 @@ actual:\n\ fn compile_test_and_save_ir(&self) -> ProcRes { let aux_dir = self.aux_output_dir_name(); - let output_file = TargetLocation::ThisDirectory( - self.output_base_name().parent().unwrap().to_path_buf()); + let output_file = + TargetLocation::ThisDirectory(self.output_base_name().parent().unwrap().to_path_buf()); let mut rustc = self.make_compile_args(&self.testpaths.file, output_file); - rustc.arg("-L").arg(aux_dir) - .arg("--emit=llvm-ir"); + rustc.arg("-L").arg(aux_dir).arg("--emit=llvm-ir"); self.compose_and_run_compiler(rustc, None) } @@ -1701,7 +1816,9 @@ actual:\n\ fn check_ir_with_filecheck(&self) -> ProcRes { let irfile = self.output_base_name().with_extension("ll"); let mut filecheck = Command::new(self.config.llvm_filecheck.as_ref().unwrap()); - filecheck.arg("--input-file").arg(irfile) + filecheck + .arg("--input-file") + .arg(irfile) .arg(&self.testpaths.file); self.compose_and_run(filecheck, "", None, None) } @@ -1763,105 +1880,119 @@ actual:\n\ } } - fn get_lines>(&self, path: &P, - mut other_files: Option<&mut Vec>) -> Vec { - let mut file = fs::File::open(path) - .expect("markdown_test_output_check_entry File::open failed"); + fn get_lines>( + &self, + path: &P, + mut other_files: Option<&mut Vec>, + ) -> Vec { + let mut file = + fs::File::open(path).expect("markdown_test_output_check_entry File::open failed"); let mut content = String::new(); file.read_to_string(&mut content) .expect("markdown_test_output_check_entry read_to_string failed"); let mut ignore = false; - content.lines() - .enumerate() - .filter_map(|(line_nb, line)| { - if (line.trim_left().starts_with("pub mod ") || - line.trim_left().starts_with("mod ")) && - line.ends_with(';') { - if let Some(ref mut other_files) = other_files { - other_files.push(line.rsplit("mod ") - .next() - .unwrap() - .replace(";", "")); - } - None - } else { - let sline = line.split("///").last().unwrap_or(""); - let line = sline.trim_left(); - if line.starts_with("```") { - if ignore { - ignore = false; - None - } else { - ignore = true; - Some(line_nb + 1) - } - } else { - None - } - } - }) - .collect() + content + .lines() + .enumerate() + .filter_map(|(line_nb, line)| { + if (line.trim_left().starts_with("pub mod ") + || line.trim_left().starts_with("mod ")) + && line.ends_with(';') + { + if let Some(ref mut other_files) = other_files { + other_files.push(line.rsplit("mod ").next().unwrap().replace(";", "")); + } + None + } else { + let sline = line.split("///").last().unwrap_or(""); + let line = sline.trim_left(); + if line.starts_with("```") { + if ignore { + ignore = false; + None + } else { + ignore = true; + Some(line_nb + 1) + } + } else { + None + } + } + }) + .collect() } fn check_rustdoc_test_option(&self, res: ProcRes) { let mut other_files = Vec::new(); let mut files: HashMap> = HashMap::new(); let cwd = env::current_dir().unwrap(); - files.insert(self.testpaths.file.strip_prefix(&cwd) - .unwrap_or(&self.testpaths.file) - .to_str() - .unwrap() - .replace('\\', "/"), - self.get_lines(&self.testpaths.file, Some(&mut other_files))); + files.insert( + self.testpaths + .file + .strip_prefix(&cwd) + .unwrap_or(&self.testpaths.file) + .to_str() + .unwrap() + .replace('\\', "/"), + self.get_lines(&self.testpaths.file, Some(&mut other_files)), + ); for other_file in other_files { let mut path = self.testpaths.file.clone(); path.set_file_name(&format!("{}.rs", other_file)); - files.insert(path.strip_prefix(&cwd) - .unwrap_or(&path) - .to_str() - .unwrap() - .replace('\\', "/"), - self.get_lines(&path, None)); + files.insert( + path.strip_prefix(&cwd) + .unwrap_or(&path) + .to_str() + .unwrap() + .replace('\\', "/"), + self.get_lines(&path, None), + ); } let mut tested = 0; - for _ in res.stdout.split('\n') - .filter(|s| s.starts_with("test ")) - .inspect(|s| { - let tmp: Vec<&str> = s.split(" - ").collect(); - if tmp.len() == 2 { - let path = tmp[0].rsplit("test ").next().unwrap(); - if let Some(ref mut v) = files.get_mut( - &path.replace('\\', "/")) { - tested += 1; - let mut iter = tmp[1].split("(line "); - iter.next(); - let line = iter.next() - .unwrap_or(")") - .split(')') - .next() - .unwrap_or("0") - .parse() - .unwrap_or(0); - if let Ok(pos) = v.binary_search(&line) { - v.remove(pos); - } else { - self.fatal_proc_rec( - &format!("Not found doc test: \"{}\" in \"{}\":{:?}", - s, path, v), - &res); - } - } - } - }) {} + for _ in res.stdout + .split('\n') + .filter(|s| s.starts_with("test ")) + .inspect(|s| { + let tmp: Vec<&str> = s.split(" - ").collect(); + if tmp.len() == 2 { + let path = tmp[0].rsplit("test ").next().unwrap(); + if let Some(ref mut v) = files.get_mut(&path.replace('\\', "/")) { + tested += 1; + let mut iter = tmp[1].split("(line "); + iter.next(); + let line = iter.next() + .unwrap_or(")") + .split(')') + .next() + .unwrap_or("0") + .parse() + .unwrap_or(0); + if let Ok(pos) = v.binary_search(&line) { + v.remove(pos); + } else { + self.fatal_proc_rec( + &format!("Not found doc test: \"{}\" in \"{}\":{:?}", s, path, v), + &res, + ); + } + } + } + }) {} if tested == 0 { self.fatal_proc_rec(&format!("No test has been found... {:?}", files), &res); } else { for (entry, v) in &files { if !v.is_empty() { - self.fatal_proc_rec(&format!("Not found test at line{} \"{}\":{:?}", - if v.len() > 1 { "s" } else { "" }, entry, v), - &res); + self.fatal_proc_rec( + &format!( + "Not found test at line{} \"{}\":{:?}", + if v.len() > 1 { "s" } else { "" }, + entry, + v + ), + &res, + ); } } } @@ -1897,13 +2028,13 @@ actual:\n\ let mut wrong_cgus = Vec::new(); for expected_item in &expected { - let actual_item_with_same_name = actual.iter() - .find(|ti| ti.name == expected_item.name); + let actual_item_with_same_name = actual.iter().find(|ti| ti.name == expected_item.name); if let Some(actual_item) = actual_item_with_same_name { if !expected_item.codegen_units.is_empty() && // Also check for codegen units - expected_item.codegen_units != actual_item.codegen_units { + expected_item.codegen_units != actual_item.codegen_units + { wrong_cgus.push((expected_item.clone(), actual_item.clone())); } } else { @@ -1911,11 +2042,11 @@ actual:\n\ } } - let unexpected: Vec<_> = - actual.iter() - .filter(|acgu| !expected.iter().any(|ecgu| acgu.name == ecgu.name)) - .map(|acgu| acgu.string.clone()) - .collect(); + let unexpected: Vec<_> = actual + .iter() + .filter(|acgu| !expected.iter().any(|ecgu| acgu.name == ecgu.name)) + .map(|acgu| acgu.string.clone()) + .collect(); if !missing.is_empty() { missing.sort(); @@ -1951,14 +2082,19 @@ actual:\n\ for &(ref expected_item, ref actual_item) in &wrong_cgus { println!("{}", expected_item.name); - println!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units)); - println!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units)); + println!( + " expected: {}", + codegen_units_to_str(&expected_item.codegen_units) + ); + println!( + " actual: {}", + codegen_units_to_str(&actual_item.codegen_units) + ); println!(""); } } - if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty()) - { + if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty()) { panic!(); } @@ -1980,22 +2116,22 @@ actual:\n\ let full_string = format!("{}{}", PREFIX, s.trim().to_owned()); let parts: Vec<&str> = s.split(CGU_MARKER) - .map(str::trim) - .filter(|s| !s.is_empty()) - .collect(); + .map(str::trim) + .filter(|s| !s.is_empty()) + .collect(); let name = parts[0].trim(); let cgus = if parts.len() > 1 { let cgus_str = parts[1]; - cgus_str.split(' ') - .map(str::trim) - .filter(|s| !s.is_empty()) - .map(str::to_owned) - .collect() - } - else { + cgus_str + .split(' ') + .map(str::trim) + .filter(|s| !s.is_empty()) + .map(str::to_owned) + .collect() + } else { HashSet::new() }; @@ -2006,8 +2142,7 @@ actual:\n\ } } - fn codegen_units_to_str(cgus: &HashSet) -> String - { + fn codegen_units_to_str(cgus: &HashSet) -> String { let mut cgus: Vec<_> = cgus.iter().collect(); cgus.sort(); @@ -2038,7 +2173,10 @@ actual:\n\ fs::create_dir_all(&incremental_dir).unwrap(); if self.config.verbose { - print!("init_incremental_test: incremental_dir={}", incremental_dir.display()); + print!( + "init_incremental_test: incremental_dir={}", + incremental_dir.display() + ); } } @@ -2062,11 +2200,15 @@ actual:\n\ // FIXME -- use non-incremental mode as an oracle? That doesn't apply // to #[rustc_dirty] and clean tests I guess - let revision = self.revision.expect("incremental tests require a list of revisions"); + let revision = self.revision + .expect("incremental tests require a list of revisions"); // Incremental workproduct directory should have already been created. let incremental_dir = self.incremental_dir(); - assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir"); + assert!( + incremental_dir.exists(), + "init_incremental_test failed to create incremental dir" + ); // Add an extra flag pointing at the incremental directory. let mut revision_props = self.props.clone(); @@ -2080,7 +2222,11 @@ actual:\n\ }; if self.config.verbose { - print!("revision={:?} revision_props={:#?}", revision, revision_props); + print!( + "revision={:?} revision_props={:#?}", + revision, + revision_props + ); } if revision.starts_with("rpass") { @@ -2090,8 +2236,7 @@ actual:\n\ } else if revision.starts_with("cfail") { revision_cx.run_cfail_test(); } else { - revision_cx.fatal( - "revision name must begin with rpass, rfail, or cfail"); + revision_cx.fatal("revision name must begin with rpass, rfail, or cfail"); } } @@ -2103,13 +2248,18 @@ actual:\n\ fn run_rmake_test(&self) { // FIXME(#11094): we should fix these tests if self.config.host != self.config.target { - return + return; } let cwd = env::current_dir().unwrap(); - let src_root = self.config.src_base.parent().unwrap() - .parent().unwrap() - .parent().unwrap(); + let src_root = self.config + .src_base + .parent() + .unwrap() + .parent() + .unwrap() + .parent() + .unwrap(); let src_root = cwd.join(&src_root); let tmpdir = cwd.join(self.output_base_name()); @@ -2119,9 +2269,10 @@ actual:\n\ create_dir_all(&tmpdir).unwrap(); let host = &self.config.host; - let make = if host.contains("bitrig") || host.contains("dragonfly") || - host.contains("freebsd") || host.contains("netbsd") || - host.contains("openbsd") { + let make = if host.contains("bitrig") || host.contains("dragonfly") + || host.contains("freebsd") || host.contains("netbsd") + || host.contains("openbsd") + { "gmake" } else { "make" @@ -2129,21 +2280,26 @@ actual:\n\ let mut cmd = Command::new(make); cmd.current_dir(&self.testpaths.file) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .env("TARGET", &self.config.target) - .env("PYTHON", &self.config.docck_python) - .env("S", src_root) - .env("RUST_BUILD_STAGE", &self.config.stage_id) - .env("RUSTC", cwd.join(&self.config.rustc_path)) - .env("RUSTDOC", - cwd.join(&self.config.rustdoc_path.as_ref().expect("--rustdoc-path passed"))) - .env("TMPDIR", &tmpdir) - .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) - .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) - .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path)) - .env("LLVM_COMPONENTS", &self.config.llvm_components) - .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags); + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .env("TARGET", &self.config.target) + .env("PYTHON", &self.config.docck_python) + .env("S", src_root) + .env("RUST_BUILD_STAGE", &self.config.stage_id) + .env("RUSTC", cwd.join(&self.config.rustc_path)) + .env( + "RUSTDOC", + cwd.join(&self.config + .rustdoc_path + .as_ref() + .expect("--rustdoc-path passed")), + ) + .env("TMPDIR", &tmpdir) + .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) + .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) + .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path)) + .env("LLVM_COMPONENTS", &self.config.llvm_components) + .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags); if let Some(ref linker) = self.config.linker { cmd.env("RUSTC_LINKER", linker); @@ -2161,25 +2317,31 @@ actual:\n\ // MSYS doesn't like passing flags of the form `/foo` as it thinks it's // a path and instead passes `C:\msys64\foo`, so convert all // `/`-arguments to MSVC here to `-` arguments. - let cflags = self.config.cflags.split(' ').map(|s| s.replace("/", "-")) - .collect::>().join(" "); + let cflags = self.config + .cflags + .split(' ') + .map(|s| s.replace("/", "-")) + .collect::>() + .join(" "); cmd.env("IS_MSVC", "1") - .env("IS_WINDOWS", "1") - .env("MSVC_LIB", format!("'{}' -nologo", lib.display())) - .env("CC", format!("'{}' {}", self.config.cc, cflags)) - .env("CXX", &self.config.cxx); + .env("IS_WINDOWS", "1") + .env("MSVC_LIB", format!("'{}' -nologo", lib.display())) + .env("CC", format!("'{}' {}", self.config.cc, cflags)) + .env("CXX", &self.config.cxx); } else { cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags)) - .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags)) - .env("AR", &self.config.ar); + .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags)) + .env("AR", &self.config.ar); if self.config.target.contains("windows") { cmd.env("IS_WINDOWS", "1"); } } - let output = cmd.spawn().and_then(read2_abbreviated).expect("failed to spawn `make`"); + let output = cmd.spawn() + .and_then(read2_abbreviated) + .expect("failed to spawn `make`"); if !output.status.success() { let res = ProcRes { status: output.status, @@ -2218,7 +2380,10 @@ actual:\n\ // if the user specified a format in the ui test // print the output to the stderr file, otherwise extract // the rendered error messages from json and print them - let explicit = self.props.compile_flags.iter().any(|s| s.contains("--error-format")); + let explicit = self.props + .compile_flags + .iter() + .any(|s| s.contains("--error-format")); let proc_res = self.compile_test(); @@ -2237,8 +2402,7 @@ actual:\n\ json::extract_rendered(&proc_res.stderr, &proc_res) }; - let normalized_stderr = - self.normalize_output(&stderr, &self.props.normalize_stderr); + let normalized_stderr = self.normalize_output(&stderr, &self.props.normalize_stderr); let mut errors = 0; errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout); @@ -2246,15 +2410,19 @@ actual:\n\ if errors > 0 { println!("To update references, run this command from build directory:"); - let relative_path_to_file = - self.testpaths.relative_dir - .join(self.testpaths.file.file_name().unwrap()); - println!("{}/update-references.sh '{}' '{}'", - self.config.src_base.display(), - self.config.build_base.display(), - relative_path_to_file.display()); - self.fatal_proc_rec(&format!("{} errors occurred comparing output.", errors), - &proc_res); + let relative_path_to_file = self.testpaths + .relative_dir + .join(self.testpaths.file.file_name().unwrap()); + println!( + "{}/update-references.sh '{}' '{}'", + self.config.src_base.display(), + self.config.build_base.display(), + relative_path_to_file.display() + ); + self.fatal_proc_rec( + &format!("{} errors occurred comparing output.", errors), + &proc_res, + ); } let expected_errors = errors::load_errors(&self.testpaths.file, self.revision); @@ -2294,13 +2462,14 @@ actual:\n\ fn check_mir_dump(&self) { let mut test_file_contents = String::new(); - fs::File::open(self.testpaths.file.clone()).unwrap() - .read_to_string(&mut test_file_contents) - .unwrap(); - if let Some(idx) = test_file_contents.find("// END RUST SOURCE") { + fs::File::open(self.testpaths.file.clone()) + .unwrap() + .read_to_string(&mut test_file_contents) + .unwrap(); + if let Some(idx) = test_file_contents.find("// END RUST SOURCE") { let (_, tests_text) = test_file_contents.split_at(idx + "// END_RUST SOURCE".len()); let tests_text_str = String::from(tests_text); - let mut curr_test : Option<&str> = None; + let mut curr_test: Option<&str> = None; let mut curr_test_contents = vec![ExpectedLine::Elision]; for l in tests_text_str.lines() { debug!("line: {:?}", l); @@ -2334,9 +2503,16 @@ actual:\n\ let output_time = t(output_file); let source_time = t(source_file); if source_time > output_time { - debug!("source file time: {:?} output file time: {:?}", source_time, output_time); - panic!("test source file `{}` is newer than potentially stale output file `{}`.", - source_file.display(), test_name); + debug!( + "source file time: {:?} output file time: {:?}", + source_time, + output_time + ); + panic!( + "test source file `{}` is newer than potentially stale output file `{}`.", + source_file.display(), + test_name + ); } } @@ -2347,8 +2523,10 @@ actual:\n\ debug!("comparing the contests of: {:?}", output_file); debug!("with: {:?}", expected_content); if !output_file.exists() { - panic!("Output file `{}` from test does not exist", - output_file.into_os_string().to_string_lossy()); + panic!( + "Output file `{}` from test does not exist", + output_file.into_os_string().to_string_lossy() + ); } self.check_mir_test_timestamp(test_name, &output_file); @@ -2356,13 +2534,16 @@ actual:\n\ let mut dumped_string = String::new(); dumped_file.read_to_string(&mut dumped_string).unwrap(); let mut dumped_lines = dumped_string.lines().filter(|l| !l.is_empty()); - let mut expected_lines = expected_content.iter().filter(|&l| { - if let &ExpectedLine::Text(l) = l { - !l.is_empty() - } else { - true - } - }).peekable(); + let mut expected_lines = expected_content + .iter() + .filter(|&l| { + if let &ExpectedLine::Text(l) = l { + !l.is_empty() + } else { + true + } + }) + .peekable(); let compare = |expected_line, dumped_line| { let e_norm = normalize_mir_line(expected_line); @@ -2373,27 +2554,31 @@ actual:\n\ }; let error = |expected_line, extra_msg| { - let normalize_all = dumped_string.lines() - .map(nocomment_mir_line) - .filter(|l| !l.is_empty()) - .collect::>() - .join("\n"); + let normalize_all = dumped_string + .lines() + .map(nocomment_mir_line) + .filter(|l| !l.is_empty()) + .collect::>() + .join("\n"); let f = |l: &ExpectedLine<_>| match l { &ExpectedLine::Elision => "... (elided)".into(), - &ExpectedLine::Text(t) => t + &ExpectedLine::Text(t) => t, }; - let expected_content = expected_content.iter() - .map(|l| f(l)) - .collect::>() - .join("\n"); - panic!("Did not find expected line, error: {}\n\ - Actual Line: {:?}\n\ - Expected:\n{}\n\ - Actual:\n{}", - extra_msg, - expected_line, - expected_content, - normalize_all); + let expected_content = expected_content + .iter() + .map(|l| f(l)) + .collect::>() + .join("\n"); + panic!( + "Did not find expected line, error: {}\n\ + Actual Line: {:?}\n\ + Expected:\n{}\n\ + Actual:\n{}", + extra_msg, + expected_line, + expected_content, + normalize_all + ); }; // We expect each non-empty line to appear consecutively, non-consecutive lines @@ -2409,11 +2594,16 @@ actual:\n\ if !compare(expected_line, dumped_line) { error!("{:?}", start_block_line); - error(expected_line, - format!("Mismatch in lines\nCurrnt block: {}\nExpected Line: {:?}", - start_block_line.unwrap_or("None"), dumped_line)); + error( + expected_line, + format!( + "Mismatch in lines\nCurrnt block: {}\nExpected Line: {:?}", + start_block_line.unwrap_or("None"), + dumped_line + ), + ); } - }, + } Some(&ExpectedLine::Elision) => { // skip any number of elisions in a row. while let Some(&&ExpectedLine::Elision) = expected_lines.peek() { @@ -2434,8 +2624,8 @@ actual:\n\ error(expected_line, "ran out of mir dump to match against".into()); } } - }, - None => {}, + } + None => {} } } } @@ -2451,10 +2641,10 @@ actual:\n\ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> String { let parent_dir = self.testpaths.file.parent().unwrap(); let cflags = self.props.compile_flags.join(" "); - let json = cflags.contains("--error-format json") || - cflags.contains("--error-format pretty-json") || - cflags.contains("--error-format=json") || - cflags.contains("--error-format=pretty-json"); + let json = cflags.contains("--error-format json") + || cflags.contains("--error-format pretty-json") + || cflags.contains("--error-format=json") + || cflags.contains("--error-format=pretty-json"); let parent_dir_str = if json { parent_dir.display().to_string().replace("\\", "\\\\") } else { @@ -2497,10 +2687,11 @@ actual:\n\ 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!("failed to load expected output from `{}`: {}", - path.display(), e)) - } + Err(e) => self.fatal(&format!( + "failed to load expected output from `{}`: {}", + path.display(), + e + )), } } @@ -2515,19 +2706,21 @@ actual:\n\ for diff in diff::lines(expected, actual) { match diff { - diff::Result::Left(l) => println!("-{}", l), + diff::Result::Left(l) => println!("-{}", l), diff::Result::Both(l, _) => println!(" {}", l), - diff::Result::Right(r) => println!("+{}", r), + diff::Result::Right(r) => println!("+{}", r), } } let output_file = self.output_base_name().with_extension(kind); match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) { - Ok(()) => { } - Err(e) => { - self.fatal(&format!("failed to write {} to `{}`: {}", - kind, output_file.display(), e)) - } + Ok(()) => {} + Err(e) => self.fatal(&format!( + "failed to write {} to `{}`: {}", + kind, + output_file.display(), + e + )), } println!("\nThe actual {0} differed from the expected {0}.", kind); @@ -2553,20 +2746,24 @@ impl ProcRes { if let Some(e) = err { println!("\nerror: {}", e); } - print!("\ - status: {}\n\ - command: {}\n\ - stdout:\n\ - ------------------------------------------\n\ - {}\n\ - ------------------------------------------\n\ - stderr:\n\ - ------------------------------------------\n\ - {}\n\ - ------------------------------------------\n\ - \n", - self.status, self.cmdline, self.stdout, - self.stderr); + print!( + "\ + status: {}\n\ + command: {}\n\ + stdout:\n\ + ------------------------------------------\n\ + {}\n\ + ------------------------------------------\n\ + stderr:\n\ + ------------------------------------------\n\ + {}\n\ + ------------------------------------------\n\ + \n", + self.status, + self.cmdline, + self.stdout, + self.stderr + ); panic!(); } } @@ -2579,12 +2776,12 @@ enum TargetLocation { #[derive(Clone, PartialEq, Eq)] enum ExpectedLine> { Elision, - Text(T) + Text(T), } impl fmt::Debug for ExpectedLine where - T: AsRef + fmt::Debug + T: AsRef + fmt::Debug, { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { if let &ExpectedLine::Text(ref t) = self { @@ -2621,7 +2818,7 @@ fn read2_abbreviated(mut child: Child) -> io::Result { head: Vec, skipped: usize, tail: Box<[u8]>, - } + }, } impl ProcOutput { @@ -2636,9 +2833,17 @@ fn read2_abbreviated(mut child: Child) -> io::Result { let tail = bytes.split_off(new_len - TAIL_LEN).into_boxed_slice(); let head = replace(bytes, Vec::new()); let skipped = new_len - HEAD_LEN - TAIL_LEN; - ProcOutput::Abbreviated { head, skipped, tail } + ProcOutput::Abbreviated { + head, + skipped, + tail, + } } - ProcOutput::Abbreviated { ref mut skipped, ref mut tail, .. } => { + ProcOutput::Abbreviated { + ref mut skipped, + ref mut tail, + .. + } => { *skipped += data.len(); if data.len() <= TAIL_LEN { tail[..data.len()].copy_from_slice(data); @@ -2655,7 +2860,11 @@ fn read2_abbreviated(mut child: Child) -> io::Result { fn into_bytes(self) -> Vec { match self { ProcOutput::Full(bytes) => bytes, - ProcOutput::Abbreviated { mut head, skipped, tail } => { + ProcOutput::Abbreviated { + mut head, + skipped, + tail, + } => { write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap(); head.extend_from_slice(&tail); head @@ -2668,10 +2877,14 @@ fn read2_abbreviated(mut child: Child) -> io::Result { let mut stderr = ProcOutput::Full(Vec::new()); drop(child.stdin.take()); - read2(child.stdout.take().unwrap(), child.stderr.take().unwrap(), &mut |is_stdout, data, _| { - if is_stdout { &mut stdout } else { &mut stderr }.extend(data); - data.clear(); - })?; + read2( + child.stdout.take().unwrap(), + child.stderr.take().unwrap(), + &mut |is_stdout, data, _| { + if is_stdout { &mut stdout } else { &mut stderr }.extend(data); + data.clear(); + }, + )?; let status = child.wait()?; Ok(Output { From 86812902402758bb2ffa2ff594fcfd3546bab6aa Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 6 Dec 2017 06:21:23 -0500 Subject: [PATCH 2/3] compiletest: account for `ui` reference files when deciding to skip --- src/tools/compiletest/src/common.rs | 16 +++++++++++++++- src/tools/compiletest/src/header.rs | 6 ++++++ src/tools/compiletest/src/main.rs | 15 +++++++++++++++ src/tools/compiletest/src/runtest.rs | 11 ++++------- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 660462ad419f7..48c3c5c819862 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -13,7 +13,7 @@ use std::fmt; use std::str::FromStr; use std::path::PathBuf; -use test::ColorConfig; +use test::{ColorConfig, TestPaths}; #[derive(Clone, Copy, PartialEq, Debug)] pub enum Mode { @@ -221,3 +221,17 @@ pub struct Config { pub llvm_cxxflags: String, pub nodejs: Option, } + +/// 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 { + assert!(UI_EXTENSIONS.contains(&kind)); + let extension = match revision { + Some(r) => format!("{}.{}", r, kind), + None => kind.to_string(), + }; + testpaths.file.with_extension(extension) +} + +pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT]; +pub const UI_STDERR: &str = "stderr"; +pub const UI_STDOUT: &str = "stdout"; diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index c853d53829c60..e7851c3632761 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -26,6 +26,7 @@ pub struct EarlyProps { pub ignore: bool, pub should_fail: bool, pub aux: Vec, + pub revisions: Vec, } impl EarlyProps { @@ -34,6 +35,7 @@ impl EarlyProps { ignore: false, should_fail: false, aux: Vec::new(), + revisions: vec![], }; iter_header(testfile, @@ -50,6 +52,10 @@ impl EarlyProps { props.aux.push(s); } + if let Some(r) = config.parse_revisions(ln) { + props.revisions.extend(r); + } + props.should_fail = props.should_fail || config.parse_name_directive(ln, "should-fail"); }); diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index d8ccb285cc513..fac3b71f82cc4 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -34,6 +34,7 @@ use filetime::FileTime; use getopts::Options; use common::Config; use common::{DebugInfoGdb, DebugInfoLldb, Mode, Pretty}; +use common::{expected_output_path, UI_EXTENSIONS}; use test::{ColorConfig, TestPaths}; use util::logv; @@ -673,6 +674,20 @@ fn up_to_date(config: &Config, testpaths: &TestPaths, props: &EarlyProps) -> boo inputs.push(mtime(&rustdoc_path)); inputs.push(mtime(&rust_src_dir.join("src/etc/htmldocck.py"))); } + + // UI test files. + for extension in UI_EXTENSIONS { + for revision in &props.revisions { + let path = &expected_output_path(testpaths, Some(revision), extension); + inputs.push(mtime(path)); + } + + if props.revisions.is_empty() { + let path = &expected_output_path(testpaths, None, extension); + inputs.push(mtime(path)); + } + } + inputs.iter().any(|input| *input > stamp) } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index d89dc855cb03c..4b430f0cd70d5 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -12,6 +12,7 @@ use common::Config; 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 diff; use errors::{self, Error, ErrorKind}; use filetime::FileTime; @@ -2387,10 +2388,10 @@ impl<'test> TestCx<'test> { let proc_res = self.compile_test(); - let expected_stderr_path = self.expected_output_path("stderr"); + 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("stdout"); + let expected_stdout_path = self.expected_output_path(UI_STDOUT); let expected_stdout = self.load_expected_output(&expected_stdout_path); let normalized_stdout = @@ -2672,11 +2673,7 @@ impl<'test> TestCx<'test> { } fn expected_output_path(&self, kind: &str) -> PathBuf { - let extension = match self.revision { - Some(r) => format!("{}.{}", r, kind), - None => kind.to_string(), - }; - self.testpaths.file.with_extension(extension) + expected_output_path(&self.testpaths, self.revision, kind) } fn load_expected_output(&self, path: &Path) -> String { From 7b456c053cb66c86919d1475b9ab418c4665a6af Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 6 Dec 2017 09:42:09 -0500 Subject: [PATCH 3/3] pacify the mercilous tidy --- src/tools/compiletest/src/runtest.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 4b430f0cd70d5..91d51d359ecec 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1073,7 +1073,8 @@ impl<'test> TestCx<'test> { self.fatal_proc_rec("process did not return an error status", proc_res); } - let file_name = format!("{}", self.testpaths.file.display()).replace(r"\", "/"); // on windows, translate all '\' path separators to '/' + // on windows, translate all '\' path separators to '/' + let file_name = format!("{}", self.testpaths.file.display()).replace(r"\", "/"); // If the testcase being checked contains at least one expected "help" // message, then we'll ensure that all "help" messages are expected.