diff --git a/Cargo.lock b/Cargo.lock
index d22a91073394a..031c998a299ed 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -81,7 +81,7 @@ dependencies = [
 
 [[package]]
 name = "backtrace"
-version = "0.3.9"
+version = "0.3.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -614,7 +614,7 @@ dependencies = [
 
 [[package]]
 name = "datafrog"
-version = "0.1.0"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -728,7 +728,7 @@ name = "error-chain"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -736,7 +736,7 @@ name = "error-chain"
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -751,7 +751,7 @@ name = "failure"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1625,10 +1625,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "polonius-engine"
-version = "0.5.0"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "datafrog 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2060,7 +2060,7 @@ name = "rustc"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2071,7 +2071,7 @@ dependencies = [
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "polonius-engine 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_apfloat 0.0.0",
@@ -2518,7 +2518,7 @@ dependencies = [
  "graphviz 0.0.0",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "polonius-engine 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_apfloat 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -3380,7 +3380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
 "checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51"
 "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
-"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
+"checksum backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "18b65ea1161bfb2dd6da6fade5edd4dbd08fba85012123dd333d2fd1b90b2782"
 "checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
 "checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a"
 "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf"
@@ -3419,7 +3419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
 "checksum curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16"
 "checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870"
-"checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142"
+"checksum datafrog 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71a3eacc779bb35090718501c2de27bb679dee18f6c28e6589590e4ed8b9fa08"
 "checksum derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c"
 "checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
@@ -3529,7 +3529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998"
 "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930"
 "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
-"checksum polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b6b0a7f5f4278b991ffd14abce1d01b013121ad297460237ef0a2f08d43201"
+"checksum polonius-engine 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d9274a1db7bffb87f7e810ef480a75b67eed0f1a3838f80c652e881f4b4970fd"
 "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
 "checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
diff --git a/README.md b/README.md
index 37442661bcbc1..dc013a1ad2be6 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ standard library, and documentation.
 
 Read ["Installation"] from [The Book].
 
-["Installation"]: https://doc.rust-lang.org/book/second-edition/ch01-01-installation.html
+["Installation"]: https://doc.rust-lang.org/book/ch01-01-installation.html
 [The Book]: https://doc.rust-lang.org/book/index.html
 
 ## Building from Source
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index c7e6af28f9d4f..4f8a3c0240e1a 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -52,8 +52,8 @@ RUN env \
     CXX=arm-linux-gnueabi-g++ CXXFLAGS="-march=armv6 -marm" \
     bash musl.sh arm && \
     env \
-    CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm" \
-    CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm" \
+    CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm -mfpu=vfp" \
+    CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm -mfpu=vfp" \
     bash musl.sh armhf && \
     env \
     CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv7-a" \
diff --git a/src/doc/rustc/src/targets/built-in.md b/src/doc/rustc/src/targets/built-in.md
index 8620346e5b748..2e94ebe345adb 100644
--- a/src/doc/rustc/src/targets/built-in.md
+++ b/src/doc/rustc/src/targets/built-in.md
@@ -6,5 +6,5 @@ the team is supporting directly.
 
 To see the list of built-in targets, you can run `rustc --print target-list`,
 or look at [the API
-docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/#modules).
+docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/index.html#modules).
 Each module there defines a builder for a particular target.
\ No newline at end of file
diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md
index 07e3a79471f5b..3d63d072befe0 100644
--- a/src/doc/rustc/src/targets/index.md
+++ b/src/doc/rustc/src/targets/index.md
@@ -4,7 +4,7 @@
 architecture. The list of *targets* are the possible architectures that you can build for.
 
 To see all the options that you can set with a target, see the docs
-[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/struct.Target.html).
+[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/struct.Target.html).
 
 To compile to a particular target, use the `--target` flag:
 
diff --git a/src/doc/unstable-book/src/language-features/unsized-locals.md b/src/doc/unstable-book/src/language-features/unsized-locals.md
index 1165ab93a1469..edc039f896b2c 100644
--- a/src/doc/unstable-book/src/language-features/unsized-locals.md
+++ b/src/doc/unstable-book/src/language-features/unsized-locals.md
@@ -8,7 +8,7 @@ The tracking issue for this feature is: [#48055]
 
 This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
 
-[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-coercions.md
+[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
 
 ```rust
 #![feature(unsized_locals)]
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index 2ef84dbade0fb..ba46fafaf169f 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -627,7 +627,9 @@ impl<T> LinkedList<T> {
         self.pop_front_node().map(Node::into_element)
     }
 
-    /// Appends an element to the back of a list
+    /// Appends an element to the back of a list.
+    ///
+    /// This operation should compute in O(1) time.
     ///
     /// # Examples
     ///
@@ -647,6 +649,8 @@ impl<T> LinkedList<T> {
     /// Removes the last element from a list and returns it, or `None` if
     /// it is empty.
     ///
+    /// This operation should compute in O(1) time.
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index e329b45a6175d..509195cd047d4 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -79,6 +79,11 @@ fn test_reserve() {
     assert!(v.capacity() >= 33)
 }
 
+#[test]
+fn test_zst_capacity() {
+    assert_eq!(Vec::<()>::new().capacity(), usize::max_value());
+}
+
 #[test]
 fn test_extend() {
     let mut v = Vec::new();
diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs
index 0c870f9e404a2..5dee1d6dd3a39 100644
--- a/src/libcore/future/future.rs
+++ b/src/libcore/future/future.rs
@@ -33,6 +33,7 @@ use task::{Poll, LocalWaker};
 ///
 /// When using a future, you generally won't call `poll` directly, but instead
 /// `await!` the value.
+#[must_use]
 pub trait Future {
     /// The result of the `Future`.
     type Output;
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 92a4aed4e27e5..c0b83a6868b38 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -98,6 +98,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item=()>) {}
     message="`{Self}` is not an iterator"
 )]
 #[doc(spotlight)]
+#[must_use]
 pub trait Iterator {
     /// The type of the elements being iterated over.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/ops/function.rs b/src/libcore/ops/function.rs
index d1be724c3264e..3b356b9a1e7b4 100644
--- a/src/libcore/ops/function.rs
+++ b/src/libcore/ops/function.rs
@@ -72,6 +72,7 @@
     label="expected an `Fn<{Args}>` closure, found `{Self}`",
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use]
 pub trait Fn<Args> : FnMut<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -150,6 +151,7 @@ pub trait Fn<Args> : FnMut<Args> {
     label="expected an `FnMut<{Args}>` closure, found `{Self}`",
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use]
 pub trait FnMut<Args> : FnOnce<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -228,6 +230,7 @@ pub trait FnMut<Args> : FnOnce<Args> {
     label="expected an `FnOnce<{Args}>` closure, found `{Self}`",
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use]
 pub trait FnOnce<Args> {
     /// The returned type after the call operator is used.
     #[stable(feature = "fn_once_output", since = "1.12.0")]
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index f61e582f7641b..79ca600b4a57f 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -2544,7 +2544,7 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
 /// assert_eq!(actual, expected);
 /// ```
 #[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")]
-pub fn hash<T, S: hash::Hasher>(hashee: *const T, into: &mut S) {
+pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) {
     use hash::Hash;
     hashee.hash(into);
 }
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 060983a702f0b..d2683e31eefb8 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -1072,6 +1072,15 @@ impl<T> AtomicPtr<T> {
 #[cfg(target_has_atomic = "8")]
 #[stable(feature = "atomic_bool_from", since = "1.24.0")]
 impl From<bool> for AtomicBool {
+    /// Converts a `bool` into an `AtomicBool`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::atomic::AtomicBool;
+    /// let atomic_bool = AtomicBool::from(true);
+    /// assert_eq!(format!("{:?}", atomic_bool), "true")
+    /// ```
     #[inline]
     fn from(b: bool) -> Self { Self::new(b) }
 }
@@ -1126,8 +1135,12 @@ macro_rules! atomic_int {
 
         #[$stable_from]
         impl From<$int_type> for $atomic_type {
-            #[inline]
-            fn from(v: $int_type) -> Self { Self::new(v) }
+            doc_comment! {
+                concat!(
+"Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`."),
+                #[inline]
+                fn from(v: $int_type) -> Self { Self::new(v) }
+            }
         }
 
         #[$stable_debug]
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index a572b6bf919e1..78f58bbe99a7f 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -17,7 +17,7 @@ jobserver = "0.1"
 lazy_static = "1.0.0"
 scoped-tls = { version = "0.1.1", features = ["nightly"] }
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
-polonius-engine = "0.5.0"
+polonius-engine = "0.6.1"
 rustc-rayon = "0.1.1"
 rustc-rayon-core = "0.1.1"
 rustc_apfloat = { path = "../librustc_apfloat" }
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 7d997a0154600..d213a5c561871 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1095,7 +1095,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             let sp = hir.span(id);
                             // `sp` only covers `T`, change it so that it covers
                             // `T:` when appropriate
-                            let sp = if has_bounds {
+                            let is_impl_trait = bound_kind.to_string().starts_with("impl ");
+                            let sp = if has_bounds && !is_impl_trait {
                                 sp.to(self.tcx
                                     .sess
                                     .source_map()
@@ -1103,7 +1104,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             } else {
                                 sp
                             };
-                            (sp, has_bounds)
+                            (sp, has_bounds, is_impl_trait)
                         })
                     } else {
                         None
@@ -1136,25 +1137,33 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
 
         fn binding_suggestion<'tcx, S: fmt::Display>(
             err: &mut DiagnosticBuilder<'tcx>,
-            type_param_span: Option<(Span, bool)>,
+            type_param_span: Option<(Span, bool, bool)>,
             bound_kind: GenericKind<'tcx>,
             sub: S,
         ) {
-            let consider = &format!(
-                "consider adding an explicit lifetime bound `{}: {}`...",
-                bound_kind, sub
+            let consider = format!(
+                "consider adding an explicit lifetime bound {}",
+                if type_param_span.map(|(_, _, is_impl_trait)| is_impl_trait).unwrap_or(false) {
+                    format!(" `{}` to `{}`...", sub, bound_kind)
+                } else {
+                    format!("`{}: {}`...", bound_kind, sub)
+                },
             );
-            if let Some((sp, has_lifetimes)) = type_param_span {
-                let tail = if has_lifetimes { " + " } else { "" };
-                let suggestion = format!("{}: {}{}", bound_kind, sub, tail);
+            if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span {
+                let suggestion = if is_impl_trait {
+                    format!("{} + {}", bound_kind, sub)
+                } else {
+                    let tail = if has_lifetimes { " + " } else { "" };
+                    format!("{}: {}{}", bound_kind, sub, tail)
+                };
                 err.span_suggestion_short_with_applicability(
                     sp,
-                    consider,
+                    &consider,
                     suggestion,
                     Applicability::MaybeIncorrect, // Issue #41966
                 );
             } else {
-                err.help(consider);
+                err.help(&consider);
             }
         }
 
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index b7759a8c92b07..82145f61b26b1 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -365,6 +365,13 @@ pub mod parser {
     }
 }
 
+declare_lint! {
+    pub DEPRECATED_IN_FUTURE,
+    Allow,
+    "detects use of items that will be deprecated in a future version",
+    report_in_external_macro: true
+}
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// that are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -427,6 +434,7 @@ impl LintPass for HardwiredLints {
             MACRO_USE_EXTERN_CRATE,
             MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
             parser::QUESTION_MARK_MACRO_SEP,
+            DEPRECATED_IN_FUTURE,
         )
     }
 }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index e576951417f93..31a75bd106e2c 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1657,11 +1657,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn report_dead_assign(&self, hir_id: HirId, sp: Span, var: Variable, is_argument: bool) {
         if let Some(name) = self.should_warn(var) {
             if is_argument {
-                self.ir.tcx.lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp,
-                    &format!("value passed to `{}` is never read", name));
+                self.ir.tcx.struct_span_lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp,
+                &format!("value passed to `{}` is never read", name))
+                .help("maybe it is overwritten before being read?")
+                .emit();
             } else {
-                self.ir.tcx.lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp,
-                    &format!("value assigned to `{}` is never read", name));
+                self.ir.tcx.struct_span_lint_hir(lint::builtin::UNUSED_ASSIGNMENTS, hir_id, sp,
+                &format!("value assigned to `{}` is never read", name))
+                .help("maybe it is overwritten before being read?")
+                .emit();
             }
         }
     }
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index ab379c910f776..61341cbc30ce4 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -13,7 +13,7 @@
 
 pub use self::StabilityLevel::*;
 
-use lint;
+use lint::{self, Lint};
 use hir::{self, Item, Generics, StructField, Variant, HirId};
 use hir::def::Def;
 use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
@@ -562,18 +562,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             return EvalResult::Allow;
         }
 
-        let lint_deprecated = |def_id: DefId, id: NodeId, note: Option<Symbol>| {
-            let path = self.item_path_str(def_id);
-
+        let lint_deprecated = |def_id: DefId,
+                               id: NodeId,
+                               note: Option<Symbol>,
+                               message: &str,
+                               lint: &'static Lint| {
             let msg = if let Some(note) = note {
-                format!("use of deprecated item '{}': {}", path, note)
+                format!("{}: {}", message, note)
             } else {
-                format!("use of deprecated item '{}'", path)
+                format!("{}", message)
             };
 
-            self.lint_node(lint::builtin::DEPRECATED, id, span, &msg);
+            self.lint_node(lint, id, span, &msg);
             if id == ast::DUMMY_NODE_ID {
-                span_bug!(span, "emitted a deprecated lint with dummy node id: {:?}", def_id);
+                span_bug!(span, "emitted a {} lint with dummy node id: {:?}", lint.name, def_id);
             }
         };
 
@@ -584,17 +586,39 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 // version, then we should display no warning message.
                 let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since {
                     let since = sym.as_str();
-                    !deprecation_in_effect(&since)
+                    if !deprecation_in_effect(&since) {
+                        Some(since)
+                    } else {
+                        None
+                    }
                 } else {
-                    false
+                    None
                 };
 
                 let parent_def_id = self.hir().local_def_id(self.hir().get_parent(id));
-                let skip = deprecated_in_future_version ||
-                           self.lookup_deprecation_entry(parent_def_id)
+                let skip = self.lookup_deprecation_entry(parent_def_id)
                                .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry));
-                if !skip {
-                    lint_deprecated(def_id, id, depr_entry.attr.note);
+
+                if let Some(since) = deprecated_in_future_version {
+                    let path = self.item_path_str(def_id);
+                    let message = format!("use of item '{}' \
+                                           that will be deprecated in future version {}",
+                                          path,
+                                          since);
+
+                    lint_deprecated(def_id,
+                                    id,
+                                    depr_entry.attr.note,
+                                    &message,
+                                    lint::builtin::DEPRECATED_IN_FUTURE);
+                } else if !skip {
+                    let path = self.item_path_str(def_id);
+                    let message = format!("use of deprecated item '{}'", path);
+                    lint_deprecated(def_id,
+                                    id,
+                                    depr_entry.attr.note,
+                                    &message,
+                                    lint::builtin::DEPRECATED);
                 }
             };
         }
@@ -614,8 +638,24 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         if let Some(&Stability{rustc_depr: Some(attr::RustcDeprecation { reason, since }), ..})
                 = stability {
             if let Some(id) = id {
+                let path = self.item_path_str(def_id);
                 if deprecation_in_effect(&since.as_str()) {
-                    lint_deprecated(def_id, id, Some(reason));
+                    let message = format!("use of deprecated item '{}'", path);
+                    lint_deprecated(def_id,
+                                    id,
+                                    Some(reason),
+                                    &message,
+                                    lint::builtin::DEPRECATED);
+                } else {
+                    let message = format!("use of item '{}' \
+                                           that will be deprecated in future version {}",
+                                          path,
+                                          since);
+                    lint_deprecated(def_id,
+                                    id,
+                                    Some(reason),
+                                    &message,
+                                    lint::builtin::DEPRECATED_IN_FUTURE);
                 }
             }
         }
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 289f693df244d..8b16aafd314d7 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -183,50 +183,14 @@ pub struct EvalError<'tcx> {
 impl<'tcx> EvalError<'tcx> {
     pub fn print_backtrace(&mut self) {
         if let Some(ref mut backtrace) = self.backtrace {
-            eprintln!("{}", print_backtrace(&mut *backtrace));
+            print_backtrace(&mut *backtrace);
         }
     }
 }
 
-fn print_backtrace(backtrace: &mut Backtrace) -> String {
-    use std::fmt::Write;
-
+fn print_backtrace(backtrace: &mut Backtrace) {
     backtrace.resolve();
-
-    let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
-    write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
-    'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
-        if frame.symbols().is_empty() {
-            write!(trace_text, "  {}: no symbols\n", i).unwrap();
-        }
-        let mut first = true;
-        for symbol in frame.symbols() {
-            if first {
-                write!(trace_text, "  {}: ", i).unwrap();
-                first = false;
-            } else {
-                let len = i.to_string().len();
-                write!(trace_text, "  {}  ", " ".repeat(len)).unwrap();
-            }
-            if let Some(name) = symbol.name() {
-                write!(trace_text, "{}\n", name).unwrap();
-            } else {
-                write!(trace_text, "<unknown>\n").unwrap();
-            }
-            write!(trace_text, "           at ").unwrap();
-            if let Some(file_path) = symbol.filename() {
-                write!(trace_text, "{}", file_path.display()).unwrap();
-            } else {
-                write!(trace_text, "<unknown_file>").unwrap();
-            }
-            if let Some(line) = symbol.lineno() {
-                write!(trace_text, ":{}\n", line).unwrap();
-            } else {
-                write!(trace_text, "\n").unwrap();
-            }
-        }
-    }
-    trace_text
+    eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
 }
 
 impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
@@ -238,7 +202,7 @@ impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
 
                 if val == "immediate" {
                     // Print it now
-                    eprintln!("{}", print_backtrace(&mut backtrace));
+                    print_backtrace(&mut backtrace);
                     None
                 } else {
                     Some(Box::new(backtrace))
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index b1e44ea761c86..66364ff88b38d 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -376,7 +376,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
     store.register_removed("resolve_trait_on_defaulted_unit",
         "converted into hard error, see https://github.com/rust-lang/rust/issues/48950");
     store.register_removed("private_no_mangle_fns",
-        "no longer an warning, #[no_mangle] functions always exported");
+        "no longer a warning, #[no_mangle] functions always exported");
     store.register_removed("private_no_mangle_statics",
-        "no longer an warning, #[no_mangle] statics always exported");
+        "no longer a warning, #[no_mangle] statics always exported");
 }
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 5044e351962ed..0f8e4104c33c6 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -15,7 +15,7 @@ either = "1.5.0"
 graphviz = { path = "../libgraphviz" }
 log = "0.4"
 log_settings = "0.1.1"
-polonius-engine = "0.5.0"
+polonius-engine = "0.6.1"
 rustc = { path = "../librustc" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs
index 8af23a8813a9e..42d20e675bad9 100644
--- a/src/librustc_mir/borrow_check/nll/invalidation.rs
+++ b/src/librustc_mir/borrow_check/nll/invalidation.rs
@@ -66,10 +66,14 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> {
 /// Visits the whole MIR and generates invalidates() facts
 /// Most of the code implementing this was stolen from borrow_check/mod.rs
 impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
-    fn visit_statement(&mut self,
-                       block: BasicBlock,
-                       statement: &Statement<'tcx>,
-                       location: Location) {
+    fn visit_statement(
+        &mut self,
+        block: BasicBlock,
+        statement: &Statement<'tcx>,
+        location: Location,
+    ) {
+        self.check_activations(location);
+
         match statement.kind {
             StatementKind::Assign(ref lhs, ref rhs) => {
                 self.consume_rvalue(
@@ -159,6 +163,8 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
         terminator: &Terminator<'tcx>,
         location: Location
     ) {
+        self.check_activations(location);
+
         match terminator.kind {
             TerminatorKind::SwitchInt {
                 ref discr,
@@ -482,5 +488,41 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> {
         let lidx = self.location_table.start_index(l);
         self.all_facts.invalidates.push((lidx, b));
     }
+
+    fn check_activations(
+        &mut self,
+        location: Location,
+    ) {
+        if !self.tcx.two_phase_borrows() {
+            return;
+        }
+
+        // Two-phase borrow support: For each activation that is newly
+        // generated at this statement, check if it interferes with
+        // another borrow.
+        for &borrow_index in self.borrow_set.activations_at_location(location) {
+            let borrow = &self.borrow_set[borrow_index];
+
+            // only mutable borrows should be 2-phase
+            assert!(match borrow.kind {
+                BorrowKind::Shared | BorrowKind::Shallow => false,
+                BorrowKind::Unique | BorrowKind::Mut { .. } => true,
+            });
+
+            self.access_place(
+                ContextKind::Activation.new(location),
+                &borrow.borrowed_place,
+                (
+                    Deep,
+                    Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index),
+                ),
+                LocalMutationIsAllowed::No,
+            );
+
+            // We do not need to call `check_if_path_or_subpath_is_moved`
+            // again, as we already called it when we made the
+            // initial reservation.
+        }
+    }
 }
 
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 42ead92783d7a..a5d2edbc5d439 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -41,7 +41,6 @@ pub mod ast_validation;
 pub mod rvalue_promotion;
 pub mod hir_stats;
 pub mod loops;
-mod mir_stats;
 
 __build_diagnostic_array! { librustc_passes, DIAGNOSTICS }
 
diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs
deleted file mode 100644
index fb37f03a1cc41..0000000000000
--- a/src/librustc_passes/mir_stats.rs
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2016 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.
-
-// The visitors in this module collect sizes and counts of the most important
-// pieces of MIR. The resulting numbers are good approximations but not
-// completely accurate (some things might be counted twice, others missed).
-
-use rustc::mir::{AggregateKind, AssertMessage, BasicBlock, BasicBlockData};
-use rustc::mir::{Constant, Location, Local, LocalDecl};
-use rustc::mir::{Place, PlaceElem, PlaceProjection};
-use rustc::mir::{Mir, Operand, ProjectionElem};
-use rustc::mir::{Rvalue, SourceInfo, Statement, StatementKind};
-use rustc::mir::{Terminator, TerminatorKind, SourceScope, SourceScopeData};
-use rustc::mir::interpret::EvalErrorKind;
-use rustc::mir::visit as mir_visit;
-use rustc::ty::{self, ClosureSubsts, TyCtxt};
-use rustc::util::nodemap::{FxHashMap};
-
-struct NodeData {
-    count: usize,
-    size: usize,
-}
-
-struct StatCollector<'a, 'tcx: 'a> {
-    _tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    data: FxHashMap<&'static str, NodeData>,
-}
-
-impl<'a, 'tcx> StatCollector<'a, 'tcx> {
-
-    fn record_with_size(&mut self, label: &'static str, node_size: usize) {
-        let entry = self.data.entry(label).or_insert(NodeData {
-            count: 0,
-            size: 0,
-        });
-
-        entry.count += 1;
-        entry.size = node_size;
-    }
-
-    fn record<T>(&mut self, label: &'static str, node: &T) {
-        self.record_with_size(label, ::std::mem::size_of_val(node));
-    }
-}
-
-impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
-    fn visit_mir(&mut self, mir: &Mir<'tcx>) {
-        self.record("Mir", mir);
-
-        // since the `super_mir` method does not traverse the MIR of
-        // promoted rvalues, (but we still want to gather statistics
-        // on the structures represented there) we manually traverse
-        // the promoted rvalues here.
-        for promoted_mir in &mir.promoted {
-            self.visit_mir(promoted_mir);
-        }
-
-        self.super_mir(mir);
-    }
-
-    fn visit_basic_block_data(&mut self, block: BasicBlock, data: &BasicBlockData<'tcx>) {
-        self.record("BasicBlockData", data);
-        self.super_basic_block_data(block, data);
-    }
-
-    fn visit_source_scope_data(&mut self, scope_data: &SourceScopeData) {
-        self.record("SourceScopeData", scope_data);
-        self.super_source_scope_data(scope_data);
-    }
-
-    fn visit_statement(&mut self,
-                       block: BasicBlock,
-                       statement: &Statement<'tcx>,
-                       location: Location) {
-        self.record("Statement", statement);
-        self.record(match statement.kind {
-            StatementKind::Assign(..) => "StatementKind::Assign",
-            StatementKind::FakeRead(..) => "StatementKind::FakeRead",
-            StatementKind::Retag { .. } => "StatementKind::Retag",
-            StatementKind::EscapeToRaw { .. } => "StatementKind::EscapeToRaw",
-            StatementKind::SetDiscriminant { .. } => "StatementKind::SetDiscriminant",
-            StatementKind::StorageLive(..) => "StatementKind::StorageLive",
-            StatementKind::StorageDead(..) => "StatementKind::StorageDead",
-            StatementKind::InlineAsm { .. } => "StatementKind::InlineAsm",
-            StatementKind::AscribeUserType(..) => "StatementKind::AscribeUserType",
-            StatementKind::Nop => "StatementKind::Nop",
-        }, &statement.kind);
-        self.super_statement(block, statement, location);
-    }
-
-    fn visit_terminator(&mut self,
-                        block: BasicBlock,
-                        terminator: &Terminator<'tcx>,
-                        location: Location) {
-        self.record("Terminator", terminator);
-        self.super_terminator(block, terminator, location);
-    }
-
-    fn visit_terminator_kind(&mut self,
-                             block: BasicBlock,
-                             kind: &TerminatorKind<'tcx>,
-                             location: Location) {
-        self.record("TerminatorKind", kind);
-        self.record(match *kind {
-            TerminatorKind::Goto { .. } => "TerminatorKind::Goto",
-            TerminatorKind::SwitchInt { .. } => "TerminatorKind::SwitchInt",
-            TerminatorKind::Resume => "TerminatorKind::Resume",
-            TerminatorKind::Abort => "TerminatorKind::Abort",
-            TerminatorKind::Return => "TerminatorKind::Return",
-            TerminatorKind::Unreachable => "TerminatorKind::Unreachable",
-            TerminatorKind::Drop { .. } => "TerminatorKind::Drop",
-            TerminatorKind::DropAndReplace { .. } => "TerminatorKind::DropAndReplace",
-            TerminatorKind::Call { .. } => "TerminatorKind::Call",
-            TerminatorKind::Assert { .. } => "TerminatorKind::Assert",
-            TerminatorKind::GeneratorDrop => "TerminatorKind::GeneratorDrop",
-            TerminatorKind::Yield { .. } => "TerminatorKind::Yield",
-            TerminatorKind::FalseEdges { .. } => "TerminatorKind::FalseEdges",
-            TerminatorKind::FalseUnwind { .. } => "TerminatorKind::FalseUnwind",
-        }, kind);
-        self.super_terminator_kind(block, kind, location);
-    }
-
-    fn visit_assert_message(&mut self, msg: &AssertMessage<'tcx>, location: Location) {
-        self.record("AssertMessage", msg);
-        self.record(match *msg {
-            EvalErrorKind::BoundsCheck { .. } => "AssertMessage::BoundsCheck",
-            EvalErrorKind::Overflow(..) => "AssertMessage::Overflow",
-            EvalErrorKind::OverflowNeg => "AssertMessage::OverflowNeg",
-            EvalErrorKind::DivisionByZero => "AssertMessage::DivisionByZero",
-            EvalErrorKind::RemainderByZero => "AssertMessage::RemainderByZero",
-            EvalErrorKind::GeneratorResumedAfterReturn => {
-                "AssertMessage::GeneratorResumedAfterReturn"
-            }
-            EvalErrorKind::GeneratorResumedAfterPanic => {
-                "AssertMessage::GeneratorResumedAfterPanic"
-            }
-            _ => bug!(),
-        }, msg);
-        self.super_assert_message(msg, location);
-    }
-
-    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
-        self.record("Rvalue", rvalue);
-        let rvalue_kind = match *rvalue {
-            Rvalue::Use(..) => "Rvalue::Use",
-            Rvalue::Repeat(..) => "Rvalue::Repeat",
-            Rvalue::Ref(..) => "Rvalue::Ref",
-            Rvalue::Len(..) => "Rvalue::Len",
-            Rvalue::Cast(..) => "Rvalue::Cast",
-            Rvalue::BinaryOp(..) => "Rvalue::BinaryOp",
-            Rvalue::CheckedBinaryOp(..) => "Rvalue::CheckedBinaryOp",
-            Rvalue::UnaryOp(..) => "Rvalue::UnaryOp",
-            Rvalue::Discriminant(..) => "Rvalue::Discriminant",
-            Rvalue::NullaryOp(..) => "Rvalue::NullaryOp",
-            Rvalue::Aggregate(ref kind, ref _operands) => {
-                // AggregateKind is not distinguished by visit API, so
-                // record it. (`super_rvalue` handles `_operands`.)
-                self.record(match **kind {
-                    AggregateKind::Array(_) => "AggregateKind::Array",
-                    AggregateKind::Tuple => "AggregateKind::Tuple",
-                    AggregateKind::Adt(..) => "AggregateKind::Adt",
-                    AggregateKind::Closure(..) => "AggregateKind::Closure",
-                    AggregateKind::Generator(..) => "AggregateKind::Generator",
-                }, kind);
-
-                "Rvalue::Aggregate"
-            }
-        };
-        self.record(rvalue_kind, rvalue);
-        self.super_rvalue(rvalue, location);
-    }
-
-    fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
-        self.record("Operand", operand);
-        self.record(match *operand {
-            Operand::Copy(..) => "Operand::Copy",
-            Operand::Move(..) => "Operand::Move",
-            Operand::Constant(..) => "Operand::Constant",
-        }, operand);
-        self.super_operand(operand, location);
-    }
-
-    fn visit_place(&mut self,
-                    place: &Place<'tcx>,
-                    context: mir_visit::PlaceContext<'tcx>,
-                    location: Location) {
-        self.record("Place", place);
-        self.record(match *place {
-            Place::Local(..) => "Place::Local",
-            Place::Static(..) => "Place::Static",
-            Place::Promoted(..) => "Place::Promoted",
-            Place::Projection(..) => "Place::Projection",
-        }, place);
-        self.super_place(place, context, location);
-    }
-
-    fn visit_projection(&mut self,
-                        place: &PlaceProjection<'tcx>,
-                        context: mir_visit::PlaceContext<'tcx>,
-                        location: Location) {
-        self.record("PlaceProjection", place);
-        self.super_projection(place, context, location);
-    }
-
-    fn visit_projection_elem(&mut self,
-                             place: &PlaceElem<'tcx>,
-                             location: Location) {
-        self.record("PlaceElem", place);
-        self.record(match *place {
-            ProjectionElem::Deref => "PlaceElem::Deref",
-            ProjectionElem::Subslice { .. } => "PlaceElem::Subslice",
-            ProjectionElem::Field(..) => "PlaceElem::Field",
-            ProjectionElem::Index(..) => "PlaceElem::Index",
-            ProjectionElem::ConstantIndex { .. } => "PlaceElem::ConstantIndex",
-            ProjectionElem::Downcast(..) => "PlaceElem::Downcast",
-        }, place);
-        self.super_projection_elem(place, location);
-    }
-
-    fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
-        self.record("Constant", constant);
-        self.super_constant(constant, location);
-    }
-
-    fn visit_source_info(&mut self, source_info: &SourceInfo) {
-        self.record("SourceInfo", source_info);
-        self.super_source_info(source_info);
-    }
-
-    fn visit_closure_substs(&mut self, substs: &ClosureSubsts<'tcx>, _: Location) {
-        self.record("ClosureSubsts", substs);
-        self.super_closure_substs(substs);
-    }
-
-    fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
-        self.record("Const", constant);
-        self.super_const(constant);
-    }
-
-    fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
-        self.record("LocalDecl", local_decl);
-        self.super_local_decl(local, local_decl);
-    }
-
-    fn visit_source_scope(&mut self, scope: &SourceScope) {
-        self.record("VisiblityScope", scope);
-        self.super_source_scope(scope);
-    }
-}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index d8e8477f3d06b..aef8770bcc69b 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -68,6 +68,7 @@ mod linux_musl_base;
 mod openbsd_base;
 mod netbsd_base;
 mod solaris_base;
+mod uefi_base;
 mod windows_base;
 mod windows_msvc_base;
 mod thumb_base;
@@ -254,12 +255,12 @@ macro_rules! supported_targets {
             }
         }
 
-        pub fn get_targets() -> Box<dyn Iterator<Item=String>> {
-            Box::new(TARGETS.iter().filter_map(|t| -> Option<String> {
+        pub fn get_targets() -> impl Iterator<Item = String> {
+            TARGETS.iter().filter_map(|t| -> Option<String> {
                 load_specific(t)
                     .and(Ok(t.to_string()))
                     .ok()
-            }))
+            })
         }
 
         #[cfg(test)]
@@ -419,6 +420,8 @@ supported_targets! {
     ("aarch64-unknown-none", aarch64_unknown_none),
 
     ("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx),
+
+    ("x86_64-unknown-uefi", x86_64_unknown_uefi),
 }
 
 /// Everything `rustc` knows about how to compile for a specific target.
diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs
new file mode 100644
index 0000000000000..9b0515837600b
--- /dev/null
+++ b/src/librustc_target/spec/uefi_base.rs
@@ -0,0 +1,74 @@
+// 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.
+
+// This defines a base target-configuration for native UEFI systems. The UEFI specification has
+// quite detailed sections on the ABI of all the supported target architectures. In almost all
+// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN
+// documentation.
+// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic
+// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated
+// by the loader if the pre-chosen memory location is already in use.
+// UEFI forbids running code on anything but the boot-CPU. Not interrupts are allowed other than
+// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
+// code runs in the same environment, no process separation is supported.
+
+use spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    let mut pre_link_args = LinkArgs::new();
+
+    pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), vec![
+            // Suppress the verbose logo and authorship debugging output, which would needlessly
+            // clog any log files.
+            "/NOLOGO".to_string(),
+
+            // UEFI is fully compatible to non-executable data pages. Tell the compiler that
+            // non-code sections can be marked as non-executable, including stack pages.
+            "/NXCOMPAT".to_string(),
+
+            // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets
+            // must be freestanding.
+            "/nodefaultlib".to_string(),
+
+            // Non-standard subsystems have no default entry-point in PE+ files. We have to define
+            // one. "efi_main" seems to be a common choice amongst other implementations and the
+            // spec.
+            "/entry:efi_main".to_string(),
+
+            // COFF images have a "Subsystem" field in their header, which defines what kind of
+            // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
+            // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
+            // which is very likely the most common option. Individual projects can override this
+            // with custom linker flags.
+            // The subsystem-type only has minor effects on the application. It defines the memory
+            // regions the application is loaded into (runtime-drivers need to be put into
+            // reserved areas), as well as whether a return from the entry-point is treated as
+            // exit (default for applications).
+            "/subsystem:efi_application".to_string(),
+        ]);
+
+    TargetOptions {
+        dynamic_linking: false,
+        executables: true,
+        disable_redzone: true,
+        exe_suffix: ".efi".to_string(),
+        allows_weak_linkage: false,
+        panic_strategy: PanicStrategy::Abort,
+        singlethread: true,
+        emit_debug_gdb_scripts: false,
+
+        linker: Some("lld-link".to_string()),
+        lld_flavor: LldFlavor::Link,
+        pre_link_args,
+
+        .. Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
index 07383b3d64862..5b6d8abc5ef3e 100644
--- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
+++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
@@ -49,6 +49,7 @@ pub fn target() -> Result<Target, String> {
         max_atomic_width: Some(64),
         panic_strategy: PanicStrategy::Abort,
         cpu: "x86-64".into(),
+        features: "+rdrnd,+rdseed".into(),
         position_independent_executables: true,
         pre_link_args: iter::once(
                 (LinkerFlavor::Gcc, PRE_LINK_ARGS.iter().cloned().map(String::from).collect())
diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs
new file mode 100644
index 0000000000000..ea68afa717335
--- /dev/null
+++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs
@@ -0,0 +1,58 @@
+// 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.
+
+// This defines the amd64 target for UEFI systems as described in the UEFI specification. See the
+// uefi-base module for generic UEFI options. On x86_64 systems (mostly called "x64" in the spec)
+// UEFI systems always run in long-mode, have the interrupt-controller pre-configured and force a
+// single-CPU execution.
+// The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
+// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::uefi_base::opts();
+    base.cpu = "x86-64".to_string();
+    base.max_atomic_width = Some(64);
+
+    // We disable MMX and SSE for now. UEFI does not prevent these from being used, but there have
+    // been reports to GRUB that some firmware does not initialize the FP exception handlers
+    // properly. Therefore, using FP coprocessors will end you up at random memory locations when
+    // you throw FP exceptions.
+    // To be safe, we disable them for now and force soft-float. This can be revisited when we
+    // have more test coverage. Disabling FP served GRUB well so far, so it should be good for us
+    // as well.
+    base.features = "-mmx,-sse,+soft-float".to_string();
+
+    // UEFI systems run without a host OS, hence we cannot assume any code locality. We must tell
+    // LLVM to expect code to reference any address in the address-space. The "large" code-model
+    // places no locality-restrictions, so it fits well here.
+    base.code_model = Some("large".to_string());
+
+    // UEFI mostly mirrors the calling-conventions used on windows. In case of x86-64 this means
+    // small structs will be returned as int. This shouldn't matter much, since the restrictions
+    // placed by the UEFI specifications forbid any ABI to return structures.
+    base.abi_return_struct_as_int = true;
+
+    Ok(Target {
+        llvm_target: "x86_64-unknown-windows".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        target_os: "uefi".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        arch: "x86_64".to_string(),
+        linker_flavor: LinkerFlavor::Lld(LldFlavor::Link),
+
+        options: base,
+    })
+}
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index b76c9101eae02..09063579c4214 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -424,10 +424,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 }
 
                 if !unsatisfied_predicates.is_empty() {
-                    let bound_list = unsatisfied_predicates.iter()
+                    let mut bound_list = unsatisfied_predicates.iter()
                         .map(|p| format!("`{} : {}`", p.self_ty(), p))
-                        .collect::<Vec<_>>()
-                        .join("\n");
+                        .collect::<Vec<_>>();
+                    bound_list.sort();
+                    bound_list.dedup();  // #35677
+                    let bound_list = bound_list.join("\n");
                     err.note(&format!("the method `{}` exists but the following trait bounds \
                                        were not satisfied:\n{}",
                                       item_name,
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index f46c4f2938b99..7e155396b8d5e 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -72,32 +72,32 @@
 //!
 //! * **From Rust to C:** [`CString`] represents an owned, C-friendly
 //! string: it is nul-terminated, and has no internal nul characters.
-//! Rust code can create a `CString` out of a normal string (provided
+//! Rust code can create a [`CString`] out of a normal string (provided
 //! that the string doesn't have nul characters in the middle), and
-//! then use a variety of methods to obtain a raw `*mut u8` that can
+//! then use a variety of methods to obtain a raw `*mut `[`u8`] that can
 //! then be passed as an argument to functions which use the C
 //! conventions for strings.
 //!
 //! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
-//! is what you would use to wrap a raw `*const u8` that you got from
-//! a C function. A `CStr` is guaranteed to be a nul-terminated array
-//! of bytes. Once you have a `CStr`, you can convert it to a Rust
-//! `&str` if it's valid UTF-8, or lossily convert it by adding
+//! is what you would use to wrap a raw `*const `[`u8`] that you got from
+//! a C function. A [`CStr`] is guaranteed to be a nul-terminated array
+//! of bytes. Once you have a [`CStr`], you can convert it to a Rust
+//! [`&str`][`str`] if it's valid UTF-8, or lossily convert it by adding
 //! replacement characters.
 //!
 //! [`OsString`] and [`OsStr`] are useful when you need to transfer
 //! strings to and from the operating system itself, or when capturing
-//! the output of external commands. Conversions between `OsString`,
-//! `OsStr` and Rust strings work similarly to those for [`CString`]
+//! the output of external commands. Conversions between [`OsString`],
+//! [`OsStr`] and Rust strings work similarly to those for [`CString`]
 //! and [`CStr`].
 //!
 //! * [`OsString`] represents an owned string in whatever
 //! representation the operating system prefers. In the Rust standard
 //! library, various APIs that transfer strings to/from the operating
-//! system use `OsString` instead of plain strings. For example,
+//! system use [`OsString`] instead of plain strings. For example,
 //! [`env::var_os()`] is used to query environment variables; it
-//! returns an `Option<OsString>`. If the environment variable exists
-//! you will get a `Some(os_string)`, which you can *then* try to
+//! returns an [`Option`]`<`[`OsString`]`>`. If the environment variable
+//! exists you will get a [`Some`]`(os_string)`, which you can *then* try to
 //! convert to a Rust string. This yields a [`Result<>`], so that
 //! your code can detect errors in case the environment variable did
 //! not in fact contain valid Unicode data.
@@ -105,7 +105,7 @@
 //! * [`OsStr`] represents a borrowed reference to a string in a
 //! format that can be passed to the operating system. It can be
 //! converted into an UTF-8 Rust string slice in a similar way to
-//! `OsString`.
+//! [`OsString`].
 //!
 //! # Conversions
 //!
@@ -131,7 +131,7 @@
 //! Additionally, on Windows [`OsString`] implements the
 //! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
 //! trait, which provides a [`from_wide`] method. The result of this
-//! method is an `OsString` which can be round-tripped to a Windows
+//! method is an [`OsString`] which can be round-tripped to a Windows
 //! string losslessly.
 //!
 //! [`String`]: ../string/struct.String.html
@@ -160,6 +160,8 @@
 //! [`collect`]: ../iter/trait.Iterator.html#method.collect
 //! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
 //! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide
+//! [`Option`]: ../option/enum.Option.html
+//! [`Some`]: ../option/enum.Option.html#variant.Some
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index d581ba1de23f2..edcfdd9e53483 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -195,9 +195,10 @@ pub struct OpenOptions(fs_imp::OpenOptions);
 /// This module only currently provides one bit of information, [`readonly`],
 /// which is exposed on all currently supported platforms. Unix-specific
 /// functionality, such as mode bits, is available through the
-/// `os::unix::PermissionsExt` trait.
+/// [`PermissionsExt`] trait.
 ///
 /// [`readonly`]: struct.Permissions.html#method.readonly
+/// [`PermissionsExt`]: ../os/unix/fs/trait.PermissionsExt.html
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Permissions(fs_imp::FilePermissions);
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index f4e9a7e409359..03c7aa9682477 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{self, Block, Ident, NodeId, PatKind, Path};
+use ast::{self, Block, Ident, LitKind, NodeId, PatKind, Path};
 use ast::{MacStmtStyle, StmtKind, ItemKind};
 use attr::{self, HasAttrs};
 use source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan};
@@ -1535,21 +1535,65 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
                             let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info);
                             items.push(dummy_spanned(ast::NestedMetaItemKind::MetaItem(item)));
                         }
-                        Err(ref e) if e.kind() == ErrorKind::InvalidData => {
-                            self.cx.span_err(
-                                at.span,
-                                &format!("{} wasn't a utf-8 file", filename.display()),
-                            );
-                        }
                         Err(e) => {
-                            self.cx.span_err(
-                                at.span,
-                                &format!("couldn't read {}: {}", filename.display(), e),
-                            );
+                            let lit = it
+                                .meta_item()
+                                .and_then(|item| item.name_value_literal())
+                                .unwrap();
+
+                            if e.kind() == ErrorKind::InvalidData {
+                                self.cx
+                                    .struct_span_err(
+                                        lit.span,
+                                        &format!("{} wasn't a utf-8 file", filename.display()),
+                                    )
+                                    .span_label(lit.span, "contains invalid utf-8")
+                                    .emit();
+                            } else {
+                                let mut err = self.cx.struct_span_err(
+                                    lit.span,
+                                    &format!("couldn't read {}: {}", filename.display(), e),
+                                );
+                                err.span_label(lit.span, "couldn't read file");
+
+                                if e.kind() == ErrorKind::NotFound {
+                                    err.help("external doc paths are relative to the crate root");
+                                }
+
+                                err.emit();
+                            }
                         }
                     }
                 } else {
-                    items.push(noop_fold_meta_list_item(it, self));
+                    let mut err = self.cx.struct_span_err(
+                        it.span,
+                        &format!("expected path to external documentation"),
+                    );
+
+                    // Check if the user erroneously used `doc(include(...))` syntax.
+                    let literal = it.meta_item_list().and_then(|list| {
+                        if list.len() == 1 {
+                            list[0].literal().map(|literal| &literal.node)
+                        } else {
+                            None
+                        }
+                    });
+
+                    let (path, applicability) = match &literal {
+                        Some(LitKind::Str(path, ..)) => {
+                            (path.to_string(), Applicability::MachineApplicable)
+                        }
+                        _ => (String::from("<path>"), Applicability::HasPlaceholders),
+                    };
+
+                    err.span_suggestion_with_applicability(
+                        it.span,
+                        "provide a file path with `=`",
+                        format!("include = \"{}\"", path),
+                        applicability,
+                    );
+
+                    err.emit();
                 }
             }
 
diff --git a/src/stdsimd b/src/stdsimd
index 5e628c5120c61..3c0503db84399 160000
--- a/src/stdsimd
+++ b/src/stdsimd
@@ -1 +1 @@
-Subproject commit 5e628c5120c619a22799187371f057ec41e06f87
+Subproject commit 3c0503db8439928e42c1175f0009c506fc874ae9
diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs
new file mode 100644
index 0000000000000..4bb5c59722ad1
--- /dev/null
+++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs
@@ -0,0 +1,47 @@
+#![deny(unused_must_use)]
+#![feature(futures_api, pin, arbitrary_self_types)]
+
+use std::iter::Iterator;
+use std::future::Future;
+
+use std::task::{Poll, LocalWaker};
+use std::pin::Pin;
+use std::unimplemented;
+
+struct MyFuture;
+
+impl Future for MyFuture {
+   type Output = u32;
+
+   fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<u32> {
+      Poll::Pending
+   }
+}
+
+fn iterator() -> impl Iterator {
+   std::iter::empty::<u32>()
+}
+
+fn future() -> impl Future {
+   MyFuture
+}
+
+fn square_fn_once() -> impl FnOnce(u32) -> u32 {
+   |x| x * x
+}
+
+fn square_fn_mut() -> impl FnMut(u32) -> u32 {
+   |x| x * x
+}
+
+fn square_fn() -> impl Fn(u32) -> u32 {
+   |x| x * x
+}
+
+fn main() {
+   iterator(); //~ ERROR unused implementer of `std::iter::Iterator` that must be used
+   future(); //~ ERROR unused implementer of `std::future::Future` that must be used
+   square_fn_once(); //~ ERROR unused implementer of `std::ops::FnOnce` that must be used
+   square_fn_mut(); //~ ERROR unused implementer of `std::ops::FnMut` that must be used
+   square_fn(); //~ ERROR unused implementer of `std::ops::Fn` that must be used
+}
diff --git a/src/test/ui/deprecation/deprecation-in-future.rs b/src/test/ui/deprecation/deprecation-in-future.rs
new file mode 100644
index 0000000000000..c6c60177e9d0e
--- /dev/null
+++ b/src/test/ui/deprecation/deprecation-in-future.rs
@@ -0,0 +1,12 @@
+// ignore-tidy-linelength
+
+#![deny(deprecated_in_future)]
+
+#[deprecated(since = "99.99.99", note = "text")]
+pub fn deprecated_future() {}
+
+fn test() {
+    deprecated_future(); //~ ERROR use of item 'deprecated_future' that will be deprecated in future version 99.99.99: text
+}
+
+fn main() {}
diff --git a/src/test/ui/deprecation/deprecation-in-future.stderr b/src/test/ui/deprecation/deprecation-in-future.stderr
new file mode 100644
index 0000000000000..38392cf96084c
--- /dev/null
+++ b/src/test/ui/deprecation/deprecation-in-future.stderr
@@ -0,0 +1,14 @@
+error: use of item 'deprecated_future' that will be deprecated in future version 99.99.99: text
+  --> $DIR/deprecation-in-future.rs:9:5
+   |
+LL |     deprecated_future(); //~ ERROR use of item 'deprecated_future' that will be deprecated in future version 99.99.99: text
+   |     ^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/deprecation-in-future.rs:3:9
+   |
+LL | #![deny(deprecated_in_future)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/extern/auxiliary/invalid-utf8.txt b/src/test/ui/extern/auxiliary/invalid-utf8.txt
new file mode 100644
index 0000000000000..dc1115b82db40
--- /dev/null
+++ b/src/test/ui/extern/auxiliary/invalid-utf8.txt
@@ -0,0 +1 @@
+�(
\ No newline at end of file
diff --git a/src/test/ui/extern/external-doc-error.rs b/src/test/ui/extern/external-doc-error.rs
index 5c6f6e49b3d77..e17dda65568e9 100644
--- a/src/test/ui/extern/external-doc-error.rs
+++ b/src/test/ui/extern/external-doc-error.rs
@@ -2,7 +2,31 @@
 
 #![feature(external_doc)]
 
-#[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
-pub struct SomeStruct;
+#[doc(include = "not-a-file.md")]
+pub struct SomeStruct; //~^ ERROR couldn't read
+                       //~| HELP external doc paths are relative to the crate root
+
+#[doc(include = "auxiliary/invalid-utf8.txt")]
+pub struct InvalidUtf8; //~^ ERROR wasn't a utf-8 file
+
+#[doc(include)]
+pub struct MissingPath; //~^ ERROR expected path
+                        //~| HELP provide a file path with `=`
+                        //~| SUGGESTION include = "<path>"
+
+#[doc(include("../README.md"))]
+pub struct InvalidPathSyntax; //~^ ERROR expected path
+                              //~| HELP provide a file path with `=`
+                              //~| SUGGESTION include = "../README.md"
+
+#[doc(include = 123)]
+pub struct InvalidPathType; //~^ ERROR expected path
+                            //~| HELP provide a file path with `=`
+                            //~| SUGGESTION include = "<path>"
+
+#[doc(include(123))]
+pub struct InvalidPathSyntaxAndType; //~^ ERROR expected path
+                                     //~| HELP provide a file path with `=`
+                                     //~| SUGGESTION include = "<path>"
 
 fn main() {}
diff --git a/src/test/ui/extern/external-doc-error.stderr b/src/test/ui/extern/external-doc-error.stderr
index 5cc7551ee03aa..a3be3277de545 100644
--- a/src/test/ui/extern/external-doc-error.stderr
+++ b/src/test/ui/extern/external-doc-error.stderr
@@ -1,8 +1,40 @@
 error: couldn't read $DIR/not-a-file.md: $FILE_NOT_FOUND_MSG (os error 2)
-  --> $DIR/external-doc-error.rs:5:1
+  --> $DIR/external-doc-error.rs:5:17
    |
-LL | #[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[doc(include = "not-a-file.md")]
+   |                 ^^^^^^^^^^^^^^^ couldn't read file
+   |
+   = help: external doc paths are relative to the crate root
+
+error: $DIR/auxiliary/invalid-utf8.txt wasn't a utf-8 file
+  --> $DIR/external-doc-error.rs:9:17
+   |
+LL | #[doc(include = "auxiliary/invalid-utf8.txt")]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ contains invalid utf-8
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:12:7
+   |
+LL | #[doc(include)]
+   |       ^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:17:7
+   |
+LL | #[doc(include("../README.md"))]
+   |       ^^^^^^^^^^^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "../README.md"`
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:22:7
+   |
+LL | #[doc(include = 123)]
+   |       ^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:27:7
+   |
+LL | #[doc(include(123))]
+   |       ^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
 
-error: aborting due to previous error
+error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr
index e2630b5b8ce47..ed6b325a01d4d 100644
--- a/src/test/ui/issues/issue-31173.stderr
+++ b/src/test/ui/issues/issue-31173.stderr
@@ -14,8 +14,8 @@ LL |         .collect(); //~ ERROR no method named `collect`
    |          ^^^^^^^
    |
    = note: the method `collect` exists but the following trait bounds were not satisfied:
-           `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
            `&mut std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
+           `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-35677.rs b/src/test/ui/issues/issue-35677.rs
new file mode 100644
index 0000000000000..46d3f7e4af00b
--- /dev/null
+++ b/src/test/ui/issues/issue-35677.rs
@@ -0,0 +1,5 @@
+use std::collections::HashMap;
+fn intersect_map<K, V>(this: &mut HashMap<K, V>, other: HashMap<K, V>) -> bool {
+    this.drain()
+    //~^ ERROR no method named
+}
diff --git a/src/test/ui/issues/issue-35677.stderr b/src/test/ui/issues/issue-35677.stderr
new file mode 100644
index 0000000000000..dca096b93f5f3
--- /dev/null
+++ b/src/test/ui/issues/issue-35677.stderr
@@ -0,0 +1,18 @@
+error[E0601]: `main` function not found in crate `issue_35677`
+   |
+   = note: consider adding a `main` function to `$DIR/issue-35677.rs`
+
+error[E0599]: no method named `drain` found for type `&mut std::collections::HashMap<K, V>` in the current scope
+  --> $DIR/issue-35677.rs:3:10
+   |
+LL |     this.drain()
+   |          ^^^^^
+   |
+   = note: the method `drain` exists but the following trait bounds were not satisfied:
+           `K : std::cmp::Eq`
+           `K : std::hash::Hash`
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0599, E0601.
+For more information about an error, try `rustc --explain E0599`.
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
index a8b0e3e4250ea..6b9e1dc70573e 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -55,6 +55,7 @@ note: lint level defined here
 LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
    |         ^^^^^^
    = note: #[warn(unused_assignments)] implied by #[warn(unused)]
+   = help: maybe it is overwritten before being read?
 
 warning: unused variable: `fire`
   --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:54:32
diff --git a/src/test/ui/lint/lint-unexported-no-mangle.stderr b/src/test/ui/lint/lint-unexported-no-mangle.stderr
index 063915d5b5f9a..1df2d7babe91b 100644
--- a/src/test/ui/lint/lint-unexported-no-mangle.stderr
+++ b/src/test/ui/lint/lint-unexported-no-mangle.stderr
@@ -1,8 +1,8 @@
-warning: lint `private_no_mangle_fns` has been removed: `no longer an warning, #[no_mangle] functions always exported`
+warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, #[no_mangle] functions always exported`
    |
    = note: requested on the command line with `-F private_no_mangle_fns`
 
-warning: lint `private_no_mangle_statics` has been removed: `no longer an warning, #[no_mangle] statics always exported`
+warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, #[no_mangle] statics always exported`
    |
    = note: requested on the command line with `-F private_no_mangle_statics`
 
diff --git a/src/test/ui/liveness/liveness-dead.stderr b/src/test/ui/liveness/liveness-dead.stderr
index 6709fee0abb72..6e43cccdccff2 100644
--- a/src/test/ui/liveness/liveness-dead.stderr
+++ b/src/test/ui/liveness/liveness-dead.stderr
@@ -9,24 +9,31 @@ note: lint level defined here
    |
 LL | #![deny(unused_assignments)]
    |         ^^^^^^^^^^^^^^^^^^
+   = help: maybe it is overwritten before being read?
 
 error: value assigned to `x` is never read
   --> $DIR/liveness-dead.rs:27:5
    |
 LL |     x = 4; //~ ERROR: value assigned to `x` is never read
    |     ^
+   |
+   = help: maybe it is overwritten before being read?
 
 error: value passed to `x` is never read
   --> $DIR/liveness-dead.rs:30:11
    |
 LL | fn f4(mut x: i32) { //~ ERROR: value passed to `x` is never read
    |           ^
+   |
+   = help: maybe it is overwritten before being read?
 
 error: value assigned to `x` is never read
   --> $DIR/liveness-dead.rs:37:5
    |
 LL |     x = 4; //~ ERROR: value assigned to `x` is never read
    |     ^
+   |
+   = help: maybe it is overwritten before being read?
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr
index 2846f242fbe4c..35ccc79a19ac0 100644
--- a/src/test/ui/liveness/liveness-unused.stderr
+++ b/src/test/ui/liveness/liveness-unused.stderr
@@ -60,6 +60,7 @@ note: lint level defined here
    |
 LL | #![deny(unused_assignments)]
    |         ^^^^^^^^^^^^^^^^^^
+   = help: maybe it is overwritten before being read?
 
 error: variable `z` is assigned to, but never used
   --> $DIR/liveness-unused.rs:47:13
@@ -106,6 +107,8 @@ error: value assigned to `x` is never read
    |
 LL |         x = 0;  //~ ERROR value assigned to `x` is never read
    |         ^
+   |
+   = help: maybe it is overwritten before being read?
 
 error: aborting due to 13 previous errors
 
diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr
index 86a92a70287e9..1fbac9d688140 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.stderr
+++ b/src/test/ui/mismatched_types/issue-36053-2.stderr
@@ -5,8 +5,8 @@ LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
    |                                                       ^^^^^
    |
    = note: the method `count` exists but the following trait bounds were not satisfied:
-           `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
            `&mut std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
+           `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/issue-36053-2.rs:17:32
diff --git a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
new file mode 100644
index 0000000000000..24676fe5e5bd9
--- /dev/null
+++ b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
@@ -0,0 +1,74 @@
+// This is a collection of examples where a function's formal
+// parameter has an explicit lifetime and a closure within that
+// function returns that formal parameter. The closure's return type,
+// to be correctly inferred, needs to include the lifetime introduced
+// by the function.
+//
+// This works today, which precludes changing things so that closures
+// follow the same lifetime-elision rules used elsehwere. See
+// rust-lang/rust#56537
+
+// compile-pass
+// We are already testing NLL explicitly via the revision system below.
+// ignore-compare-mode-nll
+
+// revisions: ll nll migrate
+//[ll] compile-flags:-Zborrowck=ast
+//[nll] compile-flags:-Zborrowck=mir -Z two-phase-borrows
+//[migrate] compile-flags:-Zborrowck=migrate -Z two-phase-borrows
+
+fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x| { p }; // no type annotation at all
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x| -> &str { p }; // type annotation on the return type
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x| -> &'w str { p }; // type+region annotation on return type
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_arg_type_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x: &str| -> &str { p }; // type annotation on arg and return types
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_arg_type_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x: &str| -> &'w str { p }; // fully annotated
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn main() {
+    let world = format!("World");
+    let w1: &str = {
+        let hello = format!("He11o");
+        willy_no_annot(&world, &hello)
+    };
+    let w2: &str = {
+        let hello = format!("He22o");
+        willy_ret_type_annot(&world, &hello)
+    };
+    let w3: &str = {
+        let hello = format!("He33o");
+        willy_ret_region_annot(&world, &hello)
+    };
+    let w4: &str = {
+        let hello = format!("He44o");
+        willy_arg_type_ret_type_annot(&world, &hello)
+    };
+    let w5: &str = {
+        let hello = format!("He55o");
+        willy_arg_type_ret_region_annot(&world, &hello)
+    };
+    assert_eq!((w1, w2, w3, w4, w5),
+               ("World","World","World","World","World"));
+}
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
new file mode 100644
index 0000000000000..8592af1262e6f
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+
+use std::fmt::Debug;
+
+fn foo(d: impl Debug + 'static) {
+//~^ HELP consider adding an explicit lifetime bound  `'static` to `impl Debug`
+    bar(d);
+//~^ ERROR the parameter type `impl Debug` may not live long enough
+//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
+}
+
+fn bar(d: impl Debug + 'static) {
+    println!("{:?}", d)
+}
+
+fn main() {
+  foo("hi");
+}
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
new file mode 100644
index 0000000000000..c67d78ea4c73b
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
@@ -0,0 +1,18 @@
+// run-rustfix
+
+use std::fmt::Debug;
+
+fn foo(d: impl Debug) {
+//~^ HELP consider adding an explicit lifetime bound  `'static` to `impl Debug`
+    bar(d);
+//~^ ERROR the parameter type `impl Debug` may not live long enough
+//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
+}
+
+fn bar(d: impl Debug + 'static) {
+    println!("{:?}", d)
+}
+
+fn main() {
+  foo("hi");
+}
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
new file mode 100644
index 0000000000000..cba231d0e86e5
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
@@ -0,0 +1,19 @@
+error[E0310]: the parameter type `impl Debug` may not live long enough
+  --> $DIR/suggest-impl-trait-lifetime.rs:7:5
+   |
+LL |     bar(d);
+   |     ^^^
+   |
+note: ...so that the type `impl Debug` will meet its required lifetime bounds
+  --> $DIR/suggest-impl-trait-lifetime.rs:7:5
+   |
+LL |     bar(d);
+   |     ^^^
+help: consider adding an explicit lifetime bound  `'static` to `impl Debug`...
+   |
+LL | fn foo(d: impl Debug + 'static) {
+   |           ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 4ade87f5d65bd..a65d263d2e3a3 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -34,6 +34,16 @@
     'rust-by-example': '@steveklabnik @marioidival @projektir',
 }
 
+EMOJI = {
+    'miri': '🛰️',
+    'clippy-driver': '📎',
+    'rls': '💻',
+    'rustfmt': '📝',
+    'book': '📖',
+    'nomicon': '👿',
+    'reference': '📚',
+    'rust-by-example': '👩‍🏫',
+}
 
 def read_current_status(current_commit, path):
     '''Reads build status of `current_commit` from content of `history/*.tsv`
@@ -63,13 +73,12 @@ def update_latest(
         }
 
         slug = 'rust-lang/rust'
-        message = textwrap.dedent('''\
-            📣 Toolstate changed by {}!
-
+        long_message = textwrap.dedent('''\
             Tested on commit {}@{}.
             Direct link to PR: <{}>
 
-        ''').format(relevant_pr_number, slug, current_commit, relevant_pr_url)
+        ''').format(slug, current_commit, relevant_pr_url)
+        emoji_status = []
         anything_changed = False
         for status in latest:
             tool = status['tool']
@@ -81,12 +90,18 @@ def update_latest(
                 status[os] = new
                 if new > old:
                     changed = True
-                    message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
-                        .format(tool, os, old, new, MAINTAINERS.get(tool))
+                    long_message += '🎉 {} on {}: {} → {}.\n' \
+                        .format(tool, os, old, new)
+                    emoji = "{}🎉".format(EMOJI.get(tool))
+                    if msg not in emoji_status:
+                        emoji_status += [msg]
                 elif new < old:
                     changed = True
-                    message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
+                    long_message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
                         .format(tool, os, old, new, MAINTAINERS.get(tool))
+                    emoji = "{}💔".format(EMOJI.get(tool))
+                    if msg not in emoji_status:
+                        emoji_status += [msg]
 
             if changed:
                 status['commit'] = current_commit
@@ -96,6 +111,9 @@ def update_latest(
         if not anything_changed:
             return ''
 
+        short_message = "📣 Toolstate changed by {}! ({})"
+            .format(relevant_pr_number, '/'.join(emoji_status))
+        message = short_message + "\n\n" + long_message
         f.seek(0)
         f.truncate(0)
         json.dump(latest, f, indent=4, separators=(',', ': '))