diff --git a/Cargo.lock b/Cargo.lock index cc707c630e5..f660ed77620 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,6 +73,37 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "camino" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3abb7553d5b9b8421c6de7cb02606ff15e0c6eea7d8eadd75ef013fd636bec36" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", +] + [[package]] name = "cc" version = "1.0.73" @@ -596,6 +627,9 @@ name = "semver" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" +dependencies = [ + "serde", +] [[package]] name = "serde" @@ -724,6 +758,7 @@ dependencies = [ name = "ui_test" version = "0.1.0" dependencies = [ + "cargo_metadata", "color-eyre", "colored", "crossbeam", diff --git a/cargo-miri/bin.rs b/cargo-miri/bin.rs index 2ab854b906a..6e140ab7143 100644 --- a/cargo-miri/bin.rs +++ b/cargo-miri/bin.rs @@ -3,6 +3,7 @@ mod version; +use std::collections::HashMap; use std::env; use std::ffi::{OsStr, OsString}; use std::fmt::Write as _; @@ -114,10 +115,14 @@ fn show_error(msg: String) -> ! { std::process::exit(1) } -// Determines whether a `--flag` is present. +/// Determines whether a `--flag` is present. fn has_arg_flag(name: &str) -> bool { - let mut args = std::env::args().take_while(|val| val != "--"); - args.any(|val| val == name) + num_arg_flag(name) > 0 +} + +/// Determines how many times a `--flag` is present. +fn num_arg_flag(name: &str) -> usize { + std::env::args().take_while(|val| val != "--").filter(|val| val == name).count() } /// Yields all values of command line flag `name` as `Ok(arg)`, and all other arguments except @@ -588,7 +593,7 @@ fn phase_cargo_miri(mut args: env::Args) { "`cargo miri` supports the following subcommands: `run`, `test`, and `setup`." )), }; - let verbose = has_arg_flag("-v"); + let verbose = num_arg_flag("-v"); // We always setup. setup(&subcommand); @@ -685,7 +690,7 @@ fn phase_cargo_miri(mut args: env::Args) { cmd.env("MIRI_LOCAL_CRATES", local_crates(&metadata)); // Run cargo. - if verbose { + if verbose > 0 { eprintln!("[cargo-miri miri] RUSTC_WRAPPER={:?}", cargo_miri_path); eprintln!("[cargo-miri miri] {}={:?}", target_runner_env_name, cargo_miri_path); if *target != host { @@ -693,7 +698,7 @@ fn phase_cargo_miri(mut args: env::Args) { } eprintln!("[cargo-miri miri] RUSTDOC={:?}", cargo_miri_path); eprintln!("[cargo-miri miri] {:?}", cmd); - cmd.env("MIRI_VERBOSE", ""); // This makes the other phases verbose. + cmd.env("MIRI_VERBOSE", verbose.to_string()); // This makes the other phases verbose. } exec(cmd) } @@ -752,7 +757,8 @@ fn out_filename(prefix: &str, suffix: &str) -> PathBuf { } } - let verbose = std::env::var_os("MIRI_VERBOSE").is_some(); + let verbose = std::env::var("MIRI_VERBOSE") + .map_or(0, |verbose| verbose.parse().expect("verbosity flag must be an integer")); let target_crate = is_target_crate(); let print = get_arg_flag_value("--print").is_some() || has_arg_flag("-vV"); // whether this is cargo/xargo invoking rustc to get some infos @@ -761,13 +767,13 @@ fn out_filename(prefix: &str, suffix: &str) -> PathBuf { // https://github.com/rust-lang/miri/issues/1724#issuecomment-787115693 // As we store a JSON file instead of building the crate here, an empty file is fine. let dep_info_name = out_filename("", ".d"); - if verbose { + if verbose > 0 { eprintln!("[cargo-miri rustc] writing stub dep-info to `{}`", dep_info_name.display()); } File::create(dep_info_name).expect("failed to create fake .d file"); let filename = out_filename("", ""); - if verbose { + if verbose > 0 { eprintln!("[cargo-miri rustc] writing run info to `{}`", filename.display()); } info.store(&filename); @@ -810,7 +816,7 @@ fn out_filename(prefix: &str, suffix: &str) -> PathBuf { cmd.args(&env.args); cmd.env("MIRI_BE_RUSTC", "target"); - if verbose { + if verbose > 0 { eprintln!( "[cargo-miri rustc] captured input:\n{}", std::str::from_utf8(&env.stdin).unwrap() @@ -877,6 +883,15 @@ fn out_filename(prefix: &str, suffix: &str) -> PathBuf { cmd.arg("-C").arg("panic=abort"); } } else { + // For host crates (but not when we are printing), we might still have to set the sysroot. + if !print { + // When we're running `cargo-miri` from `x.py` we need to pass the sysroot explicitly as rustc + // can't figure out the sysroot on its own unless it's from rustup. + if let Some(sysroot) = std::env::var_os("SYSROOT") { + cmd.arg("--sysroot").arg(sysroot); + } + } + // For host crates or when we are printing, just forward everything. cmd.args(args); } @@ -888,8 +903,14 @@ fn out_filename(prefix: &str, suffix: &str) -> PathBuf { cmd.env("MIRI_BE_RUSTC", if target_crate { "target" } else { "host" }); // Run it. - if verbose { - eprintln!("[cargo-miri rustc] {:?}", cmd); + if verbose > 0 { + eprint!("[cargo-miri rustc] "); + if verbose > 1 { + for (key, value) in env_vars_from_cmd(&cmd) { + eprintln!("{key}={value:?} \\"); + } + } + eprintln!("{:?}", cmd); } exec(cmd); @@ -908,6 +929,23 @@ fn out_filename(prefix: &str, suffix: &str) -> PathBuf { } } +fn env_vars_from_cmd(cmd: &Command) -> Vec<(String, String)> { + let mut envs = HashMap::new(); + for (key, value) in std::env::vars() { + envs.insert(key, value); + } + for (key, value) in cmd.get_envs() { + if let Some(value) = value { + envs.insert(key.to_str().unwrap().into(), value.to_str().unwrap().to_owned()); + } else { + envs.remove(key.to_str().unwrap()); + } + } + let mut envs: Vec<_> = envs.into_iter().collect(); + envs.sort(); + envs +} + #[derive(Debug, Copy, Clone, PartialEq)] enum RunnerPhase { /// `cargo` is running a binary diff --git a/test-cargo-miri/Cargo.lock b/test-cargo-miri/Cargo.lock index d34db9f14df..4cf58d723a2 100644 --- a/test-cargo-miri/Cargo.lock +++ b/test-cargo-miri/Cargo.lock @@ -15,8 +15,6 @@ dependencies = [ "byteorder", "cdylib", "exported_symbol", - "getrandom 0.1.16", - "getrandom 0.2.7", "issue_1567", "issue_1691", "issue_1705", @@ -51,17 +49,6 @@ dependencies = [ name = "exported_symbol_dep" version = "0.1.0" -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.7" @@ -70,7 +57,7 @@ checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -185,7 +172,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.7", + "getrandom", ] [[package]] @@ -223,12 +210,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/test-cargo-miri/Cargo.toml b/test-cargo-miri/Cargo.toml index 2193d354d5d..89a8463e4b3 100644 --- a/test-cargo-miri/Cargo.toml +++ b/test-cargo-miri/Cargo.toml @@ -19,8 +19,6 @@ issue_rust_86261 = { path = "issue-rust-86261" } [dev-dependencies] rand = { version = "0.8", features = ["small_rng"] } -getrandom_1 = { package = "getrandom", version = "0.1" } -getrandom_2 = { package = "getrandom", version = "0.2" } serde_derive = "1.0" # not actually used, but exercises some unique code path (`--extern` .so file) page_size = "0.4.1" diff --git a/test-cargo-miri/run-test.py b/test-cargo-miri/run-test.py index 09e7df39b1c..bc0046ffb14 100755 --- a/test-cargo-miri/run-test.py +++ b/test-cargo-miri/run-test.py @@ -5,7 +5,7 @@ Assumes the `MIRI_SYSROOT` env var to be set appropriately, and the working directory to contain the cargo-miri-test project. ''' -import sys, subprocess, os, re +import sys, subprocess, os, re, difflib CGREEN = '\33[32m' CBOLD = '\33[1m' @@ -27,6 +27,17 @@ def normalize_stdout(str): str = str.replace("src\\", "src/") # normalize paths across platforms return re.sub("finished in \d+\.\d\ds", "finished in $TIME", str) +def check_output(actual, path, name): + expected = open(path).read() + if expected == actual: + return True + print(f"{path} did not match reference!") + print(f"--- BEGIN diff {name} ---") + for text in difflib.unified_diff(expected.split("\n"), actual.split("\n")): + print(text) + print(f"--- END diff {name} ---") + return False + def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}): print("Testing {}...".format(name)) ## Call `cargo miri`, capture all output @@ -42,17 +53,14 @@ def test(name, cmd, stdout_ref, stderr_ref, stdin=b'', env={}): (stdout, stderr) = p.communicate(input=stdin) stdout = stdout.decode("UTF-8") stderr = stderr.decode("UTF-8") - if p.returncode == 0 and normalize_stdout(stdout) == open(stdout_ref).read() and stderr == open(stderr_ref).read(): + stdout = normalize_stdout(stdout) + + stdout_matches = check_output(stdout, stdout_ref, "stdout") + stderr_matches = check_output(stderr, stderr_ref, "stderr") + + if p.returncode == 0 and stdout_matches and stderr_matches: # All good! return - # Show output - print("Test stdout or stderr did not match reference!") - print("--- BEGIN test stdout ---") - print(stdout, end="") - print("--- END test stdout ---") - print("--- BEGIN test stderr ---") - print(stderr, end="") - print("--- END test stderr ---") fail("exit code was {}".format(p.returncode)) def test_no_rebuild(name, cmd, env={}): diff --git a/test-cargo-miri/tests/test.rs b/test-cargo-miri/tests/test.rs index 8a938ef3c25..eb31058e1c1 100644 --- a/test-cargo-miri/tests/test.rs +++ b/test-cargo-miri/tests/test.rs @@ -20,15 +20,9 @@ fn does_not_work_on_miri() { assert!(&x as *const _ as usize % 4 < 4); } -// We also use this to test some external crates, that we cannot depend on in the compiletest suite. - +// Make sure integration tests can access dev-dependencies #[test] fn entropy_rng() { - // Test `getrandom` directly (in multiple different versions). - let mut data = vec![0; 16]; - getrandom_1::getrandom(&mut data).unwrap(); - getrandom_2::getrandom(&mut data).unwrap(); - // Try seeding with "real" entropy. let mut rng = SmallRng::from_entropy(); let _val = rng.gen::(); diff --git a/test_dependencies/Cargo.lock b/test_dependencies/Cargo.lock new file mode 100644 index 00000000000..6b5e8c94224 --- /dev/null +++ b/test_dependencies/Cargo.lock @@ -0,0 +1,376 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "lock_api" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", +] + +[[package]] +name = "miri-test-deps" +version = "0.1.0" +dependencies = [ + "getrandom 0.1.16", + "getrandom 0.2.7", + "libc", + "rand", + "tokio", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "proc-macro2" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.7", +] + +[[package]] +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tokio" +version = "1.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" +dependencies = [ + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/test_dependencies/Cargo.toml b/test_dependencies/Cargo.toml new file mode 100644 index 00000000000..edaa6a69260 --- /dev/null +++ b/test_dependencies/Cargo.toml @@ -0,0 +1,19 @@ +[package] +authors = ["Miri Team"] +description = "dependencies that unit tests can have" +license = "MIT OR Apache-2.0" +name = "miri-test-deps" +repository = "https://github.com/rust-lang/miri" +version = "0.1.0" +edition = "2021" + +[dependencies] +# all dependencies (and their transitive ones) listed here can be used in `tests/`. +tokio = { version = "1.0", features = ["full"] } +libc = "0.2" + +getrandom_1 = { package = "getrandom", version = "0.1" } +getrandom_2 = { package = "getrandom", version = "0.2" } +rand = { version = "0.8", features = ["small_rng"] } + +[workspace] diff --git a/test_dependencies/src/main.rs b/test_dependencies/src/main.rs new file mode 100644 index 00000000000..f328e4d9d04 --- /dev/null +++ b/test_dependencies/src/main.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/tests/compiletest.rs b/tests/compiletest.rs index ec49e80ca96..37b9de7327a 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -1,8 +1,8 @@ use colored::*; use regex::Regex; -use std::env; -use std::path::PathBuf; -use ui_test::{color_eyre::Result, Config, Mode, OutputConflictHandling}; +use std::path::{Path, PathBuf}; +use std::{env, ffi::OsString}; +use ui_test::{color_eyre::Result, Config, DependencyBuilder, Mode, OutputConflictHandling}; fn miri_path() -> PathBuf { PathBuf::from(option_env!("MIRI").unwrap_or(env!("CARGO_BIN_EXE_miri"))) @@ -12,31 +12,31 @@ fn run_tests(mode: Mode, path: &str, target: Option) -> Result<()> { let in_rustc_test_suite = option_env!("RUSTC_STAGE").is_some(); // Add some flags we always want. - let mut flags = Vec::new(); - flags.push("--edition".to_owned()); - flags.push("2018".to_owned()); + let mut flags: Vec = Vec::new(); + flags.push("--edition".into()); + flags.push("2018".into()); if in_rustc_test_suite { // Less aggressive warnings to make the rustc toolstate management less painful. // (We often get warnings when e.g. a feature gets stabilized or some lint gets added/improved.) - flags.push("-Astable-features".to_owned()); - flags.push("-Aunused".to_owned()); + flags.push("-Astable-features".into()); + flags.push("-Aunused".into()); } else { - flags.push("-Dwarnings".to_owned()); - flags.push("-Dunused".to_owned()); + flags.push("-Dwarnings".into()); + flags.push("-Dunused".into()); } - if let Ok(sysroot) = env::var("MIRI_SYSROOT") { - flags.push("--sysroot".to_string()); + if let Some(sysroot) = env::var_os("MIRI_SYSROOT") { + flags.push("--sysroot".into()); flags.push(sysroot); } if let Ok(extra_flags) = env::var("MIRIFLAGS") { for flag in extra_flags.split_whitespace() { - flags.push(flag.to_string()); + flags.push(flag.into()); } } - flags.push("-Zui-testing".to_string()); + flags.push("-Zui-testing".into()); if let Some(target) = &target { - flags.push("--target".to_string()); - flags.push(target.clone()); + flags.push("--target".into()); + flags.push(target.into()); } let skip_ui_checks = env::var_os("MIRI_SKIP_UI_CHECKS").is_some(); @@ -51,6 +51,8 @@ fn run_tests(mode: Mode, path: &str, target: Option) -> Result<()> { // Pass on all arguments as filters. let path_filter = std::env::args().skip(1); + let use_std = env::var_os("MIRI_NO_STD").is_none(); + let config = Config { args: flags, target, @@ -61,6 +63,19 @@ fn run_tests(mode: Mode, path: &str, target: Option) -> Result<()> { path_filter: path_filter.collect(), program: miri_path(), output_conflict_handling, + dependencies_crate_manifest_path: use_std + .then(|| Path::new("test_dependencies").join("Cargo.toml")), + dependency_builder: Some(DependencyBuilder { + program: std::env::var_os("CARGO").unwrap().into(), + args: vec![ + "run".into(), + "--manifest-path".into(), + "cargo-miri/Cargo.toml".into(), + "--".into(), + "miri".into(), + ], + envs: vec![], + }), }; ui_test::run_tests(config) } @@ -107,6 +122,8 @@ macro_rules! regexes { "[^ `]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/", // erase platform file paths "sys/[a-z]+/" => "sys/PLATFORM/", + // erase paths into the crate registry + r"[^ ]*/\.cargo/registry/.*/(.*\.rs)" => "CARGO_REGISTRY/$1", } fn ui(mode: Mode, path: &str) -> Result<()> { diff --git a/tests/fail/concurrency/libc_pthread_create_main_terminate.rs b/tests/fail/concurrency/libc_pthread_create_main_terminate.rs index 169a021215d..9da9fbf2029 100644 --- a/tests/fail/concurrency/libc_pthread_create_main_terminate.rs +++ b/tests/fail/concurrency/libc_pthread_create_main_terminate.rs @@ -5,8 +5,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::{mem, ptr}; extern "C" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void { diff --git a/tests/fail/concurrency/libc_pthread_join_detached.rs b/tests/fail/concurrency/libc_pthread_join_detached.rs index 6f0d45e2dc0..e81978fc995 100644 --- a/tests/fail/concurrency/libc_pthread_join_detached.rs +++ b/tests/fail/concurrency/libc_pthread_join_detached.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::{mem, ptr}; extern "C" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void { diff --git a/tests/fail/concurrency/libc_pthread_join_joined.rs b/tests/fail/concurrency/libc_pthread_join_joined.rs index 77f59fabca5..11e00429c6c 100644 --- a/tests/fail/concurrency/libc_pthread_join_joined.rs +++ b/tests/fail/concurrency/libc_pthread_join_joined.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::{mem, ptr}; extern "C" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void { diff --git a/tests/fail/concurrency/libc_pthread_join_main.rs b/tests/fail/concurrency/libc_pthread_join_main.rs index aff28bcc9b5..f029f08772f 100644 --- a/tests/fail/concurrency/libc_pthread_join_main.rs +++ b/tests/fail/concurrency/libc_pthread_join_main.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::{ptr, thread}; fn main() { diff --git a/tests/fail/concurrency/libc_pthread_join_multiple.rs b/tests/fail/concurrency/libc_pthread_join_multiple.rs index d4d54d3a23f..017036ab01e 100644 --- a/tests/fail/concurrency/libc_pthread_join_multiple.rs +++ b/tests/fail/concurrency/libc_pthread_join_multiple.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::thread; use std::{mem, ptr}; diff --git a/tests/fail/concurrency/libc_pthread_join_self.rs b/tests/fail/concurrency/libc_pthread_join_self.rs index b911b2db3a1..ae614889317 100644 --- a/tests/fail/concurrency/libc_pthread_join_self.rs +++ b/tests/fail/concurrency/libc_pthread_join_self.rs @@ -6,8 +6,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::{ptr, thread}; fn main() { diff --git a/tests/fail/concurrency/too_few_args.rs b/tests/fail/concurrency/too_few_args.rs index 11e97ca290f..4760fbb6b05 100644 --- a/tests/fail/concurrency/too_few_args.rs +++ b/tests/fail/concurrency/too_few_args.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::{mem, ptr}; extern "C" fn thread_start() -> *mut libc::c_void { diff --git a/tests/fail/concurrency/too_many_args.rs b/tests/fail/concurrency/too_many_args.rs index dd44207a625..6abe767dc8a 100644 --- a/tests/fail/concurrency/too_many_args.rs +++ b/tests/fail/concurrency/too_many_args.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::{mem, ptr}; extern "C" fn thread_start(_null: *mut libc::c_void, _x: i32) -> *mut libc::c_void { diff --git a/tests/fail/concurrency/unwind_top_of_stack.rs b/tests/fail/concurrency/unwind_top_of_stack.rs index 179ff9c146e..bd49401e61f 100644 --- a/tests/fail/concurrency/unwind_top_of_stack.rs +++ b/tests/fail/concurrency/unwind_top_of_stack.rs @@ -5,8 +5,6 @@ #![feature(rustc_private, c_unwind)] -extern crate libc; - use std::{mem, ptr}; extern "C-unwind" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void { diff --git a/tests/fail/fs/close_stdout.rs b/tests/fail/fs/close_stdout.rs index bc709fe36d5..86a6239f5f3 100644 --- a/tests/fail/fs/close_stdout.rs +++ b/tests/fail/fs/close_stdout.rs @@ -5,8 +5,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { unsafe { libc::close(1); //~ ERROR: stdout cannot be closed diff --git a/tests/fail/fs/isolated_stdin.rs b/tests/fail/fs/isolated_stdin.rs index cd54de3bcec..86b04a03835 100644 --- a/tests/fail/fs/isolated_stdin.rs +++ b/tests/fail/fs/isolated_stdin.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() -> std::io::Result<()> { let mut bytes = [0u8; 512]; unsafe { diff --git a/tests/fail/fs/read_from_stdout.rs b/tests/fail/fs/read_from_stdout.rs index 949fe88f433..0fd8ba2fc41 100644 --- a/tests/fail/fs/read_from_stdout.rs +++ b/tests/fail/fs/read_from_stdout.rs @@ -3,8 +3,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() -> std::io::Result<()> { let mut bytes = [0u8; 512]; unsafe { diff --git a/tests/fail/fs/unix_open_missing_required_mode.rs b/tests/fail/fs/unix_open_missing_required_mode.rs index 1f6beadcb82..4740dcebe92 100644 --- a/tests/fail/fs/unix_open_missing_required_mode.rs +++ b/tests/fail/fs/unix_open_missing_required_mode.rs @@ -3,8 +3,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { test_file_open_missing_needed_mode(); } diff --git a/tests/fail/fs/write_to_stdin.rs b/tests/fail/fs/write_to_stdin.rs index 4ad7b648e1c..0e9109fc6e2 100644 --- a/tests/fail/fs/write_to_stdin.rs +++ b/tests/fail/fs/write_to_stdin.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() -> std::io::Result<()> { let bytes = b"hello"; unsafe { diff --git a/tests/fail/sync/libc_pthread_cond_double_destroy.rs b/tests/fail/sync/libc_pthread_cond_double_destroy.rs index d0a4ac46cb3..90d5997f871 100644 --- a/tests/fail/sync/libc_pthread_cond_double_destroy.rs +++ b/tests/fail/sync/libc_pthread_cond_double_destroy.rs @@ -2,7 +2,6 @@ #![feature(rustc_private)] /// Test that destroying a pthread_cond twice fails, even without a check for number validity -extern crate libc; fn main() { unsafe { diff --git a/tests/fail/sync/libc_pthread_condattr_double_destroy.rs b/tests/fail/sync/libc_pthread_condattr_double_destroy.rs index c64b3238138..028a924196f 100644 --- a/tests/fail/sync/libc_pthread_condattr_double_destroy.rs +++ b/tests/fail/sync/libc_pthread_condattr_double_destroy.rs @@ -2,7 +2,6 @@ #![feature(rustc_private)] /// Test that destroying a pthread_condattr twice fails, even without a check for number validity -extern crate libc; fn main() { unsafe { diff --git a/tests/fail/sync/libc_pthread_mutex_NULL_deadlock.rs b/tests/fail/sync/libc_pthread_mutex_NULL_deadlock.rs index 8797e895d8c..d87455877ab 100644 --- a/tests/fail/sync/libc_pthread_mutex_NULL_deadlock.rs +++ b/tests/fail/sync/libc_pthread_mutex_NULL_deadlock.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { unsafe { let mut mutex: libc::pthread_mutex_t = std::mem::zeroed(); diff --git a/tests/fail/sync/libc_pthread_mutex_deadlock.rs b/tests/fail/sync/libc_pthread_mutex_deadlock.rs index 7da6e516000..f77f5c2e202 100644 --- a/tests/fail/sync/libc_pthread_mutex_deadlock.rs +++ b/tests/fail/sync/libc_pthread_mutex_deadlock.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::cell::UnsafeCell; use std::sync::Arc; use std::thread; diff --git a/tests/fail/sync/libc_pthread_mutex_default_deadlock.rs b/tests/fail/sync/libc_pthread_mutex_default_deadlock.rs index 70a85aa0f98..b28101e20b2 100644 --- a/tests/fail/sync/libc_pthread_mutex_default_deadlock.rs +++ b/tests/fail/sync/libc_pthread_mutex_default_deadlock.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { unsafe { let mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); diff --git a/tests/fail/sync/libc_pthread_mutex_destroy_locked.rs b/tests/fail/sync/libc_pthread_mutex_destroy_locked.rs index fc69ace3699..0f74446fa27 100644 --- a/tests/fail/sync/libc_pthread_mutex_destroy_locked.rs +++ b/tests/fail/sync/libc_pthread_mutex_destroy_locked.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { unsafe { let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); diff --git a/tests/fail/sync/libc_pthread_mutex_double_destroy.rs b/tests/fail/sync/libc_pthread_mutex_double_destroy.rs index 9b539afc199..89022f3b562 100644 --- a/tests/fail/sync/libc_pthread_mutex_double_destroy.rs +++ b/tests/fail/sync/libc_pthread_mutex_double_destroy.rs @@ -2,7 +2,6 @@ #![feature(rustc_private)] /// Test that destroying a pthread_mutex twice fails, even without a check for number validity -extern crate libc; fn main() { unsafe { diff --git a/tests/fail/sync/libc_pthread_mutex_normal_deadlock.rs b/tests/fail/sync/libc_pthread_mutex_normal_deadlock.rs index 944e86e106d..ab6d9c7739d 100644 --- a/tests/fail/sync/libc_pthread_mutex_normal_deadlock.rs +++ b/tests/fail/sync/libc_pthread_mutex_normal_deadlock.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { unsafe { let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); diff --git a/tests/fail/sync/libc_pthread_mutex_normal_unlock_unlocked.rs b/tests/fail/sync/libc_pthread_mutex_normal_unlock_unlocked.rs index c2bdce82b6f..f259a4dee7d 100644 --- a/tests/fail/sync/libc_pthread_mutex_normal_unlock_unlocked.rs +++ b/tests/fail/sync/libc_pthread_mutex_normal_unlock_unlocked.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { unsafe { let mut mutexattr: libc::pthread_mutexattr_t = std::mem::zeroed(); diff --git a/tests/fail/sync/libc_pthread_mutex_wrong_owner.rs b/tests/fail/sync/libc_pthread_mutex_wrong_owner.rs index eea4db71159..b8e57f8f74e 100644 --- a/tests/fail/sync/libc_pthread_mutex_wrong_owner.rs +++ b/tests/fail/sync/libc_pthread_mutex_wrong_owner.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::cell::UnsafeCell; use std::sync::Arc; use std::thread; diff --git a/tests/fail/sync/libc_pthread_mutexattr_double_destroy.rs b/tests/fail/sync/libc_pthread_mutexattr_double_destroy.rs index 620dbb94a78..ac6292570e4 100644 --- a/tests/fail/sync/libc_pthread_mutexattr_double_destroy.rs +++ b/tests/fail/sync/libc_pthread_mutexattr_double_destroy.rs @@ -2,7 +2,6 @@ #![feature(rustc_private)] /// Test that destroying a pthread_mutexattr twice fails, even without a check for number validity -extern crate libc; fn main() { unsafe { diff --git a/tests/fail/sync/libc_pthread_rwlock_destroy_read_locked.rs b/tests/fail/sync/libc_pthread_rwlock_destroy_read_locked.rs index 67b77ff2864..ae7c1bbde72 100644 --- a/tests/fail/sync/libc_pthread_rwlock_destroy_read_locked.rs +++ b/tests/fail/sync/libc_pthread_rwlock_destroy_read_locked.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { diff --git a/tests/fail/sync/libc_pthread_rwlock_destroy_write_locked.rs b/tests/fail/sync/libc_pthread_rwlock_destroy_write_locked.rs index 5bc5fe3c6bc..9642595ca4e 100644 --- a/tests/fail/sync/libc_pthread_rwlock_destroy_write_locked.rs +++ b/tests/fail/sync/libc_pthread_rwlock_destroy_write_locked.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { diff --git a/tests/fail/sync/libc_pthread_rwlock_double_destroy.rs b/tests/fail/sync/libc_pthread_rwlock_double_destroy.rs index 7e756c5bb88..81b1661ce8d 100644 --- a/tests/fail/sync/libc_pthread_rwlock_double_destroy.rs +++ b/tests/fail/sync/libc_pthread_rwlock_double_destroy.rs @@ -2,7 +2,6 @@ #![feature(rustc_private)] /// Test that destroying a pthread_rwlock twice fails, even without a check for number validity -extern crate libc; fn main() { unsafe { diff --git a/tests/fail/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs b/tests/fail/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs index 76fceb315f4..158dd8c1cda 100644 --- a/tests/fail/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs +++ b/tests/fail/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { diff --git a/tests/fail/sync/libc_pthread_rwlock_read_wrong_owner.rs b/tests/fail/sync/libc_pthread_rwlock_read_wrong_owner.rs index e971fd8c302..23dda68c6a4 100644 --- a/tests/fail/sync/libc_pthread_rwlock_read_wrong_owner.rs +++ b/tests/fail/sync/libc_pthread_rwlock_read_wrong_owner.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::cell::UnsafeCell; use std::sync::Arc; use std::thread; diff --git a/tests/fail/sync/libc_pthread_rwlock_unlock_unlocked.rs b/tests/fail/sync/libc_pthread_rwlock_unlock_unlocked.rs index 29cfd36cafc..fdcf8e41d36 100644 --- a/tests/fail/sync/libc_pthread_rwlock_unlock_unlocked.rs +++ b/tests/fail/sync/libc_pthread_rwlock_unlock_unlocked.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { diff --git a/tests/fail/sync/libc_pthread_rwlock_write_read_deadlock.rs b/tests/fail/sync/libc_pthread_rwlock_write_read_deadlock.rs index e9c5c17f3eb..adbb95fc28e 100644 --- a/tests/fail/sync/libc_pthread_rwlock_write_read_deadlock.rs +++ b/tests/fail/sync/libc_pthread_rwlock_write_read_deadlock.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::cell::UnsafeCell; use std::sync::Arc; use std::thread; diff --git a/tests/fail/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs b/tests/fail/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs index 5ed25344e7c..a7d16caa7a4 100644 --- a/tests/fail/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs +++ b/tests/fail/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { diff --git a/tests/fail/sync/libc_pthread_rwlock_write_write_deadlock.rs b/tests/fail/sync/libc_pthread_rwlock_write_write_deadlock.rs index 3d15370e83d..070373255d3 100644 --- a/tests/fail/sync/libc_pthread_rwlock_write_write_deadlock.rs +++ b/tests/fail/sync/libc_pthread_rwlock_write_write_deadlock.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::cell::UnsafeCell; use std::sync::Arc; use std::thread; diff --git a/tests/fail/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs b/tests/fail/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs index 14361bee54c..867c6272c46 100644 --- a/tests/fail/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs +++ b/tests/fail/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - fn main() { let rw = std::cell::UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER); unsafe { diff --git a/tests/fail/sync/libc_pthread_rwlock_write_wrong_owner.rs b/tests/fail/sync/libc_pthread_rwlock_write_wrong_owner.rs index 668ccb3ecae..cff2a7a2e98 100644 --- a/tests/fail/sync/libc_pthread_rwlock_write_wrong_owner.rs +++ b/tests/fail/sync/libc_pthread_rwlock_write_wrong_owner.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::cell::UnsafeCell; use std::sync::Arc; use std::thread; diff --git a/tests/fail/tokio_mvp.rs b/tests/fail/tokio_mvp.rs new file mode 100644 index 00000000000..7cb42c09a96 --- /dev/null +++ b/tests/fail/tokio_mvp.rs @@ -0,0 +1,7 @@ +//@compile-flags: -Zmiri-disable-isolation +//@error-pattern: can't call foreign function: epoll_create1 +//@normalize-stderr-test: " = note: inside .*\n" -> "" +//@only-target-linux: the errors differ too much between platforms + +#[tokio::main] +async fn main() {} diff --git a/tests/fail/tokio_mvp.stderr b/tests/fail/tokio_mvp.stderr new file mode 100644 index 00000000000..cff948f3640 --- /dev/null +++ b/tests/fail/tokio_mvp.stderr @@ -0,0 +1,19 @@ +error: unsupported operation: can't call foreign function: epoll_create1 + --> CARGO_REGISTRY/epoll.rs:LL:CC + | +LL | syscall!(epoll_create1(flag)).map(|ep| Selector { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't call foreign function: epoll_create1 + | + = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + = note: backtrace: +note: inside `main` at $DIR/tokio_mvp.rs:LL:CC + --> $DIR/tokio_mvp.rs:LL:CC + | +LL | #[tokio::main] + | ^^^^^^^^^^^^^^ + = note: this error originates in the macro `syscall` which comes from the expansion of the attribute macro `tokio::main` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/tests/fail/unsupported_signal.rs b/tests/fail/unsupported_signal.rs index e9bd340fcaf..20ebcc9bc47 100644 --- a/tests/fail/unsupported_signal.rs +++ b/tests/fail/unsupported_signal.rs @@ -3,8 +3,6 @@ //@ignore-target-windows: No libc on Windows #![feature(rustc_private)] -extern crate libc; - fn main() { unsafe { libc::signal(libc::SIGPIPE, libc::SIG_IGN); diff --git a/tests/panic/panic/unsupported_syscall.rs b/tests/panic/panic/unsupported_syscall.rs index a6891728146..27595bf1071 100644 --- a/tests/panic/panic/unsupported_syscall.rs +++ b/tests/panic/panic/unsupported_syscall.rs @@ -3,8 +3,6 @@ //@compile-flags: -Zmiri-panic-on-unsupported #![feature(rustc_private)] -extern crate libc; - fn main() { unsafe { libc::syscall(0); diff --git a/tests/pass/calloc.rs b/tests/pass/calloc.rs index a9efb776b69..e155d53ce81 100644 --- a/tests/pass/calloc.rs +++ b/tests/pass/calloc.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - use core::slice; fn main() { diff --git a/tests/pass/concurrency/libc_pthread_cond.rs b/tests/pass/concurrency/libc_pthread_cond.rs index eb491486be7..c5b0e86666a 100644 --- a/tests/pass/concurrency/libc_pthread_cond.rs +++ b/tests/pass/concurrency/libc_pthread_cond.rs @@ -6,8 +6,6 @@ /// Test that conditional variable timeouts are working properly with both /// monotonic and system clocks. -extern crate libc; - use std::mem::MaybeUninit; use std::time::Instant; diff --git a/tests/pass/concurrency/linux-futex.rs b/tests/pass/concurrency/linux-futex.rs index f9c87e0723c..43216481e76 100644 --- a/tests/pass/concurrency/linux-futex.rs +++ b/tests/pass/concurrency/linux-futex.rs @@ -2,7 +2,6 @@ //@compile-flags: -Zmiri-disable-isolation #![feature(rustc_private)] -extern crate libc; use std::mem::MaybeUninit; use std::ptr; diff --git a/tests/pass/concurrency/tls_pthread_drop_order.rs b/tests/pass/concurrency/tls_pthread_drop_order.rs index c9e8b9271cc..1ccc57da25f 100644 --- a/tests/pass/concurrency/tls_pthread_drop_order.rs +++ b/tests/pass/concurrency/tls_pthread_drop_order.rs @@ -1,7 +1,6 @@ //@ignore-target-windows: No libc on Windows #![feature(rustc_private)] -extern crate libc; use std::mem; use std::ptr; diff --git a/tests/pass/foreign-fn-linkname.rs b/tests/pass/foreign-fn-linkname.rs index 391b182fda0..40aeb2ef631 100644 --- a/tests/pass/foreign-fn-linkname.rs +++ b/tests/pass/foreign-fn-linkname.rs @@ -1,8 +1,6 @@ //ignore-windows: Uses POSIX APIs #![feature(rustc_private)] -extern crate libc; - use std::ffi::CString; mod mlibc { diff --git a/tests/pass/fs.rs b/tests/pass/fs.rs index aa5cd83c69c..9d59fedb20e 100644 --- a/tests/pass/fs.rs +++ b/tests/pass/fs.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] #![feature(io_error_more)] -extern crate libc; - use std::ffi::CString; use std::fs::{ create_dir, read_dir, read_link, remove_dir, remove_dir_all, remove_file, rename, File, diff --git a/tests/pass/fs_with_isolation.rs b/tests/pass/fs_with_isolation.rs index 41ada94e276..f73e64ad17a 100644 --- a/tests/pass/fs_with_isolation.rs +++ b/tests/pass/fs_with_isolation.rs @@ -4,8 +4,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::ffi::CString; use std::fs::{self, File}; use std::io::{Error, ErrorKind}; diff --git a/tests/pass/libc.rs b/tests/pass/libc.rs index 99b7c3f249f..9b83ab45b0c 100644 --- a/tests/pass/libc.rs +++ b/tests/pass/libc.rs @@ -5,8 +5,6 @@ use std::fs::{remove_file, File}; use std::os::unix::io::AsRawFd; -extern crate libc; - fn tmp() -> std::path::PathBuf { std::env::var("MIRI_TEMP") .map(std::path::PathBuf::from) diff --git a/tests/pass/linux-getrandom-without-isolation.rs b/tests/pass/linux-getrandom-without-isolation.rs index fea3bb3fdce..12b42552bd5 100644 --- a/tests/pass/linux-getrandom-without-isolation.rs +++ b/tests/pass/linux-getrandom-without-isolation.rs @@ -1,7 +1,6 @@ //@only-target-linux //@compile-flags: -Zmiri-disable-isolation #![feature(rustc_private)] -extern crate libc; use std::ptr; diff --git a/tests/pass/linux-getrandom.rs b/tests/pass/linux-getrandom.rs index 1d0ab6ed746..e3309f480d3 100644 --- a/tests/pass/linux-getrandom.rs +++ b/tests/pass/linux-getrandom.rs @@ -1,6 +1,5 @@ //@only-target-linux #![feature(rustc_private)] -extern crate libc; use std::ptr; diff --git a/tests/pass/malloc.rs b/tests/pass/malloc.rs index d20ceddbb8e..9066e2af25f 100644 --- a/tests/pass/malloc.rs +++ b/tests/pass/malloc.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - use core::{ptr, slice}; fn main() { diff --git a/tests/pass/random.rs b/tests/pass/random.rs new file mode 100644 index 00000000000..808d1006d4f --- /dev/null +++ b/tests/pass/random.rs @@ -0,0 +1,22 @@ +use rand::{rngs::SmallRng, Rng, SeedableRng}; +// mac-os `getrandom_1` does some pointer shenanigans +//@compile-flags: -Zmiri-permissive-provenance + +fn main() { + // Test `getrandom` directly (in multiple different versions). + let mut data = vec![0; 16]; + getrandom_1::getrandom(&mut data).unwrap(); + getrandom_2::getrandom(&mut data).unwrap(); + + // Try seeding with "real" entropy. + let mut rng = SmallRng::from_entropy(); + let _val = rng.gen::(); + let _val = rng.gen::(); + let _val = rng.gen::(); + + // Also try per-thread RNG. + let mut rng = rand::thread_rng(); + let _val = rng.gen::(); + let _val = rng.gen::(); + let _val = rng.gen::(); +} diff --git a/tests/pass/regions-mock-trans.rs b/tests/pass/regions-mock-trans.rs index 5dafc88756f..7432ea95826 100644 --- a/tests/pass/regions-mock-trans.rs +++ b/tests/pass/regions-mock-trans.rs @@ -2,8 +2,6 @@ #![feature(rustc_private)] -extern crate libc; - use std::mem; struct Arena(()); diff --git a/ui_test/Cargo.lock b/ui_test/Cargo.lock index 2065cc34bef..9addea9b19d 100644 --- a/ui_test/Cargo.lock +++ b/ui_test/Cargo.lock @@ -67,6 +67,37 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "camino" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3abb7553d5b9b8421c6de7cb02606ff15e0c6eea7d8eadd75ef013fd636bec36" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", +] + [[package]] name = "cc" version = "1.0.73" @@ -390,6 +421,9 @@ name = "semver" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" +dependencies = [ + "serde", +] [[package]] name = "serde" @@ -497,6 +531,7 @@ dependencies = [ name = "ui_test" version = "0.1.0" dependencies = [ + "cargo_metadata", "color-eyre", "colored", "crossbeam", diff --git a/ui_test/Cargo.toml b/ui_test/Cargo.toml index cdc5e5db472..bb14eb7ecfe 100644 --- a/ui_test/Cargo.toml +++ b/ui_test/Cargo.toml @@ -18,4 +18,4 @@ lazy_static = "1.4.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" color-eyre = { version = "0.6.1", default-features = false, features = ["capture-spantrace"] } - +cargo_metadata = "0.15" diff --git a/ui_test/README.md b/ui_test/README.md index f1b1a5d67e0..3db3361faa5 100644 --- a/ui_test/README.md +++ b/ui_test/README.md @@ -47,3 +47,5 @@ their command specifies, or the test will fail without even being run. * `ignore-target-*` and `only-target-*` opereate solely on the triple, instead of supporting things like `macos` * only `//~` comments can be individualized per revision +* only supports `ui` tests +* tests are run in named order, so you can prefix slow tests with `0` in order to make them get run first diff --git a/ui_test/src/dependencies.rs b/ui_test/src/dependencies.rs new file mode 100644 index 00000000000..ab3a0156595 --- /dev/null +++ b/ui_test/src/dependencies.rs @@ -0,0 +1,137 @@ +use color_eyre::eyre::{bail, Result}; +use std::{ + collections::{HashMap, HashSet}, + path::{Path, PathBuf}, + process::Command, +}; + +use crate::Config; + +#[derive(Default, Debug)] +pub struct Dependencies { + /// All paths that must be imported with `-L dependency=`. This is for + /// finding proc macros run on the host and dependencies for the target. + pub import_paths: Vec, + /// The name as chosen in the `Cargo.toml` and its corresponding rmeta file. + pub dependencies: Vec<(String, PathBuf)>, +} + +/// Compiles dependencies and returns the crate names and corresponding rmeta files. +pub fn build_dependencies(config: &Config) -> Result { + let manifest_path = match &config.dependencies_crate_manifest_path { + Some(path) => path, + None => return Ok(Default::default()), + }; + let (program, args, envs): (&Path, &[_], &[_]) = match &config.dependency_builder { + Some(db) => (&db.program, &db.args, &db.envs), + None => (Path::new("cargo"), &[], &[]), + }; + let mut build = Command::new(program); + build.args(args); + // HACK: we're using `cargo run` (or `cargo miri run`), because the latter does not + // support `cargo miri build` yet. + build.arg("run"); + + if let Some(target) = &config.target { + build.arg(format!("--target={target}")); + } + + // Reusable closure for setting up the environment both for artifact generation and `cargo_metadata` + let setup_command = |cmd: &mut Command| { + cmd.envs(envs.iter().map(|(k, v)| (k, v))); + cmd.arg("--manifest-path").arg(manifest_path); + }; + + setup_command(&mut build); + build + .arg("--target-dir=target/test_dependencies") + .arg("--message-format=json") + .arg("-Zunstable-options"); + + let output = build.output()?; + + if !output.status.success() { + let stdout = String::from_utf8(output.stdout)?; + let stderr = String::from_utf8(output.stderr)?; + bail!("failed to compile dependencies:\nstderr:\n{stderr}\n\nstdout:{stdout}"); + } + + // Collect all artifacts generated + let output = output.stdout; + let output = String::from_utf8(output)?; + let mut import_paths: HashSet = HashSet::new(); + let mut artifacts: HashMap<_, _> = output + .lines() + .filter_map(|line| { + let message = serde_json::from_str::(line).ok()?; + if let cargo_metadata::Message::CompilerArtifact(artifact) = message { + for filename in &artifact.filenames { + import_paths.insert(filename.parent().unwrap().into()); + } + let filename = artifact + .filenames + .into_iter() + .find(|filename| filename.extension() == Some("rmeta"))?; + Some((artifact.package_id, filename.into_std_path_buf())) + } else { + None + } + }) + .collect(); + + // Check which crates are mentioned in the crate itself + let mut metadata = cargo_metadata::MetadataCommand::new().cargo_command(); + setup_command(&mut metadata); + let output = metadata.output()?; + + if !output.status.success() { + let stdout = String::from_utf8(output.stdout)?; + let stderr = String::from_utf8(output.stderr)?; + bail!("failed to run cargo-metadata:\nstderr:\n{stderr}\n\nstdout:{stdout}"); + } + + let output = output.stdout; + let output = String::from_utf8(output)?; + + for line in output.lines() { + if !line.starts_with('{') { + continue; + } + let metadata: cargo_metadata::Metadata = serde_json::from_str(line)?; + // Only take artifacts that are defined in the Cargo.toml + + // First, find the root artifact + let root = metadata + .packages + .iter() + .find(|package| { + package.manifest_path.as_std_path().canonicalize().unwrap() + == manifest_path.canonicalize().unwrap() + }) + .unwrap(); + + // Then go over all of its dependencies + let dependencies = root + .dependencies + .iter() + .map(|package| { + // Get the id for the package matching the version requirement of the dep + let id = &metadata + .packages + .iter() + .find(|&dep| dep.name == package.name && package.req.matches(&dep.version)) + .expect("dependency does not exist") + .id; + // Return the name chosen in `Cargo.toml` and the path to the corresponding artifact + ( + package.rename.clone().unwrap_or_else(|| package.name.clone()), + artifacts.remove(id).expect("package without artifact"), + ) + }) + .collect(); + let import_paths = import_paths.into_iter().collect(); + return Ok(Dependencies { dependencies, import_paths }); + } + + bail!("no json found in cargo-metadata output") +} diff --git a/ui_test/src/lib.rs b/ui_test/src/lib.rs index 917e382379a..4318e8a8e03 100644 --- a/ui_test/src/lib.rs +++ b/ui_test/src/lib.rs @@ -1,6 +1,7 @@ #![allow(clippy::enum_variant_names, clippy::useless_format, clippy::too_many_arguments)] use std::collections::VecDeque; +use std::ffi::OsString; use std::fmt::Write; use std::path::{Path, PathBuf}; use std::process::{Command, ExitStatus}; @@ -14,8 +15,10 @@ use regex::Regex; use rustc_stderr::{Level, Message}; +use crate::dependencies::build_dependencies; use crate::parser::{Comments, Condition}; +mod dependencies; mod parser; mod rustc_stderr; #[cfg(test)] @@ -24,7 +27,7 @@ #[derive(Debug)] pub struct Config { /// Arguments passed to the binary that is executed. - pub args: Vec, + pub args: Vec, /// `None` to run on the host, otherwise a target triple pub target: Option, /// Filters applied to stderr output before processing it @@ -38,6 +41,18 @@ pub struct Config { pub output_conflict_handling: OutputConflictHandling, /// Only run tests with one of these strings in their path/name pub path_filter: Vec, + /// Path to a `Cargo.toml` that describes which dependencies the tests can access. + pub dependencies_crate_manifest_path: Option, + /// Can be used to override what command to run instead of `cargo` to build the + /// dependencies in `manifest_path` + pub dependency_builder: Option, +} + +#[derive(Debug)] +pub struct DependencyBuilder { + pub program: PathBuf, + pub args: Vec, + pub envs: Vec<(String, String)>, } #[derive(Debug)] @@ -53,12 +68,26 @@ pub enum OutputConflictHandling { pub type Filter = Vec<(Regex, &'static str)>; -pub fn run_tests(config: Config) -> Result<()> { +pub fn run_tests(mut config: Config) -> Result<()> { eprintln!(" Compiler flags: {:?}", config.args); // Get the triple with which to run the tests let target = config.target.clone().unwrap_or_else(|| config.get_host()); + let dependencies = build_dependencies(&config)?; + for (name, dependency) in dependencies.dependencies { + config.args.push("--extern".into()); + let mut dep = OsString::from(name); + dep.push("="); + dep.push(dependency); + config.args.push(dep); + } + for import_path in dependencies.import_paths { + config.args.push("-L".into()); + config.args.push(import_path.into()); + } + let config = config; + // A channel for files to process let (submit, receive) = crossbeam::channel::unbounded(); @@ -294,9 +323,7 @@ fn run_test( for arg in &comments.compile_flags { miri.arg(arg); } - for (k, v) in &comments.env_vars { - miri.env(k, v); - } + miri.envs(comments.env_vars.iter().map(|(k, v)| (k, v))); let output = miri.output().expect("could not execute miri"); let mut errors = config.mode.ok(output.status); let stderr = check_test_result( diff --git a/ui_test/src/tests.rs b/ui_test/src/tests.rs index 96c0f362b67..8b0bd517a10 100644 --- a/ui_test/src/tests.rs +++ b/ui_test/src/tests.rs @@ -16,6 +16,8 @@ fn config() -> Config { path_filter: vec![], program: PathBuf::from("cake"), output_conflict_handling: OutputConflictHandling::Error, + dependencies_crate_manifest_path: None, + dependency_builder: None, } }