about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-07-07 03:55:28 +0000
committerbors <bors@rust-lang.org>2018-07-07 03:55:28 +0000
commit4f0ca9248f93162201ea88a99594deedf0ebd897 (patch)
treef60c4cc897ab197b4e2128f7160d54421db8ca06 /src
parent99b0ddb88a3e6aa5ddec35961be845ff361d031e (diff)
parentcd7ddae695fca0aac2f10b5eeaa3af4612cddf23 (diff)
downloadrust-4f0ca9248f93162201ea88a99594deedf0ebd897.tar.gz
rust-4f0ca9248f93162201ea88a99594deedf0ebd897.zip
Auto merge of #52123 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 9 pull requests

Successful merges:

 - #51901 (Rc: remove unused allocation and fix segfault in Weak::new())
 - #52058 (Use of unimplemented!() causing ICE with NLL)
 - #52067 (Visit the mir basic blocks in reverse-postfix order)
 - #52083 (Dont run ast borrowck on mir mode)
 - #52099 (fix typo in stable `--edition` error message)
 - #52103 (Stabilize rc_downcast)
 - #52104 (Remove unnecessary feature gate.)
 - #52117 (Dedupe filetime)
 - #52120 (ARM: expose the "mclass" target feature)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/Cargo.lock23
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/liballoc/rc.rs67
-rw-r--r--src/liballoc/sync.rs48
-rw-r--r--src/liballoc/tests/arc.rs55
-rw-r--r--src/liballoc/tests/lib.rs2
-rw-r--r--src/liballoc/tests/rc.rs55
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc/ty/context.rs6
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs2
-rw-r--r--src/librustc_codegen_llvm/llvm_util.rs1
-rw-r--r--src/librustc_driver/driver.rs6
-rw-r--r--src/librustc_mir/borrow_check/borrow_set.rs66
-rw-r--r--src/librustc_mir/borrow_check/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/path_utils.rs10
-rw-r--r--src/librustc_mir/dataflow/mod.rs3
-rw-r--r--src/librustc_mir/transform/mod.rs5
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs2
-rw-r--r--src/test/compile-fail/mir-dataflow/def-inits-1.rs2
-rw-r--r--src/test/compile-fail/mir-dataflow/inits-1.rs2
-rw-r--r--src/test/compile-fail/mir-dataflow/uninits-1.rs2
-rw-r--r--src/test/compile-fail/mir-dataflow/uninits-2.rs2
-rw-r--r--src/test/run-fail/issue-51345.rs18
-rw-r--r--src/test/run-pass/issue-51345.rs17
-rw-r--r--src/test/run-pass/weak-new-uninhabited-issue-48493.rs15
-rw-r--r--src/test/ui/error-codes/E0017.nll.stderr12
-rw-r--r--src/test/ui/error-codes/E0388.nll.stderr12
-rw-r--r--src/test/ui/issue-47184.stderr7
-rw-r--r--src/test/ui/nll/get_default.stderr24
-rw-r--r--src/test/ui/span/dropck_arr_cycle_checked.nll.stderr12
-rw-r--r--src/test/ui/span/dropck_direct_cycle_with_drop.nll.stderr16
-rw-r--r--src/test/ui/span/dropck_vec_cycle_checked.nll.stderr12
-rw-r--r--src/test/ui/span/vec-must-not-hide-type-from-dropck.nll.stderr16
-rw-r--r--src/tools/compiletest/Cargo.toml2
35 files changed, 354 insertions, 175 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index bc1b2a14f6a..7297d8a8299 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -147,7 +147,7 @@ dependencies = [
  "build_helper 0.1.0",
  "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -416,7 +416,7 @@ version = "0.0.0"
 dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -695,16 +695,6 @@ version = "0.1.0"
 
 [[package]]
 name = "filetime"
-version = "0.1.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "filetime"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -1139,11 +1129,11 @@ dependencies = [
 
 [[package]]
 name = "lzma-sys"
-version = "0.1.9"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3075,7 +3065,7 @@ name = "xz2"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3134,7 +3124,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
 "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
 "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
-"checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f"
 "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f"
 "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
 "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
@@ -3179,7 +3168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
 "checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2"
 "checksum log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd"
-"checksum lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b93b78f89e8737dac81837fc8f5521ac162abcba902e1a3db949d55346d1da"
+"checksum lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d1eaa027402541975218bb0eec67d6b0412f6233af96e0d096d31dbdfd22e614"
 "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
 "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
 "checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index af33ebf3c42..57a52603804 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -36,7 +36,7 @@ test = false
 [dependencies]
 build_helper = { path = "../build_helper" }
 cmake = "0.1.23"
-filetime = "0.1"
+filetime = "0.2"
 num_cpus = "1.0"
 getopts = "0.2"
 cc = "1.0.1"
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 32d624e8fbc..f7c12b98f48 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -253,7 +253,7 @@ use core::hash::{Hash, Hasher};
 use core::intrinsics::abort;
 use core::marker;
 use core::marker::{Unsize, PhantomData};
-use core::mem::{self, align_of_val, forget, size_of_val, uninitialized};
+use core::mem::{self, align_of_val, forget, size_of_val};
 use core::ops::Deref;
 use core::ops::CoerceUnsized;
 use core::ptr::{self, NonNull};
@@ -620,13 +620,12 @@ impl<T: Clone> Rc<T> {
 
 impl Rc<Any> {
     #[inline]
-    #[unstable(feature = "rc_downcast", issue = "44608")]
+    #[stable(feature = "rc_downcast", since = "1.29.0")]
     /// Attempt to downcast the `Rc<Any>` to a concrete type.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(rc_downcast)]
     /// use std::any::Any;
     /// use std::rc::Rc;
     ///
@@ -1153,6 +1152,10 @@ impl<T> From<Vec<T>> for Rc<[T]> {
 /// [`None`]: ../../std/option/enum.Option.html#variant.None
 #[stable(feature = "rc_weak", since = "1.4.0")]
 pub struct Weak<T: ?Sized> {
+    // This is a `NonNull` to allow optimizing the size of this type in enums,
+    // but it is not necessarily a valid pointer.
+    // `Weak::new` sets this to a dangling pointer so that it doesn’t need
+    // to allocate space on the heap.
     ptr: NonNull<RcBox<T>>,
 }
 
@@ -1165,8 +1168,8 @@ impl<T: ?Sized> !marker::Sync for Weak<T> {}
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
 
 impl<T> Weak<T> {
-    /// Constructs a new `Weak<T>`, allocating memory for `T` without initializing
-    /// it. Calling [`upgrade`] on the return value always gives [`None`].
+    /// Constructs a new `Weak<T>`, without allocating any memory.
+    /// Calling [`upgrade`] on the return value always gives [`None`].
     ///
     /// [`upgrade`]: struct.Weak.html#method.upgrade
     /// [`None`]: ../../std/option/enum.Option.html
@@ -1181,18 +1184,18 @@ impl<T> Weak<T> {
     /// ```
     #[stable(feature = "downgraded_weak", since = "1.10.0")]
     pub fn new() -> Weak<T> {
-        unsafe {
-            Weak {
-                ptr: Box::into_raw_non_null(box RcBox {
-                    strong: Cell::new(0),
-                    weak: Cell::new(1),
-                    value: uninitialized(),
-                }),
-            }
+        Weak {
+            ptr: NonNull::dangling(),
         }
     }
 }
 
+pub(crate) fn is_dangling<T: ?Sized>(ptr: NonNull<T>) -> bool {
+    let address = ptr.as_ptr() as *mut () as usize;
+    let align = align_of_val(unsafe { ptr.as_ref() });
+    address == align
+}
+
 impl<T: ?Sized> Weak<T> {
     /// Attempts to upgrade the `Weak` pointer to an [`Rc`], extending
     /// the lifetime of the value if successful.
@@ -1222,13 +1225,25 @@ impl<T: ?Sized> Weak<T> {
     /// ```
     #[stable(feature = "rc_weak", since = "1.4.0")]
     pub fn upgrade(&self) -> Option<Rc<T>> {
-        if self.strong() == 0 {
+        let inner = self.inner()?;
+        if inner.strong() == 0 {
             None
         } else {
-            self.inc_strong();
+            inner.inc_strong();
             Some(Rc { ptr: self.ptr, phantom: PhantomData })
         }
     }
+
+    /// Return `None` when the pointer is dangling and there is no allocated `RcBox`,
+    /// i.e. this `Weak` was created by `Weak::new`
+    #[inline]
+    fn inner(&self) -> Option<&RcBox<T>> {
+        if is_dangling(self.ptr) {
+            None
+        } else {
+            Some(unsafe { self.ptr.as_ref() })
+        }
+    }
 }
 
 #[stable(feature = "rc_weak", since = "1.4.0")]
@@ -1258,12 +1273,14 @@ impl<T: ?Sized> Drop for Weak<T> {
     /// assert!(other_weak_foo.upgrade().is_none());
     /// ```
     fn drop(&mut self) {
-        unsafe {
-            self.dec_weak();
+        if let Some(inner) = self.inner() {
+            inner.dec_weak();
             // the weak count starts at 1, and will only go to zero if all
             // the strong pointers have disappeared.
-            if self.weak() == 0 {
-                Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
+            if inner.weak() == 0 {
+                unsafe {
+                    Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
+                }
             }
         }
     }
@@ -1284,7 +1301,9 @@ impl<T: ?Sized> Clone for Weak<T> {
     /// ```
     #[inline]
     fn clone(&self) -> Weak<T> {
-        self.inc_weak();
+        if let Some(inner) = self.inner() {
+            inner.inc_weak()
+        }
         Weak { ptr: self.ptr }
     }
 }
@@ -1317,7 +1336,7 @@ impl<T> Default for Weak<T> {
     }
 }
 
-// NOTE: We checked_add here to deal with mem::forget safety. In particular
+// NOTE: We checked_add here to deal with mem::forget safely. In particular
 // if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
 // you can free the allocation while outstanding Rcs (or Weaks) exist.
 // We abort because this is such a degenerate scenario that we don't care about
@@ -1370,12 +1389,10 @@ impl<T: ?Sized> RcBoxPtr<T> for Rc<T> {
     }
 }
 
-impl<T: ?Sized> RcBoxPtr<T> for Weak<T> {
+impl<T: ?Sized> RcBoxPtr<T> for RcBox<T> {
     #[inline(always)]
     fn inner(&self) -> &RcBox<T> {
-        unsafe {
-            self.ptr.as_ref()
-        }
+        self
     }
 }
 
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 4244b09b18f..5a738fc5444 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -34,6 +34,7 @@ use core::convert::From;
 
 use alloc::{Global, Alloc, Layout, box_free, handle_alloc_error};
 use boxed::Box;
+use rc::is_dangling;
 use string::String;
 use vec::Vec;
 
@@ -43,9 +44,6 @@ use vec::Vec;
 /// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references.
 const MAX_REFCOUNT: usize = (isize::MAX) as usize;
 
-/// A sentinel value that is used for the pointer of `Weak::new()`.
-const WEAK_EMPTY: usize = 1;
-
 /// A thread-safe reference-counting pointer. 'Arc' stands for 'Atomically
 /// Reference Counted'.
 ///
@@ -239,9 +237,9 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
 #[stable(feature = "arc_weak", since = "1.4.0")]
 pub struct Weak<T: ?Sized> {
     // This is a `NonNull` to allow optimizing the size of this type in enums,
-    // but it is actually not truly "non-null". A `Weak::new()` will set this
-    // to a sentinel value, instead of needing to allocate some space in the
-    // heap.
+    // but it is not necessarily a valid pointer.
+    // `Weak::new` sets this to a dangling pointer so that it doesn’t need
+    // to allocate space on the heap.
     ptr: NonNull<ArcInner<T>>,
 }
 
@@ -982,13 +980,12 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
 
 impl Arc<Any + Send + Sync> {
     #[inline]
-    #[unstable(feature = "rc_downcast", issue = "44608")]
+    #[stable(feature = "rc_downcast", since = "1.29.0")]
     /// Attempt to downcast the `Arc<Any + Send + Sync>` to a concrete type.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(rc_downcast)]
     /// use std::any::Any;
     /// use std::sync::Arc;
     ///
@@ -1035,10 +1032,8 @@ impl<T> Weak<T> {
     /// ```
     #[stable(feature = "downgraded_weak", since = "1.10.0")]
     pub fn new() -> Weak<T> {
-        unsafe {
-            Weak {
-                ptr: NonNull::new_unchecked(WEAK_EMPTY as *mut _),
-            }
+        Weak {
+            ptr: NonNull::dangling(),
         }
     }
 }
@@ -1074,11 +1069,7 @@ impl<T: ?Sized> Weak<T> {
     pub fn upgrade(&self) -> Option<Arc<T>> {
         // We use a CAS loop to increment the strong count instead of a
         // fetch_add because once the count hits 0 it must never be above 0.
-        let inner = if self.ptr.as_ptr() as *const u8 as usize == WEAK_EMPTY {
-            return None;
-        } else {
-            unsafe { self.ptr.as_ref() }
-        };
+        let inner = self.inner()?;
 
         // Relaxed load because any write of 0 that we can observe
         // leaves the field in a permanently zero state (so a
@@ -1109,6 +1100,17 @@ impl<T: ?Sized> Weak<T> {
             }
         }
     }
+
+    /// Return `None` when the pointer is dangling and there is no allocated `ArcInner`,
+    /// i.e. this `Weak` was created by `Weak::new`
+    #[inline]
+    fn inner(&self) -> Option<&ArcInner<T>> {
+        if is_dangling(self.ptr) {
+            None
+        } else {
+            Some(unsafe { self.ptr.as_ref() })
+        }
+    }
 }
 
 #[stable(feature = "arc_weak", since = "1.4.0")]
@@ -1126,10 +1128,10 @@ impl<T: ?Sized> Clone for Weak<T> {
     /// ```
     #[inline]
     fn clone(&self) -> Weak<T> {
-        let inner = if self.ptr.as_ptr() as *const u8 as usize == WEAK_EMPTY {
-            return Weak { ptr: self.ptr };
+        let inner = if let Some(inner) = self.inner() {
+            inner
         } else {
-            unsafe { self.ptr.as_ref() }
+            return Weak { ptr: self.ptr };
         };
         // See comments in Arc::clone() for why this is relaxed.  This can use a
         // fetch_add (ignoring the lock) because the weak count is only locked
@@ -1204,10 +1206,10 @@ impl<T: ?Sized> Drop for Weak<T> {
         // weak count can only be locked if there was precisely one weak ref,
         // meaning that drop could only subsequently run ON that remaining weak
         // ref, which can only happen after the lock is released.
-        let inner = if self.ptr.as_ptr() as *const u8 as usize == WEAK_EMPTY {
-            return;
+        let inner = if let Some(inner) = self.inner() {
+            inner
         } else {
-            unsafe { self.ptr.as_ref() }
+            return
         };
 
         if inner.weak.fetch_sub(1, Release) == 1 {
diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs
new file mode 100644
index 00000000000..753873dd294
--- /dev/null
+++ b/src/liballoc/tests/arc.rs
@@ -0,0 +1,55 @@
+// 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.
+
+use std::any::Any;
+use std::sync::{Arc, Weak};
+
+#[test]
+fn uninhabited() {
+    enum Void {}
+    let mut a = Weak::<Void>::new();
+    a = a.clone();
+    assert!(a.upgrade().is_none());
+
+    let mut a: Weak<Any> = a;  // Unsizing
+    a = a.clone();
+    assert!(a.upgrade().is_none());
+}
+
+#[test]
+fn slice() {
+    let a: Arc<[u32; 3]> = Arc::new([3, 2, 1]);
+    let a: Arc<[u32]> = a;  // Unsizing
+    let b: Arc<[u32]> = Arc::from(&[3, 2, 1][..]);  // Conversion
+    assert_eq!(a, b);
+
+    // Exercise is_dangling() with a DST
+    let mut a = Arc::downgrade(&a);
+    a = a.clone();
+    assert!(a.upgrade().is_some());
+}
+
+#[test]
+fn trait_object() {
+    let a: Arc<u32> = Arc::new(4);
+    let a: Arc<Any> = a;  // Unsizing
+
+    // Exercise is_dangling() with a DST
+    let mut a = Arc::downgrade(&a);
+    a = a.clone();
+    assert!(a.upgrade().is_some());
+
+    let mut b = Weak::<u32>::new();
+    b = b.clone();
+    assert!(b.upgrade().is_none());
+    let mut b: Weak<Any> = b;  // Unsizing
+    b = b.clone();
+    assert!(b.upgrade().is_none());
+}
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index dbac2c0bb18..2c361598e89 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -32,12 +32,14 @@ extern crate rand;
 use std::hash::{Hash, Hasher};
 use std::collections::hash_map::DefaultHasher;
 
+mod arc;
 mod binary_heap;
 mod btree;
 mod cow_str;
 mod fmt;
 mod heap;
 mod linked_list;
+mod rc;
 mod slice;
 mod str;
 mod string;
diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs
new file mode 100644
index 00000000000..baa0406acfc
--- /dev/null
+++ b/src/liballoc/tests/rc.rs
@@ -0,0 +1,55 @@
+// 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.
+
+use std::any::Any;
+use std::rc::{Rc, Weak};
+
+#[test]
+fn uninhabited() {
+    enum Void {}
+    let mut a = Weak::<Void>::new();
+    a = a.clone();
+    assert!(a.upgrade().is_none());
+
+    let mut a: Weak<Any> = a;  // Unsizing
+    a = a.clone();
+    assert!(a.upgrade().is_none());
+}
+
+#[test]
+fn slice() {
+    let a: Rc<[u32; 3]> = Rc::new([3, 2, 1]);
+    let a: Rc<[u32]> = a;  // Unsizing
+    let b: Rc<[u32]> = Rc::from(&[3, 2, 1][..]);  // Conversion
+    assert_eq!(a, b);
+
+    // Exercise is_dangling() with a DST
+    let mut a = Rc::downgrade(&a);
+    a = a.clone();
+    assert!(a.upgrade().is_some());
+}
+
+#[test]
+fn trait_object() {
+    let a: Rc<u32> = Rc::new(4);
+    let a: Rc<Any> = a;  // Unsizing
+
+    // Exercise is_dangling() with a DST
+    let mut a = Rc::downgrade(&a);
+    a = a.clone();
+    assert!(a.upgrade().is_some());
+
+    let mut b = Weak::<u32>::new();
+    b = b.clone();
+    assert!(b.upgrade().is_none());
+    let mut b: Weak<Any> = b;  // Unsizing
+    b = b.clone();
+    assert!(b.upgrade().is_none());
+}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index b2b38820a89..bbe6ae8619f 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -122,7 +122,6 @@
 #![feature(const_slice_len)]
 #![feature(const_str_as_bytes)]
 #![feature(const_str_len)]
-#![cfg_attr(stage0, feature(repr_transparent))]
 
 #[prelude_import]
 #[allow(unused)]
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 3d7aaf1b2d8..95c68214ec7 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1816,7 +1816,7 @@ pub fn build_session_options_and_crate_config(
         early_error(
                 ErrorOutputType::default(),
                 &format!(
-                    "Edition {} is unstable an only\
+                    "Edition {} is unstable and only \
                     available for nightly builds of rustc.",
                     edition,
                 )
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 5142a30ae57..8f7f9d09423 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1354,6 +1354,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         !self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard
     }
 
+    /// If true, we should use the AST-based borrowck (we may *also* use
+    /// the MIR-based borrowck).
+    pub fn use_ast_borrowck(self) -> bool {
+        self.borrowck_mode().use_ast()
+    }
+
     /// If true, we should use the MIR-based borrowck (we may *also* use
     /// the AST-based borrowck).
     pub fn use_mir_borrowck(self) -> bool {
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 4bd8e6afa76..df1b1138f3e 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -89,6 +89,8 @@ pub struct AnalysisData<'a, 'tcx: 'a> {
 fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
     -> Lrc<BorrowCheckResult>
 {
+    assert!(tcx.use_ast_borrowck());
+
     debug!("borrowck(body_owner_def_id={:?})", owner_def_id);
 
     let owner_id = tcx.hir.as_local_node_id(owner_def_id).unwrap();
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 357b639e788..87ee9ef5adb 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -84,6 +84,7 @@ unsafe fn configure_llvm(sess: &Session) {
 // array, leading to crashes.
 
 const ARM_WHITELIST: &[(&str, Option<&str>)] = &[
+    ("mclass", Some("arm_target_feature")),
     ("neon", Some("arm_target_feature")),
     ("v7", Some("arm_target_feature")),
     ("vfp2", Some("arm_target_feature")),
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index feeac9d938b..96e9616699d 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -1279,7 +1279,11 @@ where
                 middle::liveness::check_crate(tcx)
             });
 
-            time(sess, "borrow checking", || borrowck::check_crate(tcx));
+            time(sess, "borrow checking", || {
+                if tcx.use_ast_borrowck() {
+                    borrowck::check_crate(tcx);
+                }
+            });
 
             time(sess,
                  "MIR borrow checking",
diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs
index 3d6f49c3772..e9e0c5c3613 100644
--- a/src/librustc_mir/borrow_check/borrow_set.rs
+++ b/src/librustc_mir/borrow_check/borrow_set.rs
@@ -53,15 +53,13 @@ impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
     }
 }
 
-/// Every two-phase borrow has *exactly one* use (or else it is not a
-/// proper two-phase borrow under our current definition). However, not
-/// all uses are actually ones that activate the reservation.. In
-/// particular, a shared borrow of a `&mut` does not activate the
-/// reservation.
+/// Location where a two phase borrow is activated, if a borrow
+/// is in fact a two phase borrow.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-crate enum TwoPhaseUse {
-    MutActivate,
-    SharedUse,
+crate enum TwoPhaseActivation {
+    NotTwoPhase,
+    NotActivated,
+    ActivatedAt(Location),
 }
 
 #[derive(Debug)]
@@ -69,9 +67,8 @@ crate struct BorrowData<'tcx> {
     /// Location where the borrow reservation starts.
     /// In many cases, this will be equal to the activation location but not always.
     crate reserve_location: Location,
-    /// Location where the borrow is activated. None if this is not a
-    /// 2-phase borrow.
-    crate activation_location: Option<(TwoPhaseUse, Location)>,
+    /// Location where the borrow is activated.
+    crate activation_location: TwoPhaseActivation,
     /// What kind of borrow this is
     crate kind: mir::BorrowKind,
     /// The region for which this borrow is live
@@ -116,19 +113,6 @@ impl<'tcx> BorrowSet<'tcx> {
             visitor.visit_basic_block_data(block, block_data);
         }
 
-        // Double check: We should have found an activation for every pending
-        // activation.
-        assert_eq!(
-            visitor
-                .pending_activations
-                .iter()
-                .find(|&(_local, &borrow_index)| visitor.idx_vec[borrow_index]
-                    .activation_location
-                    .is_none()),
-            None,
-            "never found an activation for this borrow!",
-        );
-
         BorrowSet {
             borrows: visitor.idx_vec,
             location_map: visitor.location_map,
@@ -183,7 +167,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
                 kind,
                 region,
                 reserve_location: location,
-                activation_location: None,
+                activation_location: TwoPhaseActivation::NotTwoPhase,
                 borrowed_place: borrowed_place.clone(),
                 assigned_place: assigned_place.clone(),
             };
@@ -232,38 +216,43 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
                         return;
                     }
 
-                    if let Some(other_activation) = borrow_data.activation_location {
+                    if let TwoPhaseActivation::ActivatedAt(other_location) =
+                            borrow_data.activation_location {
                         span_bug!(
                             self.mir.source_info(location).span,
                             "found two uses for 2-phase borrow temporary {:?}: \
                              {:?} and {:?}",
                             temp,
                             location,
-                            other_activation,
+                            other_location,
                         );
                     }
 
                     // Otherwise, this is the unique later use
                     // that we expect.
-
-                    let two_phase_use;
-
-                    match context {
+                    borrow_data.activation_location = match context {
                         // The use of TMP in a shared borrow does not
                         // count as an actual activation.
                         PlaceContext::Borrow { kind: mir::BorrowKind::Shared, .. } => {
-                            two_phase_use = TwoPhaseUse::SharedUse;
+                            TwoPhaseActivation::NotActivated
                         }
                         _ => {
-                            two_phase_use = TwoPhaseUse::MutActivate;
+                            // Double check: This borrow is indeed a two-phase borrow (that is,
+                            // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and
+                            // we've not found any other activations (checked above).
+                            assert_eq!(
+                                borrow_data.activation_location,
+                                TwoPhaseActivation::NotActivated,
+                                "never found an activation for this borrow!",
+                            );
+
                             self.activation_map
                                 .entry(location)
                                 .or_insert(Vec::new())
                                 .push(borrow_index);
+                            TwoPhaseActivation::ActivatedAt(location)
                         }
-                    }
-
-                    borrow_data.activation_location = Some((two_phase_use, location));
+                    };
                 }
 
                 None => {}
@@ -342,6 +331,11 @@ impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
             );
         };
 
+        // Consider the borrow not activated to start. When we find an activation, we'll update
+        // this field.
+        let borrow_data = &mut self.idx_vec[borrow_index];
+        borrow_data.activation_location = TwoPhaseActivation::NotActivated;
+
         // Insert `temp` into the list of pending activations. From
         // now on, we'll be on the lookout for a use of it. Note that
         // we are guaranteed that this use will come after the
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 29f13d669fa..a5db0d15d8a 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -80,7 +80,7 @@ fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowC
     let mut return_early;
 
     // Return early if we are not supposed to use MIR borrow checker for this function.
-    return_early = !tcx.has_attr(def_id, "rustc_mir_borrowck") && !tcx.use_mir_borrowck();
+    return_early = !tcx.has_attr(def_id, "rustc_mir") && !tcx.use_mir_borrowck();
 
     if tcx.is_struct_constructor(def_id) {
         // We are not borrow checking the automatically generated struct constructors
diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs
index 8ae98bde003..ca2a120ceb7 100644
--- a/src/librustc_mir/borrow_check/path_utils.rs
+++ b/src/librustc_mir/borrow_check/path_utils.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseUse};
+use borrow_check::borrow_set::{BorrowSet, BorrowData, TwoPhaseActivation};
 use borrow_check::places_conflict;
 use borrow_check::Context;
 use borrow_check::ShallowOrDeep;
@@ -83,11 +83,11 @@ pub(super) fn is_active<'tcx>(
 
     let activation_location = match borrow_data.activation_location {
         // If this is not a 2-phase borrow, it is always active.
-        None => return true,
+        TwoPhaseActivation::NotTwoPhase => return true,
         // And if the unique 2-phase use is not an activation, then it is *never* active.
-        Some((TwoPhaseUse::SharedUse, _)) => return false,
-        // Otherwise, we derive info from the activation point `v`:
-        Some((TwoPhaseUse::MutActivate, v)) => v,
+        TwoPhaseActivation::NotActivated => return false,
+        // Otherwise, we derive info from the activation point `loc`:
+        TwoPhaseActivation::ActivatedAt(loc) => loc,
     };
 
     // Otherwise, it is active for every location *except* in between
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index e4cae5fe6c8..e3b67b0a003 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -17,6 +17,7 @@ use rustc_data_structures::work_queue::WorkQueue;
 
 use rustc::ty::{self, TyCtxt};
 use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator};
+use rustc::mir::traversal;
 use rustc::session::Session;
 
 use std::borrow::Borrow;
@@ -332,7 +333,7 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> {
 
     fn analyze_results(&mut self, flow_uninit: &mut Self::FlowState) {
         let flow = flow_uninit;
-        for bb in self.mir().basic_blocks().indices() {
+        for (bb, _) in traversal::reverse_postorder(self.mir()) {
             flow.reset_to_entry_of(bb);
             self.process_basic_block(bb, flow);
         }
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 06be2bb3734..90dfebeef1b 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -225,7 +225,10 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
     // (Mir-)Borrowck uses `mir_validated`, so we have to force it to
     // execute before we can steal.
     let _ = tcx.mir_borrowck(def_id);
-    let _ = tcx.borrowck(def_id);
+
+    if tcx.use_ast_borrowck() {
+        let _ = tcx.borrowck(def_id);
+    }
 
     let mut mir = tcx.mir_validated(def_id).steal();
     run_passes![tcx, mir, def_id, 2;
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index b23f0568012..da149f42064 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -36,7 +36,7 @@ impl MirPass for SanityCheck {
                           src: MirSource, mir: &mut Mir<'tcx>) {
         let def_id = src.def_id;
         let id = tcx.hir.as_local_node_id(def_id).unwrap();
-        if !tcx.has_attr(def_id, "rustc_mir_borrowck") {
+        if !tcx.has_attr(def_id, "rustc_mir") {
             debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
             return;
         } else {
diff --git a/src/test/compile-fail/mir-dataflow/def-inits-1.rs b/src/test/compile-fail/mir-dataflow/def-inits-1.rs
index f3c9f29821e..f5f0ede6864 100644
--- a/src/test/compile-fail/mir-dataflow/def-inits-1.rs
+++ b/src/test/compile-fail/mir-dataflow/def-inits-1.rs
@@ -10,6 +10,7 @@
 
 // General test of maybe_uninits state computed by MIR dataflow.
 
+#![feature(nll)]
 #![feature(core_intrinsics, rustc_attrs)]
 
 use std::intrinsics::rustc_peek;
@@ -17,7 +18,6 @@ use std::mem::{drop, replace};
 
 struct S(i32);
 
-#[rustc_mir_borrowck]
 #[rustc_mir(rustc_peek_definite_init,stop_after_dataflow)]
 fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     let ret;
diff --git a/src/test/compile-fail/mir-dataflow/inits-1.rs b/src/test/compile-fail/mir-dataflow/inits-1.rs
index 8a5ab6e420a..595f01f7c94 100644
--- a/src/test/compile-fail/mir-dataflow/inits-1.rs
+++ b/src/test/compile-fail/mir-dataflow/inits-1.rs
@@ -10,6 +10,7 @@
 
 // General test of maybe_inits state computed by MIR dataflow.
 
+#![feature(nll)]
 #![feature(core_intrinsics, rustc_attrs)]
 
 use std::intrinsics::rustc_peek;
@@ -17,7 +18,6 @@ use std::mem::{drop, replace};
 
 struct S(i32);
 
-#[rustc_mir_borrowck]
 #[rustc_mir(rustc_peek_maybe_init,stop_after_dataflow)]
 fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     let ret;
diff --git a/src/test/compile-fail/mir-dataflow/uninits-1.rs b/src/test/compile-fail/mir-dataflow/uninits-1.rs
index 8df66ea815c..bb10c03254e 100644
--- a/src/test/compile-fail/mir-dataflow/uninits-1.rs
+++ b/src/test/compile-fail/mir-dataflow/uninits-1.rs
@@ -10,6 +10,7 @@
 
 // General test of maybe_uninits state computed by MIR dataflow.
 
+#![feature(nll)]
 #![feature(core_intrinsics, rustc_attrs)]
 
 use std::intrinsics::rustc_peek;
@@ -17,7 +18,6 @@ use std::mem::{drop, replace};
 
 struct S(i32);
 
-#[rustc_mir_borrowck]
 #[rustc_mir(rustc_peek_maybe_uninit,stop_after_dataflow)]
 fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S {
     let ret;
diff --git a/src/test/compile-fail/mir-dataflow/uninits-2.rs b/src/test/compile-fail/mir-dataflow/uninits-2.rs
index 2edd275e786..9854ea779b3 100644
--- a/src/test/compile-fail/mir-dataflow/uninits-2.rs
+++ b/src/test/compile-fail/mir-dataflow/uninits-2.rs
@@ -10,6 +10,7 @@
 
 // General test of maybe_uninits state computed by MIR dataflow.
 
+#![feature(nll)]
 #![feature(core_intrinsics, rustc_attrs)]
 
 use std::intrinsics::rustc_peek;
@@ -17,7 +18,6 @@ use std::mem::{drop, replace};
 
 struct S(i32);
 
-#[rustc_mir_borrowck]
 #[rustc_mir(rustc_peek_maybe_uninit,stop_after_dataflow)]
 fn foo(x: &mut S) {
     // `x` is initialized here, so maybe-uninit bit is 0.
diff --git a/src/test/run-fail/issue-51345.rs b/src/test/run-fail/issue-51345.rs
new file mode 100644
index 00000000000..9efd08195a1
--- /dev/null
+++ b/src/test/run-fail/issue-51345.rs
@@ -0,0 +1,18 @@
+// Copyright 2012 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.
+
+// error-pattern: thread 'main' panicked at 'explicit panic'
+
+#![feature(nll)]
+
+fn main() {
+    let mut vec = vec![];
+    vec.push((vec.len(), panic!()));
+}
diff --git a/src/test/run-pass/issue-51345.rs b/src/test/run-pass/issue-51345.rs
new file mode 100644
index 00000000000..7d392944685
--- /dev/null
+++ b/src/test/run-pass/issue-51345.rs
@@ -0,0 +1,17 @@
+// Copyright 2012 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.
+
+#![feature(nll)]
+
+fn main() {
+    let mut v = Vec::new();
+
+    loop { v.push(break) }
+}
diff --git a/src/test/run-pass/weak-new-uninhabited-issue-48493.rs b/src/test/run-pass/weak-new-uninhabited-issue-48493.rs
new file mode 100644
index 00000000000..eb57c12ed12
--- /dev/null
+++ b/src/test/run-pass/weak-new-uninhabited-issue-48493.rs
@@ -0,0 +1,15 @@
+// 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.
+
+fn main() {
+    enum Void {}
+    std::rc::Weak::<Void>::new();
+    std::sync::Weak::<Void>::new();
+}
diff --git a/src/test/ui/error-codes/E0017.nll.stderr b/src/test/ui/error-codes/E0017.nll.stderr
index ec31f5d05d7..addbbf4434f 100644
--- a/src/test/ui/error-codes/E0017.nll.stderr
+++ b/src/test/ui/error-codes/E0017.nll.stderr
@@ -10,18 +10,18 @@ error[E0017]: references in statics may only refer to immutable values
 LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                       ^^^^^^ statics require immutable values
 
-error[E0017]: references in statics may only refer to immutable values
-  --> $DIR/E0017.rs:17:38
-   |
-LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
-   |                                      ^^^^^^ statics require immutable values
-
 error[E0596]: cannot borrow immutable item `X` as mutable
   --> $DIR/E0017.rs:15:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                       ^^^^^^ cannot borrow as mutable
 
+error[E0017]: references in statics may only refer to immutable values
+  --> $DIR/E0017.rs:17:38
+   |
+LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
+   |                                      ^^^^^^ statics require immutable values
+
 error: aborting due to 4 previous errors
 
 Some errors occurred: E0017, E0596.
diff --git a/src/test/ui/error-codes/E0388.nll.stderr b/src/test/ui/error-codes/E0388.nll.stderr
index 6a4bd6b31a1..0238ca6b623 100644
--- a/src/test/ui/error-codes/E0388.nll.stderr
+++ b/src/test/ui/error-codes/E0388.nll.stderr
@@ -10,18 +10,18 @@ error[E0017]: references in statics may only refer to immutable values
 LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                       ^^^^^^ statics require immutable values
 
-error[E0017]: references in statics may only refer to immutable values
-  --> $DIR/E0388.rs:17:38
-   |
-LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
-   |                                      ^^^^^^ statics require immutable values
-
 error[E0596]: cannot borrow immutable item `X` as mutable
   --> $DIR/E0388.rs:15:39
    |
 LL | static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0017
    |                                       ^^^^^^ cannot borrow as mutable
 
+error[E0017]: references in statics may only refer to immutable values
+  --> $DIR/E0388.rs:17:38
+   |
+LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017
+   |                                      ^^^^^^ statics require immutable values
+
 error: aborting due to 4 previous errors
 
 Some errors occurred: E0017, E0596.
diff --git a/src/test/ui/issue-47184.stderr b/src/test/ui/issue-47184.stderr
index a9eb33f01e3..32a9783e9c2 100644
--- a/src/test/ui/issue-47184.stderr
+++ b/src/test/ui/issue-47184.stderr
@@ -2,10 +2,9 @@ error[E0597]: borrowed value does not live long enough
   --> $DIR/issue-47184.rs:14:44
    |
 LL |     let _vec: Vec<&'static String> = vec![&String::new()];
-   |                                            ^^^^^^^^^^^^^ temporary value does not live long enough
-LL |     //~^ ERROR borrowed value does not live long enough [E0597]
-LL | }
-   | - temporary value only lives until here
+   |                                            ^^^^^^^^^^^^^ - temporary value only lives until here
+   |                                            |
+   |                                            temporary value does not live long enough
    |
    = note: borrowed value must be valid for the static lifetime...
 
diff --git a/src/test/ui/nll/get_default.stderr b/src/test/ui/nll/get_default.stderr
index dd69e18652c..75194bf55bc 100644
--- a/src/test/ui/nll/get_default.stderr
+++ b/src/test/ui/nll/get_default.stderr
@@ -56,6 +56,18 @@ LL | | }
    | |_^
 
 error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
+  --> $DIR/get_default.rs:45:17
+   |
+LL |         match map.get() {
+   |               --- immutable borrow occurs here
+LL |             Some(v) => {
+LL |                 map.set(String::new()); // Both AST and MIR error here
+   |                 ^^^ mutable borrow occurs here
+...
+LL |                 return v;
+   |                        - borrow later used here
+
+error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
   --> $DIR/get_default.rs:51:17
    |
 LL |         match map.get() {
@@ -76,18 +88,6 @@ LL | |     }
 LL | | }
    | |_^
 
-error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir)
-  --> $DIR/get_default.rs:45:17
-   |
-LL |         match map.get() {
-   |               --- immutable borrow occurs here
-LL |             Some(v) => {
-LL |                 map.set(String::new()); // Both AST and MIR error here
-   |                 ^^^ mutable borrow occurs here
-...
-LL |                 return v;
-   |                        - borrow later used here
-
 error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0502`.
diff --git a/src/test/ui/span/dropck_arr_cycle_checked.nll.stderr b/src/test/ui/span/dropck_arr_cycle_checked.nll.stderr
index fee0d7feb6d..cbb9d0429c6 100644
--- a/src/test/ui/span/dropck_arr_cycle_checked.nll.stderr
+++ b/src/test/ui/span/dropck_arr_cycle_checked.nll.stderr
@@ -1,7 +1,7 @@
-error[E0597]: `b1` does not live long enough
-  --> $DIR/dropck_arr_cycle_checked.rs:111:24
+error[E0597]: `b3` does not live long enough
+  --> $DIR/dropck_arr_cycle_checked.rs:105:24
    |
-LL |     b3.a[0].v.set(Some(&b1));
+LL |     b1.a[1].v.set(Some(&b3));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
@@ -22,10 +22,10 @@ LL | }
    | borrowed value only lives until here
    | borrow later used here, when `b1` is dropped
 
-error[E0597]: `b3` does not live long enough
-  --> $DIR/dropck_arr_cycle_checked.rs:105:24
+error[E0597]: `b1` does not live long enough
+  --> $DIR/dropck_arr_cycle_checked.rs:111:24
    |
-LL |     b1.a[1].v.set(Some(&b3));
+LL |     b3.a[0].v.set(Some(&b1));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
diff --git a/src/test/ui/span/dropck_direct_cycle_with_drop.nll.stderr b/src/test/ui/span/dropck_direct_cycle_with_drop.nll.stderr
index 86a4f0e13b5..37fffe886e3 100644
--- a/src/test/ui/span/dropck_direct_cycle_with_drop.nll.stderr
+++ b/src/test/ui/span/dropck_direct_cycle_with_drop.nll.stderr
@@ -1,9 +1,9 @@
-error[E0597]: `d1` does not live long enough
-  --> $DIR/dropck_direct_cycle_with_drop.rs:48:19
+error[E0597]: `d2` does not live long enough
+  --> $DIR/dropck_direct_cycle_with_drop.rs:46:19
    |
-LL |     d2.p.set(Some(&d1));
+LL |     d1.p.set(Some(&d2));
    |                   ^^^ borrowed value does not live long enough
-LL |     //~^ ERROR `d1` does not live long enough
+...
 LL | }
    | -
    | |
@@ -12,12 +12,12 @@ LL | }
    |
    = note: values in a scope are dropped in the opposite order they are defined
 
-error[E0597]: `d2` does not live long enough
-  --> $DIR/dropck_direct_cycle_with_drop.rs:46:19
+error[E0597]: `d1` does not live long enough
+  --> $DIR/dropck_direct_cycle_with_drop.rs:48:19
    |
-LL |     d1.p.set(Some(&d2));
+LL |     d2.p.set(Some(&d1));
    |                   ^^^ borrowed value does not live long enough
-...
+LL |     //~^ ERROR `d1` does not live long enough
 LL | }
    | -
    | |
diff --git a/src/test/ui/span/dropck_vec_cycle_checked.nll.stderr b/src/test/ui/span/dropck_vec_cycle_checked.nll.stderr
index b7f8b85f46c..13bd1f54198 100644
--- a/src/test/ui/span/dropck_vec_cycle_checked.nll.stderr
+++ b/src/test/ui/span/dropck_vec_cycle_checked.nll.stderr
@@ -1,7 +1,7 @@
-error[E0597]: `c1` does not live long enough
-  --> $DIR/dropck_vec_cycle_checked.rs:121:24
+error[E0597]: `c3` does not live long enough
+  --> $DIR/dropck_vec_cycle_checked.rs:115:24
    |
-LL |     c3.v[0].v.set(Some(&c1));
+LL |     c1.v[1].v.set(Some(&c3));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
@@ -22,10 +22,10 @@ LL | }
    | borrowed value only lives until here
    | borrow later used here, when `c1` is dropped
 
-error[E0597]: `c3` does not live long enough
-  --> $DIR/dropck_vec_cycle_checked.rs:115:24
+error[E0597]: `c1` does not live long enough
+  --> $DIR/dropck_vec_cycle_checked.rs:121:24
    |
-LL |     c1.v[1].v.set(Some(&c3));
+LL |     c3.v[0].v.set(Some(&c1));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
diff --git a/src/test/ui/span/vec-must-not-hide-type-from-dropck.nll.stderr b/src/test/ui/span/vec-must-not-hide-type-from-dropck.nll.stderr
index 389adb231c4..100b4c1292f 100644
--- a/src/test/ui/span/vec-must-not-hide-type-from-dropck.nll.stderr
+++ b/src/test/ui/span/vec-must-not-hide-type-from-dropck.nll.stderr
@@ -1,21 +1,21 @@
-error[E0597]: `c1` does not live long enough
-  --> $DIR/vec-must-not-hide-type-from-dropck.rs:129:24
+error[E0597]: `c2` does not live long enough
+  --> $DIR/vec-must-not-hide-type-from-dropck.rs:127:24
    |
-LL |     c2.v[0].v.set(Some(&c1));
+LL |     c1.v[0].v.set(Some(&c2));
    |                        ^^^ borrowed value does not live long enough
-LL |     //~^ ERROR `c1` does not live long enough
+...
 LL | }
    | -
    | |
    | borrowed value only lives until here
    | borrow later used here, when `c1` is dropped
 
-error[E0597]: `c2` does not live long enough
-  --> $DIR/vec-must-not-hide-type-from-dropck.rs:127:24
+error[E0597]: `c1` does not live long enough
+  --> $DIR/vec-must-not-hide-type-from-dropck.rs:129:24
    |
-LL |     c1.v[0].v.set(Some(&c2));
+LL |     c2.v[0].v.set(Some(&c1));
    |                        ^^^ borrowed value does not live long enough
-...
+LL |     //~^ ERROR `c1` does not live long enough
 LL | }
    | -
    | |
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 78038758023..582ba5adfe5 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -6,7 +6,7 @@ version = "0.0.0"
 [dependencies]
 diff = "0.1.10"
 env_logger = { version = "0.5", default-features = false }
-filetime = "0.1"
+filetime = "0.2"
 getopts = "0.2"
 log = "0.4"
 regex = "0.2"