diff --git a/.travis.yml b/.travis.yml index dfc4238a6c..51b14a1b34 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,3 +38,4 @@ branches: env: global: - RUST_TEST_NOCAPTURE=1 + - RUST_BACKTRACE=1 diff --git a/README.md b/README.md index b6e1c20076..5a615e656d 100644 --- a/README.md +++ b/README.md @@ -39,17 +39,28 @@ example above), overriding it in your project directory as well, or use `rustup default nightly` (or `rustup default nightly-YYYY-MM-DD`) to globally make `nightly` the default toolchain. -Now you can run your project in miri: +Now you can run your project in Miri: 1. Run `cargo clean` to eliminate any cached dependencies. Miri needs your dependencies to be compiled the right way, that would not happen if they have previously already been compiled. 2. To run all tests in your project through Miri, use `cargo +nightly miri test`. - **NOTE**: This is currently broken, see the discussion in - [#479](https://github.com/solson/miri/issues/479). 3. If you have a binary project, you can run it through Miri using `cargo +nightly miri run`. +When running code via `cargo miri`, the `cargo-miri` feature is set. You can +use this to exclude test cases that will fail under Miri because they do things +Miri does not support: + +```rust +#[cfg(not(feature = "cargo-miri"))] +#[test] +fn does_not_work_on_miri() { + let x = 0u8; + assert!(&x as *const _ as usize % 4 < 4); +} +``` + ### Common Problems When using the above instructions, you may encounter a number of confusing compiler diff --git a/appveyor.yml b/appveyor.yml index 4f4aebd807..09040ed42a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -25,7 +25,7 @@ install: build: false test_script: - - set RUSTFLAGS=-g + - set RUST_TEST_NOCAPTURE=1 - set RUST_BACKTRACE=1 # Build miri - cargo build --release --all-features --all-targets diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs index 0a8ddd95a7..21cc7ee0e3 100644 --- a/src/bin/cargo-miri.rs +++ b/src/bin/cargo-miri.rs @@ -123,8 +123,14 @@ fn xargo_version() -> Option<(u32, u32, u32)> { let line = out.stderr.lines().nth(0) .expect("malformed `xargo --version` output: not at least one line") .expect("malformed `xargo --version` output: error reading first line"); - let version = line.split(' ').nth(1) - .expect("malformed `xargo --version` output: not at least two words"); + let (name, version) = { + let mut split = line.split(' '); + (split.next().expect("malformed `xargo --version` output: empty"), + split.next().expect("malformed `xargo --version` output: not at least two words")) + }; + if name != "xargo" { + panic!("malformed `xargo --version` output: application name is not `xargo`"); + } let mut version_pieces = version.split('.'); let major = version_pieces.next() .expect("malformed `xargo --version` output: not a major version piece") @@ -414,8 +420,6 @@ where args.push("--".to_owned()); } args.push("--emit=dep-info,metadata".to_owned()); - args.push("--cfg".to_owned()); - args.push(r#"feature="cargo-miri""#.to_owned()); let path = std::env::current_exe().expect("current executable path invalid"); let exit_status = Command::new("cargo") diff --git a/src/fn_call.rs b/src/fn_call.rs index ab82223f23..ab38270724 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -398,7 +398,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, Err(_) => -1, } } else { - warn!("Ignored output to FD {}", fd); + eprintln!("Miri: Ignored output to FD {}", fd); n as i64 // pretend it all went well }; // now result is the value we return back to the program this.write_scalar( diff --git a/test-cargo-miri/run-test.py b/test-cargo-miri/run-test.py index 19e0a14740..7f7f2660c0 100755 --- a/test-cargo-miri/run-test.py +++ b/test-cargo-miri/run-test.py @@ -7,6 +7,10 @@ import sys, subprocess +def fail(msg): + print("TEST FAIL: {}".format(msg)) + sys.exit(1) + def test(name, cmd, stdout_ref, stderr_ref): print("==> Testing `{}` <==".format(name)) ## Call `cargo miri`, capture all output @@ -25,13 +29,11 @@ def test(name, cmd, stdout_ref, stderr_ref): print(stderr, end="") # Test for failures if p.returncode != 0: - sys.exit(1) + fail("Non-zero exit status") if stdout != open(stdout_ref).read(): - print("stdout does not match reference") - sys.exit(1) + fail("stdout does not match reference") if stderr != open(stderr_ref).read(): - print("stderr does not match reference") - sys.exit(1) + fail("stderr does not match reference") def test_cargo_miri_run(): test("cargo miri run", ["cargo", "miri", "run", "-q"], "stdout.ref", "stderr.ref") diff --git a/test-cargo-miri/tests/foo.rs b/test-cargo-miri/tests/foo.rs index 9827ae82d6..bd7b2c569a 100644 --- a/test-cargo-miri/tests/foo.rs +++ b/test-cargo-miri/tests/foo.rs @@ -9,3 +9,11 @@ fn bar() { fn baz() { assert_eq!(5, 5); } + +// A test that won't work on miri +#[cfg(not(feature = "cargo-miri"))] +#[test] +fn does_not_work_on_miri() { + let x = 0u8; + assert!(&x as *const _ as usize % 4 < 4); +}