From 7d623f73cc5c592c703f68d8079f78055841e113 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 26 Nov 2018 15:31:53 +0100
Subject: [PATCH 01/18] do not use 'let _', it is strange

---
 tests/compile-fail-fullmir/ptr_offset_overflow.rs      | 2 +-
 tests/compile-fail/invalid_enum_discriminant.rs        | 2 +-
 tests/compile-fail/pointer_byte_read_1.rs              | 2 +-
 tests/compile-fail/pointer_byte_read_2.rs              | 2 +-
 tests/compile-fail/ptr_bitops2.rs                      | 2 +-
 tests/compile-fail/ptr_int_cast.rs                     | 2 +-
 tests/compile-fail/ptr_offset_int_plus_int.rs          | 2 +-
 tests/compile-fail/ptr_offset_int_plus_ptr.rs          | 2 +-
 tests/compile-fail/ptr_rem.rs                          | 2 +-
 tests/compile-fail/ptr_wrapping_offset_int_plus_ptr.rs | 2 +-
 tests/compile-fail/transmute_fat1.rs                   | 2 +-
 tests/compile-fail/validity/invalid_char.rs            | 2 +-
 tests/compile-fail/zst.rs                              | 2 +-
 tests/run-pass-fullmir/catch.rs                        | 2 +-
 tests/run-pass-fullmir/from_utf8.rs                    | 2 +-
 tests/run-pass-fullmir/threads.rs                      | 6 +++---
 tests/run-pass/closure-drop.rs                         | 2 +-
 tests/run-pass/drop_empty_slice.rs                     | 2 +-
 tests/run-pass/issue-20575.rs                          | 2 +-
 tests/run-pass/issue-26709.rs                          | 2 +-
 tests/run-pass/issue-33387.rs                          | 2 +-
 tests/run-pass/issue-miri-184.rs                       | 2 +-
 tests/run-pass/sendable-class.rs                       | 4 ++--
 tests/run-pass/slices.rs                               | 4 ++--
 24 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/tests/compile-fail-fullmir/ptr_offset_overflow.rs b/tests/compile-fail-fullmir/ptr_offset_overflow.rs
index 32ab2daebf0..babd0246e7e 100644
--- a/tests/compile-fail-fullmir/ptr_offset_overflow.rs
+++ b/tests/compile-fail-fullmir/ptr_offset_overflow.rs
@@ -2,5 +2,5 @@
 fn main() {
     let v = [1i8, 2];
     let x = &v[1] as *const i8;
-    let _ = unsafe { x.offset(isize::min_value()) };
+    let _val = unsafe { x.offset(isize::min_value()) };
 }
diff --git a/tests/compile-fail/invalid_enum_discriminant.rs b/tests/compile-fail/invalid_enum_discriminant.rs
index bd5cb55b6c9..c1b8727c129 100644
--- a/tests/compile-fail/invalid_enum_discriminant.rs
+++ b/tests/compile-fail/invalid_enum_discriminant.rs
@@ -12,5 +12,5 @@ pub enum Foo {
 
 fn main() {
     let f = unsafe { std::mem::transmute::<i32, Foo>(42) };
-    let _ = mem::discriminant(&f);
+    let _val = mem::discriminant(&f);
 }
diff --git a/tests/compile-fail/pointer_byte_read_1.rs b/tests/compile-fail/pointer_byte_read_1.rs
index b25f09d485f..a584863654c 100644
--- a/tests/compile-fail/pointer_byte_read_1.rs
+++ b/tests/compile-fail/pointer_byte_read_1.rs
@@ -3,5 +3,5 @@ fn main() {
     let y = &x;
     let z = &y as *const &i32 as *const usize;
     let ptr_bytes = unsafe { *z }; // the actual deref is fine, because we read the entire pointer at once
-    let _ = ptr_bytes / 432; //~ ERROR invalid arithmetic on pointers that would leak base addresses
+    let _val = ptr_bytes / 432; //~ ERROR invalid arithmetic on pointers that would leak base addresses
 }
diff --git a/tests/compile-fail/pointer_byte_read_2.rs b/tests/compile-fail/pointer_byte_read_2.rs
index 5df8c4782c7..ddb9bc1f995 100644
--- a/tests/compile-fail/pointer_byte_read_2.rs
+++ b/tests/compile-fail/pointer_byte_read_2.rs
@@ -3,5 +3,5 @@ fn main() {
     let y = &x;
     let z = &y as *const &i32 as *const u8;
     // the deref fails, because we are reading only a part of the pointer
-    let _ = unsafe { *z }; //~ ERROR tried to access part of a pointer value as raw bytes
+    let _val = unsafe { *z }; //~ ERROR tried to access part of a pointer value as raw bytes
 }
diff --git a/tests/compile-fail/ptr_bitops2.rs b/tests/compile-fail/ptr_bitops2.rs
index 233c9a733c9..5d5eab15508 100644
--- a/tests/compile-fail/ptr_bitops2.rs
+++ b/tests/compile-fail/ptr_bitops2.rs
@@ -1,5 +1,5 @@
 fn main() {
     let val = 13usize;
     let addr = &val as *const _ as usize;
-    let _ = addr & 13; //~ ERROR access part of a pointer value as raw bytes
+    let _val = addr & 13; //~ ERROR access part of a pointer value as raw bytes
 }
diff --git a/tests/compile-fail/ptr_int_cast.rs b/tests/compile-fail/ptr_int_cast.rs
index 576f0c333d1..a823a0f49b6 100644
--- a/tests/compile-fail/ptr_int_cast.rs
+++ b/tests/compile-fail/ptr_int_cast.rs
@@ -4,5 +4,5 @@ fn main() {
     let x = x as *const i32;
     let x = x as u8; //~ ERROR a raw memory access tried to access part of a pointer value as raw bytes
     let x = x as *const i32;
-    let _ = unsafe { *x };
+    let _val = unsafe { *x };
 }
diff --git a/tests/compile-fail/ptr_offset_int_plus_int.rs b/tests/compile-fail/ptr_offset_int_plus_int.rs
index fa4efa32365..d0273961081 100644
--- a/tests/compile-fail/ptr_offset_int_plus_int.rs
+++ b/tests/compile-fail/ptr_offset_int_plus_int.rs
@@ -3,6 +3,6 @@
 fn main() {
     // Can't offset an integer pointer by non-zero offset.
     unsafe {
-        let _ = (1 as *mut u8).offset(1);
+        let _val = (1 as *mut u8).offset(1);
     }
 }
diff --git a/tests/compile-fail/ptr_offset_int_plus_ptr.rs b/tests/compile-fail/ptr_offset_int_plus_ptr.rs
index b4554893580..b49c758c72f 100644
--- a/tests/compile-fail/ptr_offset_int_plus_ptr.rs
+++ b/tests/compile-fail/ptr_offset_int_plus_ptr.rs
@@ -4,6 +4,6 @@ fn main() {
     let ptr = Box::into_raw(Box::new(0u32));
     // Can't start with an integer pointer and get to something usable
     unsafe {
-        let _ = (1 as *mut u8).offset(ptr as isize);
+        let _val = (1 as *mut u8).offset(ptr as isize);
     }
 }
diff --git a/tests/compile-fail/ptr_rem.rs b/tests/compile-fail/ptr_rem.rs
index 8a3665872f7..dfc91e9dc1b 100644
--- a/tests/compile-fail/ptr_rem.rs
+++ b/tests/compile-fail/ptr_rem.rs
@@ -1,5 +1,5 @@
 fn main() {
     let val = 13usize;
     let addr = &val as *const _ as usize;
-    let _ = addr % 16; //~ ERROR access part of a pointer value as raw bytes
+    let _val = addr % 16; //~ ERROR access part of a pointer value as raw bytes
 }
diff --git a/tests/compile-fail/ptr_wrapping_offset_int_plus_ptr.rs b/tests/compile-fail/ptr_wrapping_offset_int_plus_ptr.rs
index b3dda27fad1..eacb9f07fff 100644
--- a/tests/compile-fail/ptr_wrapping_offset_int_plus_ptr.rs
+++ b/tests/compile-fail/ptr_wrapping_offset_int_plus_ptr.rs
@@ -4,5 +4,5 @@ fn main() {
     let ptr = Box::into_raw(Box::new(0u32));
     // Can't start with an integer pointer and get to something usable
     let ptr = (1 as *mut u8).wrapping_offset(ptr as isize);
-    let _ = unsafe { *ptr };
+    let _val = unsafe { *ptr };
 }
diff --git a/tests/compile-fail/transmute_fat1.rs b/tests/compile-fail/transmute_fat1.rs
index ede0486be41..ddc78c8bf1d 100644
--- a/tests/compile-fail/transmute_fat1.rs
+++ b/tests/compile-fail/transmute_fat1.rs
@@ -10,5 +10,5 @@ fn main() {
     let bad = unsafe {
         std::mem::transmute::<&[u8], [u8; 8]>(&[1u8])
     };
-    let _ = bad[0] + bad[bad.len()-1]; //~ ERROR a raw memory access tried to access part of a pointer value as raw bytes
+    let _val = bad[0] + bad[bad.len()-1]; //~ ERROR a raw memory access tried to access part of a pointer value as raw bytes
 }
diff --git a/tests/compile-fail/validity/invalid_char.rs b/tests/compile-fail/validity/invalid_char.rs
index 0d75ad9d289..a3f90703634 100644
--- a/tests/compile-fail/validity/invalid_char.rs
+++ b/tests/compile-fail/validity/invalid_char.rs
@@ -1,6 +1,6 @@
 fn main() {
     assert!(std::char::from_u32(-1_i32 as u32).is_none());
-    let _ = match unsafe { std::mem::transmute::<i32, char>(-1) } { //~ ERROR encountered 4294967295, but expected something less or equal to 1114111
+    let _val = match unsafe { std::mem::transmute::<i32, char>(-1) } { //~ ERROR encountered 4294967295, but expected something less or equal to 1114111
         'a' => {true},
         'b' => {false},
         _ => {true},
diff --git a/tests/compile-fail/zst.rs b/tests/compile-fail/zst.rs
index 544d65a1bff..0488926870a 100644
--- a/tests/compile-fail/zst.rs
+++ b/tests/compile-fail/zst.rs
@@ -1,4 +1,4 @@
 fn main() {
     let x = &() as *const () as *const i32;
-    let _ = unsafe { *x }; //~ ERROR access memory with alignment 1, but alignment 4 is required
+    let _val = unsafe { *x }; //~ ERROR access memory with alignment 1, but alignment 4 is required
 }
diff --git a/tests/run-pass-fullmir/catch.rs b/tests/run-pass-fullmir/catch.rs
index 960297daa7e..aa7bccaa5ff 100644
--- a/tests/run-pass-fullmir/catch.rs
+++ b/tests/run-pass-fullmir/catch.rs
@@ -3,6 +3,6 @@ use std::panic::{catch_unwind, AssertUnwindSafe};
 
 fn main() {
     let mut i = 3;
-    let _ = catch_unwind(AssertUnwindSafe(|| {i -= 2;} ));
+    let _val = catch_unwind(AssertUnwindSafe(|| {i -= 2;} ));
     println!("{}", i);
 }
diff --git a/tests/run-pass-fullmir/from_utf8.rs b/tests/run-pass-fullmir/from_utf8.rs
index 69e6c521af6..ce59e60a932 100644
--- a/tests/run-pass-fullmir/from_utf8.rs
+++ b/tests/run-pass-fullmir/from_utf8.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let _ = ::std::str::from_utf8(b"a");
+    let _val = ::std::str::from_utf8(b"a");
 }
diff --git a/tests/run-pass-fullmir/threads.rs b/tests/run-pass-fullmir/threads.rs
index f920bc52edd..dad47d85a24 100644
--- a/tests/run-pass-fullmir/threads.rs
+++ b/tests/run-pass-fullmir/threads.rs
@@ -5,15 +5,15 @@ use std::sync;
 
 fn main() {
     let m = sync::Mutex::new(0);
-    let _ = m.lock();
+    drop(m.lock());
     drop(m);
 
     // We don't provide RwLock on Windows
     #[cfg(not(target_os = "windows"))]
     {
         let rw = sync::RwLock::new(0);
-        let _ = rw.read();
-        let _ = rw.write();
+        drop(rw.read());
+        drop(rw.write());
         drop(rw);
     }
 }
diff --git a/tests/run-pass/closure-drop.rs b/tests/run-pass/closure-drop.rs
index f1bdafaeb13..374efb6032b 100644
--- a/tests/run-pass/closure-drop.rs
+++ b/tests/run-pass/closure-drop.rs
@@ -17,7 +17,7 @@ fn main() {
         // this closure never by val uses its captures
         // so it's basically a fn(&self)
         // the shim used to not drop the `x`
-        let x = move || { let _ = x; };
+        let x = move || { let _val = x; };
         f(x);
     }
     assert!(ran_drop);
diff --git a/tests/run-pass/drop_empty_slice.rs b/tests/run-pass/drop_empty_slice.rs
index b21c8a612c5..8b481a0a2dd 100644
--- a/tests/run-pass/drop_empty_slice.rs
+++ b/tests/run-pass/drop_empty_slice.rs
@@ -3,5 +3,5 @@
 fn main() {
     // With the nested Vec, this is calling Offset(Unique::empty(), 0) on drop.
     let args : Vec<Vec<i32>> = Vec::new();
-    let _ = box args;
+    let _val = box args;
 }
diff --git a/tests/run-pass/issue-20575.rs b/tests/run-pass/issue-20575.rs
index 137d84c256b..01371f5bec6 100644
--- a/tests/run-pass/issue-20575.rs
+++ b/tests/run-pass/issue-20575.rs
@@ -13,5 +13,5 @@
 fn main() {
     let functions: [Box<Fn() -> Option<()>>; 1] = [Box::new(|| None)];
 
-    let _: Option<Vec<()>> = functions.iter().map(|f| (*f)()).collect();
+    let _val: Option<Vec<()>> = functions.iter().map(|f| (*f)()).collect();
 }
diff --git a/tests/run-pass/issue-26709.rs b/tests/run-pass/issue-26709.rs
index 62626d75865..e29e5fbcc40 100644
--- a/tests/run-pass/issue-26709.rs
+++ b/tests/run-pass/issue-26709.rs
@@ -20,7 +20,7 @@ fn main() {
     let mut x = 0;
     {
         let wrapper = Box::new(Wrapper(&mut x, 123));
-        let _: Box<Wrapper<Send>> = wrapper;
+        let _val: Box<Wrapper<Send>> = wrapper;
     }
     assert_eq!(432, x)
 }
diff --git a/tests/run-pass/issue-33387.rs b/tests/run-pass/issue-33387.rs
index edbf2b81ce9..62a4263c106 100644
--- a/tests/run-pass/issue-33387.rs
+++ b/tests/run-pass/issue-33387.rs
@@ -15,5 +15,5 @@ trait Foo {}
 impl Foo for [u8; 2] {}
 
 fn main() {
-    let _: Arc<Foo + Send> = Arc::new([3, 4]);
+    let _val: Arc<Foo + Send> = Arc::new([3, 4]);
 }
diff --git a/tests/run-pass/issue-miri-184.rs b/tests/run-pass/issue-miri-184.rs
index 24775fe8a2d..39c841403ef 100644
--- a/tests/run-pass/issue-miri-184.rs
+++ b/tests/run-pass/issue-miri-184.rs
@@ -1,4 +1,4 @@
 pub fn main() {
     let bytes: [u8; 8] = unsafe { ::std::mem::transmute(0u64) };
-    let _: &[u8] = &bytes;
+    let _val: &[u8] = &bytes;
 }
diff --git a/tests/run-pass/sendable-class.rs b/tests/run-pass/sendable-class.rs
index 66f0c84e23c..3280c36e0a7 100644
--- a/tests/run-pass/sendable-class.rs
+++ b/tests/run-pass/sendable-class.rs
@@ -27,6 +27,6 @@ fn foo(i:isize, j: char) -> Foo {
 
 pub fn main() {
     let (tx, rx) = channel();
-    let _ = tx.send(foo(42, 'c'));
-    let _ = rx;
+    tx.send(foo(42, 'c')).unwrap();
+    let _val = rx;
 }
diff --git a/tests/run-pass/slices.rs b/tests/run-pass/slices.rs
index 45a2a74db08..4506a72e8dd 100644
--- a/tests/run-pass/slices.rs
+++ b/tests/run-pass/slices.rs
@@ -4,7 +4,7 @@ fn slice_of_zst() {
     fn foo<T>(v: &[T]) -> Option<&[T]> {
         let mut it = v.iter();
         for _ in 0..5 {
-            let _ = it.next();
+            it.next();
         }
         Some(it.as_slice())
     }
@@ -12,7 +12,7 @@ fn slice_of_zst() {
     fn foo_mut<T>(v: &mut [T]) -> Option<&mut [T]> {
         let mut it = v.iter_mut();
         for _ in 0..5 {
-            let _ = it.next();
+            it.next();
         }
         Some(it.into_slice())
     }

From 14d58ca8a90677e76908bcaa0df22e1ccbd5909f Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 15:44:28 +0100
Subject: [PATCH 02/18] fix clippy lint whitelisting

---
 src/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/lib.rs b/src/lib.rs
index 10a1405b2a6..78481979479 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,6 @@
 #![feature(rustc_private)]
 
-#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
+#![allow(clippy::cast_lossless)]
 
 #[macro_use]
 extern crate log;

From 6bd76c7ee1d81f97a797022c0f3cee01769d7178 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 16:08:24 +0100
Subject: [PATCH 03/18] cargo miri: factor package manifest logic into separate
 function

---
 Cargo.toml            |   1 +
 src/bin/cargo-miri.rs | 125 +++++++++++++++++++++++++-----------------
 2 files changed, 75 insertions(+), 51 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 94d13a83faf..84080538052 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,6 +42,7 @@ log = "0.4"
 vergen = "3"
 
 [features]
+default = ["cargo_miri"]
 cargo_miri = ["cargo_metadata"]
 rustc_tests = []
 
diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index da4a351368d..19296238e2b 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -1,3 +1,5 @@
+#![feature(inner_deref)]
+
 extern crate cargo_metadata;
 
 use std::path::{PathBuf, Path};
@@ -25,6 +27,13 @@ it to configure the resource limits
 available resource limits are `memory_size`, `step_limit`, `stack_limit`
 "#;
 
+#[derive(Copy, Clone, Debug)]
+enum MiriCommand {
+    Run,
+    Test,
+    Setup,
+}
+
 fn show_help() {
     println!("{}", CARGO_MIRI_HELP);
 }
@@ -34,6 +43,54 @@ fn show_version() {
         env!("CARGO_PKG_VERSION"), env!("VERGEN_SHA_SHORT"), env!("VERGEN_COMMIT_DATE"));
 }
 
+fn list_targets(mut args: impl Iterator<Item=String>) -> impl Iterator<Item=cargo_metadata::Target> {
+    // We need to get the manifest, and then the metadata, to enumerate targets.
+    let manifest_path_arg = args.find(|val| {
+        val.starts_with("--manifest-path=")
+    });
+
+    let mut metadata = if let Ok(metadata) = cargo_metadata::metadata(
+        manifest_path_arg.as_ref().map(AsRef::as_ref),
+    )
+    {
+        metadata
+    } else {
+        let _ = std::io::stderr().write_fmt(format_args!(
+            "error: Could not obtain cargo metadata."
+        ));
+        std::process::exit(101);
+    };
+
+    let manifest_path = manifest_path_arg.map(|arg| {
+        PathBuf::from(Path::new(&arg["--manifest-path=".len()..]))
+    });
+
+    let current_dir = std::env::current_dir();
+
+    let package_index = metadata
+        .packages
+        .iter()
+        .position(|package| {
+            let package_manifest_path = Path::new(&package.manifest_path);
+            if let Some(ref manifest_path) = manifest_path {
+                package_manifest_path == manifest_path
+            } else {
+                let current_dir = current_dir.as_ref().expect(
+                    "could not read current directory",
+                );
+                let package_manifest_directory = package_manifest_path.parent().expect(
+                    "could not find parent directory of package manifest",
+                );
+                package_manifest_directory == current_dir
+            }
+        })
+        .expect("could not find matching package");
+    let package = metadata.packages.remove(package_index);
+
+    // Finally we got the list of targets to build
+    package.targets.into_iter()
+}
+
 fn main() {
     // Check for version and help flags even when invoked as 'cargo-miri'
     if std::env::args().any(|a| a == "--help" || a == "-h") {
@@ -51,61 +108,27 @@ fn main() {
         // binary so that we come back in the other branch, and dispatch
         // the invocations to rustc and miri, respectively.
 
-        let test = std::env::args().nth(2).map_or(false, |text| text == "test");
-        let skip = if test { 3 } else { 2 };
-
-        // We need to get the manifest, and then the metadata, to enumerate targets.
-        let manifest_path_arg = std::env::args().skip(skip).find(|val| {
-            val.starts_with("--manifest-path=")
-        });
-
-        let mut metadata = if let Ok(metadata) = cargo_metadata::metadata(
-            manifest_path_arg.as_ref().map(AsRef::as_ref),
-        )
-        {
-            metadata
-        } else {
-            let _ = std::io::stderr().write_fmt(format_args!(
-                "error: Could not obtain cargo metadata."
-            ));
-            std::process::exit(101);
+        let (subcommand, skip) = match std::env::args().nth(2).deref() {
+            Some("test") => (MiriCommand::Test, 3),
+            Some("run") => (MiriCommand::Run, 3),
+            Some("setup") => (MiriCommand::Setup, 3),
+            // Default command, if there is an option or nothing
+            Some(s) if s.starts_with("-") => (MiriCommand::Run, 2),
+            None => (MiriCommand::Run, 2),
+            // Unvalid command
+            Some(s) => {
+                eprintln!("Unknown command `{}`", s);
+                std::process::exit(1)
+            }
         };
 
-        let manifest_path = manifest_path_arg.map(|arg| {
-            PathBuf::from(Path::new(&arg["--manifest-path=".len()..]))
-        });
-
-        let current_dir = std::env::current_dir();
-
-        let package_index = metadata
-            .packages
-            .iter()
-            .position(|package| {
-                let package_manifest_path = Path::new(&package.manifest_path);
-                if let Some(ref manifest_path) = manifest_path {
-                    package_manifest_path == manifest_path
-                } else {
-                    let current_dir = current_dir.as_ref().expect(
-                        "could not read current directory",
-                    );
-                    let package_manifest_directory = package_manifest_path.parent().expect(
-                        "could not find parent directory of package manifest",
-                    );
-                    package_manifest_directory == current_dir
-                }
-            })
-            .expect("could not find matching package");
-        let package = metadata.packages.remove(package_index);
-
-        // Finally we got the metadata, iterate all targets and see for which ones
-        // we do anything.
-        for target in package.targets {
+        for target in list_targets(std::env::args().skip(skip)) {
             let args = std::env::args().skip(skip);
             let kind = target.kind.get(0).expect(
                 "badly formatted cargo metadata: target::kind is an empty array",
             );
-            match (test, &kind[..]) {
-                (true, "test") => {
+            match (subcommand, &kind[..]) {
+                (MiriCommand::Test, "test") => {
                     // For test binaries we call `cargo rustc --test target -- <rustc args>`
                     if let Err(code) = process(
                         vec!["--test".to_string(), target.name].into_iter().chain(
@@ -116,7 +139,7 @@ fn main() {
                         std::process::exit(code);
                     }
                 }
-                (true, "lib") => {
+                (MiriCommand::Test, "lib") => {
                     // For libraries we call `cargo rustc -- --test <rustc args>`
                     // Notice now that `--test` is a rustc arg rather than a cargo arg. This tells
                     // rustc to build a test harness which calls all #[test] functions. We don't
@@ -131,7 +154,7 @@ fn main() {
                         std::process::exit(code);
                     }
                 }
-                (false, "bin") => {
+                (MiriCommand::Run, "bin") => {
                     // For ordinary binaries we call `cargo rustc --bin target -- <rustc args>`
                     if let Err(code) = process(
                         vec!["--bin".to_string(), target.name].into_iter().chain(

From c945e30d100a79a2d2c73358d54d7545d03093ac Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 16:30:11 +0100
Subject: [PATCH 04/18] setup routine to install xargo when missing

---
 src/bin/cargo-miri.rs | 58 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 53 insertions(+), 5 deletions(-)

diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index 19296238e2b..e39011db5ca 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -3,14 +3,19 @@
 extern crate cargo_metadata;
 
 use std::path::{PathBuf, Path};
-use std::io::Write;
+use std::io::{self, Write};
 use std::process::Command;
 
 
 const CARGO_MIRI_HELP: &str = r#"Interprets bin crates
 
 Usage:
-    cargo miri [options] [--] [<opts>...]
+    cargo miri [subcommand] [options] [--] [<opts>...]
+
+Subcommands:
+    run                      Run binaries (default)
+    test                     Run tests
+    setup                    Only perform automatic setup, but without asking questions (for getting a proper libstd)
 
 Common options:
     -h, --help               Print this message
@@ -27,7 +32,7 @@ it to configure the resource limits
 available resource limits are `memory_size`, `step_limit`, `stack_limit`
 "#;
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 enum MiriCommand {
     Run,
     Test,
@@ -43,6 +48,11 @@ fn show_version() {
         env!("CARGO_PKG_VERSION"), env!("VERGEN_SHA_SHORT"), env!("VERGEN_COMMIT_DATE"));
 }
 
+fn show_error(msg: String) -> ! {
+    eprintln!("fatal error: {}", msg);
+    std::process::exit(1)
+}
+
 fn list_targets(mut args: impl Iterator<Item=String>) -> impl Iterator<Item=cargo_metadata::Target> {
     // We need to get the manifest, and then the metadata, to enumerate targets.
     let manifest_path_arg = args.find(|val| {
@@ -91,6 +101,40 @@ fn list_targets(mut args: impl Iterator<Item=String>) -> impl Iterator<Item=carg
     package.targets.into_iter()
 }
 
+fn ask(question: &str) {
+    let mut buf = String::new();
+    print!("{} [Y/n] ", question);
+    io::stdout().flush().unwrap();
+    io::stdin().read_line(&mut buf).unwrap();
+    let answer = match buf.trim().to_lowercase().as_ref() {
+        "" | "y" | "yes" => true,
+        "n" | "no" => false,
+        a => show_error(format!("I do not understand `{}`", a))
+    };
+    if !answer {
+        show_error(format!("Aborting as per your request"))
+    }
+}
+
+/// Perform the setup requires to make `cargo miri` work: Getting a custom-built libstd. Then sets MIRI_SYSROOT.
+/// Skipped if MIRI_SYSROOT is already set, in that case we expect the user has done all this already.
+fn setup(ask_user: bool) {
+    if std::env::var("MIRI_SYSROOT").is_ok() {
+        return;
+    }
+
+    // First, we need xargo
+    if Command::new("xargo").arg("--version").output().is_err()
+    {
+        if ask_user {
+            ask("It seems you do not have xargo installed. I will run `cargo install xargo`. Proceed?");
+        }
+        if !Command::new("cargo").args(&["install", "xargo"]).status().unwrap().success() {
+            show_error(format!("Failed to install xargo"));
+        }
+    }
+}
+
 fn main() {
     // Check for version and help flags even when invoked as 'cargo-miri'
     if std::env::args().any(|a| a == "--help" || a == "-h") {
@@ -117,11 +161,15 @@ fn main() {
             None => (MiriCommand::Run, 2),
             // Unvalid command
             Some(s) => {
-                eprintln!("Unknown command `{}`", s);
-                std::process::exit(1)
+                show_error(format!("Unknown command `{}`", s))
             }
         };
 
+        // We always setup
+        let ask = subcommand != MiriCommand::Setup;
+        setup(ask);
+
+        // Now run the command.
         for target in list_targets(std::env::args().skip(skip)) {
             let args = std::env::args().skip(skip);
             let kind = target.kind.get(0).expect(

From 738133b379b172a37f8699085daff62b5a7d16a5 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 17:09:49 +0100
Subject: [PATCH 05/18] complete setup routine: instal rust-src, build libstd,
 use it

---
 Cargo.toml            |  3 ++-
 src/bin/cargo-miri.rs | 55 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 84080538052..111b47a551a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,6 +35,7 @@ required-features = ["rustc_tests"]
 [dependencies]
 byteorder = { version = "1.1", features = ["i128"]}
 cargo_metadata = { version = "0.6", optional = true }
+dirs = { version = "1.0.4", optional = true }
 env_logger = "0.5"
 log = "0.4"
 
@@ -43,7 +44,7 @@ vergen = "3"
 
 [features]
 default = ["cargo_miri"]
-cargo_miri = ["cargo_metadata"]
+cargo_miri = ["cargo_metadata", "dirs"]
 rustc_tests = []
 
 [dev-dependencies]
diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index e39011db5ca..1a5553ca109 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -5,7 +5,7 @@ extern crate cargo_metadata;
 use std::path::{PathBuf, Path};
 use std::io::{self, Write};
 use std::process::Command;
-
+use std::fs::{self, File};
 
 const CARGO_MIRI_HELP: &str = r#"Interprets bin crates
 
@@ -133,6 +133,59 @@ fn setup(ask_user: bool) {
             show_error(format!("Failed to install xargo"));
         }
     }
+
+    // Then, we also need rust-src.  Let's see if it is already installed.
+    let sysroot = Command::new("rustc").args(&["--print", "sysroot"]).output().unwrap().stdout;
+    let sysroot = std::str::from_utf8(&sysroot[..]).unwrap();
+    let src = Path::new(sysroot.trim_end_matches('\n')).join("lib/rustlib/src");
+    if !src.exists() {
+        println!("Could not find {:?}", src);
+        if ask_user {
+            ask("It seems you do not have the rust-src component installed. I will run `rustup component add rust-src`. Proceed?");
+        }
+        if !Command::new("rustup").args(&["component", "add", "rust-src"]).status().unwrap().success() {
+            show_error(format!("Failed to install rust-src component"));
+        }
+    }
+
+    // Next, we need our own libstd. We will do this work in ~/.miri.
+    let dir = dirs::home_dir().unwrap().join(".miri");
+    if !dir.exists() {
+        fs::create_dir(&dir).unwrap();
+    }
+    // The interesting bit: Xargo.toml
+    File::create(dir.join("Xargo.toml")).unwrap()
+        .write_all(br#"
+[dependencies.std]
+features = ["panic_unwind", "backtrace"]
+
+[dependencies.test]
+stage = 1
+        "#).unwrap();
+    // The boring bits: A dummy project for xargo
+    File::create(dir.join("Cargo.toml")).unwrap()
+        .write_all(br#"
+[package]
+name = "miri-xargo"
+description = "A dummy project for building libstd with xargo."
+version = "0.0.0"
+
+[lib]
+path = "lib.rs"
+        "#).unwrap();
+    File::create(dir.join("lib.rs")).unwrap();
+    // Run xargo
+    if !Command::new("xargo").arg("build")
+        .current_dir(&dir)
+        .env("RUSTFLAGS", miri::miri_default_args().join(" "))
+        .env("XARGO_HOME", dir.to_str().unwrap())
+        .status().unwrap().success()
+    {
+        show_error(format!("Failed to run xargo"));
+    }
+
+    // That should be it!
+    std::env::set_var("MIRI_SYSROOT", dir.join("HOST"));
 }
 
 fn main() {

From bb47df94ddf8620b10f18b528cb21b1b785f4226 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 17:17:21 +0100
Subject: [PATCH 06/18] use cargo miri setup for CI

---
 .travis.yml  |  8 +++-----
 appveyor.yml | 13 ++-----------
 2 files changed, 5 insertions(+), 16 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 85dd50cb5e3..e5a47a40a9b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -28,8 +28,6 @@ before_script:
 - rustup target add i686-unknown-linux-gnu
 - rustup target add i686-pc-windows-gnu
 - rustup target add i686-pc-windows-msvc
-- rustup component add rust-src
-- cargo install xargo || echo "Skipping xargo install"
 
 script:
 - set -e
@@ -39,9 +37,9 @@ script:
   cargo test --release --all-features &&
   cargo install --all-features --force --path .
 - |
-  # get ourselves a MIR-full libstd
-  xargo/build.sh &&
-  export MIRI_SYSROOT=~/.xargo/HOST
+  # starting here, use MIR-full libstd
+  cargo miri setup &&
+  export MIRI_SYSROOT=~/.miri/HOST
 - |
   # run all tests with full mir
   cargo test --release --all-features
diff --git a/appveyor.yml b/appveyor.yml
index 3dc47f1c67b..5757d1d2796 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -21,16 +21,6 @@ install:
     - rustup-init.exe -y --default-host %TARGET% --default-toolchain %RUST_TOOLCHAIN%
     - set PATH=%USERPROFILE%\.cargo\bin;%PATH%
     - rustc --version
-    # Customize installation.
-    - rustup component add rust-src
-    - cargo install xargo
-    # Prepare a libstd with MIR (cannot use bash script, obviously).
-    # The flags here should be kept in sync with `add_miri_default_args` in `src/lib.rs`.
-    - cd xargo
-    - set RUSTFLAGS=-Zalways-encode-mir -Zmir-emit-retag -Zmir-opt-level=0
-    - xargo build
-    - set RUSTFLAGS=
-    - cd ..
 
 build: false
 
@@ -39,7 +29,8 @@ test_script:
     - set RUST_BACKTRACE=1
     - cargo build --release --all-features --all-targets
     - cargo test --release --all-features
-    - set MIRI_SYSROOT=%USERPROFILE%\.xargo\HOST
+    - cargo run --release --all-features --bin cargo-miri -- miri setup
+    - set MIRI_SYSROOT=%USERPROFILE%\.miri\HOST
     - cargo test --release --all-features
 
 notifications:

From 16ac7ec1b1a7d07a1806d42e0f350580d537c121 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 17:30:50 +0100
Subject: [PATCH 07/18] tweak comments, remove debug output

---
 .travis.yml           | 6 +++---
 appveyor.yml          | 3 +++
 src/bin/cargo-miri.rs | 3 +--
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index e5a47a40a9b..9a8b8068900 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,7 +11,7 @@ os:
 - osx
 
 before_script:
-# macOS weirdness (https://github.com/travis-ci/travis-ci/issues/6307)
+# macOS weirdness (https://github.com/travis-ci/travis-ci/issues/6307, https://github.com/travis-ci/travis-ci/issues/10165)
 - if [[ "$TRAVIS_OS_NAME" == osx ]]; then rvm get stable; fi
 # Compute the rust version we use. We do not use "language: rust" to have more control here.
 - |
@@ -37,11 +37,11 @@ script:
   cargo test --release --all-features &&
   cargo install --all-features --force --path .
 - |
-  # starting here, use MIR-full libstd
+  # Get ourselves a MIR-full libstd
   cargo miri setup &&
   export MIRI_SYSROOT=~/.miri/HOST
 - |
-  # run all tests with full mir
+  # Test miri with full MIR
   cargo test --release --all-features
 - |
   # Test cargo integration
diff --git a/appveyor.yml b/appveyor.yml
index 5757d1d2796..4287a08613f 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -27,10 +27,13 @@ build: false
 test_script:
     - set RUSTFLAGS=-g
     - set RUST_BACKTRACE=1
+    # Test plain miri
     - cargo build --release --all-features --all-targets
     - cargo test --release --all-features
+    # Get ourselves a MIR-full libstd
     - cargo run --release --all-features --bin cargo-miri -- miri setup
     - set MIRI_SYSROOT=%USERPROFILE%\.miri\HOST
+    # Test miri with full MIR
     - cargo test --release --all-features
 
 notifications:
diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index 1a5553ca109..20d9e9ba71e 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -137,9 +137,8 @@ fn setup(ask_user: bool) {
     // Then, we also need rust-src.  Let's see if it is already installed.
     let sysroot = Command::new("rustc").args(&["--print", "sysroot"]).output().unwrap().stdout;
     let sysroot = std::str::from_utf8(&sysroot[..]).unwrap();
-    let src = Path::new(sysroot.trim_end_matches('\n')).join("lib/rustlib/src");
+    let src = Path::new(sysroot.trim_end_matches('\n')).join("lib").join("rustlib").join("src");
     if !src.exists() {
-        println!("Could not find {:?}", src);
         if ask_user {
             ask("It seems you do not have the rust-src component installed. I will run `rustup component add rust-src`. Proceed?");
         }

From cc4dd29f547ae96d6b6eb76441f166d7b3f734b7 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 18:27:24 +0100
Subject: [PATCH 08/18] kill xargo dir and update docs

---
 README.md                   | 76 +++++++++++--------------------------
 cargo-miri-test/run-test.py |  4 +-
 src/bin/cargo-miri.rs       |  2 +-
 xargo/Cargo.lock            |  4 --
 xargo/Cargo.toml            |  6 ---
 xargo/Xargo.toml            |  5 ---
 xargo/build.sh              |  4 --
 xargo/src/lib.rs            |  0
 8 files changed, 25 insertions(+), 76 deletions(-)
 delete mode 100644 xargo/Cargo.lock
 delete mode 100644 xargo/Cargo.toml
 delete mode 100644 xargo/Xargo.toml
 delete mode 100755 xargo/build.sh
 delete mode 100644 xargo/src/lib.rs

diff --git a/README.md b/README.md
index 5e5a7a23c6a..5dced653bb0 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ in this directory.
 
 [rustup]: https://www.rustup.rs
 
-## Running Miri
+## Running Miri on tiny examples
 
 ```sh
 cargo +nightly run -- -Zmiri-disable-validation tests/run-pass/vecs.rs # Or whatever test you like.
@@ -51,74 +51,42 @@ cargo +nightly run -- -Zmiri-disable-validation tests/run-pass/vecs.rs # Or what
 We have to disable validation because that can lead to errors when libstd is not
 compiled the right way.
 
-## Running Miri with full libstd
-
-Per default libstd does not contain the MIR of non-polymorphic functions, and
-also does not contain some extra MIR statements that miri needs for validation.
-When Miri hits a call to such a function, execution terminates, and even when
-the MIR is present, validation can fail.  To fix this, it is possible to compile
-libstd with full MIR:
-
-```sh
-rustup component add --toolchain nightly rust-src
-cargo +nightly install xargo
-rustup run nightly xargo/build.sh
-```
-
-Now you can run Miri against the libstd compiled by xargo:
-
-```sh
-MIRI_SYSROOT=~/.xargo/HOST cargo +nightly run tests/run-pass-fullmir/hashmap.rs
-```
-
-Notice that you will have to re-run the last step of the preparations above
-(`xargo/build.sh`) when your toolchain changes (e.g., when you update the
-nightly).
-
 ## Running Miri on your own project('s test suite)
 
-Install Miri as a cargo subcommand with `cargo +nightly install --all-features
---path .`.  Be aware that if you used `rustup override set` to fix a particular
-Rust version for the miri directory, that will *not* apply to your own project
-directory!  You have to use a consistent Rust version for building miri and your
-project for this to work, so remember to either always specify the nightly
-version manually, 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.
+Install Miri as a cargo subcommand with `cargo +nightly install --path .`.  Be
+aware that if you used `rustup override set` to fix a particular Rust version
+for the miri directory, that will *not* apply to your own project directory!
+You have to use a consistent Rust version for building miri and your project for
+this to work, so remember to either always specify the nightly version manually,
+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.
 
-We assume that you have prepared a MIR-enabled libstd as described above.  Now
-compile your project and its dependencies against that libstd:
-
-1. Run `cargo clean` to eliminate any cached dependencies that were built against
-the non-MIR `libstd`.
-2. To run all tests in your project through, Miri, use
-`MIRI_SYSROOT=~/.xargo/HOST 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
-`MIRI_SYSROOT=~/.xargo/HOST cargo +nightly 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`.
 
 ### Common Problems
 
 When using the above instructions, you may encounter a number of confusing compiler
 errors.
 
-#### "constant evaluation error: no mir for `<function>`"
-
-You may have forgotten to set `MIRI_SYSROOT` when calling `cargo miri`, and
-your program called into `std` or `core`. Be sure to set `MIRI_SYSROOT=~/.xargo/HOST`.
-
 #### "found possibly newer version of crate `std` which `<dependency>` depends on"
 
-Your build directory may contain artifacts from an earlier build that did/did not
-have `MIRI_SYSROOT` set. Run `cargo clean` before switching from non-Miri to Miri
-builds and vice-versa.
+Your build directory may contain artifacts from an earlier build that have/have
+not been built for Miri. Run `cargo clean` before switching from non-Miri to
+Miri builds and vice-versa.
 
 #### "found crate `std` compiled by an incompatible version of rustc"
 
 You may be running `cargo miri` with a different compiler version than the one
-used to build the MIR-enabled `std`. Be sure to consistently use the same toolchain,
-which should be the toolchain specified in the `rust-version` file.
+used to build the custom libstd that Miri uses, and Miri failed to detect that.
+Try deleting `~/.miri`.
 
 ## Miri `-Z` flags
 
diff --git a/cargo-miri-test/run-test.py b/cargo-miri-test/run-test.py
index f686cc47449..42745535e0e 100755
--- a/cargo-miri-test/run-test.py
+++ b/cargo-miri-test/run-test.py
@@ -8,10 +8,10 @@ and the working directory to contain the cargo-miri-test project.
 import sys, subprocess
 
 def test_cargo_miri():
-    print("==> Testing `cargo miri` <==")
+    print("==> Testing `cargo miri run` <==")
     ## Call `cargo miri`, capture all output
     p = subprocess.Popen(
-        ["cargo", "miri", "-q"],
+        ["cargo", "miri", "run", "-q"],
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE
     )
diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index 20d9e9ba71e..5b6ff084024 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -174,7 +174,7 @@ path = "lib.rs"
         "#).unwrap();
     File::create(dir.join("lib.rs")).unwrap();
     // Run xargo
-    if !Command::new("xargo").arg("build")
+    if !Command::new("xargo").arg("build").arg("-q")
         .current_dir(&dir)
         .env("RUSTFLAGS", miri::miri_default_args().join(" "))
         .env("XARGO_HOME", dir.to_str().unwrap())
diff --git a/xargo/Cargo.lock b/xargo/Cargo.lock
deleted file mode 100644
index c85820b708b..00000000000
--- a/xargo/Cargo.lock
+++ /dev/null
@@ -1,4 +0,0 @@
-[[package]]
-name = "miri-xargo"
-version = "0.0.0"
-
diff --git a/xargo/Cargo.toml b/xargo/Cargo.toml
deleted file mode 100644
index 9129c105b11..00000000000
--- a/xargo/Cargo.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-[package]
-name = "miri-xargo"
-description = "A dummy project for building libstd with xargo."
-version = "0.0.0"
-
-[dependencies]
diff --git a/xargo/Xargo.toml b/xargo/Xargo.toml
deleted file mode 100644
index e49b0dbe743..00000000000
--- a/xargo/Xargo.toml
+++ /dev/null
@@ -1,5 +0,0 @@
-[dependencies.std]
-features = ["panic_unwind", "backtrace"]
-
-[dependencies.test]
-stage = 1
diff --git a/xargo/build.sh b/xargo/build.sh
deleted file mode 100755
index 25c56d31ab5..00000000000
--- a/xargo/build.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-cd "$(dirname "$0")"
-# The flags here should be kept in sync with `add_miri_default_args` in `src/lib.rs`.
-RUSTFLAGS='-Zalways-encode-mir -Zmir-emit-retag -Zmir-opt-level=0' xargo build
diff --git a/xargo/src/lib.rs b/xargo/src/lib.rs
deleted file mode 100644
index e69de29bb2d..00000000000

From 9dd0048e665710fb29e967b3a96c7fbd9d66ee76 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 22:17:48 +0100
Subject: [PATCH 09/18] install directly from git repo

---
 README.md | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 5dced653bb0..d33b92f6de4 100644
--- a/README.md
+++ b/README.md
@@ -53,8 +53,13 @@ compiled the right way.
 
 ## Running Miri on your own project('s test suite)
 
-Install Miri as a cargo subcommand with `cargo +nightly install --path .`.  Be
-aware that if you used `rustup override set` to fix a particular Rust version
+Install Miri as a cargo subcommand:
+
+```sh
+cargo +nightly install --git https://github.com/solson/miri/
+```
+
+Be aware that if you used `rustup override set` to fix a particular Rust version
 for the miri directory, that will *not* apply to your own project directory!
 You have to use a consistent Rust version for building miri and your project for
 this to work, so remember to either always specify the nightly version manually,

From b09dfc14a0e9dc4ace798dbcf9d381159808406b Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 22:23:54 +0100
Subject: [PATCH 10/18] there are less places now to keep the flags in sync

---
 src/lib.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index 78481979479..d2ead2493c0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -54,8 +54,7 @@ pub use crate::stacked_borrows::{Borrow, Stack, Stacks, BorStackItem};
 /// set per default, for maximal validation power.
 pub fn miri_default_args() -> &'static [&'static str] {
     // The flags here should be kept in sync with what bootstrap adds when `test-miri` is
-    // set, which happens in `bootstrap/bin/rustc.rs` in the rustc sources; and also
-    // kept in sync with `xargo/build.sh` in this repo and `appveyor.yml`.
+    // set, which happens in `bootstrap/bin/rustc.rs` in the rustc sources.
     &["-Zalways-encode-mir", "-Zmir-emit-retag", "-Zmir-opt-level=0"]
 }
 

From 82caed1a483f3e02f9e92987b88a87751bde4552 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Nov 2018 22:29:25 +0100
Subject: [PATCH 11/18] cargo miri setup: print when we are executing commands

---
 src/bin/cargo-miri.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index 5b6ff084024..edc0d35fa8d 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -128,6 +128,8 @@ fn setup(ask_user: bool) {
     {
         if ask_user {
             ask("It seems you do not have xargo installed. I will run `cargo install xargo`. Proceed?");
+        } else {
+            println!("Installing xargo: `cargo install xargo`");
         }
         if !Command::new("cargo").args(&["install", "xargo"]).status().unwrap().success() {
             show_error(format!("Failed to install xargo"));
@@ -141,6 +143,8 @@ fn setup(ask_user: bool) {
     if !src.exists() {
         if ask_user {
             ask("It seems you do not have the rust-src component installed. I will run `rustup component add rust-src`. Proceed?");
+        } else {
+            println!("Installing rust-src component: `rustup component add rust-src`");
         }
         if !Command::new("rustup").args(&["component", "add", "rust-src"]).status().unwrap().success() {
             show_error(format!("Failed to install rust-src component"));

From 58982d655a3544486e8d827035e6acc4da1f0ccd Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 26 Nov 2018 08:37:31 +0100
Subject: [PATCH 12/18] remove unneeded backtrace feature

---
 src/bin/cargo-miri.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index edc0d35fa8d..28cc9f93084 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -160,7 +160,7 @@ fn setup(ask_user: bool) {
     File::create(dir.join("Xargo.toml")).unwrap()
         .write_all(br#"
 [dependencies.std]
-features = ["panic_unwind", "backtrace"]
+features = ["panic_unwind"]
 
 [dependencies.test]
 stage = 1

From 07f78a37d4e8d7c55330e90e0a36815bf615a8d9 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Nov 2018 08:16:52 +0100
Subject: [PATCH 13/18] tweaks

---
 Cargo.toml            |  4 ++--
 src/bin/cargo-miri.rs | 16 +++++-----------
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 111b47a551a..becb5c69e56 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,7 +35,7 @@ required-features = ["rustc_tests"]
 [dependencies]
 byteorder = { version = "1.1", features = ["i128"]}
 cargo_metadata = { version = "0.6", optional = true }
-dirs = { version = "1.0.4", optional = true }
+directories = { version = "1.0", optional = true }
 env_logger = "0.5"
 log = "0.4"
 
@@ -44,7 +44,7 @@ vergen = "3"
 
 [features]
 default = ["cargo_miri"]
-cargo_miri = ["cargo_metadata", "dirs"]
+cargo_miri = ["cargo_metadata", "directories"]
 rustc_tests = []
 
 [dev-dependencies]
diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index 28cc9f93084..05d1bf32208 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -65,10 +65,7 @@ fn list_targets(mut args: impl Iterator<Item=String>) -> impl Iterator<Item=carg
     {
         metadata
     } else {
-        let _ = std::io::stderr().write_fmt(format_args!(
-            "error: Could not obtain cargo metadata."
-        ));
-        std::process::exit(101);
+        show_error(format!("error: Could not obtain cargo metadata."));
     };
 
     let manifest_path = manifest_path_arg.map(|arg| {
@@ -106,14 +103,11 @@ fn ask(question: &str) {
     print!("{} [Y/n] ", question);
     io::stdout().flush().unwrap();
     io::stdin().read_line(&mut buf).unwrap();
-    let answer = match buf.trim().to_lowercase().as_ref() {
-        "" | "y" | "yes" => true,
-        "n" | "no" => false,
+    match buf.trim().to_lowercase().as_ref() {
+        "" | "y" | "yes" => {}, // proceed
+        "n" | "no" => show_error(format!("Aborting as per your request")),
         a => show_error(format!("I do not understand `{}`", a))
     };
-    if !answer {
-        show_error(format!("Aborting as per your request"))
-    }
 }
 
 /// Perform the setup requires to make `cargo miri` work: Getting a custom-built libstd. Then sets MIRI_SYSROOT.
@@ -152,7 +146,7 @@ fn setup(ask_user: bool) {
     }
 
     // Next, we need our own libstd. We will do this work in ~/.miri.
-    let dir = dirs::home_dir().unwrap().join(".miri");
+    let dir = directories::UserDirs::new().unwrap().home_dir().join(".miri");
     if !dir.exists() {
         fs::create_dir(&dir).unwrap();
     }

From b91679539e7fbbd4ee4bccbdb5de5589c77cc322 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Nov 2018 11:26:53 +0100
Subject: [PATCH 14/18] use proper platform cache dir

---
 src/bin/cargo-miri.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index 05d1bf32208..f06bb2d3723 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -145,8 +145,9 @@ fn setup(ask_user: bool) {
         }
     }
 
-    // Next, we need our own libstd. We will do this work in ~/.miri.
-    let dir = directories::UserDirs::new().unwrap().home_dir().join(".miri");
+    // Next, we need our own libstd. We will do this work in whatever is a good cache dir for this platform.
+    let dirs = directories::ProjectDirs::from("miri", "miri", "miri").unwrap();
+    let dir = dirs.cache_dir();
     if !dir.exists() {
         fs::create_dir(&dir).unwrap();
     }

From bd7f4076cdac11fb87629cc5aab1ba0fd77a806a Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Nov 2018 11:43:02 +0100
Subject: [PATCH 15/18] we need to recursively create the dir

---
 src/bin/cargo-miri.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index f06bb2d3723..fb1b97269aa 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -149,7 +149,7 @@ fn setup(ask_user: bool) {
     let dirs = directories::ProjectDirs::from("miri", "miri", "miri").unwrap();
     let dir = dirs.cache_dir();
     if !dir.exists() {
-        fs::create_dir(&dir).unwrap();
+        fs::create_dir_all(&dir).unwrap();
     }
     // The interesting bit: Xargo.toml
     File::create(dir.join("Xargo.toml")).unwrap()

From 53196554ec5c96f067611b96ffd3e1409274e4d0 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Nov 2018 12:08:46 +0100
Subject: [PATCH 16/18] inform the user when and where we are creating a cache
 dir

---
 src/bin/cargo-miri.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/bin/cargo-miri.rs b/src/bin/cargo-miri.rs
index fb1b97269aa..ed4ffa43dbc 100644
--- a/src/bin/cargo-miri.rs
+++ b/src/bin/cargo-miri.rs
@@ -149,6 +149,7 @@ fn setup(ask_user: bool) {
     let dirs = directories::ProjectDirs::from("miri", "miri", "miri").unwrap();
     let dir = dirs.cache_dir();
     if !dir.exists() {
+        println!("Creating `{}` and using it for miri's build of libstd", dir.display());
         fs::create_dir_all(&dir).unwrap();
     }
     // The interesting bit: Xargo.toml

From fbd7d119aecca4019467b2b191fcb1d88af2ed81 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Nov 2018 11:46:09 +0100
Subject: [PATCH 17/18] use new dir for CI and docs

---
 .travis.yml  | 8 ++++++--
 README.md    | 2 +-
 appveyor.yml | 4 ++--
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 9a8b8068900..ba3b8d36399 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,9 +37,13 @@ script:
   cargo test --release --all-features &&
   cargo install --all-features --force --path .
 - |
-  # Get ourselves a MIR-full libstd
+  # Get ourselves a MIR-full libstd, and use it henceforth
   cargo miri setup &&
-  export MIRI_SYSROOT=~/.miri/HOST
+  if [ "$TRAVIS_OS_NAME" == osx ]; then
+    export MIRI_SYSROOT=~/Library/Caches/miri.miri.miri/HOST
+  else
+    export MIRI_SYSROOT=~/.cache/miri/HOST
+  fi
 - |
   # Test miri with full MIR
   cargo test --release --all-features
diff --git a/README.md b/README.md
index d33b92f6de4..d6e0be40cac 100644
--- a/README.md
+++ b/README.md
@@ -91,7 +91,7 @@ Miri builds and vice-versa.
 
 You may be running `cargo miri` with a different compiler version than the one
 used to build the custom libstd that Miri uses, and Miri failed to detect that.
-Try deleting `~/.miri`.
+Try deleting `~/.cache/miri`.
 
 ## Miri `-Z` flags
 
diff --git a/appveyor.yml b/appveyor.yml
index 4287a08613f..1f38b848c00 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -30,9 +30,9 @@ test_script:
     # Test plain miri
     - cargo build --release --all-features --all-targets
     - cargo test --release --all-features
-    # Get ourselves a MIR-full libstd
+    # Get ourselves a MIR-full libstd, and use it henceforth
     - cargo run --release --all-features --bin cargo-miri -- miri setup
-    - set MIRI_SYSROOT=%USERPROFILE%\.miri\HOST
+    - set MIRI_SYSROOT=%USERPROFILE%\AppData\Local\miri\miri\cache\HOST
     # Test miri with full MIR
     - cargo test --release --all-features
 

From b72398de74161c0228d61501680ab653b9019b55 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Nov 2018 14:48:46 +0100
Subject: [PATCH 18/18] fix README install instructions

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d6e0be40cac..dcf13a8af4a 100644
--- a/README.md
+++ b/README.md
@@ -56,7 +56,7 @@ compiled the right way.
 Install Miri as a cargo subcommand:
 
 ```sh
-cargo +nightly install --git https://github.com/solson/miri/
+cargo +nightly install --git https://github.com/solson/miri/ miri
 ```
 
 Be aware that if you used `rustup override set` to fix a particular Rust version