diff --git a/COPYRIGHT b/COPYRIGHT
index 9bc018d983d7d..e2d0ed77224e3 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -10,8 +10,8 @@ Copyrights in the Rust project are retained by their contributors. No
 copyright assignment is required to contribute to the Rust project.
 
 Some files include explicit copyright notices and/or license notices.
-For full authorship information, see AUTHORS.txt and the version control
-history.
+For full authorship information, see the version control history or
+https://thanks.rust-lang.org
 
 Except as otherwise noted (below and/or in individual files), Rust is
 licensed under the Apache License, Version 2.0 <LICENSE-APACHE> or
diff --git a/RELEASES.md b/RELEASES.md
index b983851f88198..13042ab07e217 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -94,9 +94,9 @@ Misc
 
 Compatibility Notes
 -------------------
-- [Rust will no longer consider trait objects with duplicated constraints to
-  have implementations.][51276] For example the below code will now fail
-  to compile.
+- [Rust will consider trait objects with duplicated constraints to be the same
+  type as without the duplicated constraint.][51276] For example the below code will
+  now fail to compile.
   ```rust
   trait Trait {}
 
@@ -160,6 +160,17 @@ Compatibility Notes
 [`{Any + Send + Sync}::downcast_ref`]: https://doc.rust-lang.org/std/any/trait.Any.html#method.downcast_ref-2
 [`{Any + Send + Sync}::is`]: https://doc.rust-lang.org/std/any/trait.Any.html#method.is-2
 
+Version 1.27.2 (2018-07-20)
+===========================
+
+Compatibility Notes
+-------------------
+
+- The borrow checker was fixed to avoid potential unsoundness when using
+  match ergonomics: [#52213][52213].
+
+[52213]: https://github.com/rust-lang/rust/issues/52213
+
 Version 1.27.1 (2018-07-10)
 ===========================
 
@@ -190,7 +201,7 @@ Version 1.27.0 (2018-06-21)
 Language
 --------
 - [Removed 'proc' from the reserved keywords list.][49699] This allows `proc` to
-  be used as an identifer.
+  be used as an identifier.
 - [The dyn syntax is now available.][49968] This syntax is equivalent to the
   bare `Trait` syntax, and should make it clearer when being used in tandem with
   `impl Trait`. Since it is equivalent to the following syntax:
@@ -4795,7 +4806,7 @@ Language
 --------
 
 * Patterns with `ref mut` now correctly invoke [`DerefMut`] when
-  matching against dereferencable values.
+  matching against dereferenceable values.
 
 Libraries
 ---------
diff --git a/src/Cargo.lock b/src/Cargo.lock
index be32872dad80a..b2e41589893cc 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -2612,18 +2612,9 @@ dependencies = [
  "rustc_lsan 0.0.0",
  "rustc_msan 0.0.0",
  "rustc_tsan 0.0.0",
- "std_unicode 0.0.0",
  "unwind 0.0.0",
 ]
 
-[[package]]
-name = "std_unicode"
-version = "0.0.0"
-dependencies = [
- "compiler_builtins 0.0.0",
- "core 0.0.0",
-]
-
 [[package]]
 name = "string_cache"
 version = "0.7.3"
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 71c1c61e3d97e..829487163a945 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -88,7 +88,10 @@ def _download(path, url, probably_big, verbose, exception):
             option = "-#"
         else:
             option = "-s"
-        run(["curl", option, "--retry", "3", "-Sf", "-o", path, url],
+        run(["curl", option,
+             "-y", "30", "-Y", "10",    # timeout if speed is < 10 bytes/sec for > 30 seconds
+             "--connect-timeout", "30", # timeout if cannot connect within 30 seconds
+             "--retry", "3", "-Sf", "-o", path, url],
             verbose=verbose,
             exception=exception)
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 04e8e133b03a1..8c4f2df60fe6f 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -157,7 +157,6 @@ pub fn std_cargo(builder: &Builder,
         cargo.arg("--features").arg("c mem")
             .args(&["-p", "alloc"])
             .args(&["-p", "compiler_builtins"])
-            .args(&["-p", "std_unicode"])
             .arg("--manifest-path")
             .arg(builder.src.join("src/rustc/compiler_builtins_shim/Cargo.toml"));
     } else {
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index c6b39a52ae135..188e64cd668dd 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -856,7 +856,6 @@ impl Step for Src {
             "src/librustc_msan",
             "src/librustc_tsan",
             "src/libstd",
-            "src/libstd_unicode",
             "src/libunwind",
             "src/rustc/compiler_builtins_shim",
             "src/rustc/libc_shim",
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 9dbbe6bcfe490..ed9b5b1773fae 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -489,7 +489,7 @@ impl Step for Std {
         // Keep a whitelist so we do not build internal stdlib crates, these will be
         // build by the rustc step later if enabled.
         cargo.arg("--no-deps");
-        for krate in &["alloc", "core", "std", "std_unicode"] {
+        for krate in &["alloc", "core", "std"] {
             cargo.arg("-p").arg(krate);
             // Create all crate output directories first to make sure rustdoc uses
             // relative links.
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 6a013053e580c..60b4d65f44401 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -121,7 +121,10 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`"
         opts.optmulti("", "exclude", "build paths to exclude", "PATH");
         opts.optopt("", "on-fail", "command to run on failure", "CMD");
         opts.optflag("", "dry-run", "dry run; don't build anything");
-        opts.optopt("", "stage", "stage to build", "N");
+        opts.optopt("", "stage",
+            "stage to build (indicates compiler to use/test, e.g. stage 0 uses the \
+             bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)",
+            "N");
         opts.optmulti("", "keep-stage", "stage(s) to keep without recompiling", "N");
         opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
         opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
@@ -258,7 +261,7 @@ Arguments:
 
         ./x.py build --stage 1 src/libtest
 
-    This will first build everything once (like --stage 0 without further
+    This will first build everything once (like `--stage 0` without further
     arguments would), and then use the compiler built in stage 0 to build
     src/libtest and its dependencies.
     Once this is done, build/$ARCH/stage1 contains a usable compiler.",
@@ -290,10 +293,14 @@ Arguments:
 
         ./x.py test src/test/run-pass
         ./x.py test src/libstd --test-args hash_map
-        ./x.py test src/libstd --stage 0
+        ./x.py test src/libstd --stage 0 --no-doc
         ./x.py test src/test/ui --bless
         ./x.py test src/test/ui --compare-mode nll
 
+    Note that `test src/test/* --stage N` does NOT depend on `build src/rustc --stage N`;
+    just like `build src/libstd --stage N` it tests the compiler produced by the previous
+    stage.
+
     If no arguments are passed then the complete artifacts for that stage are
     compiled and tested.
 
diff --git a/src/doc/man/rustdoc.1 b/src/doc/man/rustdoc.1
index a878380f556b3..d7f78e8f6f4de 100644
--- a/src/doc/man/rustdoc.1
+++ b/src/doc/man/rustdoc.1
@@ -119,7 +119,7 @@ See <\fBhttps://github.com/rust\-lang/rust/issues\fR>
 for issues.
 
 .SH "AUTHOR"
-See \fIAUTHORS.txt\fR in the Rust source distribution.
+See the version control history or <\fBhttps://thanks.rust\-lang.org\fR>
 
 .SH "COPYRIGHT"
 This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
diff --git a/src/etc/debugger_pretty_printers_common.py b/src/etc/debugger_pretty_printers_common.py
index 4a38d4be083fd..87c7b21bb8a35 100644
--- a/src/etc/debugger_pretty_printers_common.py
+++ b/src/etc/debugger_pretty_printers_common.py
@@ -47,6 +47,7 @@
 TYPE_KIND_FIXED_SIZE_VEC    = 16
 TYPE_KIND_REGULAR_UNION     = 17
 TYPE_KIND_OS_STRING         = 18
+TYPE_KIND_STD_VECDEQUE      = 19
 
 ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$"
 ENUM_DISR_FIELD_NAME = "RUST$ENUM$DISR"
@@ -62,6 +63,14 @@
 STD_VEC_FIELD_NAMES = [STD_VEC_FIELD_NAME_BUF,
                        STD_VEC_FIELD_NAME_LENGTH]
 
+# std::collections::VecDeque<> related constants
+STD_VECDEQUE_FIELD_NAME_TAIL = "tail"
+STD_VECDEQUE_FIELD_NAME_HEAD = "head"
+STD_VECDEQUE_FIELD_NAME_BUF = "buf"
+STD_VECDEQUE_FIELD_NAMES = [STD_VECDEQUE_FIELD_NAME_TAIL,
+                            STD_VECDEQUE_FIELD_NAME_HEAD,
+                            STD_VECDEQUE_FIELD_NAME_BUF]
+
 # std::String related constants
 STD_STRING_FIELD_NAMES = ["vec"]
 
@@ -161,6 +170,11 @@ def __classify_struct(self):
             self.__conforms_to_field_layout(STD_VEC_FIELD_NAMES)):
             return TYPE_KIND_STD_VEC
 
+        # STD COLLECTION VECDEQUE
+        if (unqualified_type_name.startswith("VecDeque<") and
+            self.__conforms_to_field_layout(STD_VECDEQUE_FIELD_NAMES)):
+            return TYPE_KIND_STD_VECDEQUE
+
         # STD STRING
         if (unqualified_type_name.startswith("String") and
             self.__conforms_to_field_layout(STD_STRING_FIELD_NAMES)):
@@ -325,6 +339,25 @@ def extract_length_ptr_and_cap_from_std_vec(vec_val):
     assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
     return (length, data_ptr, capacity)
 
+
+def extract_tail_head_ptr_and_cap_from_std_vecdeque(vec_val):
+    assert vec_val.type.get_type_kind() == TYPE_KIND_STD_VECDEQUE
+    tail_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_TAIL)
+    head_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_HEAD)
+    buf_field_index = STD_VECDEQUE_FIELD_NAMES.index(STD_VECDEQUE_FIELD_NAME_BUF)
+
+    tail = vec_val.get_child_at_index(tail_field_index).as_integer()
+    head = vec_val.get_child_at_index(head_field_index).as_integer()
+    buf = vec_val.get_child_at_index(buf_field_index)
+
+    vec_ptr_val = buf.get_child_at_index(0)
+    capacity = buf.get_child_at_index(1).as_integer()
+    unique_ptr_val = vec_ptr_val.get_child_at_index(0)
+    data_ptr = unique_ptr_val.get_child_at_index(0)
+    assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
+    return (tail, head, data_ptr, capacity)
+
+
 def extract_length_and_ptr_from_slice(slice_val):
     assert (slice_val.type.get_type_kind() == TYPE_KIND_SLICE or
             slice_val.type.get_type_kind() == TYPE_KIND_STR_SLICE)
diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py
index 0612873e28153..b7de42a938417 100755
--- a/src/etc/gdb_rust_pretty_printing.py
+++ b/src/etc/gdb_rust_pretty_printing.py
@@ -124,6 +124,9 @@ def rust_pretty_printer_lookup_function(gdb_val):
     if type_kind == rustpp.TYPE_KIND_STD_VEC:
         return RustStdVecPrinter(val)
 
+    if type_kind == rustpp.TYPE_KIND_STD_VECDEQUE:
+        return RustStdVecDequePrinter(val)
+
     if type_kind == rustpp.TYPE_KIND_STD_STRING:
         return RustStdStringPrinter(val)
 
@@ -274,6 +277,28 @@ def children(self):
             yield (str(index), (gdb_ptr + index).dereference())
 
 
+class RustStdVecDequePrinter(object):
+    def __init__(self, val):
+        self.__val = val
+
+    @staticmethod
+    def display_hint():
+        return "array"
+
+    def to_string(self):
+        (tail, head, data_ptr, cap) = \
+            rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val)
+        return (self.__val.type.get_unqualified_type_name() +
+                ("(len: %i, cap: %i)" % (head - tail, cap)))
+
+    def children(self):
+        (tail, head, data_ptr, cap) = \
+            rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val)
+        gdb_ptr = data_ptr.get_wrapped_value()
+        for index in xrange(tail, head):
+            yield (str(index), (gdb_ptr + index).dereference())
+
+
 class RustStdStringPrinter(object):
     def __init__(self, val):
         self.__val = val
diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs
index 64348e05de7db..8e30b0d5d5a17 100644
--- a/src/liballoc_system/lib.rs
+++ b/src/liballoc_system/lib.rs
@@ -174,7 +174,10 @@ mod platform {
         }
     }
 
-    #[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))]
+    #[cfg(any(target_os = "android",
+              target_os = "hermit",
+              target_os = "redox",
+              target_os = "solaris"))]
     #[inline]
     unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
         // On android we currently target API level 9 which unfortunately
@@ -197,7 +200,10 @@ mod platform {
         libc::memalign(layout.align(), layout.size()) as *mut u8
     }
 
-    #[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))]
+    #[cfg(not(any(target_os = "android",
+                  target_os = "hermit",
+                  target_os = "redox",
+                  target_os = "solaris")))]
     #[inline]
     unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
         let mut out = ptr::null_mut();
diff --git a/src/libcore/char/decode.rs b/src/libcore/char/decode.rs
index 0b8dce19dffa1..cc52f048b891b 100644
--- a/src/libcore/char/decode.rs
+++ b/src/libcore/char/decode.rs
@@ -11,135 +11,8 @@
 //! UTF-8 and UTF-16 decoding iterators
 
 use fmt;
-use iter::FusedIterator;
 use super::from_u32_unchecked;
 
-/// An iterator over an iterator of bytes of the characters the bytes represent
-/// as UTF-8
-#[unstable(feature = "decode_utf8", issue = "33906")]
-#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
-    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
-#[derive(Clone, Debug)]
-#[allow(deprecated)]
-pub struct DecodeUtf8<I: Iterator<Item = u8>>(::iter::Peekable<I>);
-
-/// Decodes an `Iterator` of bytes as UTF-8.
-#[unstable(feature = "decode_utf8", issue = "33906")]
-#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
-    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
-#[allow(deprecated)]
-#[inline]
-pub fn decode_utf8<I: IntoIterator<Item = u8>>(i: I) -> DecodeUtf8<I::IntoIter> {
-    DecodeUtf8(i.into_iter().peekable())
-}
-
-/// `<DecodeUtf8 as Iterator>::next` returns this for an invalid input sequence.
-#[unstable(feature = "decode_utf8", issue = "33906")]
-#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
-    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
-#[derive(PartialEq, Eq, Debug)]
-#[allow(deprecated)]
-pub struct InvalidSequence(());
-
-#[unstable(feature = "decode_utf8", issue = "33906")]
-#[allow(deprecated)]
-impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
-    type Item = Result<char, InvalidSequence>;
-    #[inline]
-
-    fn next(&mut self) -> Option<Result<char, InvalidSequence>> {
-        self.0.next().map(|first_byte| {
-            // Emit InvalidSequence according to
-            // Unicode §5.22 Best Practice for U+FFFD Substitution
-            // http://www.unicode.org/versions/Unicode9.0.0/ch05.pdf#G40630
-
-            // Roughly: consume at least one byte,
-            // then validate one byte at a time and stop before the first unexpected byte
-            // (which might be the valid start of the next byte sequence).
-
-            let mut code_point;
-            macro_rules! first_byte {
-                ($mask: expr) => {
-                    code_point = u32::from(first_byte & $mask)
-                }
-            }
-            macro_rules! continuation_byte {
-                () => { continuation_byte!(0x80..=0xBF) };
-                ($range: pat) => {
-                    match self.0.peek() {
-                        Some(&byte @ $range) => {
-                            code_point = (code_point << 6) | u32::from(byte & 0b0011_1111);
-                            self.0.next();
-                        }
-                        _ => return Err(InvalidSequence(()))
-                    }
-                }
-            }
-
-            match first_byte {
-                0x00..=0x7F => {
-                    first_byte!(0b1111_1111);
-                }
-                0xC2..=0xDF => {
-                    first_byte!(0b0001_1111);
-                    continuation_byte!();
-                }
-                0xE0 => {
-                    first_byte!(0b0000_1111);
-                    continuation_byte!(0xA0..=0xBF);  // 0x80..=0x9F here are overlong
-                    continuation_byte!();
-                }
-                0xE1..=0xEC | 0xEE..=0xEF => {
-                    first_byte!(0b0000_1111);
-                    continuation_byte!();
-                    continuation_byte!();
-                }
-                0xED => {
-                    first_byte!(0b0000_1111);
-                    continuation_byte!(0x80..=0x9F);  // 0xA0..0xBF here are surrogates
-                    continuation_byte!();
-                }
-                0xF0 => {
-                    first_byte!(0b0000_0111);
-                    continuation_byte!(0x90..=0xBF);  // 0x80..0x8F here are overlong
-                    continuation_byte!();
-                    continuation_byte!();
-                }
-                0xF1..=0xF3 => {
-                    first_byte!(0b0000_0111);
-                    continuation_byte!();
-                    continuation_byte!();
-                    continuation_byte!();
-                }
-                0xF4 => {
-                    first_byte!(0b0000_0111);
-                    continuation_byte!(0x80..=0x8F);  // 0x90..0xBF here are beyond char::MAX
-                    continuation_byte!();
-                    continuation_byte!();
-                }
-                _ => return Err(InvalidSequence(()))  // Illegal first byte, overlong, or beyond MAX
-            }
-            unsafe {
-                Ok(from_u32_unchecked(code_point))
-            }
-        })
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        let (lower, upper) = self.0.size_hint();
-
-        // A code point is at most 4 bytes long.
-        let min_code_points = lower / 4;
-
-        (min_code_points, upper)
-    }
-}
-
-#[unstable(feature = "decode_utf8", issue = "33906")]
-#[allow(deprecated)]
-impl<I: FusedIterator<Item = u8>> FusedIterator for DecodeUtf8<I> {}
-
 /// An iterator that decodes UTF-16 encoded code points from an iterator of `u16`s.
 #[stable(feature = "decode_utf16", since = "1.9.0")]
 #[derive(Clone, Debug)]
diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs
index 59bcf1383f47a..5be673db3200d 100644
--- a/src/libcore/char/mod.rs
+++ b/src/libcore/char/mod.rs
@@ -50,11 +50,6 @@ pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error};
 pub use unicode::tables::UNICODE_VERSION;
 #[unstable(feature = "unicode_version", issue = "49726")]
 pub use unicode::version::UnicodeVersion;
-#[unstable(feature = "decode_utf8", issue = "33906")]
-#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
-    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
-#[allow(deprecated)]
-pub use self::decode::{decode_utf8, DecodeUtf8, InvalidSequence};
 
 use fmt::{self, Write};
 use iter::FusedIterator;
diff --git a/src/libcore/future/future_obj.rs b/src/libcore/future/future_obj.rs
index 98c504a3f7bef..6045fac2b4b3d 100644
--- a/src/libcore/future/future_obj.rs
+++ b/src/libcore/future/future_obj.rs
@@ -36,6 +36,8 @@ pub struct LocalFutureObj<'a, T> {
     _marker: PhantomData<&'a ()>,
 }
 
+impl<'a, T> Unpin for LocalFutureObj<'a, T> {}
+
 impl<'a, T> LocalFutureObj<'a, T> {
     /// Create a `LocalFutureObj` from a custom trait object representation.
     #[inline]
@@ -104,6 +106,7 @@ impl<'a, T> Drop for LocalFutureObj<'a, T> {
 ///   information #44874)
 pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>);
 
+impl<'a, T> Unpin for FutureObj<'a, T> {}
 unsafe impl<'a, T> Send for FutureObj<'a, T> {}
 
 impl<'a, T> FutureObj<'a, T> {
diff --git a/src/libcore/ops/unsize.rs b/src/libcore/ops/unsize.rs
index cd896859b16bc..da72f3748425d 100644
--- a/src/libcore/ops/unsize.rs
+++ b/src/libcore/ops/unsize.rs
@@ -13,7 +13,7 @@ use marker::Unsize;
 /// Trait that indicates that this is a pointer or a wrapper for one,
 /// where unsizing can be performed on the pointee.
 ///
-/// See the [DST coercion RfC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce]
+/// See the [DST coercion RFC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce]
 /// for more details.
 ///
 /// For builtin pointer types, pointers to `T` will coerce to pointers to `U` if `T: Unsize<U>`
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index fe5914c72e1ac..479c10c4ffbae 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -680,46 +680,6 @@ impl<T: ?Sized> *const T {
         }
     }
 
-    /// Calculates the distance between two pointers. The returned value is in
-    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
-    ///
-    /// If the address different between the two pointers ia not a multiple of
-    /// `mem::size_of::<T>()` then the result of the division is rounded towards
-    /// zero.
-    ///
-    /// This function returns `None` if `T` is a zero-sized type.
-    ///
-    /// # Examples
-    ///
-    /// Basic usage:
-    ///
-    /// ```
-    /// #![feature(offset_to)]
-    /// #![allow(deprecated)]
-    ///
-    /// fn main() {
-    ///     let a = [0; 5];
-    ///     let ptr1: *const i32 = &a[1];
-    ///     let ptr2: *const i32 = &a[3];
-    ///     assert_eq!(ptr1.offset_to(ptr2), Some(2));
-    ///     assert_eq!(ptr2.offset_to(ptr1), Some(-2));
-    ///     assert_eq!(unsafe { ptr1.offset(2) }, ptr2);
-    ///     assert_eq!(unsafe { ptr2.offset(-2) }, ptr1);
-    /// }
-    /// ```
-    #[unstable(feature = "offset_to", issue = "41079")]
-    #[rustc_deprecated(since = "1.27.0", reason = "Replaced by `wrapping_offset_from`, with the \
-        opposite argument order.  If you're writing unsafe code, consider `offset_from`.")]
-    #[inline]
-    pub fn offset_to(self, other: *const T) -> Option<isize> where T: Sized {
-        let size = mem::size_of::<T>();
-        if size == 0 {
-            None
-        } else {
-            Some(other.wrapping_offset_from(self))
-        }
-    }
-
     /// Calculates the distance between two pointers. The returned value is in
     /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
     ///
@@ -1464,46 +1424,6 @@ impl<T: ?Sized> *mut T {
         }
     }
 
-    /// Calculates the distance between two pointers. The returned value is in
-    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
-    ///
-    /// If the address different between the two pointers ia not a multiple of
-    /// `mem::size_of::<T>()` then the result of the division is rounded towards
-    /// zero.
-    ///
-    /// This function returns `None` if `T` is a zero-sized type.
-    ///
-    /// # Examples
-    ///
-    /// Basic usage:
-    ///
-    /// ```
-    /// #![feature(offset_to)]
-    /// #![allow(deprecated)]
-    ///
-    /// fn main() {
-    ///     let mut a = [0; 5];
-    ///     let ptr1: *mut i32 = &mut a[1];
-    ///     let ptr2: *mut i32 = &mut a[3];
-    ///     assert_eq!(ptr1.offset_to(ptr2), Some(2));
-    ///     assert_eq!(ptr2.offset_to(ptr1), Some(-2));
-    ///     assert_eq!(unsafe { ptr1.offset(2) }, ptr2);
-    ///     assert_eq!(unsafe { ptr2.offset(-2) }, ptr1);
-    /// }
-    /// ```
-    #[unstable(feature = "offset_to", issue = "41079")]
-    #[rustc_deprecated(since = "1.27.0", reason = "Replaced by `wrapping_offset_from`, with the \
-        opposite argument order.  If you're writing unsafe code, consider `offset_from`.")]
-    #[inline]
-    pub fn offset_to(self, other: *const T) -> Option<isize> where T: Sized {
-        let size = mem::size_of::<T>();
-        if size == 0 {
-            None
-        } else {
-            Some(other.wrapping_offset_from(self))
-        }
-    }
-
     /// Calculates the distance between two pointers. The returned value is in
     /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
     ///
diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs
index 321b432d3f430..d770536ef4279 100644
--- a/src/libcore/task/wake.rs
+++ b/src/libcore/task/wake.rs
@@ -42,7 +42,7 @@ impl Waker {
     /// `Arc` type and the safe `Wake` trait.
     #[inline]
     pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self {
-        Waker { inner: inner }
+        Waker { inner }
     }
 
     /// Wake up the task associated with this `Waker`.
@@ -120,7 +120,7 @@ impl LocalWaker {
     /// on the current thread.
     #[inline]
     pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self {
-        LocalWaker { inner: inner }
+        LocalWaker { inner }
     }
 
     /// Wake up the task associated with this `LocalWaker`.
@@ -159,7 +159,9 @@ impl LocalWaker {
 impl From<LocalWaker> for Waker {
     #[inline]
     fn from(local_waker: LocalWaker) -> Self {
-        Waker { inner: local_waker.inner }
+        let inner = local_waker.inner;
+        mem::forget(local_waker);
+        Waker { inner }
     }
 }
 
diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs
index d2a9ed75be658..46c54056e2cc9 100644
--- a/src/libcore/tests/char.rs
+++ b/src/libcore/tests/char.rs
@@ -363,54 +363,3 @@ fn eu_iterator_specializations() {
     check('\u{12340}');
     check('\u{10FFFF}');
 }
-
-#[test]
-#[allow(deprecated)]
-fn test_decode_utf8() {
-    macro_rules! assert_decode_utf8 {
-        ($input_bytes: expr, $expected_str: expr) => {
-            let input_bytes: &[u8] = &$input_bytes;
-            let s = char::decode_utf8(input_bytes.iter().cloned())
-                .map(|r_b| r_b.unwrap_or('\u{FFFD}'))
-                .collect::<String>();
-            assert_eq!(s, $expected_str,
-                       "input bytes: {:?}, expected str: {:?}, result: {:?}",
-                       input_bytes, $expected_str, s);
-            assert_eq!(String::from_utf8_lossy(&$input_bytes), $expected_str);
-        }
-    }
-
-    assert_decode_utf8!([], "");
-    assert_decode_utf8!([0x41], "A");
-    assert_decode_utf8!([0xC1, 0x81], "��");
-    assert_decode_utf8!([0xE2, 0x99, 0xA5], "♥");
-    assert_decode_utf8!([0xE2, 0x99, 0xA5, 0x41], "♥A");
-    assert_decode_utf8!([0xE2, 0x99], "�");
-    assert_decode_utf8!([0xE2, 0x99, 0x41], "�A");
-    assert_decode_utf8!([0xC0], "�");
-    assert_decode_utf8!([0xC0, 0x41], "�A");
-    assert_decode_utf8!([0x80], "�");
-    assert_decode_utf8!([0x80, 0x41], "�A");
-    assert_decode_utf8!([0xFE], "�");
-    assert_decode_utf8!([0xFE, 0x41], "�A");
-    assert_decode_utf8!([0xFF], "�");
-    assert_decode_utf8!([0xFF, 0x41], "�A");
-    assert_decode_utf8!([0xC0, 0x80], "��");
-
-    // Surrogates
-    assert_decode_utf8!([0xED, 0x9F, 0xBF], "\u{D7FF}");
-    assert_decode_utf8!([0xED, 0xA0, 0x80], "���");
-    assert_decode_utf8!([0xED, 0xBF, 0x80], "���");
-    assert_decode_utf8!([0xEE, 0x80, 0x80], "\u{E000}");
-
-    // char::MAX
-    assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0xBF], "\u{10FFFF}");
-    assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0x41], "�A");
-    assert_decode_utf8!([0xF4, 0x90, 0x80, 0x80], "����");
-
-    // 5 and 6 bytes sequence
-    // Part of the original design of UTF-8,
-    // but invalid now that UTF-8 is artificially restricted to match the range of UTF-16.
-    assert_decode_utf8!([0xF8, 0x80, 0x80, 0x80, 0x80], "�����");
-    assert_decode_utf8!([0xFC, 0x80, 0x80, 0x80, 0x80, 0x80], "������");
-}
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 14cfaa8153377..15630157722fa 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -42,7 +42,7 @@ use util::nodemap::FxHashMap;
 use std::default::Default as StdDefault;
 use syntax::ast;
 use syntax::edition;
-use syntax_pos::{MultiSpan, Span};
+use syntax_pos::{MultiSpan, Span, symbol::LocalInternedString};
 use errors::DiagnosticBuilder;
 use hir;
 use hir::def_id::LOCAL_CRATE;
@@ -133,6 +133,12 @@ pub enum CheckLintNameResult<'a> {
     /// The lint is either renamed or removed. This is the warning
     /// message, and an optional new name (`None` if removed).
     Warning(String, Option<String>),
+    /// The lint is from a tool. If the Option is None, then either
+    /// the lint does not exist in the tool or the code was not
+    /// compiled with the tool and therefore the lint was never
+    /// added to the `LintStore`. Otherwise the `LintId` will be
+    /// returned as if it where a rustc lint.
+    Tool(Option<&'a [LintId]>),
 }
 
 impl LintStore {
@@ -288,7 +294,7 @@ impl LintStore {
                                    sess: &Session,
                                    lint_name: &str,
                                    level: Level) {
-        let db = match self.check_lint_name(lint_name) {
+        let db = match self.check_lint_name(lint_name, None) {
             CheckLintNameResult::Ok(_) => None,
             CheckLintNameResult::Warning(ref msg, _) => {
                 Some(sess.struct_warn(msg))
@@ -296,6 +302,7 @@ impl LintStore {
             CheckLintNameResult::NoLint => {
                 Some(struct_err!(sess, E0602, "unknown lint: `{}`", lint_name))
             }
+            CheckLintNameResult::Tool(_) => unreachable!(),
         };
 
         if let Some(mut db) = db {
@@ -319,26 +326,41 @@ impl LintStore {
     /// it emits non-fatal warnings and there are *two* lint passes that
     /// inspect attributes, this is only run from the late pass to avoid
     /// printing duplicate warnings.
-    pub fn check_lint_name(&self, lint_name: &str) -> CheckLintNameResult {
-        match self.by_name.get(lint_name) {
-            Some(&Renamed(ref new_name, _)) => {
-                CheckLintNameResult::Warning(
-                    format!("lint `{}` has been renamed to `{}`", lint_name, new_name),
-                    Some(new_name.to_owned())
-                )
-            },
-            Some(&Removed(ref reason)) => {
-                CheckLintNameResult::Warning(
-                    format!("lint `{}` has been removed: `{}`", lint_name, reason),
-                    None
-                )
-            },
-            None => {
-                match self.lint_groups.get(lint_name) {
-                    None => CheckLintNameResult::NoLint,
-                    Some(ids) => CheckLintNameResult::Ok(&ids.0),
-                }
+    pub fn check_lint_name(
+        &self,
+        lint_name: &str,
+        tool_name: Option<LocalInternedString>,
+    ) -> CheckLintNameResult {
+        let complete_name = if let Some(tool_name) = tool_name {
+            format!("{}::{}", tool_name, lint_name)
+        } else {
+            lint_name.to_string()
+        };
+        if let Some(_) = tool_name {
+            match self.by_name.get(&complete_name) {
+                None => match self.lint_groups.get(&*complete_name) {
+                    None => return CheckLintNameResult::Tool(None),
+                    Some(ids) => return CheckLintNameResult::Tool(Some(&ids.0)),
+                },
+                Some(&Id(ref id)) => return CheckLintNameResult::Tool(Some(slice::from_ref(id))),
+                // If the lint was registered as removed or renamed by the lint tool, we don't need
+                // to treat tool_lints and rustc lints different and can use the code below.
+                _ => {}
             }
+        }
+        match self.by_name.get(&complete_name) {
+            Some(&Renamed(ref new_name, _)) => CheckLintNameResult::Warning(
+                format!("lint `{}` has been renamed to `{}`", lint_name, new_name),
+                Some(new_name.to_owned()),
+            ),
+            Some(&Removed(ref reason)) => CheckLintNameResult::Warning(
+                format!("lint `{}` has been removed: `{}`", lint_name, reason),
+                None,
+            ),
+            None => match self.lint_groups.get(&*complete_name) {
+                None => CheckLintNameResult::NoLint,
+                Some(ids) => CheckLintNameResult::Ok(&ids.0),
+            },
             Some(&Id(ref id)) => CheckLintNameResult::Ok(slice::from_ref(id)),
         }
     }
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index b7b6aba970bff..483e2ea8a96cd 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -227,8 +227,10 @@ impl<'a> LintLevelsBuilder<'a> {
                         continue
                     }
                 };
-                if let Some(lint_tool) = word.is_scoped() {
-                    if !self.sess.features_untracked().tool_lints {
+                let tool_name = if let Some(lint_tool) = word.is_scoped() {
+                    let gate_feature = !self.sess.features_untracked().tool_lints;
+                    let known_tool = attr::is_known_lint_tool(lint_tool);
+                    if gate_feature {
                         feature_gate::emit_feature_err(&sess.parse_sess,
                                                        "tool_lints",
                                                        word.span,
@@ -236,8 +238,7 @@ impl<'a> LintLevelsBuilder<'a> {
                                                        &format!("scoped lint `{}` is experimental",
                                                                 word.ident));
                     }
-
-                    if !attr::is_known_lint_tool(lint_tool) {
+                    if !known_tool {
                         span_err!(
                             sess,
                             lint_tool.span,
@@ -247,10 +248,16 @@ impl<'a> LintLevelsBuilder<'a> {
                         );
                     }
 
-                    continue
-                }
+                    if gate_feature || !known_tool {
+                        continue
+                    }
+
+                    Some(lint_tool.as_str())
+                } else {
+                    None
+                };
                 let name = word.name();
-                match store.check_lint_name(&name.as_str()) {
+                match store.check_lint_name(&name.as_str(), tool_name) {
                     CheckLintNameResult::Ok(ids) => {
                         let src = LintSource::Node(name, li.span);
                         for id in ids {
@@ -258,6 +265,20 @@ impl<'a> LintLevelsBuilder<'a> {
                         }
                     }
 
+                    CheckLintNameResult::Tool(result) => {
+                        if let Some(ids) = result {
+                            let complete_name = &format!("{}::{}", tool_name.unwrap(), name);
+                            let src = LintSource::Node(Symbol::intern(complete_name), li.span);
+                            for id in ids {
+                                specs.insert(*id, (level, src));
+                            }
+                        }
+                        // If Tool(None) is returned, then either the lint does not exist in the
+                        // tool or the code was not compiled with the tool and therefore the lint
+                        // was never added to the `LintStore`. To detect this is the responsibility
+                        // of the lint tool.
+                    }
+
                     _ if !self.warn_about_weird_lints => {}
 
                     CheckLintNameResult::Warning(msg, renamed) => {
@@ -298,7 +319,7 @@ impl<'a> LintLevelsBuilder<'a> {
                         if name.as_str().chars().any(|c| c.is_uppercase()) {
                             let name_lower = name.as_str().to_lowercase().to_string();
                             if let CheckLintNameResult::NoLint =
-                                    store.check_lint_name(&name_lower) {
+                                    store.check_lint_name(&name_lower, tool_name) {
                                 db.emit();
                             } else {
                                 db.span_suggestion_with_applicability(
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 3c1b205620892..6940826ba8653 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -139,6 +139,26 @@ macro_rules! declare_lint {
     );
 }
 
+#[macro_export]
+macro_rules! declare_tool_lint {
+    ($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr) => (
+        declare_tool_lint!{$vis $tool::$NAME, $Level, $desc, false}
+    );
+    ($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr,
+     report_in_external_macro: $rep: expr) => (
+         declare_tool_lint!{$vis $tool::$NAME, $Level, $desc, $rep}
+    );
+    ($vis: vis $tool: ident ::$NAME: ident, $Level: ident, $desc: expr, $external: expr) => (
+        $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint {
+            name: &concat!(stringify!($tool), "::", stringify!($NAME)),
+            default_level: $crate::lint::$Level,
+            desc: $desc,
+            edition_lint_opts: None,
+            report_in_external_macro: $external,
+        };
+    );
+}
+
 /// Declare a static `LintArray` and return it as an expression.
 #[macro_export]
 macro_rules! lint_array {
diff --git a/src/librustc_data_structures/small_vec.rs b/src/librustc_data_structures/small_vec.rs
index 4a72ab57fcc08..b5f52d54ae471 100644
--- a/src/librustc_data_structures/small_vec.rs
+++ b/src/librustc_data_structures/small_vec.rs
@@ -169,10 +169,18 @@ impl<A: Array> FromIterator<A::Element> for SmallVec<A> {
 
 impl<A: Array> Extend<A::Element> for SmallVec<A> {
     fn extend<I: IntoIterator<Item=A::Element>>(&mut self, iter: I) {
-        let iter = iter.into_iter();
-        self.reserve(iter.size_hint().0);
-        for el in iter {
-            self.push(el);
+        if self.is_array() {
+            let iter = iter.into_iter();
+            self.reserve(iter.size_hint().0);
+
+            for el in iter {
+                self.push(el);
+            }
+        } else {
+            match self.0 {
+                AccumulateVec::Heap(ref mut vec) => vec.extend(iter),
+                _ => unreachable!()
+            }
         }
     }
 }
@@ -213,3 +221,119 @@ impl<A> Decodable for SmallVec<A>
         })
     }
 }
+
+#[cfg(test)]
+mod tests {
+    extern crate test;
+    use self::test::Bencher;
+
+    use super::*;
+
+    #[bench]
+    fn fill_small_vec_1_10_with_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 1]> = SmallVec::with_capacity(10);
+
+            sv.extend(0..10);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_1_10_wo_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 1]> = SmallVec::new();
+
+            sv.extend(0..10);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_8_10_with_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 8]> = SmallVec::with_capacity(10);
+
+            sv.extend(0..10);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_8_10_wo_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 8]> = SmallVec::new();
+
+            sv.extend(0..10);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_32_10_with_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 32]> = SmallVec::with_capacity(10);
+
+            sv.extend(0..10);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_32_10_wo_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 32]> = SmallVec::new();
+
+            sv.extend(0..10);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_1_50_with_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 1]> = SmallVec::with_capacity(50);
+
+            sv.extend(0..50);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_1_50_wo_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 1]> = SmallVec::new();
+
+            sv.extend(0..50);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_8_50_with_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 8]> = SmallVec::with_capacity(50);
+
+            sv.extend(0..50);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_8_50_wo_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 8]> = SmallVec::new();
+
+            sv.extend(0..50);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_32_50_with_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 32]> = SmallVec::with_capacity(50);
+
+            sv.extend(0..50);
+        })
+    }
+
+    #[bench]
+    fn fill_small_vec_32_50_wo_cap(b: &mut Bencher) {
+        b.iter(|| {
+            let mut sv: SmallVec<[usize; 32]> = SmallVec::new();
+
+            sv.extend(0..50);
+        })
+    }
+}
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 4ba96f643b0cc..27221296ff31f 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -331,6 +331,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
     }
 
     if mbcx.errors_buffer.len() > 0 {
+        mbcx.errors_buffer.sort_by_key(|diag| diag.span.primary_span());
+
         if tcx.migrate_borrowck() {
             match tcx.borrowck(def_id).signalled_any_error {
                 SignalledError::NoErrorsSeen => {
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index 103f431d4bac9..4d988fef450b8 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -341,7 +341,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                 // another match arm
                 binds_to.sort();
                 binds_to.dedup();
-                for local in binds_to {
+                let mut multipart_suggestion = Vec::with_capacity(binds_to.len());
+                for (j, local) in binds_to.into_iter().enumerate() {
                     let bind_to = &self.mir.local_decls[local];
                     let binding_span = bind_to.source_info.span;
 
@@ -350,13 +351,15 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                         Mutability::Not => "ref",
                         Mutability::Mut => "ref mut",
                     };
+                    if j == 0 {
+                        err.span_label(binding_span, format!("data moved here"));
+                    } else {
+                        err.span_label(binding_span, format!("... and here"));
+                    }
                     match bind_to.name {
                         Some(name) => {
-                            err.span_suggestion(
-                                binding_span,
-                                "to prevent move, use ref or ref mut",
-                                format!("{} {:?}", ref_kind, name),
-                            );
+                            multipart_suggestion.push((binding_span,
+                                                       format!("{} {}", ref_kind, name)));
                         }
                         None => {
                             err.span_label(
@@ -366,6 +369,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                         }
                     }
                 }
+                err.multipart_suggestion("to prevent move, use ref or ref mut",
+                                         multipart_suggestion);
             }
             // Nothing to suggest.
             GroupedMoveError::OtherIllegalMove { .. } => (),
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 9a84daf53dbd4..cd2de3247cfba 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -307,7 +307,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                 let local_decl = &self.mir.local_decls[*local];
                 let suggestion = match local_decl.is_user_variable.as_ref().unwrap() {
                     ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf) => {
-                        Some(suggest_ampmut_self(local_decl))
+                        Some(suggest_ampmut_self(self.tcx, local_decl))
                     }
 
                     ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
@@ -418,8 +418,22 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
     }
 }
 
-fn suggest_ampmut_self<'cx, 'gcx, 'tcx>(local_decl: &mir::LocalDecl<'tcx>) -> (Span, String) {
-    (local_decl.source_info.span, "&mut self".to_string())
+fn suggest_ampmut_self<'cx, 'gcx, 'tcx>(
+    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
+    local_decl: &mir::LocalDecl<'tcx>,
+) -> (Span, String) {
+    let sp = local_decl.source_info.span;
+    (sp, match tcx.sess.codemap().span_to_snippet(sp) {
+        Ok(snippet) => {
+            let lt_pos = snippet.find('\'');
+            if let Some(lt_pos) = lt_pos {
+                format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4])
+            } else {
+                "&mut self".to_string()
+            }
+        }
+        _ => "&mut self".to_string()
+    })
 }
 
 // When we want to suggest a user change a local variable to be a `&mut`, there
@@ -447,9 +461,15 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>(
     let locations = mir.find_assignments(local);
     if locations.len() > 0 {
         let assignment_rhs_span = mir.source_info(locations[0]).span;
-        let snippet = tcx.sess.codemap().span_to_snippet(assignment_rhs_span);
-        if let Ok(src) = snippet {
-            if src.starts_with('&') {
+        if let Ok(src) = tcx.sess.codemap().span_to_snippet(assignment_rhs_span) {
+            if let (true, Some(ws_pos)) = (
+                src.starts_with("&'"),
+                src.find(|c: char| -> bool { c.is_whitespace() }),
+            ) {
+                let lt_name = &src[1..ws_pos];
+                let ty = &src[ws_pos..];
+                return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
+            } else if src.starts_with('&') {
                 let borrowed_expr = src[1..].to_string();
                 return (assignment_rhs_span, format!("&mut {}", borrowed_expr));
             }
@@ -466,13 +486,25 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>(
         None => local_decl.source_info.span,
     };
 
+    if let Ok(src) = tcx.sess.codemap().span_to_snippet(highlight_span) {
+        if let (true, Some(ws_pos)) = (
+            src.starts_with("&'"),
+            src.find(|c: char| -> bool { c.is_whitespace() }),
+        ) {
+            let lt_name = &src[1..ws_pos];
+            let ty = &src[ws_pos..];
+            return (highlight_span, format!("&{} mut{}", lt_name, ty));
+        }
+    }
+
     let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
     assert_eq!(ty_mut.mutbl, hir::MutImmutable);
-    if local_decl.ty.is_region_ptr() {
-        (highlight_span, format!("&mut {}", ty_mut.ty))
-    } else {
-        (highlight_span, format!("*mut {}", ty_mut.ty))
-    }
+    (highlight_span,
+     if local_decl.ty.is_region_ptr() {
+         format!("&mut {}", ty_mut.ty)
+     } else {
+         format!("*mut {}", ty_mut.ty)
+     })
 }
 
 fn is_closure_or_generator(ty: ty::Ty) -> bool {
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index a509ec08a142e..6a447d81dc3cb 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -1213,11 +1213,17 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         let locals = if has_guard.0 && tcx.all_pat_vars_are_implicit_refs_within_guards() {
             let mut vals_for_guard = Vec::with_capacity(num_patterns);
             for _ in 0..num_patterns {
-                let val_for_guard_idx =  self.local_decls.push(local.clone());
+                let val_for_guard_idx = self.local_decls.push(LocalDecl {
+                    // This variable isn't mutated but has a name, so has to be
+                    // immutable to avoid the unused mut lint.
+                    mutability: Mutability::Not,
+                    ..local.clone()
+                });
                 vals_for_guard.push(val_for_guard_idx);
             }
             let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> {
-                mutability,
+                // See previous comment.
+                mutability: Mutability::Not,
                 ty: tcx.mk_imm_ref(tcx.types.re_empty, var_ty),
                 name: Some(name),
                 source_info,
diff --git a/src/librustc_target/spec/aarch64_unknown_hermit.rs b/src/librustc_target/spec/aarch64_unknown_hermit.rs
new file mode 100644
index 0000000000000..6b81c62e48b87
--- /dev/null
+++ b/src/librustc_target/spec/aarch64_unknown_hermit.rs
@@ -0,0 +1,32 @@
+// 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.
+
+use spec::{LinkerFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::hermit_base::opts();
+    base.max_atomic_width = Some(128);
+    base.abi_blacklist = super::arm_base::abi_blacklist();
+    base.linker = Some("aarch64-hermit-gcc".to_string());
+
+    Ok(Target {
+        llvm_target: "aarch64-unknown-hermit".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
+        arch: "aarch64".to_string(),
+        target_os: "hermit".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: base,
+    })
+}
diff --git a/src/librustc_target/spec/hermit_base.rs b/src/librustc_target/spec/hermit_base.rs
new file mode 100644
index 0000000000000..2a24f771e9289
--- /dev/null
+++ b/src/librustc_target/spec/hermit_base.rs
@@ -0,0 +1,37 @@
+// Copyright 2014 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 spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions};
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    let mut args = LinkArgs::new();
+    args.insert(LinkerFlavor::Gcc, vec![
+        "-Wl,-Bstatic".to_string(),
+        "-Wl,--no-dynamic-linker".to_string(),
+        "-Wl,--gc-sections".to_string(),
+        "-Wl,--as-needed".to_string(),
+    ]);
+
+    TargetOptions {
+        exe_allocation_crate: None,
+        executables: true,
+        has_elf_tls: true,
+        linker_is_gnu: true,
+        no_default_libraries: false,
+        panic_strategy: PanicStrategy::Abort,
+        position_independent_executables: false,
+        pre_link_args: args,
+        relocation_model: "static".to_string(),
+        target_family: Some("unix".to_string()),
+        tls_model: "local-exec".to_string(),
+        .. Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index c5d21cdc46adb..6c2d16d6a17eb 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -62,6 +62,7 @@ mod cloudabi_base;
 mod dragonfly_base;
 mod freebsd_base;
 mod haiku_base;
+mod hermit_base;
 mod linux_base;
 mod linux_musl_base;
 mod openbsd_base;
@@ -373,6 +374,9 @@ supported_targets! {
     ("armv7-unknown-cloudabi-eabihf", armv7_unknown_cloudabi_eabihf),
     ("i686-unknown-cloudabi", i686_unknown_cloudabi),
     ("x86_64-unknown-cloudabi", x86_64_unknown_cloudabi),
+
+    ("aarch64-unknown-hermit", aarch64_unknown_hermit),
+    ("x86_64-unknown-hermit", x86_64_unknown_hermit),
 }
 
 /// Everything `rustc` knows about how to compile for a specific target.
diff --git a/src/librustc_target/spec/x86_64_unknown_hermit.rs b/src/librustc_target/spec/x86_64_unknown_hermit.rs
new file mode 100644
index 0000000000000..9f9f2e6ec43e9
--- /dev/null
+++ b/src/librustc_target/spec/x86_64_unknown_hermit.rs
@@ -0,0 +1,33 @@
+// 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.
+
+use spec::{LinkerFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::hermit_base::opts();
+    base.cpu = "x86-64".to_string();
+    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
+    base.linker = Some("x86_64-hermit-gcc".to_string());
+    base.max_atomic_width = Some(64);
+
+    Ok(Target {
+        llvm_target: "x86_64-unknown-hermit".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        arch: "x86_64".to_string(),
+        target_os: "hermit".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: base,
+    })
+}
diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs
index 10b6c9850ae77..9631ea059cc43 100644
--- a/src/librustdoc/externalfiles.rs
+++ b/src/librustdoc/externalfiles.rs
@@ -12,7 +12,9 @@ use std::fs;
 use std::path::Path;
 use std::str;
 use errors;
-use html::markdown::Markdown;
+use syntax::feature_gate::UnstableFeatures;
+use html::markdown::{IdMap, ErrorCodes, Markdown};
+use std::cell::RefCell;
 
 #[derive(Clone)]
 pub struct ExternalHtml {
@@ -29,8 +31,10 @@ pub struct ExternalHtml {
 
 impl ExternalHtml {
     pub fn load(in_header: &[String], before_content: &[String], after_content: &[String],
-                md_before_content: &[String], md_after_content: &[String], diag: &errors::Handler)
+                md_before_content: &[String], md_after_content: &[String], diag: &errors::Handler,
+                id_map: &mut IdMap)
             -> Option<ExternalHtml> {
+        let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
         load_external_files(in_header, diag)
             .and_then(|ih|
                 load_external_files(before_content, diag)
@@ -38,7 +42,8 @@ impl ExternalHtml {
             )
             .and_then(|(ih, bc)|
                 load_external_files(md_before_content, diag)
-                    .map(|m_bc| (ih, format!("{}{}", bc, Markdown(&m_bc, &[]))))
+                    .map(|m_bc| (ih,
+                            format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map), codes))))
             )
             .and_then(|(ih, bc)|
                 load_external_files(after_content, diag)
@@ -46,7 +51,8 @@ impl ExternalHtml {
             )
             .and_then(|(ih, bc, ac)|
                 load_external_files(md_after_content, diag)
-                    .map(|m_ac| (ih, bc, format!("{}{}", ac, Markdown(&m_ac, &[]))))
+                    .map(|m_ac| (ih, bc,
+                            format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map), codes))))
             )
             .map(|(ih, bc, ac)|
                 ExternalHtml {
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 065778d8d0725..73d7a9ab8599d 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -13,12 +13,7 @@
 //! This module uses libsyntax's lexer to provide token-based highlighting for
 //! the HTML documentation generated by rustdoc.
 //!
-//! If you just want to syntax highlighting for a Rust program, then you can use
-//! the `render_inner_with_highlighting` or `render_with_highlighting`
-//! functions. For more advanced use cases (if you want to supply your own css
-//! classes or control how the HTML is generated, or even generate something
-//! other then HTML), then you should implement the `Writer` trait and use a
-//! `Classifier`.
+//! Use the `render_with_highlighting` to highlight some rust code.
 
 use html::escape::Escape;
 
@@ -33,7 +28,7 @@ use syntax::parse;
 use syntax_pos::{Span, FileName};
 
 /// Highlights `src`, returning the HTML output.
-pub fn render_with_highlighting(src: &str, class: Option<&str>, id: Option<&str>,
+pub fn render_with_highlighting(src: &str, class: Option<&str>,
                                 extension: Option<&str>,
                                 tooltip: Option<(&str, &str)>) -> String {
     debug!("highlighting: ================\n{}\n==============", src);
@@ -46,7 +41,7 @@ pub fn render_with_highlighting(src: &str, class: Option<&str>, id: Option<&str>
                      class='tooltiptext'>{}</span></div></div>",
                class, tooltip).unwrap();
     }
-    write_header(class, id, &mut out).unwrap();
+    write_header(class, &mut out).unwrap();
 
     let mut classifier = Classifier::new(lexer::StringReader::new(&sess, fm, None), sess.codemap());
     if let Err(_) = classifier.write_source(&mut out) {
@@ -63,7 +58,7 @@ pub fn render_with_highlighting(src: &str, class: Option<&str>, id: Option<&str>
 /// Processes a program (nested in the internal `lexer`), classifying strings of
 /// text by highlighting category (`Class`). Calls out to a `Writer` to write
 /// each span of text in sequence.
-pub struct Classifier<'a> {
+struct Classifier<'a> {
     lexer: lexer::StringReader<'a>,
     codemap: &'a CodeMap,
 
@@ -75,7 +70,7 @@ pub struct Classifier<'a> {
 
 /// How a span of text is classified. Mostly corresponds to token kinds.
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub enum Class {
+enum Class {
     None,
     Comment,
     DocComment,
@@ -103,7 +98,7 @@ pub enum Class {
 /// The classifier will call into the `Writer` implementation as it finds spans
 /// of text to highlight. Exactly how that text should be highlighted is up to
 /// the implementation.
-pub trait Writer {
+trait Writer {
     /// Called when we start processing a span of text that should be highlighted.
     /// The `Class` argument specifies how it should be highlighted.
     fn enter_span(&mut self, _: Class) -> io::Result<()>;
@@ -111,11 +106,9 @@ pub trait Writer {
     /// Called at the end of a span of highlighted text.
     fn exit_span(&mut self) -> io::Result<()>;
 
-    /// Called for a span of text, usually, but not always, a single token. If
-    /// the string of text (`T`) does correspond to a token, then the token will
-    /// also be passed. If the text should be highlighted differently from the
-    /// surrounding text, then the `Class` argument will be a value other than
-    /// `None`.
+    /// Called for a span of text.  If the text should be highlighted differently from the
+    /// surrounding text, then the `Class` argument will be a value other than `None`.
+    ///
     /// The following sequences of callbacks are equivalent:
     /// ```plain
     ///     enter_span(Foo), string("text", None), exit_span()
@@ -125,8 +118,7 @@ pub trait Writer {
     /// more flexible.
     fn string<T: Display>(&mut self,
                           text: T,
-                          klass: Class,
-                          tok: Option<&TokenAndSpan>)
+                          klass: Class)
                           -> io::Result<()>;
 }
 
@@ -135,8 +127,7 @@ pub trait Writer {
 impl<U: Write> Writer for U {
     fn string<T: Display>(&mut self,
                           text: T,
-                          klass: Class,
-                          _tas: Option<&TokenAndSpan>)
+                          klass: Class)
                           -> io::Result<()> {
         match klass {
             Class::None => write!(self, "{}", text),
@@ -154,7 +145,7 @@ impl<U: Write> Writer for U {
 }
 
 impl<'a> Classifier<'a> {
-    pub fn new(lexer: lexer::StringReader<'a>, codemap: &'a CodeMap) -> Classifier<'a> {
+    fn new(lexer: lexer::StringReader<'a>, codemap: &'a CodeMap) -> Classifier<'a> {
         Classifier {
             lexer,
             codemap,
@@ -186,7 +177,7 @@ impl<'a> Classifier<'a> {
     /// is used. All source code emission is done as slices from the source map,
     /// not from the tokens themselves, in order to stay true to the original
     /// source.
-    pub fn write_source<W: Writer>(&mut self,
+    fn write_source<W: Writer>(&mut self,
                                    out: &mut W)
                                    -> io::Result<()> {
         loop {
@@ -208,7 +199,7 @@ impl<'a> Classifier<'a> {
                               -> io::Result<()> {
         let klass = match tas.tok {
             token::Shebang(s) => {
-                out.string(Escape(&s.as_str()), Class::None, Some(&tas))?;
+                out.string(Escape(&s.as_str()), Class::None)?;
                 return Ok(());
             },
 
@@ -272,8 +263,8 @@ impl<'a> Classifier<'a> {
                         self.in_attribute = true;
                         out.enter_span(Class::Attribute)?;
                     }
-                    out.string("#", Class::None, None)?;
-                    out.string("!", Class::None, None)?;
+                    out.string("#", Class::None)?;
+                    out.string("!", Class::None)?;
                     return Ok(());
                 }
 
@@ -282,13 +273,13 @@ impl<'a> Classifier<'a> {
                     self.in_attribute = true;
                     out.enter_span(Class::Attribute)?;
                 }
-                out.string("#", Class::None, None)?;
+                out.string("#", Class::None)?;
                 return Ok(());
             }
             token::CloseDelim(token::Bracket) => {
                 if self.in_attribute {
                     self.in_attribute = false;
-                    out.string("]", Class::None, None)?;
+                    out.string("]", Class::None)?;
                     out.exit_span()?;
                     return Ok(());
                 } else {
@@ -344,7 +335,7 @@ impl<'a> Classifier<'a> {
 
         // Anything that didn't return above is the simple case where we the
         // class just spans a single token, so we can use the `string` method.
-        out.string(Escape(&self.snip(tas.sp)), klass, Some(&tas))
+        out.string(Escape(&self.snip(tas.sp)), klass)
     }
 
     // Helper function to get a snippet from the codemap.
@@ -355,7 +346,7 @@ impl<'a> Classifier<'a> {
 
 impl Class {
     /// Returns the css class expected by rustdoc for each `Class`.
-    pub fn rustdoc_class(self) -> &'static str {
+    fn rustdoc_class(self) -> &'static str {
         match self {
             Class::None => "",
             Class::Comment => "comment",
@@ -379,15 +370,8 @@ impl Class {
     }
 }
 
-fn write_header(class: Option<&str>,
-                id: Option<&str>,
-                out: &mut dyn Write)
-                -> io::Result<()> {
-    write!(out, "<pre ")?;
-    if let Some(id) = id {
-        write!(out, "id='{}' ", id)?;
-    }
-    write!(out, "class=\"rust {}\">\n", class.unwrap_or(""))
+fn write_header(class: Option<&str>, out: &mut dyn Write) -> io::Result<()> {
+    write!(out, "<pre class=\"rust {}\">\n", class.unwrap_or(""))
 }
 
 fn write_footer(out: &mut dyn Write) -> io::Result<()> {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 8d85adfb3d0ff..b22e239e20a0e 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -18,16 +18,17 @@
 //! ```
 //! #![feature(rustc_private)]
 //!
-//! use rustdoc::html::markdown::Markdown;
+//! use rustdoc::html::markdown::{IdMap, Markdown, ErrorCodes};
+//! use std::cell::RefCell;
 //!
 //! let s = "My *markdown* _text_";
-//! let html = format!("{}", Markdown(s, &[]));
+//! let mut id_map = IdMap::new();
+//! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map), ErrorCodes::Yes));
 //! // ... something using html
 //! ```
 
 #![allow(non_camel_case_types)]
 
-use rustc::session;
 use std::cell::RefCell;
 use std::collections::{HashMap, VecDeque};
 use std::default::Default;
@@ -35,10 +36,7 @@ use std::fmt::{self, Write};
 use std::borrow::Cow;
 use std::ops::Range;
 use std::str;
-use syntax::feature_gate::UnstableFeatures;
-use syntax::codemap::Span;
 
-use html::render::derive_id;
 use html::toc::TocBuilder;
 use html::highlight;
 use test;
@@ -50,15 +48,38 @@ use pulldown_cmark::{Options, OPTION_ENABLE_FOOTNOTES, OPTION_ENABLE_TABLES};
 /// formatted, this struct will emit the HTML corresponding to the rendered
 /// version of the contained markdown string.
 /// The second parameter is a list of link replacements
-pub struct Markdown<'a>(pub &'a str, pub &'a [(String, String)]);
+pub struct Markdown<'a>(
+    pub &'a str, pub &'a [(String, String)], pub RefCell<&'a mut IdMap>, pub ErrorCodes);
 /// A unit struct like `Markdown`, that renders the markdown with a
 /// table of contents.
-pub struct MarkdownWithToc<'a>(pub &'a str);
+pub struct MarkdownWithToc<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes);
 /// A unit struct like `Markdown`, that renders the markdown escaping HTML tags.
-pub struct MarkdownHtml<'a>(pub &'a str);
+pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes);
 /// A unit struct like `Markdown`, that renders only the first paragraph.
 pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]);
 
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum ErrorCodes {
+    Yes,
+    No,
+}
+
+impl ErrorCodes {
+    pub fn from(b: bool) -> Self {
+        match b {
+            true => ErrorCodes::Yes,
+            false => ErrorCodes::No,
+        }
+    }
+
+    pub fn as_bool(self) -> bool {
+        match self {
+            ErrorCodes::Yes => true,
+            ErrorCodes::No => false,
+        }
+    }
+}
+
 /// Controls whether a line will be hidden or shown in HTML output.
 ///
 /// All lines are used in documentation tests.
@@ -129,12 +150,14 @@ thread_local!(pub static PLAYGROUND: RefCell<Option<(Option<String>, String)>> =
 /// Adds syntax highlighting and playground Run buttons to rust code blocks.
 struct CodeBlocks<'a, I: Iterator<Item = Event<'a>>> {
     inner: I,
+    check_error_codes: ErrorCodes,
 }
 
 impl<'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'a, I> {
-    fn new(iter: I) -> Self {
+    fn new(iter: I, error_codes: ErrorCodes) -> Self {
         CodeBlocks {
             inner: iter,
+            check_error_codes: error_codes,
         }
     }
 }
@@ -147,7 +170,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
         let compile_fail;
         let ignore;
         if let Some(Event::Start(Tag::CodeBlock(lang))) = event {
-            let parse_result = LangString::parse(&lang);
+            let parse_result = LangString::parse(&lang, self.check_error_codes);
             if !parse_result.rust {
                 return Some(Event::Start(Tag::CodeBlock(lang)));
             }
@@ -224,7 +247,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
                                       if ignore { " ignore" }
                                       else if compile_fail { " compile_fail" }
                                       else { "" })),
-                        None,
                         playground_button.as_ref().map(String::as_str),
                         tooltip));
             Some(Event::Html(s.into()))
@@ -266,23 +288,25 @@ impl<'a, 'b, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, 'b, I>
 }
 
 /// Make headings links with anchor ids and build up TOC.
-struct HeadingLinks<'a, 'b, I: Iterator<Item = Event<'a>>> {
+struct HeadingLinks<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> {
     inner: I,
     toc: Option<&'b mut TocBuilder>,
     buf: VecDeque<Event<'a>>,
+    id_map: &'ids mut IdMap,
 }
 
-impl<'a, 'b, I: Iterator<Item = Event<'a>>> HeadingLinks<'a, 'b, I> {
-    fn new(iter: I, toc: Option<&'b mut TocBuilder>) -> Self {
+impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> HeadingLinks<'a, 'b, 'ids, I> {
+    fn new(iter: I, toc: Option<&'b mut TocBuilder>, ids: &'ids mut IdMap) -> Self {
         HeadingLinks {
             inner: iter,
             toc,
             buf: VecDeque::new(),
+            id_map: ids,
         }
     }
 }
 
-impl<'a, 'b, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a, 'b, I> {
+impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a, 'b, 'ids, I> {
     type Item = Event<'a>;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -301,7 +325,7 @@ impl<'a, 'b, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a, 'b, I>
                 }
                 self.buf.push_back(event);
             }
-            let id = derive_id(id);
+            let id = self.id_map.derive(id);
 
             if let Some(ref mut builder) = self.toc {
                 let mut html_header = String::new();
@@ -467,10 +491,17 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
     }
 }
 
-pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span,
-                          sess: Option<&session::Session>) {
-    tests.set_position(position);
+pub struct TestableCodeError(());
 
+impl fmt::Display for TestableCodeError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "invalid start of a new code block")
+    }
+}
+
+pub fn find_testable_code(
+    doc: &str, tests: &mut test::Collector, error_codes: ErrorCodes,
+) -> Result<(), TestableCodeError> {
     let mut parser = Parser::new(doc);
     let mut prev_offset = 0;
     let mut nb_lines = 0;
@@ -481,7 +512,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
                 let block_info = if s.is_empty() {
                     LangString::all_false()
                 } else {
-                    LangString::parse(&*s)
+                    LangString::parse(&*s, error_codes)
                 };
                 if !block_info.rust {
                     continue
@@ -510,18 +541,10 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
                     let text = lines.collect::<Vec<Cow<str>>>().join("\n");
                     nb_lines += doc[prev_offset..offset].lines().count();
                     let line = tests.get_line() + (nb_lines - 1);
-                    let filename = tests.get_filename();
-                    tests.add_test(text.to_owned(),
-                                   block_info.should_panic, block_info.no_run,
-                                   block_info.ignore, block_info.test_harness,
-                                   block_info.compile_fail, block_info.error_codes,
-                                   line, filename, block_info.allow_fail);
+                    tests.add_test(text, block_info, line);
                     prev_offset = offset;
                 } else {
-                    if let Some(ref sess) = sess {
-                        sess.span_warn(position, "invalid start of a new code block");
-                    }
-                    break;
+                    return Err(TestableCodeError(()));
                 }
             }
             Event::Start(Tag::Header(level)) => {
@@ -539,19 +562,20 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
             _ => {}
         }
     }
+    Ok(())
 }
 
 #[derive(Eq, PartialEq, Clone, Debug)]
-struct LangString {
+pub struct LangString {
     original: String,
-    should_panic: bool,
-    no_run: bool,
-    ignore: bool,
-    rust: bool,
-    test_harness: bool,
-    compile_fail: bool,
-    error_codes: Vec<String>,
-    allow_fail: bool,
+    pub should_panic: bool,
+    pub no_run: bool,
+    pub ignore: bool,
+    pub rust: bool,
+    pub test_harness: bool,
+    pub compile_fail: bool,
+    pub error_codes: Vec<String>,
+    pub allow_fail: bool,
 }
 
 impl LangString {
@@ -569,14 +593,11 @@ impl LangString {
         }
     }
 
-    fn parse(string: &str) -> LangString {
+    fn parse(string: &str, allow_error_code_check: ErrorCodes) -> LangString {
+        let allow_error_code_check = allow_error_code_check.as_bool();
         let mut seen_rust_tags = false;
         let mut seen_other_tags = false;
         let mut data = LangString::all_false();
-        let mut allow_error_code_check = false;
-        if UnstableFeatures::from_environment().is_nightly_build() {
-            allow_error_code_check = true;
-        }
 
         data.original = string.to_owned();
         let tokens = string.split(|c: char|
@@ -623,7 +644,8 @@ impl LangString {
 
 impl<'a> fmt::Display for Markdown<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        let Markdown(md, links) = *self;
+        let Markdown(md, links, ref ids, codes) = *self;
+        let mut ids = ids.borrow_mut();
 
         // This is actually common enough to special-case
         if md.is_empty() { return Ok(()) }
@@ -643,12 +665,11 @@ impl<'a> fmt::Display for Markdown<'a> {
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
-        html::push_html(&mut s,
-                        Footnotes::new(
-                            CodeBlocks::new(
-                                LinkReplacer::new(
-                                    HeadingLinks::new(p, None),
-                                    links))));
+        let p = HeadingLinks::new(p, None, &mut ids);
+        let p = LinkReplacer::new(p, links);
+        let p = CodeBlocks::new(p, codes);
+        let p = Footnotes::new(p);
+        html::push_html(&mut s, p);
 
         fmt.write_str(&s)
     }
@@ -656,7 +677,8 @@ impl<'a> fmt::Display for Markdown<'a> {
 
 impl<'a> fmt::Display for MarkdownWithToc<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        let MarkdownWithToc(md) = *self;
+        let MarkdownWithToc(md, ref ids, codes) = *self;
+        let mut ids = ids.borrow_mut();
 
         let mut opts = Options::empty();
         opts.insert(OPTION_ENABLE_TABLES);
@@ -668,8 +690,12 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
 
         let mut toc = TocBuilder::new();
 
-        html::push_html(&mut s,
-                        Footnotes::new(CodeBlocks::new(HeadingLinks::new(p, Some(&mut toc)))));
+        {
+            let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
+            let p = CodeBlocks::new(p, codes);
+            let p = Footnotes::new(p);
+            html::push_html(&mut s, p);
+        }
 
         write!(fmt, "<nav id=\"TOC\">{}</nav>", toc.into_toc())?;
 
@@ -679,7 +705,8 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
 
 impl<'a> fmt::Display for MarkdownHtml<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        let MarkdownHtml(md) = *self;
+        let MarkdownHtml(md, ref ids, codes) = *self;
+        let mut ids = ids.borrow_mut();
 
         // This is actually common enough to special-case
         if md.is_empty() { return Ok(()) }
@@ -697,8 +724,10 @@ impl<'a> fmt::Display for MarkdownHtml<'a> {
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
-        html::push_html(&mut s,
-                        Footnotes::new(CodeBlocks::new(HeadingLinks::new(p, None))));
+        let p = HeadingLinks::new(p, None, &mut ids);
+        let p = CodeBlocks::new(p, codes);
+        let p = Footnotes::new(p);
+        html::push_html(&mut s, p);
 
         fmt.write_str(&s)
     }
@@ -812,7 +841,10 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
         let p = Parser::new_with_broken_link_callback(md, opts,
             Some(&push));
 
-        let iter = Footnotes::new(HeadingLinks::new(p, None));
+        // There's no need to thread an IdMap through to here because
+        // the IDs generated aren't going to be emitted anywhere.
+        let mut ids = IdMap::new();
+        let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids));
 
         for ev in iter {
             if let Event::Start(Tag::Link(dest, _)) = ev {
@@ -831,18 +863,74 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
     links
 }
 
+#[derive(Default)]
+pub struct IdMap {
+    map: HashMap<String, usize>,
+}
+
+impl IdMap {
+    pub fn new() -> Self {
+        IdMap::default()
+    }
+
+    pub fn populate<I: IntoIterator<Item=String>>(&mut self, ids: I) {
+        for id in ids {
+            let _ = self.derive(id);
+        }
+    }
+
+    pub fn reset(&mut self) {
+        self.map = HashMap::new();
+    }
+
+    pub fn derive(&mut self, candidate: String) -> String {
+        let id = match self.map.get_mut(&candidate) {
+            None => candidate,
+            Some(a) => {
+                let id = format!("{}-{}", candidate, *a);
+                *a += 1;
+                id
+            }
+        };
+
+        self.map.insert(id.clone(), 1);
+        id
+    }
+}
+
+#[cfg(test)]
+#[test]
+fn test_unique_id() {
+    let input = ["foo", "examples", "examples", "method.into_iter","examples",
+                 "method.into_iter", "foo", "main", "search", "methods",
+                 "examples", "method.into_iter", "assoc_type.Item", "assoc_type.Item"];
+    let expected = ["foo", "examples", "examples-1", "method.into_iter", "examples-2",
+                    "method.into_iter-1", "foo-1", "main", "search", "methods",
+                    "examples-3", "method.into_iter-2", "assoc_type.Item", "assoc_type.Item-1"];
+
+    let map = RefCell::new(IdMap::new());
+    let test = || {
+        let mut map = map.borrow_mut();
+        let actual: Vec<String> = input.iter().map(|s| map.derive(s.to_string())).collect();
+        assert_eq!(&actual[..], expected);
+    };
+    test();
+    map.borrow_mut().reset();
+    test();
+}
+
 #[cfg(test)]
 mod tests {
-    use super::{LangString, Markdown, MarkdownHtml};
+    use super::{ErrorCodes, LangString, Markdown, MarkdownHtml, IdMap};
     use super::plain_summary_line;
-    use html::render::reset_ids;
+    use std::cell::RefCell;
 
     #[test]
     fn test_lang_string_parse() {
         fn t(s: &str,
             should_panic: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool,
             compile_fail: bool, allow_fail: bool, error_codes: Vec<String>) {
-            assert_eq!(LangString::parse(s), LangString {
+            assert_eq!(LangString::parse(s, ErrorCodes::Yes), LangString {
                 should_panic,
                 no_run,
                 ignore,
@@ -878,19 +966,12 @@ mod tests {
         t("text,no_run",           false,        true,   false,  false, false, false, false, v());
     }
 
-    #[test]
-    fn issue_17736() {
-        let markdown = "# title";
-        Markdown(markdown, &[]).to_string();
-        reset_ids(true);
-    }
-
     #[test]
     fn test_header() {
         fn t(input: &str, expect: &str) {
-            let output = Markdown(input, &[]).to_string();
+            let mut map = IdMap::new();
+            let output = Markdown(input, &[], RefCell::new(&mut map), ErrorCodes::Yes).to_string();
             assert_eq!(output, expect, "original: {}", input);
-            reset_ids(true);
         }
 
         t("# Foo bar", "<h1 id=\"foo-bar\" class=\"section-header\">\
@@ -909,28 +990,24 @@ mod tests {
 
     #[test]
     fn test_header_ids_multiple_blocks() {
-        fn t(input: &str, expect: &str) {
-            let output = Markdown(input, &[]).to_string();
+        let mut map = IdMap::new();
+        fn t(map: &mut IdMap, input: &str, expect: &str) {
+            let output = Markdown(input, &[], RefCell::new(map), ErrorCodes::Yes).to_string();
             assert_eq!(output, expect, "original: {}", input);
         }
 
-        let test = || {
-            t("# Example", "<h1 id=\"example\" class=\"section-header\">\
-              <a href=\"#example\">Example</a></h1>");
-            t("# Panics", "<h1 id=\"panics\" class=\"section-header\">\
-              <a href=\"#panics\">Panics</a></h1>");
-            t("# Example", "<h1 id=\"example-1\" class=\"section-header\">\
-              <a href=\"#example-1\">Example</a></h1>");
-            t("# Main", "<h1 id=\"main-1\" class=\"section-header\">\
-              <a href=\"#main-1\">Main</a></h1>");
-            t("# Example", "<h1 id=\"example-2\" class=\"section-header\">\
-              <a href=\"#example-2\">Example</a></h1>");
-            t("# Panics", "<h1 id=\"panics-1\" class=\"section-header\">\
-              <a href=\"#panics-1\">Panics</a></h1>");
-        };
-        test();
-        reset_ids(true);
-        test();
+        t(&mut map, "# Example", "<h1 id=\"example\" class=\"section-header\">\
+            <a href=\"#example\">Example</a></h1>");
+        t(&mut map, "# Panics", "<h1 id=\"panics\" class=\"section-header\">\
+            <a href=\"#panics\">Panics</a></h1>");
+        t(&mut map, "# Example", "<h1 id=\"example-1\" class=\"section-header\">\
+            <a href=\"#example-1\">Example</a></h1>");
+        t(&mut map, "# Main", "<h1 id=\"main\" class=\"section-header\">\
+            <a href=\"#main\">Main</a></h1>");
+        t(&mut map, "# Example", "<h1 id=\"example-2\" class=\"section-header\">\
+            <a href=\"#example-2\">Example</a></h1>");
+        t(&mut map, "# Panics", "<h1 id=\"panics-1\" class=\"section-header\">\
+            <a href=\"#panics-1\">Panics</a></h1>");
     }
 
     #[test]
@@ -951,7 +1028,8 @@ mod tests {
     #[test]
     fn test_markdown_html_escape() {
         fn t(input: &str, expect: &str) {
-            let output = MarkdownHtml(input).to_string();
+            let mut idmap = IdMap::new();
+            let output = MarkdownHtml(input, RefCell::new(&mut idmap), ErrorCodes::Yes).to_string();
             assert_eq!(output, expect, "original: {}", input);
         }
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 24a9bf416e444..c2978a62489a0 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -50,12 +50,14 @@ use std::mem;
 use std::path::{PathBuf, Path, Component};
 use std::str;
 use std::sync::Arc;
+use std::rc::Rc;
 
 use externalfiles::ExternalHtml;
 
 use serialize::json::{ToJson, Json, as_json};
 use syntax::ast;
 use syntax::codemap::FileName;
+use syntax::feature_gate::UnstableFeatures;
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
 use rustc::middle::privacy::AccessLevels;
 use rustc::middle::stability;
@@ -72,7 +74,7 @@ use html::format::{GenericBounds, WhereClause, href, AbiSpace};
 use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
 use html::format::fmt_impl_for_trait_page;
 use html::item_type::ItemType;
-use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine};
+use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine, ErrorCodes, IdMap};
 use html::{highlight, layout};
 
 use minifier;
@@ -88,7 +90,7 @@ pub type NameDoc = (String, Option<String>);
 /// easily cloned because it is cloned per work-job (about once per item in the
 /// rustdoc tree).
 #[derive(Clone)]
-pub struct Context {
+struct Context {
     /// Current hierarchy of components leading down to what's currently being
     /// rendered
     pub current: Vec<String>,
@@ -99,10 +101,13 @@ pub struct Context {
     /// real location of an item. This is used to allow external links to
     /// publicly reused items to redirect to the right location.
     pub render_redirect_pages: bool,
+    pub codes: ErrorCodes,
+    /// The map used to ensure all generated 'id=' attributes are unique.
+    id_map: Rc<RefCell<IdMap>>,
     pub shared: Arc<SharedContext>,
 }
 
-pub struct SharedContext {
+struct SharedContext {
     /// The path to the crate root source minus the file name.
     /// Used for simplifying paths to the highlighted source code files.
     pub src_root: PathBuf,
@@ -450,9 +455,8 @@ impl ToJson for IndexItemFunctionType {
 
 thread_local!(static CACHE_KEY: RefCell<Arc<Cache>> = Default::default());
 thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> = RefCell::new(Vec::new()));
-thread_local!(pub static USED_ID_MAP: RefCell<FxHashMap<String, usize>> = RefCell::new(init_ids()));
 
-fn init_ids() -> FxHashMap<String, usize> {
+pub fn initial_ids() -> Vec<String> {
     [
      "main",
      "search",
@@ -470,36 +474,7 @@ fn init_ids() -> FxHashMap<String, usize> {
      "methods",
      "deref-methods",
      "implementations",
-    ].into_iter().map(|id| (String::from(*id), 1)).collect()
-}
-
-/// This method resets the local table of used ID attributes. This is typically
-/// used at the beginning of rendering an entire HTML page to reset from the
-/// previous state (if any).
-pub fn reset_ids(embedded: bool) {
-    USED_ID_MAP.with(|s| {
-        *s.borrow_mut() = if embedded {
-            init_ids()
-        } else {
-            FxHashMap()
-        };
-    });
-}
-
-pub fn derive_id(candidate: String) -> String {
-    USED_ID_MAP.with(|map| {
-        let id = match map.borrow_mut().get_mut(&candidate) {
-            None => candidate,
-            Some(a) => {
-                let id = format!("{}-{}", candidate, *a);
-                *a += 1;
-                id
-            }
-        };
-
-        map.borrow_mut().insert(id.clone(), 1);
-        id
-    })
+    ].into_iter().map(|id| (String::from(*id))).collect()
 }
 
 /// Generates the documentation for `crate` into the directory `dst`
@@ -513,7 +488,8 @@ pub fn run(mut krate: clean::Crate,
            renderinfo: RenderInfo,
            sort_modules_alphabetically: bool,
            themes: Vec<PathBuf>,
-           enable_minification: bool) -> Result<(), Error> {
+           enable_minification: bool,
+           id_map: IdMap) -> Result<(), Error> {
     let src_root = match krate.src {
         FileName::Real(ref p) => match p.parent() {
             Some(p) => p.to_path_buf(),
@@ -581,6 +557,8 @@ pub fn run(mut krate: clean::Crate,
         current: Vec::new(),
         dst,
         render_redirect_pages: false,
+        codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
+        id_map: Rc::new(RefCell::new(id_map)),
         shared: Arc::new(scx),
     };
 
@@ -1708,6 +1686,11 @@ impl<'a> fmt::Display for Settings<'a> {
 }
 
 impl Context {
+    fn derive_id(&self, id: String) -> String {
+        let mut map = self.id_map.borrow_mut();
+        map.derive(id)
+    }
+
     /// String representation of how to get back to the root path of the 'doc/'
     /// folder in terms of a relative URL.
     fn root_path(&self) -> String {
@@ -1862,7 +1845,10 @@ impl Context {
             resource_suffix: &self.shared.resource_suffix,
         };
 
-        reset_ids(true);
+        {
+            self.id_map.borrow_mut().reset();
+            self.id_map.borrow_mut().populate(initial_ids());
+        }
 
         if !self.render_redirect_pages {
             layout::render(writer, &self.shared.layout, &page,
@@ -2219,14 +2205,17 @@ fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Re
 
 /// Render md_text as markdown.
 fn render_markdown(w: &mut fmt::Formatter,
+                   cx: &Context,
                    md_text: &str,
                    links: Vec<(String, String)>,
-                   prefix: &str,)
+                   prefix: &str)
                    -> fmt::Result {
-    write!(w, "<div class='docblock'>{}{}</div>", prefix, Markdown(md_text, &links))
+    let mut ids = cx.id_map.borrow_mut();
+    write!(w, "<div class='docblock'>{}{}</div>",
+        prefix, Markdown(md_text, &links, RefCell::new(&mut ids), cx.codes))
 }
 
-fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLink,
+fn document_short(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item, link: AssocItemLink,
                   prefix: &str) -> fmt::Result {
     if let Some(s) = item.doc_value() {
         let markdown = if s.contains('\n') {
@@ -2235,7 +2224,7 @@ fn document_short(w: &mut fmt::Formatter, item: &clean::Item, link: AssocItemLin
         } else {
             plain_summary_line(Some(s)).to_string()
         };
-        render_markdown(w, &markdown, item.links(), prefix)?;
+        render_markdown(w, cx, &markdown, item.links(), prefix)?;
     } else if !prefix.is_empty() {
         write!(w, "<div class='docblock'>{}</div>", prefix)?;
     }
@@ -2250,7 +2239,6 @@ fn render_assoc_const_value(item: &clean::Item) -> String {
                 None,
                 None,
                 None,
-                None,
             )
         }
         _ => String::new(),
@@ -2261,7 +2249,7 @@ fn document_full(w: &mut fmt::Formatter, item: &clean::Item,
                  cx: &Context, prefix: &str) -> fmt::Result {
     if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) {
         debug!("Doc block: =====\n{}\n=====", s);
-        render_markdown(w, &*s, item.links(), prefix)?;
+        render_markdown(w, cx, &*s, item.links(), prefix)?;
     } else if !prefix.is_empty() {
         write!(w, "<div class='docblock'>{}</div>", prefix)?;
     }
@@ -2427,7 +2415,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
             let (short, name) = item_ty_to_strs(&myty.unwrap());
             write!(w, "<h2 id='{id}' class='section-header'>\
                        <a href=\"#{id}\">{name}</a></h2>\n<table>",
-                   id = derive_id(short.to_owned()), name = name)?;
+                   id = cx.derive_id(short.to_owned()), name = name)?;
         }
 
         match myitem.inner {
@@ -2508,6 +2496,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
 
 fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<String> {
     let mut stability = vec![];
+    let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
 
     if let Some(stab) = item.stability.as_ref() {
         let deprecated_reason = if show_reason && !stab.deprecated_reason.is_empty() {
@@ -2521,14 +2510,12 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
             } else {
                 String::new()
             };
+            let mut ids = cx.id_map.borrow_mut();
+            let html = MarkdownHtml(&deprecated_reason, RefCell::new(&mut ids), error_codes);
             let text = if stability::deprecation_in_effect(&stab.deprecated_since) {
-                format!("Deprecated{}{}",
-                        since,
-                        MarkdownHtml(&deprecated_reason))
+                format!("Deprecated{}{}", since, html)
             } else {
-                format!("Deprecating in {}{}",
-                        Escape(&stab.deprecated_since),
-                        MarkdownHtml(&deprecated_reason))
+                format!("Deprecating in {}{}", Escape(&stab.deprecated_since), html)
             };
             stability.push(format!("<div class='stab deprecated'>{}</div>", text))
         };
@@ -2555,11 +2542,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
                                             </div>",
                                            unstable_extra));
                 } else {
+                    let mut ids = cx.id_map.borrow_mut();
                     let text = format!("<summary><span class=microscope>🔬</span> \
                                         This is a nightly-only experimental API. {}\
                                         </summary>{}",
                                        unstable_extra,
-                                       MarkdownHtml(&stab.unstable_reason));
+                                       MarkdownHtml(
+                                           &stab.unstable_reason,
+                                           RefCell::new(&mut ids),
+                                           error_codes));
                     stability.push(format!("<div class='stab unstable'><details>{}</details></div>",
                                    text));
                 }
@@ -2579,14 +2570,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<S
             String::new()
         };
 
+        let mut ids = cx.id_map.borrow_mut();
         let text = if stability::deprecation_in_effect(&depr.since) {
             format!("Deprecated{}{}",
                     since,
-                    MarkdownHtml(&note))
+                    MarkdownHtml(&note, RefCell::new(&mut ids), error_codes))
         } else {
             format!("Deprecating in {}{}",
                     Escape(&depr.since),
-                    MarkdownHtml(&note))
+                    MarkdownHtml(&note, RefCell::new(&mut ids), error_codes))
         };
         stability.push(format!("<div class='stab deprecated'>{}</div>", text))
     }
@@ -2827,8 +2819,8 @@ fn item_trait(
                   -> fmt::Result {
         let name = m.name.as_ref().unwrap();
         let item_type = m.type_();
-        let id = derive_id(format!("{}.{}", item_type, name));
-        let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
+        let id = cx.derive_id(format!("{}.{}", item_type, name));
+        let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
         write!(w, "{extra}<h3 id='{id}' class='method'>\
                    <span id='{ns_id}' class='invisible'><code>",
                extra = render_spotlight_traits(m)?,
@@ -3183,10 +3175,10 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                        document_non_exhaustive_header(it))?;
             document_non_exhaustive(w, it)?;
             for (field, ty) in fields {
-                let id = derive_id(format!("{}.{}",
+                let id = cx.derive_id(format!("{}.{}",
                                            ItemType::StructField,
                                            field.name.as_ref().unwrap()));
-                let ns_id = derive_id(format!("{}.{}",
+                let ns_id = cx.derive_id(format!("{}.{}",
                                               field.name.as_ref().unwrap(),
                                               ItemType::StructField.name_space()));
                 write!(w, "<span id=\"{id}\" class=\"{item_type} small-section-header\">
@@ -3317,10 +3309,10 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                    document_non_exhaustive_header(it))?;
         document_non_exhaustive(w, it)?;
         for variant in &e.variants {
-            let id = derive_id(format!("{}.{}",
+            let id = cx.derive_id(format!("{}.{}",
                                        ItemType::Variant,
                                        variant.name.as_ref().unwrap()));
-            let ns_id = derive_id(format!("{}.{}",
+            let ns_id = cx.derive_id(format!("{}.{}",
                                           variant.name.as_ref().unwrap(),
                                           ItemType::Variant.name_space()));
             write!(w, "<span id=\"{id}\" class=\"variant small-section-header\">\
@@ -3348,7 +3340,7 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
             if let clean::VariantItem(Variant {
                 kind: VariantKind::Struct(ref s)
             }) = variant.inner {
-                let variant_id = derive_id(format!("{}.{}.fields",
+                let variant_id = cx.derive_id(format!("{}.{}.fields",
                                                    ItemType::Variant,
                                                    variant.name.as_ref().unwrap()));
                 write!(w, "<span class='docblock autohide sub-variant' id='{id}'>",
@@ -3358,10 +3350,10 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
                 for field in &s.fields {
                     use clean::StructFieldItem;
                     if let StructFieldItem(ref ty) = field.inner {
-                        let id = derive_id(format!("variant.{}.field.{}",
+                        let id = cx.derive_id(format!("variant.{}.field.{}",
                                                    variant.name.as_ref().unwrap(),
                                                    field.name.as_ref().unwrap()));
-                        let ns_id = derive_id(format!("{}.{}.{}.{}",
+                        let ns_id = cx.derive_id(format!("{}.{}.{}.{}",
                                                       variant.name.as_ref().unwrap(),
                                                       ItemType::Variant.name_space(),
                                                       field.name.as_ref().unwrap(),
@@ -3790,7 +3782,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
                render_mode: RenderMode, outer_version: Option<&str>,
                show_def_docs: bool) -> fmt::Result {
     if render_mode == RenderMode::Normal {
-        let id = derive_id(match i.inner_impl().trait_ {
+        let id = cx.derive_id(match i.inner_impl().trait_ {
             Some(ref t) => format!("impl-{}", small_url_encode(&format!("{:#}", t))),
             None => "impl".to_string(),
         });
@@ -3810,8 +3802,9 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
         }
         write!(w, "</span></td></tr></tbody></table></h3>")?;
         if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
+            let mut ids = cx.id_map.borrow_mut();
             write!(w, "<div class='docblock'>{}</div>",
-                   Markdown(&*dox, &i.impl_item.links()))?;
+                   Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids), cx.codes))?;
         }
     }
 
@@ -3832,8 +3825,8 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
             clean::TyMethodItem(clean::TyMethod{ ref decl, .. }) => {
                 // Only render when the method is not static or we allow static methods
                 if render_method_item {
-                    let id = derive_id(format!("{}.{}", item_type, name));
-                    let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
+                    let id = cx.derive_id(format!("{}.{}", item_type, name));
+                    let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
                     write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?;
                     write!(w, "{}", spotlight_decl(decl)?)?;
                     write!(w, "<span id='{}' class='invisible'>", ns_id)?;
@@ -3854,24 +3847,24 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
                 }
             }
             clean::TypedefItem(ref tydef, _) => {
-                let id = derive_id(format!("{}.{}", ItemType::AssociatedType, name));
-                let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
+                let id = cx.derive_id(format!("{}.{}", ItemType::AssociatedType, name));
+                let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
                 write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?;
                 write!(w, "<span id='{}' class='invisible'><code>", ns_id)?;
                 assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id))?;
                 write!(w, "</code></span></h4>\n")?;
             }
             clean::AssociatedConstItem(ref ty, ref default) => {
-                let id = derive_id(format!("{}.{}", item_type, name));
-                let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
+                let id = cx.derive_id(format!("{}.{}", item_type, name));
+                let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
                 write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?;
                 write!(w, "<span id='{}' class='invisible'><code>", ns_id)?;
                 assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?;
                 write!(w, "</code></span></h4>\n")?;
             }
             clean::AssociatedTypeItem(ref bounds, ref default) => {
-                let id = derive_id(format!("{}.{}", item_type, name));
-                let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
+                let id = cx.derive_id(format!("{}.{}", item_type, name));
+                let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
                 write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?;
                 write!(w, "<span id='{}' class='invisible'><code>", ns_id)?;
                 assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id))?;
@@ -3897,7 +3890,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
                         } else if show_def_docs {
                             // In case the item isn't documented,
                             // provide short documentation from the trait.
-                            document_short(w, it, link, &prefix)?;
+                            document_short(w, cx, it, link, &prefix)?;
                         }
                     }
                 } else {
@@ -3909,7 +3902,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
             } else {
                 document_stability(w, cx, item)?;
                 if show_def_docs {
-                    document_short(w, item, link, &prefix)?;
+                    document_short(w, cx, item, link, &prefix)?;
                 }
             }
         }
@@ -4557,7 +4550,7 @@ impl<'a> fmt::Display for Source<'a> {
         }
         write!(fmt, "</pre>")?;
         write!(fmt, "{}",
-               highlight::render_with_highlighting(s, None, None, None, None))?;
+               highlight::render_with_highlighting(s, None, None, None))?;
         Ok(())
     }
 }
@@ -4568,7 +4561,6 @@ fn item_macro(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
         w.write_str(&highlight::render_with_highlighting(&t.source,
                                                          Some("macro"),
                                                          None,
-                                                         None,
                                                          None))
     })?;
     document(w, cx, it)
@@ -4715,25 +4707,6 @@ pub fn cache() -> Arc<Cache> {
     CACHE_KEY.with(|c| c.borrow().clone())
 }
 
-#[cfg(test)]
-#[test]
-fn test_unique_id() {
-    let input = ["foo", "examples", "examples", "method.into_iter","examples",
-                 "method.into_iter", "foo", "main", "search", "methods",
-                 "examples", "method.into_iter", "assoc_type.Item", "assoc_type.Item"];
-    let expected = ["foo", "examples", "examples-1", "method.into_iter", "examples-2",
-                    "method.into_iter-1", "foo-1", "main-1", "search-1", "methods-1",
-                    "examples-3", "method.into_iter-2", "assoc_type.Item", "assoc_type.Item-1"];
-
-    let test = || {
-        let actual: Vec<String> = input.iter().map(|s| derive_id(s.to_string())).collect();
-        assert_eq!(&actual[..], expected);
-    };
-    test();
-    reset_ids(true);
-    test();
-}
-
 #[cfg(test)]
 #[test]
 fn test_name_key() {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 041a233617083..0a4955f4fbd10 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -500,12 +500,14 @@ fn main_args(args: &[String]) -> isize {
         }
     }
 
+    let mut id_map = html::markdown::IdMap::new();
+    id_map.populate(html::render::initial_ids());
     let external_html = match ExternalHtml::load(
             &matches.opt_strs("html-in-header"),
             &matches.opt_strs("html-before-content"),
             &matches.opt_strs("html-after-content"),
             &matches.opt_strs("markdown-before-content"),
-            &matches.opt_strs("markdown-after-content"), &diag) {
+            &matches.opt_strs("markdown-after-content"), &diag, &mut id_map) {
         Some(eh) => eh,
         None => return 3,
     };
@@ -562,7 +564,7 @@ fn main_args(args: &[String]) -> isize {
                                   renderinfo,
                                   sort_modules_alphabetically,
                                   themes,
-                                  enable_minification)
+                                  enable_minification, id_map)
                     .expect("failed to generate documentation");
                 0
             }
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 36a8fc94dba2f..05661dc685663 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -12,6 +12,7 @@ use std::default::Default;
 use std::fs::File;
 use std::io::prelude::*;
 use std::path::{PathBuf, Path};
+use std::cell::RefCell;
 
 use errors;
 use getopts;
@@ -19,14 +20,14 @@ use testing;
 use rustc::session::search_paths::SearchPaths;
 use rustc::session::config::{Externs, CodegenOptions};
 use syntax::codemap::DUMMY_SP;
+use syntax::feature_gate::UnstableFeatures;
 use syntax::edition::Edition;
 
 use externalfiles::{ExternalHtml, LoadStringError, load_string};
 
-use html::render::reset_ids;
 use html::escape::Escape;
 use html::markdown;
-use html::markdown::{Markdown, MarkdownWithToc, find_testable_code};
+use html::markdown::{ErrorCodes, IdMap, Markdown, MarkdownWithToc, find_testable_code};
 use test::{TestOptions, Collector};
 
 /// Separate any lines at the start of the file that begin with `# ` or `%`.
@@ -86,12 +87,12 @@ pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches,
     }
     let title = metadata[0];
 
-    reset_ids(false);
-
+    let mut ids = IdMap::new();
+    let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
     let text = if include_toc {
-        MarkdownWithToc(text).to_string()
+        MarkdownWithToc(text, RefCell::new(&mut ids), error_codes).to_string()
     } else {
-        Markdown(text, &[]).to_string()
+        Markdown(text, &[], RefCell::new(&mut ids), error_codes).to_string()
     };
 
     let err = write!(
@@ -156,7 +157,12 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
                                        true, opts, maybe_sysroot, None,
                                        Some(PathBuf::from(input)),
                                        linker, edition);
-    find_testable_code(&input_str, &mut collector, DUMMY_SP, None);
+    collector.set_position(DUMMY_SP);
+    let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
+    let res = find_testable_code(&input_str, &mut collector, codes);
+    if let Err(err) = res {
+        diag.span_warn(DUMMY_SP, &err.to_string());
+    }
     test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&test_args, collector.tests,
                        testing::Options::new().display_output(display_warnings));
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 2966b9e9819b4..650a2408aa6ed 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -42,7 +42,7 @@ use errors;
 use errors::emitter::ColorConfig;
 
 use clean::Attributes;
-use html::markdown;
+use html::markdown::{self, ErrorCodes, LangString};
 
 #[derive(Clone, Default)]
 pub struct TestOptions {
@@ -145,7 +145,8 @@ pub fn run(input_path: &Path,
             let mut hir_collector = HirCollector {
                 sess: &sess,
                 collector: &mut collector,
-                map: &map
+                map: &map,
+                codes: ErrorCodes::from(sess.opts.unstable_features.is_nightly_build()),
             };
             hir_collector.visit_testable("".to_string(), &krate.attrs, |this| {
                 intravisit::walk_crate(this, krate);
@@ -533,10 +534,8 @@ impl Collector {
         format!("{} - {} (line {})", filename, self.names.join("::"), line)
     }
 
-    pub fn add_test(&mut self, test: String,
-                    should_panic: bool, no_run: bool, should_ignore: bool,
-                    as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
-                    line: usize, filename: FileName, allow_fail: bool) {
+    pub fn add_test(&mut self, test: String, config: LangString, line: usize) {
+        let filename = self.get_filename();
         let name = self.generate_name(line, &filename);
         let cfgs = self.cfgs.clone();
         let libs = self.libs.clone();
@@ -551,10 +550,10 @@ impl Collector {
         self.tests.push(testing::TestDescAndFn {
             desc: testing::TestDesc {
                 name: testing::DynTestName(name.clone()),
-                ignore: should_ignore,
+                ignore: config.ignore,
                 // compiler failures are test failures
                 should_panic: testing::ShouldPanic::No,
-                allow_fail,
+                allow_fail: config.allow_fail,
             },
             testfn: testing::DynTestFn(box move || {
                 let panic = io::set_panic(None);
@@ -572,11 +571,11 @@ impl Collector {
                                  libs,
                                  cg,
                                  externs,
-                                 should_panic,
-                                 no_run,
-                                 as_test_harness,
-                                 compile_fail,
-                                 error_codes,
+                                 config.should_panic,
+                                 config.no_run,
+                                 config.test_harness,
+                                 config.compile_fail,
+                                 config.error_codes,
                                  &opts,
                                  maybe_sysroot,
                                  linker,
@@ -604,7 +603,7 @@ impl Collector {
         self.position = position;
     }
 
-    pub fn get_filename(&self) -> FileName {
+    fn get_filename(&self) -> FileName {
         if let Some(ref codemap) = self.codemap {
             let filename = codemap.span_to_filename(self.position);
             if let FileName::Real(ref filename) = filename {
@@ -664,7 +663,8 @@ impl Collector {
 struct HirCollector<'a, 'hir: 'a> {
     sess: &'a session::Session,
     collector: &'a mut Collector,
-    map: &'a hir::map::Map<'hir>
+    map: &'a hir::map::Map<'hir>,
+    codes: ErrorCodes,
 }
 
 impl<'a, 'hir> HirCollector<'a, 'hir> {
@@ -689,10 +689,12 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
         // the collapse-docs pass won't combine sugared/raw doc attributes, or included files with
         // anything else, this will combine them for us
         if let Some(doc) = attrs.collapsed_doc_value() {
-            markdown::find_testable_code(&doc,
-                                         self.collector,
-                                         attrs.span.unwrap_or(DUMMY_SP),
-                                         Some(self.sess));
+            self.collector.set_position(attrs.span.unwrap_or(DUMMY_SP));
+            let res = markdown::find_testable_code(&doc, self.collector, self.codes);
+            if let Err(err) = res {
+                self.sess.diagnostic().span_warn(attrs.span.unwrap_or(DUMMY_SP),
+                    &err.to_string());
+            }
         }
 
         nested(self);
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 7341dec5156d4..ed94194ffcc05 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -46,58 +46,67 @@ pub trait Encoder {
 
     // Compound types:
     fn emit_enum<F>(&mut self, _name: &str, f: F) -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) }
-
-    fn emit_enum_variant<F>(&mut self, _v_name: &str,
-                            v_id: usize,
-                            _len: usize,
-                            f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+    {
+        f(self)
+    }
+
+    fn emit_enum_variant<F>(&mut self, _v_name: &str, v_id: usize, _len: usize, f: F)
+        -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error>
     {
         self.emit_usize(v_id)?;
         f(self)
     }
-    fn emit_enum_variant_arg<F>(&mut self, _a_idx: usize, f: F)
-                                -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) }
 
-    fn emit_enum_struct_variant<F>(&mut self, v_name: &str,
-                                   v_id: usize,
-                                   len: usize,
-                                   f: F) -> Result<(), Self::Error>
+    fn emit_enum_variant_arg<F>(&mut self, _a_idx: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+    {
+        f(self)
+    }
+
+    fn emit_enum_struct_variant<F>(&mut self, v_name: &str, v_id: usize, len: usize, f: F)
+        -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error>
     {
         self.emit_enum_variant(v_name, v_id, len, f)
     }
-    fn emit_enum_struct_variant_field<F>(&mut self,
-                                         _f_name: &str,
-                                         f_idx: usize,
-                                         f: F) -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+
+    fn emit_enum_struct_variant_field<F>(&mut self, _f_name: &str, f_idx: usize, f: F)
+        -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error>
     {
         self.emit_enum_variant_arg(f_idx, f)
     }
 
-    fn emit_struct<F>(&mut self, _name: &str, _len: usize, f: F)
-                      -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) }
+    fn emit_struct<F>(&mut self, _name: &str, _len: usize, f: F) -> Result<(), Self::Error>
+        where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+    {
+        f(self)
+    }
+
     fn emit_struct_field<F>(&mut self, _f_name: &str, _f_idx: usize, f: F)
-                            -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) }
+        -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+    {
+        f(self)
+    }
 
     fn emit_tuple<F>(&mut self, _len: usize, f: F) -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) }
+        where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+    {
+        f(self)
+    }
+
     fn emit_tuple_arg<F>(&mut self, _idx: usize, f: F) -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) }
+        where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+    {
+        f(self)
+    }
 
-    fn emit_tuple_struct<F>(&mut self, _name: &str, len: usize, f: F)
-                            -> Result<(), Self::Error>
+    fn emit_tuple_struct<F>(&mut self, _name: &str, len: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>
     {
         self.emit_tuple(len, f)
     }
-    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F)
-                                -> Result<(), Self::Error>
+
+    fn emit_tuple_struct_arg<F>(&mut self, f_idx: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>
     {
         self.emit_tuple_arg(f_idx, f)
@@ -109,13 +118,14 @@ pub trait Encoder {
     {
         self.emit_enum("Option", f)
     }
+
     fn emit_option_none(&mut self) -> Result<(), Self::Error> {
         self.emit_enum_variant("None", 0, 0, |_| Ok(()))
     }
+
     fn emit_option_some<F>(&mut self, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>
     {
-
         self.emit_enum_variant("Some", 1, 1, f)
     }
 
@@ -125,8 +135,12 @@ pub trait Encoder {
         self.emit_usize(len)?;
         f(self)
     }
+
     fn emit_seq_elt<F>(&mut self, _idx: usize, f: F) -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) }
+        where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+    {
+        f(self)
+    }
 
     fn emit_map<F>(&mut self, len: usize, f: F) -> Result<(), Self::Error>
         where F: FnOnce(&mut Self) -> Result<(), Self::Error>
@@ -134,10 +148,18 @@ pub trait Encoder {
         self.emit_usize(len)?;
         f(self)
     }
+
     fn emit_map_elt_key<F>(&mut self, _idx: usize, f: F) -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) }
+        where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+    {
+        f(self)
+    }
+
     fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> Result<(), Self::Error>
-        where F: FnOnce(&mut Self) -> Result<(), Self::Error> { f(self) }
+        where F: FnOnce(&mut Self) -> Result<(), Self::Error>
+    {
+        f(self)
+    }
 }
 
 pub trait Decoder {
@@ -165,59 +187,67 @@ pub trait Decoder {
 
     // Compound types:
     fn read_enum<T, F>(&mut self, _name: &str, f: F) -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error> { f(self) }
+        where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+    {
+        f(self)
+    }
 
-    fn read_enum_variant<T, F>(&mut self, _names: &[&str], mut f: F)
-                               -> Result<T, Self::Error>
+    fn read_enum_variant<T, F>(&mut self, _names: &[&str], mut f: F) -> Result<T, Self::Error>
         where F: FnMut(&mut Self, usize) -> Result<T, Self::Error>
     {
         let disr = self.read_usize()?;
         f(self, disr)
     }
-    fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, f: F)
-                                   -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error> { f(self) }
 
-    fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F)
-                                      -> Result<T, Self::Error>
+    fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, f: F) -> Result<T, Self::Error>
+        where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+    {
+        f(self)
+    }
+
+    fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, Self::Error>
         where F: FnMut(&mut Self, usize) -> Result<T, Self::Error>
     {
         self.read_enum_variant(names, f)
     }
-    fn read_enum_struct_variant_field<T, F>(&mut self,
-                                            _f_name: &str,
-                                            f_idx: usize,
-                                            f: F)
-                                            -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+
+    fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, f_idx: usize, f: F)
+        -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error>
     {
         self.read_enum_variant_arg(f_idx, f)
     }
 
-    fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, f: F)
-                         -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error> { f(self) }
-    fn read_struct_field<T, F>(&mut self,
-                               _f_name: &str,
-                               _f_idx: usize,
-                               f: F)
-                               -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error> { f(self) }
+    fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, f: F) -> Result<T, Self::Error>
+        where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+    {
+        f(self)
+    }
+
+    fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, f: F)
+        -> Result<T, Self::Error> where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+    {
+        f(self)
+    }
 
     fn read_tuple<T, F>(&mut self, _len: usize, f: F) -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error> { f(self) }
-    fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, f: F)
-                            -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error> { f(self) }
+        where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+    {
+        f(self)
+    }
+
+    fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, f: F) -> Result<T, Self::Error>
+        where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+    {
+        f(self)
+    }
 
-    fn read_tuple_struct<T, F>(&mut self, _s_name: &str, len: usize, f: F)
-                               -> Result<T, Self::Error>
+    fn read_tuple_struct<T, F>(&mut self, _s_name: &str, len: usize, f: F) -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>
     {
         self.read_tuple(len, f)
     }
-    fn read_tuple_struct_arg<T, F>(&mut self, a_idx: usize, f: F)
-                                   -> Result<T, Self::Error>
+
+    fn read_tuple_struct_arg<T, F>(&mut self, a_idx: usize, f: F) -> Result<T, Self::Error>
         where F: FnOnce(&mut Self) -> Result<T, Self::Error>
     {
         self.read_tuple_arg(a_idx, f)
@@ -244,8 +274,12 @@ pub trait Decoder {
         let len = self.read_usize()?;
         f(self, len)
     }
+
     fn read_seq_elt<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error> { f(self) }
+        where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+    {
+        f(self)
+    }
 
     fn read_map<T, F>(&mut self, f: F) -> Result<T, Self::Error>
         where F: FnOnce(&mut Self, usize) -> Result<T, Self::Error>
@@ -253,12 +287,18 @@ pub trait Decoder {
         let len = self.read_usize()?;
         f(self, len)
     }
-    fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F)
-                              -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error> { f(self) }
-    fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F)
-                              -> Result<T, Self::Error>
-        where F: FnOnce(&mut Self) -> Result<T, Self::Error> { f(self) }
+
+    fn read_map_elt_key<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Self::Error>
+        where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+    {
+        f(self)
+    }
+
+    fn read_map_elt_val<T, F>(&mut self, _idx: usize, f: F) -> Result<T, Self::Error>
+        where F: FnOnce(&mut Self) -> Result<T, Self::Error>
+    {
+        f(self)
+    }
 
     // Failure
     fn error(&mut self, err: &str) -> Self::Error;
@@ -567,9 +607,7 @@ impl<T:Decodable> Decodable for Vec<T> {
     }
 }
 
-impl<'a, T:Encodable> Encodable for Cow<'a, [T]>
-where [T]: ToOwned<Owned = Vec<T>>
-{
+impl<'a, T:Encodable> Encodable for Cow<'a, [T]> where [T]: ToOwned<Owned = Vec<T>> {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_seq(self.len(), |s| {
             for (i, e) in self.iter().enumerate() {
@@ -580,9 +618,7 @@ where [T]: ToOwned<Owned = Vec<T>>
     }
 }
 
-impl<T:Decodable+ToOwned> Decodable for Cow<'static, [T]>
-where [T]: ToOwned<Owned = Vec<T>>
-{
+impl<T:Decodable+ToOwned> Decodable for Cow<'static, [T]> where [T]: ToOwned<Owned = Vec<T>> {
     fn decode<D: Decoder>(d: &mut D) -> Result<Cow<'static, [T]>, D::Error> {
         d.read_seq(|d, len| {
             let mut v = Vec::with_capacity(len);
@@ -685,8 +721,7 @@ macro_rules! tuple {
                 let len: usize = count_idents!($($name,)*);
                 d.read_tuple(len, |d| {
                     let mut i = 0;
-                    let ret = ($(d.read_tuple_arg({ i+=1; i-1 },
-                                                  |d| -> Result<$name,D::Error> {
+                    let ret = ($(d.read_tuple_arg({ i+=1; i-1 }, |d| -> Result<$name, D::Error> {
                         Decodable::decode(d)
                     })?,)*);
                     Ok(ret)
@@ -778,13 +813,11 @@ pub trait SpecializationError {
     /// `T` is the type being encoded/decoded, and
     /// the arguments are the names of the trait
     /// and method that should've been overridden.
-    fn not_found<S, T: ?Sized>(trait_name: &'static str,
-                               method_name: &'static str) -> Self;
+    fn not_found<S, T: ?Sized>(trait_name: &'static str, method_name: &'static str) -> Self;
 }
 
 impl<E> SpecializationError for E {
-    default fn not_found<S, T: ?Sized>(trait_name: &'static str,
-                                       method_name: &'static str) -> E {
+    default fn not_found<S, T: ?Sized>(trait_name: &'static str, method_name: &'static str) -> E {
         panic!("missing specialization: `<{} as {}<{}>>::{}` not overridden",
                unsafe { intrinsics::type_name::<S>() },
                trait_name,
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 5a2dce5930a4b..5348c9a0f3498 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -22,7 +22,6 @@ core = { path = "../libcore" }
 libc = { path = "../rustc/libc_shim" }
 compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
-std_unicode = { path = "../libstd_unicode" }
 unwind = { path = "../libunwind" }
 
 [dev-dependencies]
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 376410677346c..0c8e95aa42624 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -154,180 +154,6 @@ pub trait AsciiExt {
     /// [`to_ascii_lowercase`]: #tymethod.to_ascii_lowercase
     #[stable(feature = "ascii", since = "1.9.0")]
     fn make_ascii_lowercase(&mut self);
-
-    /// Checks if the value is an ASCII alphabetic character:
-    /// U+0041 'A' ... U+005A 'Z' or U+0061 'a' ... U+007A 'z'.
-    /// For strings, true if all characters in the string are
-    /// ASCII alphabetic.
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_alphabetic)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_alphabetic)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_alphabetic(&self) -> bool { unimplemented!(); }
-
-    /// Checks if the value is an ASCII uppercase character:
-    /// U+0041 'A' ... U+005A 'Z'.
-    /// For strings, true if all characters in the string are
-    /// ASCII uppercase.
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_uppercase)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_uppercase)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_uppercase(&self) -> bool { unimplemented!(); }
-
-    /// Checks if the value is an ASCII lowercase character:
-    /// U+0061 'a' ... U+007A 'z'.
-    /// For strings, true if all characters in the string are
-    /// ASCII lowercase.
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_lowercase)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_lowercase)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_lowercase(&self) -> bool { unimplemented!(); }
-
-    /// Checks if the value is an ASCII alphanumeric character:
-    /// U+0041 'A' ... U+005A 'Z', U+0061 'a' ... U+007A 'z', or
-    /// U+0030 '0' ... U+0039 '9'.
-    /// For strings, true if all characters in the string are
-    /// ASCII alphanumeric.
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_alphanumeric)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_alphanumeric)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_alphanumeric(&self) -> bool { unimplemented!(); }
-
-    /// Checks if the value is an ASCII decimal digit:
-    /// U+0030 '0' ... U+0039 '9'.
-    /// For strings, true if all characters in the string are
-    /// ASCII digits.
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_digit)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_digit)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_digit(&self) -> bool { unimplemented!(); }
-
-    /// Checks if the value is an ASCII hexadecimal digit:
-    /// U+0030 '0' ... U+0039 '9', U+0041 'A' ... U+0046 'F', or
-    /// U+0061 'a' ... U+0066 'f'.
-    /// For strings, true if all characters in the string are
-    /// ASCII hex digits.
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_hexdigit)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_hexdigit)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_hexdigit(&self) -> bool { unimplemented!(); }
-
-    /// Checks if the value is an ASCII punctuation character:
-    ///
-    /// U+0021 ... U+002F `! " # $ % & ' ( ) * + , - . /`
-    /// U+003A ... U+0040 `: ; < = > ? @`
-    /// U+005B ... U+0060 ``[ \\ ] ^ _ ` ``
-    /// U+007B ... U+007E `{ | } ~`
-    ///
-    /// For strings, true if all characters in the string are
-    /// ASCII punctuation.
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_punctuation)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_punctuation)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_punctuation(&self) -> bool { unimplemented!(); }
-
-    /// Checks if the value is an ASCII graphic character:
-    /// U+0021 '!' ... U+007E '~'.
-    /// For strings, true if all characters in the string are
-    /// ASCII graphic characters.
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_graphic)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_graphic)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_graphic(&self) -> bool { unimplemented!(); }
-
-    /// Checks if the value is an ASCII whitespace character:
-    /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
-    /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
-    /// For strings, true if all characters in the string are
-    /// ASCII whitespace.
-    ///
-    /// Rust uses the WhatWG Infra Standard's [definition of ASCII
-    /// whitespace][infra-aw].  There are several other definitions in
-    /// wide use.  For instance, [the POSIX locale][pct] includes
-    /// U+000B VERTICAL TAB as well as all the above characters,
-    /// but—from the very same specification—[the default rule for
-    /// "field splitting" in the Bourne shell][bfs] considers *only*
-    /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
-    ///
-    /// If you are writing a program that will process an existing
-    /// file format, check what that format's definition of whitespace is
-    /// before using this function.
-    ///
-    /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
-    /// [pct]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
-    /// [bfs]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_whitespace)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_whitespace)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_whitespace(&self) -> bool { unimplemented!(); }
-
-    /// Checks if the value is an ASCII control character:
-    /// U+0000 NUL ... U+001F UNIT SEPARATOR, or U+007F DELETE.
-    /// Note that most ASCII whitespace characters are control
-    /// characters, but SPACE is not.
-    ///
-    /// # Note
-    ///
-    /// This method will be deprecated in favor of the identically-named
-    /// inherent methods on `u8` and `char`.
-    /// For `[u8]` use `.iter().all(u8::is_ascii_control)`.
-    /// For `str` use `.bytes().all(u8::is_ascii_control)`.
-    #[unstable(feature = "ascii_ctype", issue = "39658")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")]
-    fn is_ascii_control(&self) -> bool { unimplemented!(); }
 }
 
 macro_rules! delegating_ascii_methods {
@@ -352,47 +178,12 @@ macro_rules! delegating_ascii_methods {
     }
 }
 
-macro_rules! delegating_ascii_ctype_methods {
-    () => {
-        #[inline]
-        fn is_ascii_alphabetic(&self) -> bool { self.is_ascii_alphabetic() }
-
-        #[inline]
-        fn is_ascii_uppercase(&self) -> bool { self.is_ascii_uppercase() }
-
-        #[inline]
-        fn is_ascii_lowercase(&self) -> bool { self.is_ascii_lowercase() }
-
-        #[inline]
-        fn is_ascii_alphanumeric(&self) -> bool { self.is_ascii_alphanumeric() }
-
-        #[inline]
-        fn is_ascii_digit(&self) -> bool { self.is_ascii_digit() }
-
-        #[inline]
-        fn is_ascii_hexdigit(&self) -> bool { self.is_ascii_hexdigit() }
-
-        #[inline]
-        fn is_ascii_punctuation(&self) -> bool { self.is_ascii_punctuation() }
-
-        #[inline]
-        fn is_ascii_graphic(&self) -> bool { self.is_ascii_graphic() }
-
-        #[inline]
-        fn is_ascii_whitespace(&self) -> bool { self.is_ascii_whitespace() }
-
-        #[inline]
-        fn is_ascii_control(&self) -> bool { self.is_ascii_control() }
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated)]
 impl AsciiExt for u8 {
     type Owned = u8;
 
     delegating_ascii_methods!();
-    delegating_ascii_ctype_methods!();
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -401,7 +192,6 @@ impl AsciiExt for char {
     type Owned = char;
 
     delegating_ascii_methods!();
-    delegating_ascii_ctype_methods!();
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -410,56 +200,6 @@ impl AsciiExt for [u8] {
     type Owned = Vec<u8>;
 
     delegating_ascii_methods!();
-
-    #[inline]
-    fn is_ascii_alphabetic(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_alphabetic())
-    }
-
-    #[inline]
-    fn is_ascii_uppercase(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_uppercase())
-    }
-
-    #[inline]
-    fn is_ascii_lowercase(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_lowercase())
-    }
-
-    #[inline]
-    fn is_ascii_alphanumeric(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_alphanumeric())
-    }
-
-    #[inline]
-    fn is_ascii_digit(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_digit())
-    }
-
-    #[inline]
-    fn is_ascii_hexdigit(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_hexdigit())
-    }
-
-    #[inline]
-    fn is_ascii_punctuation(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_punctuation())
-    }
-
-    #[inline]
-    fn is_ascii_graphic(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_graphic())
-    }
-
-    #[inline]
-    fn is_ascii_whitespace(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_whitespace())
-    }
-
-    #[inline]
-    fn is_ascii_control(&self) -> bool {
-        self.iter().all(|b| b.is_ascii_control())
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -468,54 +208,4 @@ impl AsciiExt for str {
     type Owned = String;
 
     delegating_ascii_methods!();
-
-    #[inline]
-    fn is_ascii_alphabetic(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_alphabetic())
-    }
-
-    #[inline]
-    fn is_ascii_uppercase(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_uppercase())
-    }
-
-    #[inline]
-    fn is_ascii_lowercase(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_lowercase())
-    }
-
-    #[inline]
-    fn is_ascii_alphanumeric(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_alphanumeric())
-    }
-
-    #[inline]
-    fn is_ascii_digit(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_digit())
-    }
-
-    #[inline]
-    fn is_ascii_hexdigit(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_hexdigit())
-    }
-
-    #[inline]
-    fn is_ascii_punctuation(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_punctuation())
-    }
-
-    #[inline]
-    fn is_ascii_graphic(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_graphic())
-    }
-
-    #[inline]
-    fn is_ascii_whitespace(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_whitespace())
-    }
-
-    #[inline]
-    fn is_ascii_control(&self) -> bool {
-        self.bytes().all(|b| b.is_ascii_control())
-    }
 }
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 754e2bbc4122b..b2777f5c48541 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -642,6 +642,12 @@ impl fmt::Debug for CString {
 
 #[stable(feature = "cstring_into", since = "1.7.0")]
 impl From<CString> for Vec<u8> {
+    /// Converts a [`CString`] into a [`Vec`]`<u8>`.
+    ///
+    /// The conversion consumes the [`CString`], and removes the terminating NUL byte.
+    ///
+    /// [`Vec`]: ../vec/struct.Vec.html
+    /// [`CString`]: ../ffi/struct.CString.html
     #[inline]
     fn from(s: CString) -> Vec<u8> {
         s.into_bytes()
@@ -700,6 +706,10 @@ impl<'a> From<&'a CStr> for Box<CStr> {
 
 #[stable(feature = "c_string_from_box", since = "1.18.0")]
 impl From<Box<CStr>> for CString {
+    /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
+    ///
+    /// [`Box`]: ../boxed/struct.Box.html
+    /// [`CString`]: ../ffi/struct.CString.html
     #[inline]
     fn from(s: Box<CStr>) -> CString {
         s.into_c_string()
@@ -716,6 +726,10 @@ impl Clone for Box<CStr> {
 
 #[stable(feature = "box_from_c_string", since = "1.20.0")]
 impl From<CString> for Box<CStr> {
+    /// Converts a [`CString`] into a [`Box`]`<CStr>` without copying or allocating.
+    ///
+    /// [`CString`]: ../ffi/struct.CString.html
+    /// [`Box`]: ../boxed/struct.Box.html
     #[inline]
     fn from(s: CString) -> Box<CStr> {
         s.into_boxed_c_str()
@@ -748,6 +762,10 @@ impl<'a> From<&'a CString> for Cow<'a, CStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<CString> for Arc<CStr> {
+    /// Converts a [`CString`] into a [`Arc`]`<CStr>` without copying or allocating.
+    ///
+    /// [`CString`]: ../ffi/struct.CString.html
+    /// [`Arc`]: ../sync/struct.Arc.html
     #[inline]
     fn from(s: CString) -> Arc<CStr> {
         let arc: Arc<[u8]> = Arc::from(s.into_inner());
@@ -766,6 +784,10 @@ impl<'a> From<&'a CStr> for Arc<CStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<CString> for Rc<CStr> {
+    /// Converts a [`CString`] into a [`Rc`]`<CStr>` without copying or allocating.
+    ///
+    /// [`CString`]: ../ffi/struct.CString.html
+    /// [`Rc`]: ../rc/struct.Rc.html
     #[inline]
     fn from(s: CString) -> Rc<CStr> {
         let rc: Rc<[u8]> = Rc::from(s.into_inner());
@@ -839,6 +861,10 @@ impl fmt::Display for NulError {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<NulError> for io::Error {
+    /// Converts a [`NulError`] into a [`io::Error`].
+    ///
+    /// [`NulError`]: ../ffi/struct.NulError.html
+    /// [`io::Error`]: ../io/struct.Error.html
     fn from(_: NulError) -> io::Error {
         io::Error::new(io::ErrorKind::InvalidInput,
                        "data provided contains a nul byte")
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index b1c6e7af693d0..9e501a84e05ec 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -348,6 +348,12 @@ impl OsString {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<String> for OsString {
+    /// Converts a [`String`] into a [`OsString`].
+    ///
+    /// The conversion copies the data, and includes an allocation on the heap.
+    ///
+    /// [`String`]: ../string/struct.String.html
+    /// [`OsString`]: struct.OsString.html
     fn from(s: String) -> OsString {
         OsString { inner: Buf::from_string(s) }
     }
@@ -630,6 +636,10 @@ impl<'a> From<&'a OsStr> for Box<OsStr> {
 
 #[stable(feature = "os_string_from_box", since = "1.18.0")]
 impl From<Box<OsStr>> for OsString {
+    /// Converts a `Box<OsStr>` into a `OsString` without copying or allocating.
+    ///
+    /// [`Box`]: ../boxed/struct.Box.html
+    /// [`OsString`]: ../ffi/struct.OsString.html
     fn from(boxed: Box<OsStr>) -> OsString {
         boxed.into_os_string()
     }
@@ -637,6 +647,10 @@ impl From<Box<OsStr>> for OsString {
 
 #[stable(feature = "box_from_os_string", since = "1.20.0")]
 impl From<OsString> for Box<OsStr> {
+    /// Converts a [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating.
+    ///
+    /// [`Box`]: ../boxed/struct.Box.html
+    /// [`OsString`]: ../ffi/struct.OsString.html
     fn from(s: OsString) -> Box<OsStr> {
         s.into_boxed_os_str()
     }
@@ -652,6 +666,10 @@ impl Clone for Box<OsStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<OsString> for Arc<OsStr> {
+    /// Converts a [`OsString`] into a [`Arc`]`<OsStr>` without copying or allocating.
+    ///
+    /// [`Arc`]: ../sync/struct.Arc.html
+    /// [`OsString`]: ../ffi/struct.OsString.html
     #[inline]
     fn from(s: OsString) -> Arc<OsStr> {
         let arc = s.inner.into_arc();
@@ -670,6 +688,10 @@ impl<'a> From<&'a OsStr> for Arc<OsStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<OsString> for Rc<OsStr> {
+    /// Converts a [`OsString`] into a [`Rc`]`<OsStr>` without copying or allocating.
+    ///
+    /// [`Rc`]: ../rc/struct.Rc.html
+    /// [`OsString`]: ../ffi/struct.OsString.html
     #[inline]
     fn from(s: OsString) -> Rc<OsStr> {
         let rc = s.inner.into_rc();
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 2babf508fdcc3..03c97de6ec1e9 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -154,33 +154,6 @@ impl<R: Read> BufReader<R> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
 
-    /// Returns `true` if there are no bytes in the internal buffer.
-    ///
-    /// # Examples
-    //
-    /// ```no_run
-    /// # #![feature(bufreader_is_empty)]
-    /// use std::io::BufReader;
-    /// use std::io::BufRead;
-    /// use std::fs::File;
-    ///
-    /// fn main() -> std::io::Result<()> {
-    ///     let f1 = File::open("log.txt")?;
-    ///     let mut reader = BufReader::new(f1);
-    ///     assert!(reader.is_empty());
-    ///
-    ///     if reader.fill_buf()?.len() > 0 {
-    ///         assert!(!reader.is_empty());
-    ///     }
-    ///     Ok(())
-    /// }
-    /// ```
-    #[unstable(feature = "bufreader_is_empty", issue = "45323", reason = "recently added")]
-    #[rustc_deprecated(since = "1.26.0", reason = "use .buffer().is_empty() instead")]
-    pub fn is_empty(&self) -> bool {
-        self.buffer().is_empty()
-    }
-
     /// Returns a reference to the internally buffered data.
     ///
     /// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty.
@@ -1265,25 +1238,6 @@ mod tests {
         assert_eq!(reader.read(&mut buf).unwrap(), 0);
     }
 
-    #[test]
-    #[allow(deprecated)]
-    fn read_char_buffered() {
-        let buf = [195, 159];
-        let reader = BufReader::with_capacity(1, &buf[..]);
-        assert_eq!(reader.chars().next().unwrap().unwrap(), 'ß');
-    }
-
-    #[test]
-    #[allow(deprecated)]
-    fn test_chars() {
-        let buf = [195, 159, b'a'];
-        let reader = BufReader::with_capacity(1, &buf[..]);
-        let mut it = reader.chars();
-        assert_eq!(it.next().unwrap().unwrap(), 'ß');
-        assert_eq!(it.next().unwrap().unwrap(), 'a');
-        assert!(it.next().is_none());
-    }
-
     #[test]
     #[should_panic]
     fn dont_panic_in_drop_on_panicked_flush() {
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 3622df16b9d0b..14f20151dca86 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -550,26 +550,6 @@ mod tests {
         assert_eq!(reader.read(&mut buf).unwrap(), 0);
     }
 
-    #[test]
-    #[allow(deprecated)]
-    fn test_read_char() {
-        let b = &b"Vi\xE1\xBB\x87t"[..];
-        let mut c = Cursor::new(b).chars();
-        assert_eq!(c.next().unwrap().unwrap(), 'V');
-        assert_eq!(c.next().unwrap().unwrap(), 'i');
-        assert_eq!(c.next().unwrap().unwrap(), 'ệ');
-        assert_eq!(c.next().unwrap().unwrap(), 't');
-        assert!(c.next().is_none());
-    }
-
-    #[test]
-    #[allow(deprecated)]
-    fn test_read_bad_char() {
-        let b = &b"\x80"[..];
-        let mut c = Cursor::new(b).chars();
-        assert!(c.next().unwrap().is_err());
-    }
-
     #[test]
     fn seek_past_end() {
         let buf = [0xff];
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 8530487484827..5e89ad45f81d2 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -270,10 +270,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use cmp;
-use core::str as core_str;
-use error as std_error;
 use fmt;
-use result;
 use str;
 use memchr;
 use ptr;
@@ -800,53 +797,6 @@ pub trait Read {
         Bytes { inner: self }
     }
 
-    /// Transforms this `Read` instance to an [`Iterator`] over [`char`]s.
-    ///
-    /// This adaptor will attempt to interpret this reader as a UTF-8 encoded
-    /// sequence of characters. The returned iterator will return [`None`] once
-    /// EOF is reached for this reader. Otherwise each element yielded will be a
-    /// [`Result`]`<`[`char`]`, E>` where `E` may contain information about what I/O error
-    /// occurred or where decoding failed.
-    ///
-    /// Currently this adaptor will discard intermediate data read, and should
-    /// be avoided if this is not desired.
-    ///
-    /// # Examples
-    ///
-    /// [`File`]s implement `Read`:
-    ///
-    /// [`File`]: ../fs/struct.File.html
-    /// [`Iterator`]: ../../std/iter/trait.Iterator.html
-    /// [`Result`]: ../../std/result/enum.Result.html
-    /// [`char`]: ../../std/primitive.char.html
-    /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    ///
-    /// ```no_run
-    /// #![feature(io)]
-    /// use std::io;
-    /// use std::io::prelude::*;
-    /// use std::fs::File;
-    ///
-    /// fn main() -> io::Result<()> {
-    ///     let mut f = File::open("foo.txt")?;
-    ///
-    ///     for c in f.chars() {
-    ///         println!("{}", c.unwrap());
-    ///     }
-    ///     Ok(())
-    /// }
-    /// ```
-    #[unstable(feature = "io", reason = "the semantics of a partial read/write \
-                                         of where errors happen is currently \
-                                         unclear and may change",
-               issue = "27802")]
-    #[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
-        https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
-    #[allow(deprecated)]
-    fn chars(self) -> Chars<Self> where Self: Sized {
-        Chars { inner: self }
-    }
-
     /// Creates an adaptor which will chain this stream with another.
     ///
     /// The returned `Read` instance will first read all bytes from this object
@@ -2005,104 +1955,6 @@ impl<R: Read> Iterator for Bytes<R> {
     }
 }
 
-/// An iterator over the `char`s of a reader.
-///
-/// This struct is generally created by calling [`chars`][chars] on a reader.
-/// Please see the documentation of `chars()` for more details.
-///
-/// [chars]: trait.Read.html#method.chars
-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
-           issue = "27802")]
-#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
-    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
-#[derive(Debug)]
-#[allow(deprecated)]
-pub struct Chars<R> {
-    inner: R,
-}
-
-/// An enumeration of possible errors that can be generated from the `Chars`
-/// adapter.
-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
-           issue = "27802")]
-#[rustc_deprecated(since = "1.27.0", reason = "Use str::from_utf8 instead:
-    https://doc.rust-lang.org/nightly/std/str/struct.Utf8Error.html#examples")]
-#[derive(Debug)]
-#[allow(deprecated)]
-pub enum CharsError {
-    /// Variant representing that the underlying stream was read successfully
-    /// but it did not contain valid utf8 data.
-    NotUtf8,
-
-    /// Variant representing that an I/O error occurred.
-    Other(Error),
-}
-
-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
-           issue = "27802")]
-#[allow(deprecated)]
-impl<R: Read> Iterator for Chars<R> {
-    type Item = result::Result<char, CharsError>;
-
-    fn next(&mut self) -> Option<result::Result<char, CharsError>> {
-        let first_byte = match read_one_byte(&mut self.inner)? {
-            Ok(b) => b,
-            Err(e) => return Some(Err(CharsError::Other(e))),
-        };
-        let width = core_str::utf8_char_width(first_byte);
-        if width == 1 { return Some(Ok(first_byte as char)) }
-        if width == 0 { return Some(Err(CharsError::NotUtf8)) }
-        let mut buf = [first_byte, 0, 0, 0];
-        {
-            let mut start = 1;
-            while start < width {
-                match self.inner.read(&mut buf[start..width]) {
-                    Ok(0) => return Some(Err(CharsError::NotUtf8)),
-                    Ok(n) => start += n,
-                    Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
-                    Err(e) => return Some(Err(CharsError::Other(e))),
-                }
-            }
-        }
-        Some(match str::from_utf8(&buf[..width]).ok() {
-            Some(s) => Ok(s.chars().next().unwrap()),
-            None => Err(CharsError::NotUtf8),
-        })
-    }
-}
-
-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
-           issue = "27802")]
-#[allow(deprecated)]
-impl std_error::Error for CharsError {
-    fn description(&self) -> &str {
-        match *self {
-            CharsError::NotUtf8 => "invalid utf8 encoding",
-            CharsError::Other(ref e) => std_error::Error::description(e),
-        }
-    }
-    fn cause(&self) -> Option<&dyn std_error::Error> {
-        match *self {
-            CharsError::NotUtf8 => None,
-            CharsError::Other(ref e) => e.cause(),
-        }
-    }
-}
-
-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
-           issue = "27802")]
-#[allow(deprecated)]
-impl fmt::Display for CharsError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            CharsError::NotUtf8 => {
-                "byte stream did not contain valid utf8".fmt(f)
-            }
-            CharsError::Other(ref e) => e.fmt(f),
-        }
-    }
-}
-
 /// An iterator over the contents of an instance of `BufRead` split on a
 /// particular byte.
 ///
diff --git a/src/libstd/os/hermit/fs.rs b/src/libstd/os/hermit/fs.rs
new file mode 100644
index 0000000000000..d2e751668a67b
--- /dev/null
+++ b/src/libstd/os/hermit/fs.rs
@@ -0,0 +1,389 @@
+// 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.
+
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use libc;
+
+use fs::Metadata;
+use sys_common::AsInner;
+
+#[allow(deprecated)]
+use os::hermit::raw;
+
+/// OS-specific extensions to [`fs::Metadata`].
+///
+/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    /// Gain a reference to the underlying `stat` structure which contains
+    /// the raw information returned by the OS.
+    ///
+    /// The contents of the returned [`stat`] are **not** consistent across
+    /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
+    /// cross-Unix abstractions contained within the raw stat.
+    ///
+    /// [`stat`]: ../../../../std/os/linux/raw/struct.stat.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let stat = meta.as_raw_stat();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    #[rustc_deprecated(since = "1.8.0",
+                       reason = "deprecated in favor of the accessor \
+                                 methods of this trait")]
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat;
+
+    /// Returns the device ID on which this file resides.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_dev());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+    /// Returns the inode number.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ino());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+    /// Returns the file type and mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mode());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mode(&self) -> u32;
+    /// Returns the number of hard links to file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_nlink());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+    /// Returns the user ID of the file owner.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_uid());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+    /// Returns the group ID of the file owner.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_gid());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+    /// Returns the device ID that this file represents. Only relevant for special file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_rdev());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+    /// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
+    ///
+    /// The size of a symbolic link is the length of the pathname it contains,
+    /// without a terminating null byte.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_size());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+    /// Returns the last access time.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_atime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+    /// Returns the last access time, nano seconds part.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_atime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+    /// Returns the last modification time.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mtime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+    /// Returns the last modification time, nano seconds part.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mtime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+    /// Returns the last status change time.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ctime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+    /// Returns the last status change time, nano seconds part.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ctime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+    /// Returns the "preferred" blocksize for efficient filesystem I/O.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_blksize());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+    /// Returns the number of blocks allocated to the file, 512-byte units.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::linux::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_blocks());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat {
+        unsafe {
+            &*(self.as_inner().as_inner() as *const libc::stat64
+                                          as *const raw::stat)
+        }
+    }
+    fn st_dev(&self) -> u64 {
+        self.as_inner().as_inner().st_dev as u64
+    }
+    fn st_ino(&self) -> u64 {
+        self.as_inner().as_inner().st_ino as u64
+    }
+    fn st_mode(&self) -> u32 {
+        self.as_inner().as_inner().st_mode as u32
+    }
+    fn st_nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
+    fn st_uid(&self) -> u32 {
+        self.as_inner().as_inner().st_uid as u32
+    }
+    fn st_gid(&self) -> u32 {
+        self.as_inner().as_inner().st_gid as u32
+    }
+    fn st_rdev(&self) -> u64 {
+        self.as_inner().as_inner().st_rdev as u64
+    }
+    fn st_size(&self) -> u64 {
+        self.as_inner().as_inner().st_size as u64
+    }
+    fn st_atime(&self) -> i64 {
+        self.as_inner().as_inner().st_atime as i64
+    }
+    fn st_atime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_atime_nsec as i64
+    }
+    fn st_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime as i64
+    }
+    fn st_mtime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime_nsec as i64
+    }
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime as i64
+    }
+    fn st_ctime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime_nsec as i64
+    }
+    fn st_blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+    fn st_blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
+}
diff --git a/src/libstd/os/hermit/mod.rs b/src/libstd/os/hermit/mod.rs
new file mode 100644
index 0000000000000..fcb22cdad641f
--- /dev/null
+++ b/src/libstd/os/hermit/mod.rs
@@ -0,0 +1,16 @@
+// 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.
+
+//! HermitCore-specific definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+pub mod raw;
+pub mod fs;
diff --git a/src/libstd/os/hermit/raw.rs b/src/libstd/os/hermit/raw.rs
new file mode 100644
index 0000000000000..282afe0b6e1c0
--- /dev/null
+++ b/src/libstd/os/hermit/raw.rs
@@ -0,0 +1,27 @@
+// 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.
+
+//! HermitCore-specific raw type definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![rustc_deprecated(since = "1.8.0",
+                    reason = "these type aliases are no longer supported by \
+                              the standard library, the `libc` crate on \
+                              crates.io should be used instead for the correct \
+                              definitions")]
+#![allow(deprecated)]
+#![allow(missing_debug_implementations)]
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub use libc::pthread_t;
+
+#[doc(inline)]
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub use libc::{dev_t, mode_t, off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t};
diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs
index ac7809451d152..c384ec9168ac4 100644
--- a/src/libstd/os/mod.rs
+++ b/src/libstd/os/mod.rs
@@ -47,6 +47,7 @@ cfg_if! {
         #[cfg(target_os = "solaris")]    pub mod solaris;
         #[cfg(target_os = "emscripten")] pub mod emscripten;
         #[cfg(target_os = "fuchsia")]    pub mod fuchsia;
+        #[cfg(target_os = "hermit")]     pub mod hermit;
 
         #[cfg(any(target_os = "redox", unix))]
         #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
index dc1dba6f2f9b7..7e32ec1347e9e 100644
--- a/src/libstd/sys/unix/args.rs
+++ b/src/libstd/sys/unix/args.rs
@@ -66,7 +66,8 @@ impl DoubleEndedIterator for Args {
           target_os = "emscripten",
           target_os = "haiku",
           target_os = "l4re",
-          target_os = "fuchsia"))]
+          target_os = "fuchsia",
+          target_os = "hermit"))]
 mod imp {
     use os::unix::prelude::*;
     use ptr;
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs
index 4f878d8ad1fa8..2007da7b1f6be 100644
--- a/src/libstd/sys/unix/condvar.rs
+++ b/src/libstd/sys/unix/condvar.rs
@@ -41,13 +41,15 @@ impl Condvar {
     #[cfg(any(target_os = "macos",
               target_os = "ios",
               target_os = "l4re",
-              target_os = "android"))]
+              target_os = "android",
+              target_os = "hermit"))]
     pub unsafe fn init(&mut self) {}
 
     #[cfg(not(any(target_os = "macos",
                   target_os = "ios",
                   target_os = "l4re",
-                  target_os = "android")))]
+                  target_os = "android",
+                  target_os = "hermit")))]
     pub unsafe fn init(&mut self) {
         use mem;
         let mut attr: libc::pthread_condattr_t = mem::uninitialized();
@@ -83,7 +85,10 @@ impl Condvar {
     // where we configure condition variable to use monotonic clock (instead of
     // default system clock). This approach avoids all problems that result
     // from changes made to the system time.
-    #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
+    #[cfg(not(any(target_os = "macos",
+                  target_os = "ios",
+                  target_os = "android",
+                  target_os = "hermit")))]
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         use mem;
 
@@ -113,7 +118,7 @@ impl Condvar {
     // This implementation is modeled after libcxx's condition_variable
     // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46
     // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367
-    #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
+    #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android", target_os = "hermit"))]
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool {
         use ptr;
         use time::Instant;
diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs
index 00cf7eca75dc3..ad116c57f557e 100644
--- a/src/libstd/sys/unix/env.rs
+++ b/src/libstd/sys/unix/env.rs
@@ -172,3 +172,14 @@ pub mod os {
     pub const EXE_SUFFIX: &'static str = "";
     pub const EXE_EXTENSION: &'static str = "";
 }
+
+#[cfg(target_os = "hermit")]
+pub mod os {
+    pub const FAMILY: &'static str = "unix";
+    pub const OS: &'static str = "hermit";
+    pub const DLL_PREFIX: &'static str = "lib";
+    pub const DLL_SUFFIX: &'static str = ".so";
+    pub const DLL_EXTENSION: &'static str = "so";
+    pub const EXE_SUFFIX: &'static str = "";
+    pub const EXE_EXTENSION: &'static str = "";
+}
diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/fast_thread_local.rs
index d59d800a57947..c13a0fea1e05c 100644
--- a/src/libstd/sys/unix/fast_thread_local.rs
+++ b/src/libstd/sys/unix/fast_thread_local.rs
@@ -20,7 +20,7 @@
 // fallback implementation to use as well.
 //
 // Due to rust-lang/rust#18804, make sure this is not generic!
-#[cfg(any(target_os = "linux", target_os = "fuchsia"))]
+#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit"))]
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
     use libc;
     use mem;
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 662a76d6725a6..7a89d9857bbcf 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -325,12 +325,12 @@ impl DirEntry {
         lstat(&self.path())
     }
 
-    #[cfg(any(target_os = "solaris", target_os = "haiku"))]
+    #[cfg(any(target_os = "solaris", target_os = "haiku", target_os = "hermit"))]
     pub fn file_type(&self) -> io::Result<FileType> {
         lstat(&self.path()).map(|m| m.file_type())
     }
 
-    #[cfg(not(any(target_os = "solaris", target_os = "haiku")))]
+    #[cfg(not(any(target_os = "solaris", target_os = "haiku", target_os = "hermit")))]
     pub fn file_type(&self) -> io::Result<FileType> {
         match self.entry.d_type {
             libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }),
@@ -352,7 +352,8 @@ impl DirEntry {
               target_os = "solaris",
               target_os = "haiku",
               target_os = "l4re",
-              target_os = "fuchsia"))]
+              target_os = "fuchsia",
+              target_os = "hermit"))]
     pub fn ino(&self) -> u64 {
         self.entry.d_ino as u64
     }
@@ -383,7 +384,8 @@ impl DirEntry {
               target_os = "linux",
               target_os = "emscripten",
               target_os = "l4re",
-              target_os = "haiku"))]
+              target_os = "haiku",
+              target_os = "hermit"))]
     fn name_bytes(&self) -> &[u8] {
         unsafe {
             CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes()
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index c1298e5040dbe..c738003caf1d9 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -28,6 +28,7 @@ use libc;
 #[cfg(all(not(dox), target_os = "emscripten"))] pub use os::emscripten as platform;
 #[cfg(all(not(dox), target_os = "fuchsia"))]   pub use os::fuchsia as platform;
 #[cfg(all(not(dox), target_os = "l4re"))]      pub use os::linux as platform;
+#[cfg(all(not(dox), target_os = "hermit"))]    pub use os::hermit as platform;
 
 pub use self::rand::hashmap_random_keys;
 pub use libc::strlen;
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index addf555eb1065..1d92e8fc97c7a 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -47,6 +47,7 @@ extern {
                    target_os = "netbsd",
                    target_os = "openbsd",
                    target_os = "android",
+                   target_os = "hermit",
                    target_env = "newlib"),
                link_name = "__errno")]
     #[cfg_attr(target_os = "solaris", link_name = "___errno")]
@@ -376,7 +377,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     }
 }
 
-#[cfg(any(target_os = "fuchsia", target_os = "l4re"))]
+#[cfg(any(target_os = "fuchsia", target_os = "l4re", target_os = "hermit"))]
 pub fn current_exe() -> io::Result<PathBuf> {
     use io::ErrorKind;
     Err(io::Error::new(ErrorKind::Other, "Not yet implemented!"))
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index e26306c045d31..f3a45d2465739 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -138,7 +138,8 @@ impl Thread {
               target_os = "solaris",
               target_os = "haiku",
               target_os = "l4re",
-              target_os = "emscripten"))]
+              target_os = "emscripten",
+              target_os = "hermit"))]
     pub fn set_name(_name: &CStr) {
         // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name.
     }
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index 89786eb2a6c48..0b1fb726357e1 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -345,9 +345,9 @@ mod inner {
         }
     }
 
-    #[cfg(not(target_os = "dragonfly"))]
+    #[cfg(not(any(target_os = "dragonfly", target_os = "hermit")))]
     pub type clock_t = libc::c_int;
-    #[cfg(target_os = "dragonfly")]
+    #[cfg(any(target_os = "dragonfly", target_os = "hermit"))]
     pub type clock_t = libc::c_ulong;
 
     fn now(clock: clock_t) -> Timespec {
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index ae804ad409ee3..bbe80df7e8bdb 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -731,7 +731,8 @@ const NOTIFIED: usize = 2;
 ///   specifying a maximum time to block the thread for.
 ///
 /// * The [`unpark`] method on a [`Thread`] atomically makes the token available
-///   if it wasn't already.
+///   if it wasn't already. Because the token is initially absent, [`unpark`]
+///   followed by [`park`] will result in the second call returning immediately.
 ///
 /// In other words, each [`Thread`] acts a bit like a spinlock that can be
 /// locked and unlocked using `park` and `unpark`.
@@ -766,6 +767,8 @@ const NOTIFIED: usize = 2;
 /// // Let some time pass for the thread to be spawned.
 /// thread::sleep(Duration::from_millis(10));
 ///
+/// // There is no race condition here, if `unpark`
+/// // happens first, `park` will return immediately.
 /// println!("Unpark the thread");
 /// parked_thread.thread().unpark();
 ///
diff --git a/src/libstd_unicode/Cargo.toml b/src/libstd_unicode/Cargo.toml
deleted file mode 100644
index b1c55c2e4b6ce..0000000000000
--- a/src/libstd_unicode/Cargo.toml
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "std_unicode"
-version = "0.0.0"
-
-[lib]
-name = "std_unicode"
-path = "lib.rs"
-test = false
-bench = false
-
-[dependencies]
-core = { path = "../libcore" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs
deleted file mode 100644
index c0d47f1fcb42b..0000000000000
--- a/src/libstd_unicode/lib.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2012-2014 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 Unicode Library
-//!
-//! Unicode-intensive functions for `char` and `str` types.
-//!
-//! This crate provides a collection of Unicode-related functionality,
-//! including decompositions, conversions, etc., and provides traits
-//! implementing these functions for the `char` and `str` types.
-//!
-//! The functionality included here is only that which is necessary to
-//! provide for basic string-related manipulations. This crate does not
-//! (yet) aim to provide a full set of Unicode tables.
-
-#![unstable(feature = "unicode", issue = "27783")]
-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
-       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
-       html_root_url = "https://doc.rust-lang.org/nightly/",
-       html_playground_url = "https://play.rust-lang.org/",
-       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
-       test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
-#![no_std]
-
-#![feature(unicode_internals)]
-#![feature(staged_api)]
-#![rustc_deprecated(since = "1.27.0", reason = "moved into libcore")]
-
-pub use core::unicode::*;
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 40fb2c69e57cb..37a021a952914 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -396,7 +396,7 @@ declare_features! (
     // Infer outlives requirements; RFC 2093
     (active, infer_outlives_requirements, "1.26.0", Some(44493), None),
 
-    // Infer outlives requirements; RFC 2093
+    // Infer static outlives requirements; RFC 2093
     (active, infer_static_outlives_requirements, "1.26.0", Some(44493), None),
 
     // Multiple patterns with `|` in `if let` and `while let`
diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs
index 23a37ca34853c..6eba3c4f2bbc9 100644
--- a/src/libsyntax_ext/format_foreign.rs
+++ b/src/libsyntax_ext/format_foreign.rs
@@ -774,31 +774,41 @@ pub mod shell {
 
     #[derive(Clone, PartialEq, Debug)]
     pub enum Substitution<'a> {
-        Ordinal(u8),
-        Name(&'a str),
-        Escape,
+        Ordinal(u8, (usize, usize)),
+        Name(&'a str, (usize, usize)),
+        Escape((usize, usize)),
     }
 
     impl<'a> Substitution<'a> {
         pub fn as_str(&self) -> String {
-            match *self {
-                Substitution::Ordinal(n) => format!("${}", n),
-                Substitution::Name(n) => format!("${}", n),
-                Substitution::Escape => "$$".into(),
+            match self {
+                Substitution::Ordinal(n, _) => format!("${}", n),
+                Substitution::Name(n, _) => format!("${}", n),
+                Substitution::Escape(_) => "$$".into(),
             }
         }
 
         pub fn position(&self) -> Option<(usize, usize)> {
-            match *self {
-                _ => None,
+            match self {
+                Substitution::Ordinal(_, pos) |
+                Substitution::Name(_, pos) |
+                Substitution::Escape(pos) => Some(*pos),
+            }
+        }
+
+        pub fn set_position(&mut self, start: usize, end: usize) {
+            match self {
+                Substitution::Ordinal(_, ref mut pos) |
+                Substitution::Name(_, ref mut pos) |
+                Substitution::Escape(ref mut pos) => *pos = (start, end),
             }
         }
 
         pub fn translate(&self) -> Option<String> {
             match *self {
-                Substitution::Ordinal(n) => Some(format!("{{{}}}", n)),
-                Substitution::Name(n) => Some(format!("{{{}}}", n)),
-                Substitution::Escape => None,
+                Substitution::Ordinal(n, _) => Some(format!("{{{}}}", n)),
+                Substitution::Name(n, _) => Some(format!("{{{}}}", n)),
+                Substitution::Escape(_) => None,
             }
         }
     }
@@ -807,20 +817,26 @@ pub mod shell {
     pub fn iter_subs(s: &str) -> Substitutions {
         Substitutions {
             s,
+            pos: 0,
         }
     }
 
     /// Iterator over substitutions in a string.
     pub struct Substitutions<'a> {
         s: &'a str,
+        pos: usize,
     }
 
     impl<'a> Iterator for Substitutions<'a> {
         type Item = Substitution<'a>;
         fn next(&mut self) -> Option<Self::Item> {
             match parse_next_substitution(self.s) {
-                Some((sub, tail)) => {
+                Some((mut sub, tail)) => {
                     self.s = tail;
+                    if let Some((start, end)) = sub.position() {
+                        sub.set_position(start + self.pos, end + self.pos);
+                        self.pos += end;
+                    }
                     Some(sub)
                 },
                 None => None,
@@ -837,15 +853,15 @@ pub mod shell {
         let at = {
             let start = s.find('$')?;
             match s[start+1..].chars().next()? {
-                '$' => return Some((Substitution::Escape, &s[start+2..])),
+                '$' => return Some((Substitution::Escape((start, start+2)), &s[start+2..])),
                 c @ '0' ..= '9' => {
                     let n = (c as u8) - b'0';
-                    return Some((Substitution::Ordinal(n), &s[start+2..]));
+                    return Some((Substitution::Ordinal(n, (start, start+2)), &s[start+2..]));
                 },
                 _ => {/* fall-through */},
             }
 
-            Cur::new_at_start(&s[start..])
+            Cur::new_at(&s[..], start)
         };
 
         let at = at.at_next_cp()?;
@@ -855,7 +871,10 @@ pub mod shell {
             None
         } else {
             let end = at_next_cp_while(inner, is_ident_tail);
-            Some((Substitution::Name(at.slice_between(end).unwrap()), end.slice_after()))
+            let slice = at.slice_between(end).unwrap();
+            let start = at.at - 1;
+            let end_pos = at.at + slice.len();
+            Some((Substitution::Name(slice, (start, end_pos)), end.slice_after()))
         }
     }
 
@@ -907,24 +926,24 @@ pub mod shell {
         fn test_escape() {
             assert_eq!(pns("has no escapes"), None);
             assert_eq!(pns("has no escapes, either $"), None);
-            assert_eq!(pns("*so* has a $$ escape"), Some((S::Escape, " escape")));
-            assert_eq!(pns("$$ leading escape"), Some((S::Escape, " leading escape")));
-            assert_eq!(pns("trailing escape $$"), Some((S::Escape, "")));
+            assert_eq!(pns("*so* has a $$ escape"), Some((S::Escape((11, 13)), " escape")));
+            assert_eq!(pns("$$ leading escape"), Some((S::Escape((0, 2)), " leading escape")));
+            assert_eq!(pns("trailing escape $$"), Some((S::Escape((16, 18)), "")));
         }
 
         #[test]
         fn test_parse() {
             macro_rules! assert_pns_eq_sub {
-                ($in_:expr, $kind:ident($arg:expr)) => {
-                    assert_eq!(pns(concat!($in_, "!")), Some((S::$kind($arg.into()), "!")))
+                ($in_:expr, $kind:ident($arg:expr, $pos:expr)) => {
+                    assert_eq!(pns(concat!($in_, "!")), Some((S::$kind($arg.into(), $pos), "!")))
                 };
             }
 
-            assert_pns_eq_sub!("$0", Ordinal(0));
-            assert_pns_eq_sub!("$1", Ordinal(1));
-            assert_pns_eq_sub!("$9", Ordinal(9));
-            assert_pns_eq_sub!("$N", Name("N"));
-            assert_pns_eq_sub!("$NAME", Name("NAME"));
+            assert_pns_eq_sub!("$0", Ordinal(0, (0, 2)));
+            assert_pns_eq_sub!("$1", Ordinal(1, (0, 2)));
+            assert_pns_eq_sub!("$9", Ordinal(9, (0, 2)));
+            assert_pns_eq_sub!("$N", Name("N", (0, 2)));
+            assert_pns_eq_sub!("$NAME", Name("NAME", (0, 5)));
         }
 
         #[test]
@@ -961,13 +980,6 @@ mod strcursor {
     }
 
     impl<'a> StrCursor<'a> {
-        pub fn new_at_start(s: &'a str) -> StrCursor<'a> {
-            StrCursor {
-                s,
-                at: 0,
-            }
-        }
-
         pub fn new_at(s: &'a str, at: usize) -> StrCursor<'a> {
             StrCursor {
                 s,
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 3f5550bf95fd2..a13e4ffa8f829 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -1075,7 +1075,7 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
     auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
 
     if (!MOrErr)
-      return std::move(MOrErr);
+      return MOrErr;
 
     // The rest of this closure is a workaround for
     // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
@@ -1093,14 +1093,14 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
     // shouldn't be a perf hit.
     if (Error Err = (*MOrErr)->materializeMetadata()) {
       Expected<std::unique_ptr<Module>> Ret(std::move(Err));
-      return std::move(Ret);
+      return Ret;
     }
 
     auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
     if (WasmCustomSections)
       WasmCustomSections->eraseFromParent();
 
-    return std::move(MOrErr);
+    return MOrErr;
   };
   FunctionImporter Importer(Data->Index, Loader);
   Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
diff --git a/src/test/codegen/slice-position-bounds-check.rs b/src/test/codegen/slice-position-bounds-check.rs
new file mode 100644
index 0000000000000..a6c846d7dab51
--- /dev/null
+++ b/src/test/codegen/slice-position-bounds-check.rs
@@ -0,0 +1,42 @@
+// Copyright 2017 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.
+
+// no-system-llvm
+// compile-flags: -O -C panic=abort
+#![crate_type = "lib"]
+
+fn search<T: Ord + Eq>(arr: &mut [T], a: &T) -> Result<usize, ()> {
+    match arr.iter().position(|x| x == a) {
+        Some(p) => {
+            Ok(p)
+        },
+        None => Err(()),
+    }
+}
+
+// CHECK-LABEL: @position_no_bounds_check
+#[no_mangle]
+pub fn position_no_bounds_check(y: &mut [u32], x: &u32, z: &u32) -> bool {
+    // This contains "call assume" so we cannot just rule out all calls
+    // CHECK-NOT: panic_bounds_check
+    if let Ok(p) = search(y, x) {
+      y[p] == *z
+    } else {
+      false
+    }
+}
+
+// just to make sure that panicking really emits "panic_bounds_check" somewhere in the IR
+// CHECK-LABEL: @test_check
+#[no_mangle]
+pub fn test_check(y: &[i32]) -> i32 {
+    // CHECK: panic_bounds_check
+    y[12]
+}
diff --git a/src/test/codegen/sparc-struct-abi.rs b/src/test/codegen/sparc-struct-abi.rs
index d3b7a5cd59882..56c4364d598e7 100644
--- a/src/test/codegen/sparc-struct-abi.rs
+++ b/src/test/codegen/sparc-struct-abi.rs
@@ -11,6 +11,7 @@
 // Checks that we correctly codegen extern "C" functions returning structs.
 // See issue #52638.
 
+// only-sparc64
 // compile-flags: -O --target=sparc64-unknown-linux-gnu --crate-type=rlib
 #![feature(no_core, lang_items)]
 #![no_core]
diff --git a/src/test/run-pass/const-endianess.rs b/src/test/run-pass/const-endianess.rs
index fa34b49210a6a..95c738d3ec49a 100644
--- a/src/test/run-pass/const-endianess.rs
+++ b/src/test/run-pass/const-endianess.rs
@@ -25,7 +25,7 @@ fn main() {
     #[cfg(not(target_arch = "asmjs"))]
     {
         const BE_U128: u128 = 999999u128.to_be();
-        const LE_I128: i128 = -999999i128.to_le();
+        const LE_I128: i128 = (-999999i128).to_le();
         assert_eq!(BE_U128, b(999999u128).to_be());
         assert_eq!(LE_I128, b(-999999i128).to_le());
     }
diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout
index cf417f8d412ee..dbc65569afa87 100644
--- a/src/test/rustdoc-ui/failed-doctest-output.stdout
+++ b/src/test/rustdoc-ui/failed-doctest-output.stdout
@@ -12,7 +12,7 @@ error[E0425]: cannot find value `no` in this scope
 3 | no
   | ^^ not found in this scope
 
-thread '$DIR/failed-doctest-output.rs - OtherStruct (line 26)' panicked at 'couldn't compile the test', librustdoc/test.rs:332:13
+thread '$DIR/failed-doctest-output.rs - OtherStruct (line 26)' panicked at 'couldn't compile the test', librustdoc/test.rs:333:13
 note: Run with `RUST_BACKTRACE=1` for a backtrace.
 
 ---- $DIR/failed-doctest-output.rs - SomeStruct (line 20) stdout ----
@@ -21,7 +21,7 @@ thread '$DIR/failed-doctest-output.rs - SomeStruct (line 20)' panicked at 'test
 thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
 note: Run with `RUST_BACKTRACE=1` for a backtrace.
 
-', librustdoc/test.rs:367:17
+', librustdoc/test.rs:368:17
 
 
 failures:
diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
new file mode 100644
index 0000000000000..01fa2f3459ea7
--- /dev/null
+++ b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
@@ -0,0 +1,48 @@
+// 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.
+
+#![feature(plugin_registrar)]
+#![feature(box_syntax, rustc_private)]
+#![feature(macro_vis_matcher)]
+#![feature(macro_at_most_once_rep)]
+
+extern crate syntax;
+
+// Load rustc as a plugin to get macros
+#[macro_use]
+extern crate rustc;
+extern crate rustc_plugin;
+
+use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass,
+                  LintArray};
+use rustc_plugin::Registry;
+use syntax::ast;
+declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff");
+
+struct Pass;
+
+impl LintPass for Pass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(TEST_LINT)
+    }
+}
+
+impl EarlyLintPass for Pass {
+    fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
+        if it.ident.name == "lintme" {
+            cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
+        }
+    }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_early_lint_pass(box Pass);
+}
diff --git a/src/test/ui-fulldeps/lint_tool_test.rs b/src/test/ui-fulldeps/lint_tool_test.rs
new file mode 100644
index 0000000000000..ccdcd2df31b4f
--- /dev/null
+++ b/src/test/ui-fulldeps/lint_tool_test.rs
@@ -0,0 +1,24 @@
+// 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.
+
+// run-pass
+// aux-build:lint_tool_test.rs
+// ignore-stage1
+#![feature(plugin)]
+#![feature(tool_lints)]
+#![plugin(lint_tool_test)]
+#![allow(dead_code)]
+
+fn lintme() { } //~ WARNING item is named 'lintme'
+
+#[allow(clippy::test_lint)]
+pub fn main() {
+    fn lintme() { }
+}
diff --git a/src/test/ui-fulldeps/lint_tool_test.stderr b/src/test/ui-fulldeps/lint_tool_test.stderr
new file mode 100644
index 0000000000000..22d0f458e7d7b
--- /dev/null
+++ b/src/test/ui-fulldeps/lint_tool_test.stderr
@@ -0,0 +1,8 @@
+warning: item is named 'lintme'
+  --> $DIR/lint_tool_test.rs:19:1
+   |
+LL | fn lintme() { } //~ WARNING item is named 'lintme'
+   | ^^^^^^^^^^^^^^^
+   |
+   = note: #[warn(clippy::test_lint)] on by default
+
diff --git a/src/test/ui/borrowck/borrowck-move-error-with-note.nll.stderr b/src/test/ui/borrowck/borrowck-move-error-with-note.nll.stderr
index a34c97974da11..1b913471924b7 100644
--- a/src/test/ui/borrowck/borrowck-move-error-with-note.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-move-error-with-note.nll.stderr
@@ -19,14 +19,16 @@ error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
    |
 LL |     match (S {f: "foo".to_string(), g: "bar".to_string()}) {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
+...
+LL |             f: _s,
+   |                -- data moved here
+LL |             g: _t
+   |                -- ... and here
 help: to prevent move, use ref or ref mut
    |
 LL |             f: ref _s,
-   |                ^^^^^^
-help: to prevent move, use ref or ref mut
-   |
 LL |             g: ref _t
-   |                ^^^^^^
+   |
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/borrowck-move-error-with-note.rs:57:11
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.nll.stderr b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.nll.stderr
index d01b24507d9fe..95a7894d53254 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.nll.stderr
@@ -3,14 +3,19 @@ error[E0508]: cannot move out of type `[Foo]`, a non-copy slice
    |
 LL |             match tail {
    |                   ^^^^ cannot move out of here
+LL |                 &[Foo { string: a },
+   |                                 - data moved here
+...
+LL |                   Foo { string: b }] => {
+   |                                 - ... and here
 help: to prevent move, use ref or ref mut
    |
 LL |                 &[Foo { string: ref a },
-   |                                 ^^^^^
-help: to prevent move, use ref or ref mut
-   |
+LL |                 //~^ ERROR cannot move out of type `[Foo]`
+LL |                 //~| cannot move out
+LL |                 //~| to prevent move
 LL |                   Foo { string: ref b }] => {
-   |                                 ^^^^^
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.nll.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.nll.stderr
index 50ef3ba40e7b2..2779132590e2c 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.nll.stderr
@@ -28,7 +28,10 @@ error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy sli
 LL |     match vec {
    |           ^^^ cannot move out of here
 LL |         &mut [_a, //~ ERROR cannot move out
-   |               -- help: to prevent move, use ref or ref mut: `ref _a`
+   |               --
+   |               |
+   |               data moved here
+   |               help: to prevent move, use ref or ref mut: `ref _a`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
   --> $DIR/borrowck-vec-pattern-nesting.rs:57:13
@@ -46,7 +49,10 @@ LL |     match vec {
    |           ^^^ cannot move out of here
 ...
 LL |          _b] => {}
-   |          -- help: to prevent move, use ref or ref mut: `ref _b`
+   |          --
+   |          |
+   |          data moved here
+   |          help: to prevent move, use ref or ref mut: `ref _b`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
   --> $DIR/borrowck-vec-pattern-nesting.rs:70:13
@@ -62,18 +68,15 @@ error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy sli
    |
 LL |     match vec {
    |           ^^^ cannot move out of here
+LL |         &mut [_a, _b, _c] => {}  //~ ERROR cannot move out
+   |               --  --  -- ... and here
+   |               |   |
+   |               |   ... and here
+   |               data moved here
 help: to prevent move, use ref or ref mut
    |
-LL |         &mut [ref _a, _b, _c] => {}  //~ ERROR cannot move out
-   |               ^^^^^^
-help: to prevent move, use ref or ref mut
-   |
-LL |         &mut [_a, ref _b, _c] => {}  //~ ERROR cannot move out
-   |                   ^^^^^^
-help: to prevent move, use ref or ref mut
-   |
-LL |         &mut [_a, _b, ref _c] => {}  //~ ERROR cannot move out
-   |                       ^^^^^^
+LL |         &mut [ref _a, ref _b, ref _c] => {}  //~ ERROR cannot move out
+   |               ^^^^^^  ^^^^^^  ^^^^^^
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
   --> $DIR/borrowck-vec-pattern-nesting.rs:82:13
diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr
index 4048243acfa2b..b6e005a6673eb 100644
--- a/src/test/ui/borrowck/issue-41962.stderr
+++ b/src/test/ui/borrowck/issue-41962.stderr
@@ -17,41 +17,41 @@ LL |         if let Some(thing) = maybe {
    = note: move occurs because the value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `maybe` (Mir)
-  --> $DIR/issue-41962.rs:17:30
+  --> $DIR/issue-41962.rs:17:16
    |
 LL |         if let Some(thing) = maybe {
-   |                     -----    ^^^^^ value used here after move
-   |                     |
-   |                     value moved here
+   |                ^^^^^-----^
+   |                |    |
+   |                |    value moved here
+   |                value used here after move
    |
    = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
-error[E0382]: borrow of moved value: `maybe` (Mir)
-  --> $DIR/issue-41962.rs:17:30
+error[E0382]: use of moved value (Mir)
+  --> $DIR/issue-41962.rs:17:21
    |
 LL |         if let Some(thing) = maybe {
-   |                     -----    ^^^^^ value borrowed here after move
-   |                     |
-   |                     value moved here
+   |                     ^^^^^ value moved here in previous iteration of loop
    |
    = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `maybe` (Mir)
-  --> $DIR/issue-41962.rs:17:16
+  --> $DIR/issue-41962.rs:17:30
    |
 LL |         if let Some(thing) = maybe {
-   |                ^^^^^-----^
-   |                |    |
-   |                |    value moved here
-   |                value used here after move
+   |                     -----    ^^^^^ value used here after move
+   |                     |
+   |                     value moved here
    |
    = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
-error[E0382]: use of moved value (Mir)
-  --> $DIR/issue-41962.rs:17:21
+error[E0382]: borrow of moved value: `maybe` (Mir)
+  --> $DIR/issue-41962.rs:17:30
    |
 LL |         if let Some(thing) = maybe {
-   |                     ^^^^^ value moved here in previous iteration of loop
+   |                     -----    ^^^^^ value borrowed here after move
+   |                     |
+   |                     value moved here
    |
    = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
diff --git a/src/test/ui/borrowck/issue-51415.nll.stderr b/src/test/ui/borrowck/issue-51415.nll.stderr
index d872c7efe2bc1..20713c3392e8e 100644
--- a/src/test/ui/borrowck/issue-51415.nll.stderr
+++ b/src/test/ui/borrowck/issue-51415.nll.stderr
@@ -4,6 +4,7 @@ error[E0507]: cannot move out of borrowed content
 LL |     let opt = a.iter().enumerate().find(|(_, &s)| {
    |                                          ^^^^^-^
    |                                          |    |
+   |                                          |    data moved here
    |                                          |    help: to prevent move, use ref or ref mut: `ref s`
    |                                          cannot move out of borrowed content
 
diff --git a/src/test/ui/borrowck/two-phase-multi-mut.stderr b/src/test/ui/borrowck/two-phase-multi-mut.stderr
index 0c02acf654855..a7e1dd9536453 100644
--- a/src/test/ui/borrowck/two-phase-multi-mut.stderr
+++ b/src/test/ui/borrowck/two-phase-multi-mut.stderr
@@ -1,21 +1,21 @@
 error[E0499]: cannot borrow `foo` as mutable more than once at a time
-  --> $DIR/two-phase-multi-mut.rs:23:16
+  --> $DIR/two-phase-multi-mut.rs:23:5
    |
 LL |     foo.method(&mut foo);
-   |     -----------^^^^^^^^-
+   |     ^^^^^^^^^^^--------^
    |     |          |
-   |     |          second mutable borrow occurs here
-   |     first mutable borrow occurs here
+   |     |          first mutable borrow occurs here
+   |     second mutable borrow occurs here
    |     borrow later used here
 
 error[E0499]: cannot borrow `foo` as mutable more than once at a time
-  --> $DIR/two-phase-multi-mut.rs:23:5
+  --> $DIR/two-phase-multi-mut.rs:23:16
    |
 LL |     foo.method(&mut foo);
-   |     ^^^^^^^^^^^--------^
+   |     -----------^^^^^^^^-
    |     |          |
-   |     |          first mutable borrow occurs here
-   |     second mutable borrow occurs here
+   |     |          second mutable borrow occurs here
+   |     first mutable borrow occurs here
    |     borrow later used here
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/codemap_tests/overlapping_spans.nll.stderr b/src/test/ui/codemap_tests/overlapping_spans.nll.stderr
index 34616a8de45ed..a1fbcf1430db9 100644
--- a/src/test/ui/codemap_tests/overlapping_spans.nll.stderr
+++ b/src/test/ui/codemap_tests/overlapping_spans.nll.stderr
@@ -4,7 +4,10 @@ error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
 LL |     match (S {f:"foo".to_string()}) {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
 LL |         S {f:_s} => {} //~ ERROR cannot move out
-   |              -- help: to prevent move, use ref or ref mut: `ref _s`
+   |              --
+   |              |
+   |              data moved here
+   |              help: to prevent move, use ref or ref mut: `ref _s`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/did_you_mean/issue-39544.nll.stderr b/src/test/ui/did_you_mean/issue-39544.nll.stderr
index 00e4cc6b0c35d..8c848b33241ca 100644
--- a/src/test/ui/did_you_mean/issue-39544.nll.stderr
+++ b/src/test/ui/did_you_mean/issue-39544.nll.stderr
@@ -10,7 +10,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
   --> $DIR/issue-39544.rs:26:17
    |
 LL |     fn foo<'z>(&'z self) {
-   |                -------- help: consider changing this to be a mutable reference: `&mut self`
+   |                -------- help: consider changing this to be a mutable reference: `&'z mut self`
 LL |         let _ = &mut self.x; //~ ERROR cannot borrow
    |                 ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
@@ -35,7 +35,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
   --> $DIR/issue-39544.rs:35:17
    |
 LL |     fn foo2<'a>(&'a self, other: &Z) {
-   |                 -------- help: consider changing this to be a mutable reference: `&mut self`
+   |                 -------- help: consider changing this to be a mutable reference: `&'a mut self`
 LL |         let _ = &mut self.x; //~ ERROR cannot borrow
    |                 ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
@@ -52,7 +52,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
   --> $DIR/issue-39544.rs:40:17
    |
 LL |     fn foo3<'a>(self: &'a Self, other: &Z) {
-   |                       -------- help: consider changing this to be a mutable reference: `&mut Z`
+   |                       -------- help: consider changing this to be a mutable reference: `&'a mut Self`
 LL |         let _ = &mut self.x; //~ ERROR cannot borrow
    |                 ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
diff --git a/src/test/ui/hygiene/fields-move.nll.stderr b/src/test/ui/hygiene/fields-move.nll.stderr
index 51f8067b8ce5b..56b77714991ca 100644
--- a/src/test/ui/hygiene/fields-move.nll.stderr
+++ b/src/test/ui/hygiene/fields-move.nll.stderr
@@ -1,27 +1,27 @@
 error[E0382]: use of moved value: `foo.x`
-  --> $DIR/fields-move.rs:38:42
+  --> $DIR/fields-move.rs:28:9
    |
 LL |    $foo.x
    |    ------ value moved here
 ...
+LL |         $foo.x //~ ERROR use of moved value: `foo.x`
+   |         ^^^^^^ value used here after move
+...
 LL |     assert_two_copies(copy_modern!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
-   |                                          ^^^^^ value used here after move
+   |                                          ----- value moved here
+LL |     assert_two_copies(copy_legacy!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
+   |                       ----------------- in this macro invocation
    |
    = note: move occurs because `foo.x` has type `NonCopy`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `foo.x`
-  --> $DIR/fields-move.rs:28:9
+  --> $DIR/fields-move.rs:38:42
    |
 LL |    $foo.x
    |    ------ value moved here
 ...
-LL |         $foo.x //~ ERROR use of moved value: `foo.x`
-   |         ^^^^^^ value used here after move
-...
 LL |     assert_two_copies(copy_modern!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
-   |                                          ----- value moved here
-LL |     assert_two_copies(copy_legacy!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
-   |                       ----------------- in this macro invocation
+   |                                          ^^^^^ value used here after move
    |
    = note: move occurs because `foo.x` has type `NonCopy`, which does not implement the `Copy` trait
 
diff --git a/src/test/ui/issue-12567.nll.stderr b/src/test/ui/issue-12567.nll.stderr
index a040f7c3c8d1b..29bda252b9115 100644
--- a/src/test/ui/issue-12567.nll.stderr
+++ b/src/test/ui/issue-12567.nll.stderr
@@ -3,28 +3,40 @@ error[E0508]: cannot move out of type `[T]`, a non-copy slice
    |
 LL |     match (l1, l2) {
    |           ^^^^^^^^ cannot move out of here
+LL |         (&[], &[]) => println!("both empty"),
+LL |         (&[], &[hd, ..]) | (&[hd, ..], &[])
+   |                 -- data moved here
+...
+LL |         (&[hd1, ..], &[hd2, ..])
+   |                        --- ... and here
 help: to prevent move, use ref or ref mut
    |
 LL |         (&[], &[ref hd, ..]) | (&[hd, ..], &[])
-   |                 ^^^^^^
-help: to prevent move, use ref or ref mut
-   |
+LL |             => println!("one empty"),
+LL |         //~^^ ERROR: cannot move out of type `[T]`, a non-copy slice
+LL |         //~^^^ ERROR: cannot move out of type `[T]`, a non-copy slice
 LL |         (&[hd1, ..], &[ref hd2, ..])
-   |                        ^^^^^^^
+   |
 
 error[E0508]: cannot move out of type `[T]`, a non-copy slice
   --> $DIR/issue-12567.rs:14:11
    |
 LL |     match (l1, l2) {
    |           ^^^^^^^^ cannot move out of here
+LL |         (&[], &[]) => println!("both empty"),
+LL |         (&[], &[hd, ..]) | (&[hd, ..], &[])
+   |                 -- data moved here
+...
+LL |         (&[hd1, ..], &[hd2, ..])
+   |            --- ... and here
 help: to prevent move, use ref or ref mut
    |
 LL |         (&[], &[ref hd, ..]) | (&[hd, ..], &[])
-   |                 ^^^^^^
-help: to prevent move, use ref or ref mut
-   |
+LL |             => println!("one empty"),
+LL |         //~^^ ERROR: cannot move out of type `[T]`, a non-copy slice
+LL |         //~^^^ ERROR: cannot move out of type `[T]`, a non-copy slice
 LL |         (&[ref hd1, ..], &[hd2, ..])
-   |            ^^^^^^^
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issue-27592.nll.stderr b/src/test/ui/issue-27592.nll.stderr
index 0b55117cad2ce..36a15e79ac825 100644
--- a/src/test/ui/issue-27592.nll.stderr
+++ b/src/test/ui/issue-27592.nll.stderr
@@ -1,11 +1,3 @@
-error[E0597]: borrowed value does not live long enough
-  --> $DIR/issue-27592.rs:26:33
-   |
-LL |     write(|| format_args!("{}", String::from("Hello world")));
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value only lives until here
-   |                                 |
-   |                                 temporary value does not live long enough
-
 error[E0597]: borrowed value does not live long enough
   --> $DIR/issue-27592.rs:26:27
    |
@@ -14,6 +6,14 @@ LL |     write(|| format_args!("{}", String::from("Hello world")));
    |                           |
    |                           temporary value does not live long enough
 
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/issue-27592.rs:26:33
+   |
+LL |     write(|| format_args!("{}", String::from("Hello world")));
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value only lives until here
+   |                                 |
+   |                                 temporary value does not live long enough
+
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/macros/format-foreign.rs b/src/test/ui/macros/format-foreign.rs
index 33401424c9ada..ac00ce3af9624 100644
--- a/src/test/ui/macros/format-foreign.rs
+++ b/src/test/ui/macros/format-foreign.rs
@@ -22,4 +22,6 @@ fn main() {
     println!("{} %f", "one", 2.0); //~ ERROR never used
 
     println!("Hi there, $NAME.", NAME="Tim"); //~ ERROR never used
+    println!("$1 $0 $$ $NAME", 1, 2, NAME=3);
+    //~^ ERROR multiple unused formatting arguments
 }
diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr
index 5e76c0a322e51..d5e2b514c405c 100644
--- a/src/test/ui/macros/format-foreign.stderr
+++ b/src/test/ui/macros/format-foreign.stderr
@@ -52,10 +52,25 @@ error: named argument never used
   --> $DIR/format-foreign.rs:24:39
    |
 LL |     println!("Hi there, $NAME.", NAME="Tim"); //~ ERROR never used
-   |                                       ^^^^^
+   |                         -----         ^^^^^
+   |                         |
+   |                         help: format specifiers use curly braces: `{NAME}`
    |
-   = help: `$NAME` should be written as `{NAME}`
    = note: shell formatting not supported; see the documentation for `std::fmt`
 
-error: aborting due to 5 previous errors
+error: multiple unused formatting arguments
+  --> $DIR/format-foreign.rs:25:32
+   |
+LL |     println!("$1 $0 $$ $NAME", 1, 2, NAME=3);
+   |              ----------------  ^  ^       ^
+   |              |
+   |              multiple missing formatting specifiers
+   |
+   = note: shell formatting not supported; see the documentation for `std::fmt`
+help: format specifiers use curly braces
+   |
+LL |     println!("{1} {0} $$ {NAME}", 1, 2, NAME=3);
+   |               ^^^ ^^^    ^^^^^^
+
+error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/macros/format-unused-lables.stderr b/src/test/ui/macros/format-unused-lables.stderr
index 81171a1ed01de..67ffeec67cc8b 100644
--- a/src/test/ui/macros/format-unused-lables.stderr
+++ b/src/test/ui/macros/format-unused-lables.stderr
@@ -30,7 +30,10 @@ error: multiple unused formatting arguments
   --> $DIR/format-unused-lables.rs:24:9
    |
 LL |     println!("Some more $STUFF",
-   |              ------------------ multiple missing formatting specifiers
+   |              ------------------
+   |              |          |
+   |              |          help: format specifiers use curly braces: `{STUFF}`
+   |              multiple missing formatting specifiers
 LL |         "woo!",  //~ ERROR multiple unused formatting arguments
    |         ^^^^^^
 LL |             STUFF=
@@ -39,7 +42,6 @@ LL |        "things"
 LL |              , UNUSED="args");
    |                       ^^^^^^
    |
-   = help: `$STUFF` should be written as `{STUFF}`
    = note: shell formatting not supported; see the documentation for `std::fmt`
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index ccf116e640d42..862d1f0b179c0 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -4,15 +4,6 @@ warning: not reporting region error due to nll
 LL |         let mut closure = expect_sig(|p, y| *p = y);
    |                                                  ^
 
-error: unsatisfied lifetime constraints
-  --> $DIR/escape-argument-callee.rs:36:45
-   |
-LL |         let mut closure = expect_sig(|p, y| *p = y);
-   |                                       -  -  ^^^^^^ requires that `'1` must outlive `'2`
-   |                                       |  |
-   |                                       |  has type `&'1 i32`
-   |                                       has type `&mut &'2 i32`
-
 note: No external requirements
   --> $DIR/escape-argument-callee.rs:36:38
    |
@@ -24,6 +15,15 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
                for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) i32))
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/escape-argument-callee.rs:36:45
+   |
+LL |         let mut closure = expect_sig(|p, y| *p = y);
+   |                                       -  -  ^^^^^^ requires that `'1` must outlive `'2`
+   |                                       |  |
+   |                                       |  has type `&'1 i32`
+   |                                       has type `&mut &'2 i32`
+
 note: No external requirements
   --> $DIR/escape-argument-callee.rs:30:1
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index b450882490195..72b7104b99dd3 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -4,17 +4,6 @@ warning: not reporting region error due to nll
 LL |             let p = x.get();
    |                     ^^^^^^^
 
-error: unsatisfied lifetime constraints
-  --> $DIR/propagate-approximated-fail-no-postdom.rs:57:13
-   |
-LL |         |_outlives1, _outlives2, _outlives3, x, y| {
-   |          ----------              ---------- has type `std::cell::Cell<&'2 &u32>`
-   |          |
-   |          has type `std::cell::Cell<&&'1 u32>`
-...
-LL |             demand_y(x, y, p) //~ ERROR
-   |             ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
-
 note: No external requirements
   --> $DIR/propagate-approximated-fail-no-postdom.rs:53:9
    |
@@ -31,6 +20,17 @@ LL | |         },
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-approximated-fail-no-postdom.rs:57:13
+   |
+LL |         |_outlives1, _outlives2, _outlives3, x, y| {
+   |          ----------              ---------- has type `std::cell::Cell<&'2 &u32>`
+   |          |
+   |          has type `std::cell::Cell<&&'1 u32>`
+...
+LL |             demand_y(x, y, p) //~ ERROR
+   |             ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
 note: No external requirements
   --> $DIR/propagate-approximated-fail-no-postdom.rs:48:1
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index a3588ff07e6a5..43c39dee2448a 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -4,17 +4,6 @@ warning: not reporting region error due to nll
 LL |     foo(cell, |cell_a, cell_x| {
    |     ^^^
 
-error: borrowed data escapes outside of closure
-  --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:9
-   |
-LL |     foo(cell, |cell_a, cell_x| {
-   |                ------  ------ `cell_x` is a reference that is only valid in the closure body
-   |                |
-   |                `cell_a` is declared here, outside of the closure body
-LL |         //~^ WARNING not reporting region error due to nll
-LL |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here
-
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:31:15
    |
@@ -31,6 +20,17 @@ LL | |     })
                for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>))
            ]
 
+error: borrowed data escapes outside of closure
+  --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:9
+   |
+LL |     foo(cell, |cell_a, cell_x| {
+   |                ------  ------ `cell_x` is a reference that is only valid in the closure body
+   |                |
+   |                `cell_a` is declared here, outside of the closure body
+LL |         //~^ WARNING not reporting region error due to nll
+LL |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here
+
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:28:1
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index d5495b69c7ced..c3bbf1035dbc5 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -23,19 +23,6 @@ LL | |     });
    = note: number of external vids: 4
    = note: where '_#1r: '_#0r
 
-error: borrowed data escapes outside of function
-  --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5
-   |
-LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-   |                     ------ `cell_a` is a reference that is only valid in the function body
-LL | /     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-LL | |         //~^ ERROR
-LL | |
-LL | |         // Only works if 'x: 'y:
-LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
-LL | |     });
-   | |______^ `cell_a` escapes the function body here
-
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1
    |
@@ -50,5 +37,18 @@ LL | | }
    |
    = note: defining type: DefId(0/0:6 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]) with substs []
 
+error: borrowed data escapes outside of function
+  --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5
+   |
+LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+   |                     ------ `cell_a` is a reference that is only valid in the function body
+LL | /     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
+LL | |         //~^ ERROR
+LL | |
+LL | |         // Only works if 'x: 'y:
+LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
+LL | |     });
+   | |______^ `cell_a` escapes the function body here
+
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index 50e2dd23da8a8..9f259e2dee590 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -23,19 +23,6 @@ LL | |     });
    = note: number of external vids: 5
    = note: where '_#1r: '_#0r
 
-error: borrowed data escapes outside of function
-  --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5
-   |
-LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-   |                     ------ `cell_a` is a reference that is only valid in the function body
-LL | /     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | |         //~^ ERROR
-LL | |         // Only works if 'x: 'y:
-LL | |         demand_y(x, y, x.get())
-LL | |         //~^ WARNING not reporting region error due to nll
-LL | |     });
-   | |______^ `cell_a` escapes the function body here
-
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1
    |
@@ -50,5 +37,18 @@ LL | | }
    |
    = note: defining type: DefId(0/0:6 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]) with substs []
 
+error: borrowed data escapes outside of function
+  --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5
+   |
+LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+   |                     ------ `cell_a` is a reference that is only valid in the function body
+LL | /     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
+LL | |         //~^ ERROR
+LL | |         // Only works if 'x: 'y:
+LL | |         demand_y(x, y, x.get())
+LL | |         //~^ WARNING not reporting region error due to nll
+LL | |     });
+   | |______^ `cell_a` escapes the function body here
+
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 40ebda4419b2a..cd5e6f29f5f48 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -4,17 +4,6 @@ warning: not reporting region error due to nll
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: unsatisfied lifetime constraints
-  --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
-   |
-LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-   |                                                ---------  - has type `&std::cell::Cell<&'1 u32>`
-   |                                                |
-   |                                                has type `&std::cell::Cell<&'2 &u32>`
-LL |         // Only works if 'x: 'y:
-LL |         demand_y(x, y, x.get())
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
-
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:45:47
    |
@@ -32,6 +21,17 @@ LL | |     });
                for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
+   |
+LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
+   |                                                ---------  - has type `&std::cell::Cell<&'1 u32>`
+   |                                                |
+   |                                                has type `&std::cell::Cell<&'2 &u32>`
+LL |         // Only works if 'x: 'y:
+LL |         demand_y(x, y, x.get())
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:44:1
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 37ea610397696..2176575e0aa12 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -4,17 +4,6 @@ warning: not reporting region error due to nll
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: unsatisfied lifetime constraints
-  --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
-   |
-LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-   |                                                ----------  ---------- has type `&std::cell::Cell<&'2 &u32>`
-   |                                                |
-   |                                                has type `&std::cell::Cell<&'1 &u32>`
-LL |         // Only works if 'x: 'y:
-LL |         demand_y(x, y, x.get())
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
-
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:49:47
    |
@@ -32,6 +21,17 @@ LL | |     });
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
+   |
+LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
+   |                                                ----------  ---------- has type `&std::cell::Cell<&'2 &u32>`
+   |                                                |
+   |                                                has type `&std::cell::Cell<&'1 &u32>`
+LL |         // Only works if 'x: 'y:
+LL |         demand_y(x, y, x.get())
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:48:1
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
index 42d5b15bd5a29..8f8a99df5f052 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
@@ -26,21 +26,6 @@ LL | |     });
    = note: number of external vids: 3
    = note: where T: '_#1r
 
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/propagate-from-trait-match.rs:42:36
-   |
-LL |       establish_relationships(value, |value| {
-   |  ____________________________________^
-LL | |         //~^ ERROR the parameter type `T` may not live long enough
-LL | |
-LL | |         // This function call requires that
-...  |
-LL | |         //~^ WARNING not reporting region error due to nll
-LL | |     });
-   | |_____^
-   |
-   = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
-
 note: No external requirements
   --> $DIR/propagate-from-trait-match.rs:38:1
    |
@@ -58,6 +43,21 @@ LL | | }
                T
            ]
 
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/propagate-from-trait-match.rs:42:36
+   |
+LL |       establish_relationships(value, |value| {
+   |  ____________________________________^
+LL | |         //~^ ERROR the parameter type `T` may not live long enough
+LL | |
+LL | |         // This function call requires that
+...  |
+LL | |         //~^ WARNING not reporting region error due to nll
+LL | |     });
+   | |_____^
+   |
+   = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
+
 error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index d6d1645ceeacc..d2e088815e118 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -4,15 +4,6 @@ warning: not reporting region error due to nll
 LL |     expect_sig(|a, b| b); // ought to return `a`
    |                       ^
 
-error: unsatisfied lifetime constraints
-  --> $DIR/return-wrong-bound-region.rs:21:23
-   |
-LL |     expect_sig(|a, b| b); // ought to return `a`
-   |                 -  -  ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2`
-   |                 |  |
-   |                 |  has type `&'1 i32`
-   |                 has type `&'2 i32`
-
 note: No external requirements
   --> $DIR/return-wrong-bound-region.rs:21:16
    |
@@ -24,6 +15,15 @@ LL |     expect_sig(|a, b| b); // ought to return `a`
                for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32)) -> &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) i32
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/return-wrong-bound-region.rs:21:23
+   |
+LL |     expect_sig(|a, b| b); // ought to return `a`
+   |                 -  -  ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2`
+   |                 |  |
+   |                 |  has type `&'1 i32`
+   |                 has type `&'2 i32`
+
 note: No external requirements
   --> $DIR/return-wrong-bound-region.rs:20:1
    |
diff --git a/src/test/ui/nll/extra-unused-mut.rs b/src/test/ui/nll/extra-unused-mut.rs
index ce07e2b0e2184..472ac2cf1e84c 100644
--- a/src/test/ui/nll/extra-unused-mut.rs
+++ b/src/test/ui/nll/extra-unused-mut.rs
@@ -55,10 +55,19 @@ fn parse_dot_or_call_expr_with(mut attrs: Vec<u32>) {
     );
 }
 
+// Found when trying to bootstrap rustc
+fn if_guard(x: Result<i32, i32>) {
+    match x {
+        Ok(mut r) | Err(mut r) if true => r = 1,
+        _ => (),
+    }
+}
+
 fn main() {
     ref_argument(0);
     mutable_upvar();
     generator_mutable_upvar();
     ref_closure_argument();
     parse_dot_or_call_expr_with(Vec::new());
+    if_guard(Ok(0));
 }
diff --git a/src/test/ui/nll/issue-52133.rs b/src/test/ui/nll/issue-52113.rs
similarity index 100%
rename from src/test/ui/nll/issue-52133.rs
rename to src/test/ui/nll/issue-52113.rs
diff --git a/src/test/ui/nll/issue-52133.stderr b/src/test/ui/nll/issue-52113.stderr
similarity index 94%
rename from src/test/ui/nll/issue-52133.stderr
rename to src/test/ui/nll/issue-52113.stderr
index c1841004cf620..4a7c10c3f1af8 100644
--- a/src/test/ui/nll/issue-52133.stderr
+++ b/src/test/ui/nll/issue-52113.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/issue-52133.rs:43:9
+  --> $DIR/issue-52113.rs:43:9
    |
 LL | fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl Bazinga + 'b {
    |                                  --------------------         ------- these two types are declared with different lifetimes...
diff --git a/src/test/ui/nll/move-errors.stderr b/src/test/ui/nll/move-errors.stderr
index 3f2c651ae3a6a..53d60d3f6d649 100644
--- a/src/test/ui/nll/move-errors.stderr
+++ b/src/test/ui/nll/move-errors.stderr
@@ -59,6 +59,7 @@ error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
 LL |     let C(D(s)) = c;
    |             -     ^ cannot move out of here
    |             |
+   |             data moved here
    |             help: to prevent move, use ref or ref mut: `ref s`
 
 error[E0507]: cannot move out of borrowed content
@@ -88,7 +89,10 @@ LL |     match x {
    |           ^ cannot move out of here
 ...
 LL |         B::U(D(s)) => (),
-   |                - help: to prevent move, use ref or ref mut: `ref s`
+   |                -
+   |                |
+   |                data moved here
+   |                help: to prevent move, use ref or ref mut: `ref s`
 
 error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
   --> $DIR/move-errors.rs:105:11
@@ -97,7 +101,10 @@ LL |     match x {
    |           ^ cannot move out of here
 ...
 LL |         (D(s), &t) => (),
-   |            - help: to prevent move, use ref or ref mut: `ref s`
+   |            -
+   |            |
+   |            data moved here
+   |            help: to prevent move, use ref or ref mut: `ref s`
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/move-errors.rs:105:11
@@ -106,21 +113,25 @@ LL |     match x {
    |           ^ cannot move out of borrowed content
 ...
 LL |         (D(s), &t) => (),
-   |                 - help: to prevent move, use ref or ref mut: `ref t`
+   |                 -
+   |                 |
+   |                 data moved here
+   |                 help: to prevent move, use ref or ref mut: `ref t`
 
 error[E0509]: cannot move out of type `F`, which implements the `Drop` trait
   --> $DIR/move-errors.rs:115:11
    |
 LL |     match x {
    |           ^ cannot move out of here
+LL |     //~^ ERROR
+LL |         F(s, mut t) => (),
+   |           -  ----- ... and here
+   |           |
+   |           data moved here
 help: to prevent move, use ref or ref mut
    |
-LL |         F(ref s, mut t) => (),
-   |           ^^^^^
-help: to prevent move, use ref or ref mut
-   |
-LL |         F(s, ref mut t) => (),
-   |              ^^^^^^^^^
+LL |         F(ref s, ref mut t) => (),
+   |           ^^^^^  ^^^^^^^^^
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/move-errors.rs:123:11
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
index dd12e8220c456..6d2170729ffb9 100644
--- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
@@ -25,14 +25,6 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
    = note: number of external vids: 4
    = note: where <T as std::iter::Iterator>::Item: '_#2r
 
-error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
-  --> $DIR/projection-no-regions-closure.rs:35:23
-   |
-LL |     with_signature(x, |mut y| Box::new(y.next()))
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `<T as std::iter::Iterator>::Item: ReEarlyBound(0, 'a)`...
-
 note: No external requirements
   --> $DIR/projection-no-regions-closure.rs:31:1
    |
@@ -50,6 +42,14 @@ LL | | }
                T
            ]
 
+error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
+  --> $DIR/projection-no-regions-closure.rs:35:23
+   |
+LL |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `<T as std::iter::Iterator>::Item: ReEarlyBound(0, 'a)`...
+
 note: External requirements
   --> $DIR/projection-no-regions-closure.rs:45:23
    |
@@ -97,14 +97,6 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
    = note: number of external vids: 5
    = note: where <T as std::iter::Iterator>::Item: '_#3r
 
-error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
-  --> $DIR/projection-no-regions-closure.rs:53:23
-   |
-LL |     with_signature(x, |mut y| Box::new(y.next()))
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `<T as std::iter::Iterator>::Item: ReEarlyBound(0, 'a)`...
-
 note: No external requirements
   --> $DIR/projection-no-regions-closure.rs:49:1
    |
@@ -123,6 +115,14 @@ LL | | }
                T
            ]
 
+error[E0309]: the associated type `<T as std::iter::Iterator>::Item` may not live long enough
+  --> $DIR/projection-no-regions-closure.rs:53:23
+   |
+LL |     with_signature(x, |mut y| Box::new(y.next()))
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `<T as std::iter::Iterator>::Item: ReEarlyBound(0, 'a)`...
+
 note: External requirements
   --> $DIR/projection-no-regions-closure.rs:64:23
    |
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
index 456c52d3a51b8..ed8491349a257 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
@@ -32,20 +32,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: where T: '_#2r
    = note: where '_#1r: '_#2r
 
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/projection-one-region-closure.rs:55:29
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`...
-
-error: unsatisfied lifetime constraints
-  --> $DIR/projection-one-region-closure.rs:55:5
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
-
 note: No external requirements
   --> $DIR/projection-one-region-closure.rs:51:1
    |
@@ -63,6 +49,20 @@ LL | | }
                T
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/projection-one-region-closure.rs:55:5
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/projection-one-region-closure.rs:55:29
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`...
+
 note: External requirements
   --> $DIR/projection-one-region-closure.rs:67:29
    |
@@ -80,20 +80,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: where T: '_#3r
    = note: where '_#2r: '_#3r
 
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/projection-one-region-closure.rs:67:29
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
-
-error: unsatisfied lifetime constraints
-  --> $DIR/projection-one-region-closure.rs:67:5
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
-
 note: No external requirements
   --> $DIR/projection-one-region-closure.rs:62:1
    |
@@ -112,6 +98,20 @@ LL | | }
                T
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/projection-one-region-closure.rs:67:5
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/projection-one-region-closure.rs:67:29
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
+
 note: External requirements
   --> $DIR/projection-one-region-closure.rs:89:29
    |
@@ -129,20 +129,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: where T: '_#3r
    = note: where '_#2r: '_#3r
 
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/projection-one-region-closure.rs:89:29
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
-
-error: unsatisfied lifetime constraints
-  --> $DIR/projection-one-region-closure.rs:89:5
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
-
 note: No external requirements
   --> $DIR/projection-one-region-closure.rs:74:1
    |
@@ -161,6 +147,20 @@ LL | | }
                T
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/projection-one-region-closure.rs:89:5
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/projection-one-region-closure.rs:89:29
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
+
 note: External requirements
   --> $DIR/projection-one-region-closure.rs:102:29
    |
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
index 35c0405ff89e2..8318ce10745d3 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
@@ -31,12 +31,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 5
    = note: where '_#1r: '_#2r
 
-error: unsatisfied lifetime constraints
-  --> $DIR/projection-one-region-trait-bound-closure.rs:47:5
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
-
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:43:1
    |
@@ -54,6 +48,12 @@ LL | | }
                T
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/projection-one-region-trait-bound-closure.rs:47:5
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
 note: External requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:58:29
    |
@@ -70,12 +70,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 5
    = note: where '_#2r: '_#3r
 
-error: unsatisfied lifetime constraints
-  --> $DIR/projection-one-region-trait-bound-closure.rs:58:5
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
-
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:53:1
    |
@@ -94,6 +88,12 @@ LL | | }
                T
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/projection-one-region-trait-bound-closure.rs:58:5
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
 note: External requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:79:29
    |
@@ -110,12 +110,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 5
    = note: where '_#2r: '_#3r
 
-error: unsatisfied lifetime constraints
-  --> $DIR/projection-one-region-trait-bound-closure.rs:79:5
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
-
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:64:1
    |
@@ -134,6 +128,12 @@ LL | | }
                T
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/projection-one-region-trait-bound-closure.rs:79:5
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
 note: External requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:90:29
    |
diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
index a713971d17cb3..1452573d57a25 100644
--- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
@@ -38,14 +38,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 6
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#2r)>>::AssocType: '_#3r
 
-error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
-  --> $DIR/projection-two-region-trait-bound-closure.rs:48:29
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `<T as Anything<'_#6r, '_#7r>>::AssocType: ReFree(DefId(0/0:8 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:18), 'a))`...
-
 note: No external requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:44:1
    |
@@ -64,6 +56,14 @@ LL | | }
                T
            ]
 
+error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
+  --> $DIR/projection-two-region-trait-bound-closure.rs:48:29
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `<T as Anything<'_#6r, '_#7r>>::AssocType: ReFree(DefId(0/0:8 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:18), 'a))`...
+
 note: External requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:59:29
    |
@@ -81,14 +81,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 6
    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
 
-error[E0309]: the associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
-  --> $DIR/projection-two-region-trait-bound-closure.rs:59:29
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `<T as Anything<'_#7r, '_#8r>>::AssocType: ReEarlyBound(0, 'a)`...
-
 note: No external requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:54:1
    |
@@ -108,6 +100,14 @@ LL | | }
                T
            ]
 
+error[E0309]: the associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
+  --> $DIR/projection-two-region-trait-bound-closure.rs:59:29
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `<T as Anything<'_#7r, '_#8r>>::AssocType: ReEarlyBound(0, 'a)`...
+
 note: External requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:80:29
    |
@@ -125,14 +125,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 6
    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
 
-error[E0309]: the associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
-  --> $DIR/projection-two-region-trait-bound-closure.rs:80:29
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `<T as Anything<'_#7r, '_#8r>>::AssocType: ReEarlyBound(0, 'a)`...
-
 note: No external requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:65:1
    |
@@ -152,6 +144,14 @@ LL | | }
                T
            ]
 
+error[E0309]: the associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
+  --> $DIR/projection-two-region-trait-bound-closure.rs:80:29
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `<T as Anything<'_#7r, '_#8r>>::AssocType: ReEarlyBound(0, 'a)`...
+
 note: External requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:91:29
    |
@@ -239,12 +239,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 5
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
 
-error: unsatisfied lifetime constraints
-  --> $DIR/projection-two-region-trait-bound-closure.rs:108:5
-   |
-LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
-
 note: No external requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:104:1
    |
@@ -262,6 +256,12 @@ LL | | }
                T
            ]
 
+error: unsatisfied lifetime constraints
+  --> $DIR/projection-two-region-trait-bound-closure.rs:108:5
+   |
+LL |     with_signature(cell, t, |cell, t| require(cell, t));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
 note: External requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:119:29
    |
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 39382df8d8a91..87f55b4e14d96 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -60,14 +60,6 @@ LL |     twice(cell, value, |a, b| invoke(a, b));
    = note: number of external vids: 4
    = note: where T: '_#1r
 
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/ty-param-closure-approximate-lower-bound.rs:42:24
-   |
-LL |     twice(cell, value, |a, b| invoke(a, b));
-   |                        ^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:6 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]), BrNamed(crate0:DefIndex(1:15), 'a))`...
-
 note: No external requirements
   --> $DIR/ty-param-closure-approximate-lower-bound.rs:41:1
    |
@@ -83,6 +75,14 @@ LL | | }
                T
            ]
 
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/ty-param-closure-approximate-lower-bound.rs:42:24
+   |
+LL |     twice(cell, value, |a, b| invoke(a, b));
+   |                        ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:6 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]), BrNamed(crate0:DefIndex(1:15), 'a))`...
+
 error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0309`.
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
index 8babbe3fd97d2..aec0d98c79aa4 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
@@ -25,14 +25,6 @@ LL |     with_signature(x, |y| y)
    = note: number of external vids: 4
    = note: where T: '_#2r
 
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/ty-param-closure-outlives-from-return-type.rs:36:23
-   |
-LL |     with_signature(x, |y| y)
-   |                       ^^^^^
-   |
-   = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
-
 note: No external requirements
   --> $DIR/ty-param-closure-outlives-from-return-type.rs:25:1
    |
@@ -50,6 +42,14 @@ LL | | }
                T
            ]
 
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/ty-param-closure-outlives-from-return-type.rs:36:23
+   |
+LL |     with_signature(x, |y| y)
+   |                       ^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
+
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/ty-param-closure-outlives-from-return-type.rs:52:5
    |
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
index b9426eba0f66d..67a158860d64c 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
@@ -31,21 +31,6 @@ LL | |     })
    = note: number of external vids: 4
    = note: where T: '_#1r
 
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:37:26
-   |
-LL |       with_signature(a, b, |x, y| {
-   |  __________________________^
-LL | |         //~^ ERROR the parameter type `T` may not live long enough
-LL | |         //
-LL | |         // See `correct_region`, which explains the point of this
-...  |
-LL | |         //~^ WARNING not reporting region error due to nll
-LL | |     })
-   | |_____^
-   |
-   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:6 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]), BrNamed(crate0:DefIndex(1:14), 'a))`...
-
 note: No external requirements
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:36:1
    |
@@ -62,6 +47,21 @@ LL | | }
                T
            ]
 
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:37:26
+   |
+LL |       with_signature(a, b, |x, y| {
+   |  __________________________^
+LL | |         //~^ ERROR the parameter type `T` may not live long enough
+LL | |         //
+LL | |         // See `correct_region`, which explains the point of this
+...  |
+LL | |         //~^ WARNING not reporting region error due to nll
+LL | |     })
+   | |_____^
+   |
+   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:6 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]), BrNamed(crate0:DefIndex(1:14), 'a))`...
+
 note: External requirements
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:54:26
    |
@@ -122,20 +122,6 @@ LL | |     })
    = note: number of external vids: 5
    = note: where T: '_#2r
 
-error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:75:26
-   |
-LL |       with_signature(a, b, |x, y| {
-   |  __________________________^
-LL | |         //~^ ERROR the parameter type `T` may not live long enough
-LL | |         // See `correct_region`
-LL | |         require(&x, &y)
-LL | |         //~^ WARNING not reporting region error due to nll
-LL | |     })
-   | |_____^
-   |
-   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]), BrNamed(crate0:DefIndex(1:20), 'a))`...
-
 note: No external requirements
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:71:1
    |
@@ -153,6 +139,20 @@ LL | | }
                T
            ]
 
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/ty-param-closure-outlives-from-where-clause.rs:75:26
+   |
+LL |       with_signature(a, b, |x, y| {
+   |  __________________________^
+LL | |         //~^ ERROR the parameter type `T` may not live long enough
+LL | |         // See `correct_region`
+LL | |         require(&x, &y)
+LL | |         //~^ WARNING not reporting region error due to nll
+LL | |     })
+   | |_____^
+   |
+   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]), BrNamed(crate0:DefIndex(1:20), 'a))`...
+
 note: External requirements
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:89:26
    |
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.nll.stderr b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.nll.stderr
index 366bfc8fa20a5..4a693a3b05d4e 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.nll.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.nll.stderr
@@ -26,7 +26,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:102:5
    |
 LL | fn assign_field2<'a>(x: &'a Own<Point>) {
-   |                         -------------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
+   |                         -------------- help: consider changing this to be a mutable reference: `&'a mut Own<Point>`
 LL |     x.y = 3; //~ ERROR cannot borrow
    |     ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
@@ -58,7 +58,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:143:6
    |
 LL | fn assign_method2<'a>(x: &'a Own<Point>) {
-   |                          -------------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
+   |                          -------------- help: consider changing this to be a mutable reference: `&'a mut Own<Point>`
 LL |     *x.y_mut() = 3; //~ ERROR cannot borrow
    |      ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.nll.stderr b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.nll.stderr
index 69bf246ff3fef..44a5062cb4d43 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.nll.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.nll.stderr
@@ -10,7 +10,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:51:11
    |
 LL | fn deref_extend_mut1<'a>(x: &'a Own<isize>) -> &'a mut isize {
-   |                             -------------- help: consider changing this to be a mutable reference: `&mut Own<isize>`
+   |                             -------------- help: consider changing this to be a mutable reference: `&'a mut Own<isize>`
 LL |     &mut **x //~ ERROR cannot borrow
    |           ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
@@ -26,7 +26,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:63:6
    |
 LL | fn assign2<'a>(x: &'a Own<isize>) {
-   |                   -------------- help: consider changing this to be a mutable reference: `&mut Own<isize>`
+   |                   -------------- help: consider changing this to be a mutable reference: `&'a mut Own<isize>`
 LL |     **x = 3; //~ ERROR cannot borrow
    |      ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
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 6c0373ce1570a..76a25fa661ece 100644
--- a/src/test/ui/span/dropck_arr_cycle_checked.nll.stderr
+++ b/src/test/ui/span/dropck_arr_cycle_checked.nll.stderr
@@ -1,25 +1,25 @@
-error[E0597]: `b3` does not live long enough
-  --> $DIR/dropck_arr_cycle_checked.rs:105:24
+error[E0597]: `b2` does not live long enough
+  --> $DIR/dropck_arr_cycle_checked.rs:103:24
    |
-LL |     b1.a[1].v.set(Some(&b3));
+LL |     b1.a[0].v.set(Some(&b2));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
    | -
    | |
-   | `b3` dropped here while still borrowed
+   | `b2` dropped here while still borrowed
    | borrow later used here, when `b1` is dropped
 
-error[E0597]: `b2` does not live long enough
-  --> $DIR/dropck_arr_cycle_checked.rs:103:24
+error[E0597]: `b3` does not live long enough
+  --> $DIR/dropck_arr_cycle_checked.rs:105:24
    |
-LL |     b1.a[0].v.set(Some(&b2));
+LL |     b1.a[1].v.set(Some(&b3));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
    | -
    | |
-   | `b2` dropped here while still borrowed
+   | `b3` dropped here while still borrowed
    | borrow later used here, when `b1` is dropped
 
 error[E0597]: `b1` does not live long enough
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 c0950e7929678..e6f43e0a71b56 100644
--- a/src/test/ui/span/dropck_vec_cycle_checked.nll.stderr
+++ b/src/test/ui/span/dropck_vec_cycle_checked.nll.stderr
@@ -1,25 +1,25 @@
-error[E0597]: `c3` does not live long enough
-  --> $DIR/dropck_vec_cycle_checked.rs:115:24
+error[E0597]: `c2` does not live long enough
+  --> $DIR/dropck_vec_cycle_checked.rs:113:24
    |
-LL |     c1.v[1].v.set(Some(&c3));
+LL |     c1.v[0].v.set(Some(&c2));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
    | -
    | |
-   | `c3` dropped here while still borrowed
+   | `c2` dropped here while still borrowed
    | borrow later used here, when `c1` is dropped
 
-error[E0597]: `c2` does not live long enough
-  --> $DIR/dropck_vec_cycle_checked.rs:113:24
+error[E0597]: `c3` does not live long enough
+  --> $DIR/dropck_vec_cycle_checked.rs:115:24
    |
-LL |     c1.v[0].v.set(Some(&c2));
+LL |     c1.v[1].v.set(Some(&c3));
    |                        ^^^ borrowed value does not live long enough
 ...
 LL | }
    | -
    | |
-   | `c2` dropped here while still borrowed
+   | `c3` dropped here while still borrowed
    | borrow later used here, when `c1` is dropped
 
 error[E0597]: `c1` does not live long enough
diff --git a/src/test/ui/span/mut-arg-hint.nll.stderr b/src/test/ui/span/mut-arg-hint.nll.stderr
index f264ea1f91676..f42cf6500e2ea 100644
--- a/src/test/ui/span/mut-arg-hint.nll.stderr
+++ b/src/test/ui/span/mut-arg-hint.nll.stderr
@@ -10,7 +10,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
   --> $DIR/mut-arg-hint.rs:18:5
    |
 LL | pub fn foo<'a>(mut a: &'a String) {
-   |                       ---------- help: consider changing this to be a mutable reference: `&mut std::string::String`
+   |                       ---------- help: consider changing this to be a mutable reference: `&'a mut String`
 LL |     a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content
    |     ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
diff --git a/src/test/ui/span/range-2.nll.stderr b/src/test/ui/span/range-2.nll.stderr
index 049618fe4744b..2a82e1b8ada8c 100644
--- a/src/test/ui/span/range-2.nll.stderr
+++ b/src/test/ui/span/range-2.nll.stderr
@@ -1,21 +1,21 @@
-error[E0597]: `b` does not live long enough
-  --> $DIR/range-2.rs:17:13
+error[E0597]: `a` does not live long enough
+  --> $DIR/range-2.rs:17:9
    |
 LL |         &a..&b
-   |             ^^ borrowed value does not live long enough
+   |         ^^ borrowed value does not live long enough
 LL |     };
-   |     - `b` dropped here while still borrowed
+   |     - `a` dropped here while still borrowed
 ...
 LL |     r.use_ref();
    |     - borrow later used here
 
-error[E0597]: `a` does not live long enough
-  --> $DIR/range-2.rs:17:9
+error[E0597]: `b` does not live long enough
+  --> $DIR/range-2.rs:17:13
    |
 LL |         &a..&b
-   |         ^^ borrowed value does not live long enough
+   |             ^^ borrowed value does not live long enough
 LL |     };
-   |     - `a` dropped here while still borrowed
+   |     - `b` dropped here while still borrowed
 ...
 LL |     r.use_ref();
    |     - borrow later used here
diff --git a/src/test/ui/span/regions-escape-loop-via-vec.nll.stderr b/src/test/ui/span/regions-escape-loop-via-vec.nll.stderr
index 33fca7fa703b0..4d81211673e6e 100644
--- a/src/test/ui/span/regions-escape-loop-via-vec.nll.stderr
+++ b/src/test/ui/span/regions-escape-loop-via-vec.nll.stderr
@@ -20,6 +20,17 @@ LL |         let mut z = x; //~ ERROR cannot use `x` because it was mutably borr
 LL |         _y.push(&mut z);
    |         -- borrow later used here
 
+error[E0597]: `z` does not live long enough
+  --> $DIR/regions-escape-loop-via-vec.rs:17:17
+   |
+LL |         _y.push(&mut z);
+   |         --      ^^^^^^ borrowed value does not live long enough
+   |         |
+   |         borrow later used here
+...
+LL |     }
+   |     - `z` dropped here while still borrowed
+
 error[E0503]: cannot use `x` because it was mutably borrowed
   --> $DIR/regions-escape-loop-via-vec.rs:19:9
    |
@@ -32,17 +43,6 @@ LL |         //~^ ERROR `z` does not live long enough
 LL |         x += 1; //~ ERROR cannot assign
    |         ^^^^^^ use of borrowed `x`
 
-error[E0597]: `z` does not live long enough
-  --> $DIR/regions-escape-loop-via-vec.rs:17:17
-   |
-LL |         _y.push(&mut z);
-   |         --      ^^^^^^ borrowed value does not live long enough
-   |         |
-   |         borrow later used here
-...
-LL |     }
-   |     - `z` dropped here while still borrowed
-
 error: aborting due to 4 previous errors
 
 Some errors occurred: E0503, E0597.
diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr b/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr
index 7f7217b8004a6..1753f710b8842 100644
--- a/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr
+++ b/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr
@@ -1,3 +1,15 @@
+error[E0597]: `x` does not live long enough
+  --> $DIR/send-is-not-static-ensures-scoping.rs:26:17
+   |
+LL |         let y = &x;
+   |                 ^^ borrowed value does not live long enough
+...
+LL |     };
+   |     - `x` dropped here while still borrowed
+LL | 
+LL |     bad.join();
+   |     --- borrow later used here
+
 error[E0597]: `y` does not live long enough
   --> $DIR/send-is-not-static-ensures-scoping.rs:29:16
    |
@@ -13,18 +25,6 @@ LL |
 LL |       bad.join();
    |       --- borrow later used here
 
-error[E0597]: `x` does not live long enough
-  --> $DIR/send-is-not-static-ensures-scoping.rs:26:17
-   |
-LL |         let y = &x;
-   |                 ^^ borrowed value does not live long enough
-...
-LL |     };
-   |     - `x` dropped here while still borrowed
-LL | 
-LL |     bad.join();
-   |     --- borrow later used here
-
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/span/vec_refs_data_with_early_death.nll.stderr b/src/test/ui/span/vec_refs_data_with_early_death.nll.stderr
index 73256b4fb17c9..60905367063a4 100644
--- a/src/test/ui/span/vec_refs_data_with_early_death.nll.stderr
+++ b/src/test/ui/span/vec_refs_data_with_early_death.nll.stderr
@@ -1,27 +1,27 @@
-error[E0597]: `y` does not live long enough
-  --> $DIR/vec_refs_data_with_early_death.rs:29:12
+error[E0597]: `x` does not live long enough
+  --> $DIR/vec_refs_data_with_early_death.rs:27:12
    |
-LL |     v.push(&y);
+LL |     v.push(&x);
    |            ^^ borrowed value does not live long enough
 ...
 LL | }
    | -
    | |
-   | `y` dropped here while still borrowed
+   | `x` dropped here while still borrowed
    | borrow later used here, when `v` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
 
-error[E0597]: `x` does not live long enough
-  --> $DIR/vec_refs_data_with_early_death.rs:27:12
+error[E0597]: `y` does not live long enough
+  --> $DIR/vec_refs_data_with_early_death.rs:29:12
    |
-LL |     v.push(&x);
+LL |     v.push(&y);
    |            ^^ borrowed value does not live long enough
 ...
 LL | }
    | -
    | |
-   | `x` dropped here while still borrowed
+   | `y` dropped here while still borrowed
    | borrow later used here, when `v` is dropped
    |
    = note: values in a scope are dropped in the opposite order they are defined
diff --git a/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.nll.stderr b/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.nll.stderr
index 215faf6c73c36..56897baeb4eff 100644
--- a/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.nll.stderr
+++ b/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.nll.stderr
@@ -2,7 +2,7 @@ error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
   --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:16:5
    |
 LL | fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
-   |                        --------------- help: consider changing this to be a mutable reference: `&mut &mut i32`
+   |                        --------------- help: consider changing this to be a mutable reference: `&'a mut &'a mut i32`
 LL |     *t //~ ERROR
    |     ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
@@ -10,7 +10,7 @@ error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
   --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:20:6
    |
 LL | fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
-   |                             --------------- help: consider changing this to be a mutable reference: `&mut &mut i32`
+   |                             --------------- help: consider changing this to be a mutable reference: `&'a mut &'a mut i32`
 LL |     {*t} //~ ERROR
    |      ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
 
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 83b2895e1d65d..bbce87a7c9adf 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -109,6 +109,7 @@ static TARGETS: &'static [&'static str] = &[
     "x86_64-sun-solaris",
     "x86_64-unknown-cloudabi",
     "x86_64-unknown-freebsd",
+    "x86_64-unknown-hermit",
     "x86_64-unknown-linux-gnu",
     "x86_64-unknown-linux-gnux32",
     "x86_64-unknown-linux-musl",
diff --git a/src/tools/clippy b/src/tools/clippy
index afd91248eda02..b0dabce47803c 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit afd91248eda02cf2968e4e02c77b6c10ecd3fd4f
+Subproject commit b0dabce47803c18b935ec5390de69e04ad5304c2
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 91e7399f1f492..2a716970ca7b9 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -25,6 +25,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[
     ("freebsd", "freebsd"),
     ("fuchsia", "fuchsia"),
     ("haiku", "haiku"),
+    ("hermit", "hermit"),
     ("ios", "ios"),
     ("l4re", "l4re"),
     ("linux", "linux"),
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index e72f90554d3c5..40917cc5db0d5 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -21,10 +21,11 @@ use std::fs::{read_dir, File};
 use std::io::{Read, Write};
 use std::path::Path;
 use std::path::PathBuf;
+use std::cell::RefCell;
 
 use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
 
-use rustdoc::html::markdown::{Markdown, PLAYGROUND};
+use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, PLAYGROUND};
 use rustc_serialize::json;
 
 enum OutputFormat {
@@ -36,7 +37,7 @@ enum OutputFormat {
 impl OutputFormat {
     fn from(format: &str) -> OutputFormat {
         match &*format.to_lowercase() {
-            "html"     => OutputFormat::HTML(HTMLFormatter),
+            "html"     => OutputFormat::HTML(HTMLFormatter(RefCell::new(IdMap::new()))),
             "markdown" => OutputFormat::Markdown(MarkdownFormatter),
             s          => OutputFormat::Unknown(s.to_owned()),
         }
@@ -51,7 +52,7 @@ trait Formatter {
     fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
 }
 
-struct HTMLFormatter;
+struct HTMLFormatter(RefCell<IdMap>);
 struct MarkdownFormatter;
 
 impl Formatter for HTMLFormatter {
@@ -100,7 +101,11 @@ impl Formatter for HTMLFormatter {
 
         // Description rendered as markdown.
         match info.description {
-            Some(ref desc) => write!(output, "{}", Markdown(desc, &[]))?,
+            Some(ref desc) => {
+                let mut id_map = self.0.borrow_mut();
+                write!(output, "{}",
+                    Markdown(desc, &[], RefCell::new(&mut id_map), ErrorCodes::Yes))?
+            },
             None => write!(output, "<p>No description.</p>\n")?,
         }