Rollup merge of #50806 - oli-obk:gesundheit, r=ehuss
Add `bless` x.py subcommand for easy ui test replacement fixes #49815 r? @nikomatsakis
This commit is contained in:
@@ -297,7 +297,12 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if verbose > 1 {
|
if verbose > 1 {
|
||||||
eprintln!("rustc command: {:?}", cmd);
|
eprintln!(
|
||||||
|
"rustc command: {:?}={:?} {:?}",
|
||||||
|
bootstrap::util::dylib_path_var(),
|
||||||
|
env::join_paths(&dylib_path).unwrap(),
|
||||||
|
cmd,
|
||||||
|
);
|
||||||
eprintln!("sysroot: {:?}", sysroot);
|
eprintln!("sysroot: {:?}", sysroot);
|
||||||
eprintln!("libdir: {:?}", libdir);
|
eprintln!("libdir: {:?}", libdir);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1460,6 +1460,7 @@ mod __test {
|
|||||||
rustc_args: vec![],
|
rustc_args: vec![],
|
||||||
fail_fast: true,
|
fail_fast: true,
|
||||||
doc_tests: DocTests::No,
|
doc_tests: DocTests::No,
|
||||||
|
bless: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let build = Build::new(config);
|
let build = Build::new(config);
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ pub enum Subcommand {
|
|||||||
},
|
},
|
||||||
Test {
|
Test {
|
||||||
paths: Vec<PathBuf>,
|
paths: Vec<PathBuf>,
|
||||||
|
/// Whether to automatically update stderr/stdout files
|
||||||
|
bless: bool,
|
||||||
test_args: Vec<String>,
|
test_args: Vec<String>,
|
||||||
rustc_args: Vec<String>,
|
rustc_args: Vec<String>,
|
||||||
fail_fast: bool,
|
fail_fast: bool,
|
||||||
@@ -173,6 +175,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
|
|||||||
);
|
);
|
||||||
opts.optflag("", "no-doc", "do not run doc tests");
|
opts.optflag("", "no-doc", "do not run doc tests");
|
||||||
opts.optflag("", "doc", "only run doc tests");
|
opts.optflag("", "doc", "only run doc tests");
|
||||||
|
opts.optflag("", "bless", "update all stderr/stdout files of failing ui tests");
|
||||||
},
|
},
|
||||||
"bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
|
"bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
|
||||||
"clean" => { opts.optflag("", "all", "clean all build artifacts"); },
|
"clean" => { opts.optflag("", "all", "clean all build artifacts"); },
|
||||||
@@ -258,6 +261,7 @@ Arguments:
|
|||||||
./x.py test src/test/run-pass
|
./x.py test src/test/run-pass
|
||||||
./x.py test src/libstd --test-args hash_map
|
./x.py test src/libstd --test-args hash_map
|
||||||
./x.py test src/libstd --stage 0
|
./x.py test src/libstd --stage 0
|
||||||
|
./x.py test src/test/ui --bless
|
||||||
|
|
||||||
If no arguments are passed then the complete artifacts for that stage are
|
If no arguments are passed then the complete artifacts for that stage are
|
||||||
compiled and tested.
|
compiled and tested.
|
||||||
@@ -322,6 +326,7 @@ Arguments:
|
|||||||
"test" => {
|
"test" => {
|
||||||
Subcommand::Test {
|
Subcommand::Test {
|
||||||
paths,
|
paths,
|
||||||
|
bless: matches.opt_present("bless"),
|
||||||
test_args: matches.opt_strs("test-args"),
|
test_args: matches.opt_strs("test-args"),
|
||||||
rustc_args: matches.opt_strs("rustc-args"),
|
rustc_args: matches.opt_strs("rustc-args"),
|
||||||
fail_fast: !matches.opt_present("no-fail-fast"),
|
fail_fast: !matches.opt_present("no-fail-fast"),
|
||||||
@@ -424,6 +429,13 @@ impl Subcommand {
|
|||||||
_ => DocTests::Yes,
|
_ => DocTests::Yes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bless(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Subcommand::Test { bless, .. } => bless,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split(s: Vec<String>) -> Vec<String> {
|
fn split(s: Vec<String>) -> Vec<String> {
|
||||||
|
|||||||
@@ -47,6 +47,16 @@ pub enum TestKind {
|
|||||||
Bench,
|
Bench,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Kind> for TestKind {
|
||||||
|
fn from(kind: Kind) -> Self {
|
||||||
|
match kind {
|
||||||
|
Kind::Test => TestKind::Test,
|
||||||
|
Kind::Bench => TestKind::Bench,
|
||||||
|
_ => panic!("unexpected kind in crate: {:?}", kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TestKind {
|
impl TestKind {
|
||||||
// Return the cargo subcommand for this test kind
|
// Return the cargo subcommand for this test kind
|
||||||
fn subcommand(self) -> &'static str {
|
fn subcommand(self) -> &'static str {
|
||||||
@@ -951,6 +961,10 @@ impl Step for Compiletest {
|
|||||||
cmd.arg("--host").arg(&*compiler.host);
|
cmd.arg("--host").arg(&*compiler.host);
|
||||||
cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.build));
|
cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.build));
|
||||||
|
|
||||||
|
if builder.config.cmd.bless() {
|
||||||
|
cmd.arg("--bless");
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(ref nodejs) = builder.config.nodejs {
|
if let Some(ref nodejs) = builder.config.nodejs {
|
||||||
cmd.arg("--nodejs").arg(nodejs);
|
cmd.arg("--nodejs").arg(nodejs);
|
||||||
}
|
}
|
||||||
@@ -1342,13 +1356,7 @@ impl Step for CrateLibrustc {
|
|||||||
|
|
||||||
for krate in builder.in_tree_crates("rustc-main") {
|
for krate in builder.in_tree_crates("rustc-main") {
|
||||||
if run.path.ends_with(&krate.path) {
|
if run.path.ends_with(&krate.path) {
|
||||||
let test_kind = if builder.kind == Kind::Test {
|
let test_kind = builder.kind.into();
|
||||||
TestKind::Test
|
|
||||||
} else if builder.kind == Kind::Bench {
|
|
||||||
TestKind::Bench
|
|
||||||
} else {
|
|
||||||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.ensure(CrateLibrustc {
|
builder.ensure(CrateLibrustc {
|
||||||
compiler,
|
compiler,
|
||||||
@@ -1394,13 +1402,7 @@ impl Step for CrateNotDefault {
|
|||||||
let builder = run.builder;
|
let builder = run.builder;
|
||||||
let compiler = builder.compiler(builder.top_stage, run.host);
|
let compiler = builder.compiler(builder.top_stage, run.host);
|
||||||
|
|
||||||
let test_kind = if builder.kind == Kind::Test {
|
let test_kind = builder.kind.into();
|
||||||
TestKind::Test
|
|
||||||
} else if builder.kind == Kind::Bench {
|
|
||||||
TestKind::Bench
|
|
||||||
} else {
|
|
||||||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.ensure(CrateNotDefault {
|
builder.ensure(CrateNotDefault {
|
||||||
compiler,
|
compiler,
|
||||||
@@ -1461,13 +1463,7 @@ impl Step for Crate {
|
|||||||
let compiler = builder.compiler(builder.top_stage, run.host);
|
let compiler = builder.compiler(builder.top_stage, run.host);
|
||||||
|
|
||||||
let make = |mode: Mode, krate: &CargoCrate| {
|
let make = |mode: Mode, krate: &CargoCrate| {
|
||||||
let test_kind = if builder.kind == Kind::Test {
|
let test_kind = builder.kind.into();
|
||||||
TestKind::Test
|
|
||||||
} else if builder.kind == Kind::Bench {
|
|
||||||
TestKind::Bench
|
|
||||||
} else {
|
|
||||||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.ensure(Crate {
|
builder.ensure(Crate {
|
||||||
compiler,
|
compiler,
|
||||||
@@ -1625,13 +1621,7 @@ impl Step for CrateRustdoc {
|
|||||||
fn make_run(run: RunConfig) {
|
fn make_run(run: RunConfig) {
|
||||||
let builder = run.builder;
|
let builder = run.builder;
|
||||||
|
|
||||||
let test_kind = if builder.kind == Kind::Test {
|
let test_kind = builder.kind.into();
|
||||||
TestKind::Test
|
|
||||||
} else if builder.kind == Kind::Bench {
|
|
||||||
TestKind::Bench
|
|
||||||
} else {
|
|
||||||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.ensure(CrateRustdoc {
|
builder.ensure(CrateRustdoc {
|
||||||
host: run.host,
|
host: run.host,
|
||||||
|
|||||||
@@ -140,13 +140,9 @@ check that the test compiles successfully.
|
|||||||
### Editing and updating the reference files
|
### Editing and updating the reference files
|
||||||
|
|
||||||
If you have changed the compiler's output intentionally, or you are
|
If you have changed the compiler's output intentionally, or you are
|
||||||
making a new test, you can use the script `ui/update-references.sh` to
|
making a new test, you can pass `--bless` to the command you used to
|
||||||
update the references. When you run the test framework, it will report
|
run the tests. This will then copy over the files
|
||||||
various errors: in those errors is a command you can use to run the
|
from the build directory and use them as the new reference.
|
||||||
`ui/update-references.sh` script, which will then copy over the files
|
|
||||||
from the build directory and use them as the new reference. You can
|
|
||||||
also just run `ui/update-all-references.sh`. In both cases, you can run
|
|
||||||
the script with `--help` to get a help message.
|
|
||||||
|
|
||||||
### Normalization
|
### Normalization
|
||||||
|
|
||||||
|
|||||||
9
src/test/ui/E0508.ast.nll.stderr
Normal file
9
src/test/ui/E0508.ast.nll.stderr
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
|
||||||
|
--> $DIR/E0508.rs:18:18
|
||||||
|
|
|
||||||
|
LL | let _value = array[0]; //[ast]~ ERROR [E0508]
|
||||||
|
| ^^^^^^^^ cannot move out of here
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0508`.
|
||||||
12
src/test/ui/E0508.ast.stderr
Normal file
12
src/test/ui/E0508.ast.stderr
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
|
||||||
|
--> $DIR/E0508.rs:18:18
|
||||||
|
|
|
||||||
|
LL | let _value = array[0]; //[ast]~ ERROR [E0508]
|
||||||
|
| ^^^^^^^^
|
||||||
|
| |
|
||||||
|
| cannot move out of here
|
||||||
|
| help: consider using a reference instead: `&array[0]`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0508`.
|
||||||
9
src/test/ui/E0508.mir.stderr
Normal file
9
src/test/ui/E0508.mir.stderr
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
|
||||||
|
--> $DIR/E0508.rs:18:18
|
||||||
|
|
|
||||||
|
LL | let _value = array[0]; //[ast]~ ERROR [E0508]
|
||||||
|
| ^^^^^^^^ cannot move out of here
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0508`.
|
||||||
20
src/test/ui/E0508.rs
Normal file
20
src/test/ui/E0508.rs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// revisions: ast mir
|
||||||
|
//[mir]compile-flags: -Z borrowck=mir
|
||||||
|
|
||||||
|
struct NonCopy;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let array = [NonCopy; 1];
|
||||||
|
let _value = array[0]; //[ast]~ ERROR [E0508]
|
||||||
|
//[mir]~^ ERROR [E0508]
|
||||||
|
}
|
||||||
@@ -118,6 +118,9 @@ impl CompareMode {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
/// Whether to overwrite stderr/stdout files instead of complaining about changes in output
|
||||||
|
pub bless: bool,
|
||||||
|
|
||||||
/// The library paths required for running the compiler
|
/// The library paths required for running the compiler
|
||||||
pub compile_lib_path: PathBuf,
|
pub compile_lib_path: PathBuf,
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||||||
"FLAGS",
|
"FLAGS",
|
||||||
)
|
)
|
||||||
.optflag("", "verbose", "run tests verbosely, showing all output")
|
.optflag("", "verbose", "run tests verbosely, showing all output")
|
||||||
|
.optflag(
|
||||||
|
"",
|
||||||
|
"bless",
|
||||||
|
"overwrite stderr/stdout files instead of complaining about a mismatch",
|
||||||
|
)
|
||||||
.optflag(
|
.optflag(
|
||||||
"",
|
"",
|
||||||
"quiet",
|
"quiet",
|
||||||
@@ -290,6 +295,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||||||
let src_base = opt_path(matches, "src-base");
|
let src_base = opt_path(matches, "src-base");
|
||||||
let run_ignored = matches.opt_present("ignored");
|
let run_ignored = matches.opt_present("ignored");
|
||||||
Config {
|
Config {
|
||||||
|
bless: matches.opt_present("bless"),
|
||||||
compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
|
compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
|
||||||
run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
|
run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
|
||||||
rustc_path: opt_path(matches, "rustc-path"),
|
rustc_path: opt_path(matches, "rustc-path"),
|
||||||
|
|||||||
@@ -2596,15 +2596,13 @@ impl<'test> TestCx<'test> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if errors > 0 {
|
if errors > 0 {
|
||||||
println!("To update references, run this command from build directory:");
|
println!("To update references, rerun the tests and pass the `--bless` flag");
|
||||||
let relative_path_to_file = self.testpaths
|
let relative_path_to_file = self.testpaths
|
||||||
.relative_dir
|
.relative_dir
|
||||||
.join(self.testpaths.file.file_name().unwrap());
|
.join(self.testpaths.file.file_name().unwrap());
|
||||||
println!(
|
println!(
|
||||||
"{}/update-references.sh '{}' '{}'",
|
"To only update this specific test, also pass `--test-args {}`",
|
||||||
self.config.src_base.display(),
|
relative_path_to_file.display(),
|
||||||
self.config.build_base.display(),
|
|
||||||
relative_path_to_file.display()
|
|
||||||
);
|
);
|
||||||
self.fatal_proc_rec(
|
self.fatal_proc_rec(
|
||||||
&format!("{} errors occurred comparing output.", errors),
|
&format!("{} errors occurred comparing output.", errors),
|
||||||
@@ -2926,6 +2924,7 @@ impl<'test> TestCx<'test> {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.config.bless {
|
||||||
if expected.is_empty() {
|
if expected.is_empty() {
|
||||||
println!("normalized {}:\n{}\n", kind, actual);
|
println!("normalized {}:\n{}\n", kind, actual);
|
||||||
} else {
|
} else {
|
||||||
@@ -2951,6 +2950,7 @@ impl<'test> TestCx<'test> {
|
|||||||
println!("");
|
println!("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mode = self.config.compare_mode.as_ref().map_or("", |m| m.to_str());
|
let mode = self.config.compare_mode.as_ref().map_or("", |m| m.to_str());
|
||||||
let output_file = self.output_base_name()
|
let output_file = self.output_base_name()
|
||||||
@@ -2958,6 +2958,26 @@ impl<'test> TestCx<'test> {
|
|||||||
.with_extra_extension(mode)
|
.with_extra_extension(mode)
|
||||||
.with_extra_extension(kind);
|
.with_extra_extension(kind);
|
||||||
|
|
||||||
|
let mut files = vec![output_file];
|
||||||
|
if self.config.bless {
|
||||||
|
files.push(expected_output_path(
|
||||||
|
self.testpaths,
|
||||||
|
self.revision,
|
||||||
|
&self.config.compare_mode,
|
||||||
|
kind,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
for output_file in &files {
|
||||||
|
if actual.is_empty() {
|
||||||
|
if let Err(e) = ::std::fs::remove_file(output_file) {
|
||||||
|
self.fatal(&format!(
|
||||||
|
"failed to delete `{}`: {}",
|
||||||
|
output_file.display(),
|
||||||
|
e,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) {
|
match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(e) => self.fatal(&format!(
|
Err(e) => self.fatal(&format!(
|
||||||
@@ -2967,11 +2987,19 @@ impl<'test> TestCx<'test> {
|
|||||||
e
|
e
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
println!("\nThe actual {0} differed from the expected {0}.", kind);
|
println!("\nThe actual {0} differed from the expected {0}.", kind);
|
||||||
|
for output_file in files {
|
||||||
println!("Actual {} saved to {}", kind, output_file.display());
|
println!("Actual {} saved to {}", kind, output_file.display());
|
||||||
|
}
|
||||||
|
if self.config.bless {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn create_stamp(&self) {
|
fn create_stamp(&self) {
|
||||||
let mut f = File::create(::stamp(&self.config, self.testpaths, self.revision)).unwrap();
|
let mut f = File::create(::stamp(&self.config, self.testpaths, self.revision)).unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user