summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-02-12 03:50:56 +0000
committerbors <bors@rust-lang.org>2018-02-12 03:50:56 +0000
commited2c0f08442915c628fc855e6a784c5979a4dc83 (patch)
tree40914f689409661abcd1df2f46797dd0203aced4 /src
parent03f456d3c3c4246868f3844e417d85b0488b2a31 (diff)
parent17d0d6a8b35241cd8d393ca746399a8cb6b6051a (diff)
downloadrust-ed2c0f08442915c628fc855e6a784c5979a4dc83.tar.gz
rust-ed2c0f08442915c628fc855e6a784c5979a4dc83.zip
Auto merge of #48146 - Mark-Simulacrum:beta-next, r=alexcrichton
[beta] Release notes, dist with time crate, and #48092

Backports of
 - #48092
 - #48013
 - #47286
 - #48144
Diffstat (limited to 'src')
-rw-r--r--src/Cargo.lock34
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/dist.rs6
-rw-r--r--src/bootstrap/lib.rs1
-rw-r--r--src/librustc/mir/tcx.rs5
-rw-r--r--src/librustc_mir/build/matches/mod.rs16
-rw-r--r--src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs28
-rw-r--r--src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs4
-rw-r--r--src/test/compile-fail/issue-47412.rs31
-rw-r--r--src/test/mir-opt/match_false_edges.rs107
-rw-r--r--src/tools/compiletest/src/runtest.rs10
11 files changed, 168 insertions, 75 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index a21ad12700b..56db3ad74a7 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -136,6 +136,7 @@ dependencies = [
  "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2584,6 +2585,16 @@ name = "tidy"
 version = "0.1.0"
 
 [[package]]
+name = "time"
+version = "0.1.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "toml"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2740,11 +2751,30 @@ version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "winapi"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "winapi-build"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "wincolor"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2980,6 +3010,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
 "checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
 "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
+"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
 "checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4"
 "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
@@ -3001,7 +3032,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
+"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 "checksum wincolor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a39ee4464208f6430992ff20154216ab2357772ac871d994c51628d60e58b8b0"
 "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
 "checksum xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5f04de8a1346489a2f9e9bd8526b73d135ec554227b17568456e86aa35b6f3fc"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index bbbbf0e1915..2d478341317 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -41,3 +41,4 @@ serde_derive = "1.0.8"
 serde_json = "1.0.2"
 toml = "0.4"
 lazy_static = "0.2"
+time = "0.1"
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 57f0cde574a..f011069a700 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -33,6 +33,7 @@ use builder::{Builder, RunConfig, ShouldRun, Step};
 use compile;
 use tool::{self, Tool};
 use cache::{INTERNER, Interned};
+use time;
 
 pub fn pkgname(build: &Build, component: &str) -> String {
     if component == "cargo" {
@@ -436,8 +437,7 @@ impl Step for Rustc {
             t!(fs::create_dir_all(image.join("share/man/man1")));
             let man_src = build.src.join("src/doc/man");
             let man_dst = image.join("share/man/man1");
-            let date_output = output(Command::new("date").arg("+%B %Y"));
-            let month_year = date_output.trim();
+            let month_year = t!(time::strftime("%B %Y", &time::now()));
             // don't use our `bootstrap::util::{copy, cp_r}`, because those try
             // to hardlink, and we don't want to edit the source templates
             for entry_result in t!(fs::read_dir(man_src)) {
@@ -447,7 +447,7 @@ impl Step for Rustc {
                 t!(fs::copy(&page_src, &page_dst));
                 // template in month/year and version number
                 replace_in_file(&page_dst,
-                                &[("<INSERT DATE HERE>", month_year),
+                                &[("<INSERT DATE HERE>", &month_year),
                                   ("<INSERT VERSION HERE>", channel::CFG_RELEASE_NUM)]);
             }
 
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index ae53c054e41..63a9c3ab905 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -130,6 +130,7 @@ extern crate cc;
 extern crate getopts;
 extern crate num_cpus;
 extern crate toml;
+extern crate time;
 
 #[cfg(unix)]
 extern crate libc;
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 23f360d5c39..c7b26d97da8 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -182,9 +182,8 @@ impl<'tcx> Rvalue<'tcx> {
                 if let ty::TyAdt(adt_def, _) = ty.sty {
                     adt_def.repr.discr_type().to_ty(tcx)
                 } else {
-                    // Undefined behaviour, bug for now; may want to return something for
-                    // the `discriminant` intrinsic later.
-                    bug!("Rvalue::Discriminant on Place of type {:?}", ty);
+                    // This can only be `0`, for now, so `u8` will suffice.
+                    tcx.types.u8
                 }
             }
             Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 6cb92177766..6b0b5b0ab9e 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -38,6 +38,22 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                       -> BlockAnd<()> {
         let discriminant_place = unpack!(block = self.as_place(block, discriminant));
 
+        // Matching on a `discriminant_place` with an uninhabited type doesn't
+        // generate any memory reads by itself, and so if the place "expression"
+        // contains unsafe operations like raw pointer dereferences or union
+        // field projections, we wouldn't know to require an `unsafe` block
+        // around a `match` equivalent to `std::intrinsics::unreachable()`.
+        // See issue #47412 for this hole being discovered in the wild.
+        //
+        // HACK(eddyb) Work around the above issue by adding a dummy inspection
+        // of `discriminant_place`, specifically by applying `Rvalue::Discriminant`
+        // (which will work regardless of type) and storing the result in a temp.
+        let dummy_source_info = self.source_info(span);
+        let dummy_access = Rvalue::Discriminant(discriminant_place.clone());
+        let dummy_ty = dummy_access.ty(&self.local_decls, self.hir.tcx());
+        let dummy_temp = self.temp(dummy_ty, dummy_source_info.span);
+        self.cfg.push_assign(block, dummy_source_info, &dummy_temp, dummy_access);
+
         let mut arm_blocks = ArmBlocks {
             blocks: arms.iter()
                         .map(|_| self.cfg.start_new_block())
diff --git a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
index 062cc976a3d..1d08b807465 100644
--- a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
+++ b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
@@ -72,7 +72,7 @@ fn main() {
     {
         let mut e = Baz::X(2);
         let _e0 = e.x();
-        match e {
+        match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
             Baz::X(value) => value
             //[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed
             //[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed
@@ -110,7 +110,7 @@ fn main() {
     {
         let mut e = Box::new(Baz::X(3));
         let _e0 = e.x();
-        match *e {
+        match *e { //[mir]~ ERROR cannot use `*e` because it was mutably borrowed
             Baz::X(value) => value
             //[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed
             //[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed
@@ -127,25 +127,25 @@ fn main() {
     {
         let mut v = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
         let _v = &mut v;
-        match v {
+        match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[x, _, .., _, _] => println!("{}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
                             _ => panic!("other case"),
         }
-        match v {
+        match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[_, x, .., _, _] => println!("{}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
                             _ => panic!("other case"),
         }
-        match v {
+        match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[_, _, .., x, _] => println!("{}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
                             _ => panic!("other case"),
         }
-        match v {
+        match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[_, _, .., _, x] => println!("{}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
@@ -156,25 +156,25 @@ fn main() {
     {
         let mut v = &[1, 2, 3, 4, 5];
         let _v = &mut v;
-        match v {
+        match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[x..] => println!("{:?}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
             _ => panic!("other case"),
         }
-        match v {
+        match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[_, x..] => println!("{:?}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
             _ => panic!("other case"),
         }
-        match v {
+        match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[x.., _] => println!("{:?}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
             _ => panic!("other case"),
         }
-        match v {
+        match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[_, x.., _] => println!("{:?}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
@@ -187,7 +187,7 @@ fn main() {
 
         let mut e = E::A(3);
         let _e = &mut e;
-        match e {
+        match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
             E::A(ref ax) =>
                 //[ast]~^ ERROR cannot borrow `e.0` as immutable because `e` is also borrowed as mutable
                 //[mir]~^^ ERROR cannot borrow `e.0` as immutable because it is also borrowed as mutable
@@ -205,14 +205,14 @@ fn main() {
         struct S { x: F, y: (u32, u32), };
         let mut s = S { x: F { x: 1, y: 2}, y: (999, 998) };
         let _s = &mut s;
-        match s {
+        match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
             S  { y: (ref y0, _), .. } =>
                 //[ast]~^ ERROR cannot borrow `s.y.0` as immutable because `s` is also borrowed as mutable
                 //[mir]~^^ ERROR cannot borrow `s.y.0` as immutable because it is also borrowed as mutable
                 println!("y0: {:?}", y0),
             _ => panic!("other case"),
         }
-        match s {
+        match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
             S  { x: F { y: ref x0, .. }, .. } =>
                 //[ast]~^ ERROR cannot borrow `s.x.y` as immutable because `s` is also borrowed as mutable
                 //[mir]~^^ ERROR cannot borrow `s.x.y` as immutable because it is also borrowed as mutable
@@ -263,7 +263,7 @@ fn main() {
         struct F {x: u32, y: u32};
         let mut v = &[F{x: 1, y: 2}, F{x: 3, y: 4}];
         let _v = &mut v;
-        match v {
+        match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[_, F {x: ref xf, ..}] => println!("{}", xf),
             //[mir]~^ ERROR cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
             // No errors in AST
diff --git a/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs b/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs
index 4336812af9b..3e57ac0ca19 100644
--- a/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs
+++ b/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs
@@ -19,7 +19,7 @@ enum Foo {
 fn match_enum() {
     let mut foo = Foo::B;
     let p = &mut foo;
-    let _ = match foo {
+    let _ = match foo { //[mir]~ ERROR [E0503]
         Foo::B => 1, //[mir]~ ERROR [E0503]
         _ => 2,
         Foo::A(x) => x //[ast]~ ERROR [E0503]
@@ -31,7 +31,7 @@ fn match_enum() {
 fn main() {
     let mut x = 1;
     let _x = &mut x;
-    let _ = match x {
+    let _ = match x { //[mir]~ ERROR [E0503]
         x => x + 1, //[ast]~ ERROR [E0503]
                     //[mir]~^ ERROR [E0503]
         y => y + 2, //[ast]~ ERROR [E0503]
diff --git a/src/test/compile-fail/issue-47412.rs b/src/test/compile-fail/issue-47412.rs
new file mode 100644
index 00000000000..7481befcb79
--- /dev/null
+++ b/src/test/compile-fail/issue-47412.rs
@@ -0,0 +1,31 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[derive(Copy, Clone)]
+enum Void {}
+
+// Tests that we detect unsafe places (specifically, union fields and
+// raw pointer dereferences), even when they're matched on while having
+// an uninhabited type (equivalent to `std::intrinsics::unreachable()`).
+
+fn union_field() {
+    union Union { unit: (), void: Void }
+    let u = Union { unit: () };
+    match u.void {}
+    //~^ ERROR access to union field requires unsafe function or block
+}
+
+fn raw_ptr_deref() {
+    let ptr = std::ptr::null::<Void>();
+    match *ptr {}
+    //~^ ERROR dereference of raw pointer requires unsafe function or block
+}
+
+fn main() {}
diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs
index 1f892b0f958..ba1b54d59f6 100644
--- a/src/test/mir-opt/match_false_edges.rs
+++ b/src/test/mir-opt/match_false_edges.rs
@@ -53,17 +53,18 @@ fn main() {
 //  bb0: {
 //      ...
 //      _2 = std::option::Option<i32>::Some(const 42i32,);
-//      _5 = discriminant(_2);
-//      switchInt(move _5) -> [0isize: bb6, 1isize: bb4, otherwise: bb8];
+//      _3 = discriminant(_2);
+//      _6 = discriminant(_2);
+//      switchInt(move _6) -> [0isize: bb6, 1isize: bb4, otherwise: bb8];
 //  }
 //  bb1: {
 //      resume;
 //  }
 //  bb2: {  // arm1
-//      StorageLive(_7);
-//      _7 = _3;
-//      _1 = (const 1i32, move _7);
-//      StorageDead(_7);
+//      StorageLive(_8);
+//      _8 = _4;
+//      _1 = (const 1i32, move _8);
+//      StorageDead(_8);
 //      goto -> bb13;
 //  }
 //  bb3: { // binding3(empty) and arm3
@@ -86,24 +87,24 @@ fn main() {
 //      unreachable;
 //  }
 //  bb9: { // binding1 and guard
-//      StorageLive(_3);
-//      _3 = ((_2 as Some).0: i32);
-//      StorageLive(_6);
-//      _6 = const guard() -> [return: bb10, unwind: bb1];
+//      StorageLive(_4);
+//      _4 = ((_2 as Some).0: i32);
+//      StorageLive(_7);
+//      _7 = const guard() -> [return: bb10, unwind: bb1];
 //  }
 //  bb10: { // end of guard
-//      switchInt(move _6) -> [0u8: bb11, otherwise: bb2];
+//      switchInt(move _7) -> [0u8: bb11, otherwise: bb2];
 //  }
 //  bb11: { // to pre_binding2
 //      falseEdges -> [real: bb5, imaginary: bb5];
 //  }
 //  bb12: { // bindingNoLandingPads.before.mir2 and arm2
-//      StorageLive(_4);
-//      _4 = ((_2 as Some).0: i32);
-//      StorageLive(_8);
-//      _8 = _4;
-//      _1 = (const 2i32, move _8);
-//      StorageDead(_8);
+//      StorageLive(_5);
+//      _5 = ((_2 as Some).0: i32);
+//      StorageLive(_9);
+//      _9 = _5;
+//      _1 = (const 2i32, move _9);
+//      StorageDead(_9);
 //      goto -> bb13;
 //  }
 //  bb13: {
@@ -116,17 +117,18 @@ fn main() {
 //  bb0: {
 //      ...
 //      _2 = std::option::Option<i32>::Some(const 42i32,);
-//      _5 = discriminant(_2);
-//      switchInt(move _5) -> [0isize: bb5, 1isize: bb4, otherwise: bb8];
+//      _3 = discriminant(_2);
+//      _6 = discriminant(_2);
+//      switchInt(move _6) -> [0isize: bb5, 1isize: bb4, otherwise: bb8];
 //  }
 //  bb1: {
 //      resume;
 //  }
 //  bb2: { // arm1
-//      StorageLive(_7);
-//      _7 = _3;
-//      _1 = (const 1i32, move _7);
-//      StorageDead(_7);
+//      StorageLive(_8);
+//      _8 = _4;
+//      _1 = (const 1i32, move _8);
+//      StorageDead(_8);
 //      goto -> bb13;
 //  }
 //  bb3: { // binding3(empty) and arm3
@@ -149,24 +151,24 @@ fn main() {
 //      unreachable;
 //  }
 //  bb9: { // binding1 and guard
-//      StorageLive(_3);
-//      _3 = ((_2 as Some).0: i32);
-//      StorageLive(_6);
-//      _6 = const guard() -> [return: bb10, unwind: bb1];
+//      StorageLive(_4);
+//      _4 = ((_2 as Some).0: i32);
+//      StorageLive(_7);
+//      _7 = const guard() -> [return: bb10, unwind: bb1];
 //  }
 //  bb10: { // end of guard
-//      switchInt(move _6) -> [0u8: bb11, otherwise: bb2];
+//      switchInt(move _7) -> [0u8: bb11, otherwise: bb2];
 //  }
 //  bb11: { // to pre_binding2
 //      falseEdges -> [real: bb6, imaginary: bb5];
 //  }
 //  bb12: { // binding2 and arm2
-//      StorageLive(_4);
-//      _4 = ((_2 as Some).0: i32);
-//      StorageLive(_8);
-//      _8 = _4;
-//      _1 = (const 2i32, move _8);
-//      StorageDead(_8);
+//      StorageLive(_5);
+//      _5 = ((_2 as Some).0: i32);
+//      StorageLive(_9);
+//      _9 = _5;
+//      _1 = (const 2i32, move _9);
+//      StorageDead(_9);
 //      goto -> bb13;
 //  }
 //  bb13: {
@@ -179,8 +181,9 @@ fn main() {
 // bb0: {
 //     ...
 //     _2 = std::option::Option<i32>::Some(const 1i32,);
-//     _7 = discriminant(_2);
-//     switchInt(move _7) -> [1isize: bb4, otherwise: bb5];
+//     _3 = discriminant(_2);
+//     _8 = discriminant(_2);
+//     switchInt(move _8) -> [1isize: bb4, otherwise: bb5];
 // }
 // bb1: {
 //     resume;
@@ -210,41 +213,41 @@ fn main() {
 //     unreachable;
 // }
 // bb9: { // binding1: Some(w) if guard()
-//     StorageLive(_3);
-//     _3 = ((_2 as Some).0: i32);
-//     StorageLive(_8);
-//     _8 = const guard() -> [return: bb10, unwind: bb1];
+//     StorageLive(_4);
+//     _4 = ((_2 as Some).0: i32);
+//     StorageLive(_9);
+//     _9 = const guard() -> [return: bb10, unwind: bb1];
 // }
 // bb10: { //end of guard
-//    switchInt(move _8) -> [0u8: bb11, otherwise: bb2];
+//    switchInt(move _9) -> [0u8: bb11, otherwise: bb2];
 // }
 // bb11: { // to pre_binding2
 //     falseEdges -> [real: bb5, imaginary: bb5];
 // }
 // bb12: { // binding2 & arm2
-//     StorageLive(_4);
-//     _4 = _2;
+//     StorageLive(_5);
+//     _5 = _2;
 //     _1 = const 2i32;
 //     goto -> bb17;
 // }
 // bb13: { // binding3: Some(y) if guard2(y)
-//     StorageLive(_5);
-//     _5 = ((_2 as Some).0: i32);
-//     StorageLive(_10);
+//     StorageLive(_6);
+//     _6 = ((_2 as Some).0: i32);
 //     StorageLive(_11);
-//     _11 = _5;
-//     _10 = const guard2(move _11) -> [return: bb14, unwind: bb1];
+//     StorageLive(_12);
+//     _12 = _6;
+//     _11 = const guard2(move _12) -> [return: bb14, unwind: bb1];
 // }
 // bb14: { // end of guard2
-//     StorageDead(_11);
-//     switchInt(move _10) -> [0u8: bb15, otherwise: bb3];
+//     StorageDead(_12);
+//     switchInt(move _11) -> [0u8: bb15, otherwise: bb3];
 // }
 // bb15: { // to pre_binding4
 //     falseEdges -> [real: bb7, imaginary: bb7];
 // }
 // bb16: { // binding4 & arm4
-//     StorageLive(_6);
-//     _6 = _2;
+//     StorageLive(_7);
+//     _7 = _2;
 //     _1 = const 4i32;
 //     goto -> bb17;
 // }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 25605cebba0..7612b2d6e81 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1255,7 +1255,7 @@ impl<'test> TestCx<'test> {
     fn exec_compiled_test(&self) -> ProcRes {
         let env = &self.props.exec_env;
 
-        match &*self.config.target {
+        let proc_res = match &*self.config.target {
             // This is pretty similar to below, we're transforming:
             //
             //      program arg1 arg2
@@ -1310,7 +1310,15 @@ impl<'test> TestCx<'test> {
                     None,
                 )
             }
+        };
+
+        if proc_res.status.success() {
+            // delete the executable after running it to save space.
+            // it is ok if the deletion failed.
+            let _ = fs::remove_file(self.make_exe_name());
         }
+
+        proc_res
     }
 
     /// For each `aux-build: foo/bar` annotation, we check to find the