diff --git a/Cargo.lock b/Cargo.lock
index d22a91073394a..be4a1c2f1d3c4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -81,7 +81,7 @@ dependencies = [
 
 [[package]]
 name = "backtrace"
-version = "0.3.9"
+version = "0.3.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -728,7 +728,7 @@ name = "error-chain"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -736,7 +736,7 @@ name = "error-chain"
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -751,7 +751,7 @@ name = "failure"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2060,7 +2060,7 @@ name = "rustc"
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3380,7 +3380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
 "checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51"
 "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
-"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
+"checksum backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "18b65ea1161bfb2dd6da6fade5edd4dbd08fba85012123dd333d2fd1b90b2782"
 "checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
 "checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a"
 "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf"
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 32f3e573d6845..c1d56865da55c 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -416,6 +416,7 @@ impl<'a> Builder<'a> {
                 test::Rustfmt,
                 test::Miri,
                 test::Clippy,
+                test::CompiletestTest,
                 test::RustdocJS,
                 test::RustdocTheme,
                 // Run bootstrap close to the end as it's unlikely to fail
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index dc061fe5099a5..87d5737e2a0a2 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -429,6 +429,45 @@ impl Step for Miri {
     }
 }
 
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CompiletestTest {
+    stage: u32,
+    host: Interned<String>,
+}
+
+impl Step for CompiletestTest {
+    type Output = ();
+
+    fn should_run(run: ShouldRun) -> ShouldRun {
+        run.path("src/tools/compiletest")
+    }
+
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(CompiletestTest {
+            stage: run.builder.top_stage,
+            host: run.target,
+        });
+    }
+
+    /// Runs `cargo test` for compiletest.
+    fn run(self, builder: &Builder) {
+        let stage = self.stage;
+        let host = self.host;
+        let compiler = builder.compiler(stage, host);
+
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolBootstrap,
+                                                 host,
+                                                 "test",
+                                                 "src/tools/compiletest",
+                                                 SourceType::InTree,
+                                                 &[]);
+
+        try_run(builder, &mut cargo);
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Clippy {
     stage: u32,
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index c7e6af28f9d4f..4f8a3c0240e1a 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -52,8 +52,8 @@ RUN env \
     CXX=arm-linux-gnueabi-g++ CXXFLAGS="-march=armv6 -marm" \
     bash musl.sh arm && \
     env \
-    CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm" \
-    CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm" \
+    CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv6 -marm -mfpu=vfp" \
+    CXX=arm-linux-gnueabihf-g++ CXXFLAGS="-march=armv6 -marm -mfpu=vfp" \
     bash musl.sh armhf && \
     env \
     CC=arm-linux-gnueabihf-gcc CFLAGS="-march=armv7-a" \
diff --git a/src/doc/rustc/src/targets/built-in.md b/src/doc/rustc/src/targets/built-in.md
index 8620346e5b748..2e94ebe345adb 100644
--- a/src/doc/rustc/src/targets/built-in.md
+++ b/src/doc/rustc/src/targets/built-in.md
@@ -6,5 +6,5 @@ the team is supporting directly.
 
 To see the list of built-in targets, you can run `rustc --print target-list`,
 or look at [the API
-docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/#modules).
+docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/index.html#modules).
 Each module there defines a builder for a particular target.
\ No newline at end of file
diff --git a/src/doc/rustc/src/targets/index.md b/src/doc/rustc/src/targets/index.md
index 07e3a79471f5b..3d63d072befe0 100644
--- a/src/doc/rustc/src/targets/index.md
+++ b/src/doc/rustc/src/targets/index.md
@@ -4,7 +4,7 @@
 architecture. The list of *targets* are the possible architectures that you can build for.
 
 To see all the options that you can set with a target, see the docs
-[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_back/target/struct.Target.html).
+[here](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/spec/struct.Target.html).
 
 To compile to a particular target, use the `--target` flag:
 
diff --git a/src/doc/unstable-book/src/language-features/unsized-locals.md b/src/doc/unstable-book/src/language-features/unsized-locals.md
index 1165ab93a1469..edc039f896b2c 100644
--- a/src/doc/unstable-book/src/language-features/unsized-locals.md
+++ b/src/doc/unstable-book/src/language-features/unsized-locals.md
@@ -8,7 +8,7 @@ The tracking issue for this feature is: [#48055]
 
 This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
 
-[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-coercions.md
+[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
 
 ```rust
 #![feature(unsized_locals)]
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index f61e582f7641b..79ca600b4a57f 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -2544,7 +2544,7 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
 /// assert_eq!(actual, expected);
 /// ```
 #[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")]
-pub fn hash<T, S: hash::Hasher>(hashee: *const T, into: &mut S) {
+pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) {
     use hash::Hash;
     hashee.hash(into);
 }
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 7d997a0154600..d213a5c561871 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1095,7 +1095,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             let sp = hir.span(id);
                             // `sp` only covers `T`, change it so that it covers
                             // `T:` when appropriate
-                            let sp = if has_bounds {
+                            let is_impl_trait = bound_kind.to_string().starts_with("impl ");
+                            let sp = if has_bounds && !is_impl_trait {
                                 sp.to(self.tcx
                                     .sess
                                     .source_map()
@@ -1103,7 +1104,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             } else {
                                 sp
                             };
-                            (sp, has_bounds)
+                            (sp, has_bounds, is_impl_trait)
                         })
                     } else {
                         None
@@ -1136,25 +1137,33 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
 
         fn binding_suggestion<'tcx, S: fmt::Display>(
             err: &mut DiagnosticBuilder<'tcx>,
-            type_param_span: Option<(Span, bool)>,
+            type_param_span: Option<(Span, bool, bool)>,
             bound_kind: GenericKind<'tcx>,
             sub: S,
         ) {
-            let consider = &format!(
-                "consider adding an explicit lifetime bound `{}: {}`...",
-                bound_kind, sub
+            let consider = format!(
+                "consider adding an explicit lifetime bound {}",
+                if type_param_span.map(|(_, _, is_impl_trait)| is_impl_trait).unwrap_or(false) {
+                    format!(" `{}` to `{}`...", sub, bound_kind)
+                } else {
+                    format!("`{}: {}`...", bound_kind, sub)
+                },
             );
-            if let Some((sp, has_lifetimes)) = type_param_span {
-                let tail = if has_lifetimes { " + " } else { "" };
-                let suggestion = format!("{}: {}{}", bound_kind, sub, tail);
+            if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span {
+                let suggestion = if is_impl_trait {
+                    format!("{} + {}", bound_kind, sub)
+                } else {
+                    let tail = if has_lifetimes { " + " } else { "" };
+                    format!("{}: {}{}", bound_kind, sub, tail)
+                };
                 err.span_suggestion_short_with_applicability(
                     sp,
-                    consider,
+                    &consider,
                     suggestion,
                     Applicability::MaybeIncorrect, // Issue #41966
                 );
             } else {
-                err.help(consider);
+                err.help(&consider);
             }
         }
 
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 289f693df244d..8b16aafd314d7 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -183,50 +183,14 @@ pub struct EvalError<'tcx> {
 impl<'tcx> EvalError<'tcx> {
     pub fn print_backtrace(&mut self) {
         if let Some(ref mut backtrace) = self.backtrace {
-            eprintln!("{}", print_backtrace(&mut *backtrace));
+            print_backtrace(&mut *backtrace);
         }
     }
 }
 
-fn print_backtrace(backtrace: &mut Backtrace) -> String {
-    use std::fmt::Write;
-
+fn print_backtrace(backtrace: &mut Backtrace) {
     backtrace.resolve();
-
-    let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
-    write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
-    'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
-        if frame.symbols().is_empty() {
-            write!(trace_text, "  {}: no symbols\n", i).unwrap();
-        }
-        let mut first = true;
-        for symbol in frame.symbols() {
-            if first {
-                write!(trace_text, "  {}: ", i).unwrap();
-                first = false;
-            } else {
-                let len = i.to_string().len();
-                write!(trace_text, "  {}  ", " ".repeat(len)).unwrap();
-            }
-            if let Some(name) = symbol.name() {
-                write!(trace_text, "{}\n", name).unwrap();
-            } else {
-                write!(trace_text, "<unknown>\n").unwrap();
-            }
-            write!(trace_text, "           at ").unwrap();
-            if let Some(file_path) = symbol.filename() {
-                write!(trace_text, "{}", file_path.display()).unwrap();
-            } else {
-                write!(trace_text, "<unknown_file>").unwrap();
-            }
-            if let Some(line) = symbol.lineno() {
-                write!(trace_text, ":{}\n", line).unwrap();
-            } else {
-                write!(trace_text, "\n").unwrap();
-            }
-        }
-    }
-    trace_text
+    eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
 }
 
 impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
@@ -238,7 +202,7 @@ impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
 
                 if val == "immediate" {
                     // Print it now
-                    eprintln!("{}", print_backtrace(&mut backtrace));
+                    print_backtrace(&mut backtrace);
                     None
                 } else {
                     Some(Box::new(backtrace))
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index b1e44ea761c86..66364ff88b38d 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -376,7 +376,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
     store.register_removed("resolve_trait_on_defaulted_unit",
         "converted into hard error, see https://github.com/rust-lang/rust/issues/48950");
     store.register_removed("private_no_mangle_fns",
-        "no longer an warning, #[no_mangle] functions always exported");
+        "no longer a warning, #[no_mangle] functions always exported");
     store.register_removed("private_no_mangle_statics",
-        "no longer an warning, #[no_mangle] statics always exported");
+        "no longer a warning, #[no_mangle] statics always exported");
 }
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index d8e8477f3d06b..aef8770bcc69b 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -68,6 +68,7 @@ mod linux_musl_base;
 mod openbsd_base;
 mod netbsd_base;
 mod solaris_base;
+mod uefi_base;
 mod windows_base;
 mod windows_msvc_base;
 mod thumb_base;
@@ -254,12 +255,12 @@ macro_rules! supported_targets {
             }
         }
 
-        pub fn get_targets() -> Box<dyn Iterator<Item=String>> {
-            Box::new(TARGETS.iter().filter_map(|t| -> Option<String> {
+        pub fn get_targets() -> impl Iterator<Item = String> {
+            TARGETS.iter().filter_map(|t| -> Option<String> {
                 load_specific(t)
                     .and(Ok(t.to_string()))
                     .ok()
-            }))
+            })
         }
 
         #[cfg(test)]
@@ -419,6 +420,8 @@ supported_targets! {
     ("aarch64-unknown-none", aarch64_unknown_none),
 
     ("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx),
+
+    ("x86_64-unknown-uefi", x86_64_unknown_uefi),
 }
 
 /// Everything `rustc` knows about how to compile for a specific target.
diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs
new file mode 100644
index 0000000000000..9b0515837600b
--- /dev/null
+++ b/src/librustc_target/spec/uefi_base.rs
@@ -0,0 +1,74 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This defines a base target-configuration for native UEFI systems. The UEFI specification has
+// quite detailed sections on the ABI of all the supported target architectures. In almost all
+// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN
+// documentation.
+// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic
+// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated
+// by the loader if the pre-chosen memory location is already in use.
+// UEFI forbids running code on anything but the boot-CPU. Not interrupts are allowed other than
+// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all
+// code runs in the same environment, no process separation is supported.
+
+use spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions};
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    let mut pre_link_args = LinkArgs::new();
+
+    pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), vec![
+            // Suppress the verbose logo and authorship debugging output, which would needlessly
+            // clog any log files.
+            "/NOLOGO".to_string(),
+
+            // UEFI is fully compatible to non-executable data pages. Tell the compiler that
+            // non-code sections can be marked as non-executable, including stack pages.
+            "/NXCOMPAT".to_string(),
+
+            // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets
+            // must be freestanding.
+            "/nodefaultlib".to_string(),
+
+            // Non-standard subsystems have no default entry-point in PE+ files. We have to define
+            // one. "efi_main" seems to be a common choice amongst other implementations and the
+            // spec.
+            "/entry:efi_main".to_string(),
+
+            // COFF images have a "Subsystem" field in their header, which defines what kind of
+            // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION,
+            // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION,
+            // which is very likely the most common option. Individual projects can override this
+            // with custom linker flags.
+            // The subsystem-type only has minor effects on the application. It defines the memory
+            // regions the application is loaded into (runtime-drivers need to be put into
+            // reserved areas), as well as whether a return from the entry-point is treated as
+            // exit (default for applications).
+            "/subsystem:efi_application".to_string(),
+        ]);
+
+    TargetOptions {
+        dynamic_linking: false,
+        executables: true,
+        disable_redzone: true,
+        exe_suffix: ".efi".to_string(),
+        allows_weak_linkage: false,
+        panic_strategy: PanicStrategy::Abort,
+        singlethread: true,
+        emit_debug_gdb_scripts: false,
+
+        linker: Some("lld-link".to_string()),
+        lld_flavor: LldFlavor::Link,
+        pre_link_args,
+
+        .. Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs
new file mode 100644
index 0000000000000..ea68afa717335
--- /dev/null
+++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs
@@ -0,0 +1,58 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This defines the amd64 target for UEFI systems as described in the UEFI specification. See the
+// uefi-base module for generic UEFI options. On x86_64 systems (mostly called "x64" in the spec)
+// UEFI systems always run in long-mode, have the interrupt-controller pre-configured and force a
+// single-CPU execution.
+// The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
+// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
+
+use spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::uefi_base::opts();
+    base.cpu = "x86-64".to_string();
+    base.max_atomic_width = Some(64);
+
+    // We disable MMX and SSE for now. UEFI does not prevent these from being used, but there have
+    // been reports to GRUB that some firmware does not initialize the FP exception handlers
+    // properly. Therefore, using FP coprocessors will end you up at random memory locations when
+    // you throw FP exceptions.
+    // To be safe, we disable them for now and force soft-float. This can be revisited when we
+    // have more test coverage. Disabling FP served GRUB well so far, so it should be good for us
+    // as well.
+    base.features = "-mmx,-sse,+soft-float".to_string();
+
+    // UEFI systems run without a host OS, hence we cannot assume any code locality. We must tell
+    // LLVM to expect code to reference any address in the address-space. The "large" code-model
+    // places no locality-restrictions, so it fits well here.
+    base.code_model = Some("large".to_string());
+
+    // UEFI mostly mirrors the calling-conventions used on windows. In case of x86-64 this means
+    // small structs will be returned as int. This shouldn't matter much, since the restrictions
+    // placed by the UEFI specifications forbid any ABI to return structures.
+    base.abi_return_struct_as_int = true;
+
+    Ok(Target {
+        llvm_target: "x86_64-unknown-windows".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        target_os: "uefi".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        arch: "x86_64".to_string(),
+        linker_flavor: LinkerFlavor::Lld(LldFlavor::Link),
+
+        options: base,
+    })
+}
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index b76c9101eae02..09063579c4214 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -424,10 +424,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 }
 
                 if !unsatisfied_predicates.is_empty() {
-                    let bound_list = unsatisfied_predicates.iter()
+                    let mut bound_list = unsatisfied_predicates.iter()
                         .map(|p| format!("`{} : {}`", p.self_ty(), p))
-                        .collect::<Vec<_>>()
-                        .join("\n");
+                        .collect::<Vec<_>>();
+                    bound_list.sort();
+                    bound_list.dedup();  // #35677
+                    let bound_list = bound_list.join("\n");
                     err.note(&format!("the method `{}` exists but the following trait bounds \
                                        were not satisfied:\n{}",
                                       item_name,
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index f46c4f2938b99..7e155396b8d5e 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -72,32 +72,32 @@
 //!
 //! * **From Rust to C:** [`CString`] represents an owned, C-friendly
 //! string: it is nul-terminated, and has no internal nul characters.
-//! Rust code can create a `CString` out of a normal string (provided
+//! Rust code can create a [`CString`] out of a normal string (provided
 //! that the string doesn't have nul characters in the middle), and
-//! then use a variety of methods to obtain a raw `*mut u8` that can
+//! then use a variety of methods to obtain a raw `*mut `[`u8`] that can
 //! then be passed as an argument to functions which use the C
 //! conventions for strings.
 //!
 //! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
-//! is what you would use to wrap a raw `*const u8` that you got from
-//! a C function. A `CStr` is guaranteed to be a nul-terminated array
-//! of bytes. Once you have a `CStr`, you can convert it to a Rust
-//! `&str` if it's valid UTF-8, or lossily convert it by adding
+//! is what you would use to wrap a raw `*const `[`u8`] that you got from
+//! a C function. A [`CStr`] is guaranteed to be a nul-terminated array
+//! of bytes. Once you have a [`CStr`], you can convert it to a Rust
+//! [`&str`][`str`] if it's valid UTF-8, or lossily convert it by adding
 //! replacement characters.
 //!
 //! [`OsString`] and [`OsStr`] are useful when you need to transfer
 //! strings to and from the operating system itself, or when capturing
-//! the output of external commands. Conversions between `OsString`,
-//! `OsStr` and Rust strings work similarly to those for [`CString`]
+//! the output of external commands. Conversions between [`OsString`],
+//! [`OsStr`] and Rust strings work similarly to those for [`CString`]
 //! and [`CStr`].
 //!
 //! * [`OsString`] represents an owned string in whatever
 //! representation the operating system prefers. In the Rust standard
 //! library, various APIs that transfer strings to/from the operating
-//! system use `OsString` instead of plain strings. For example,
+//! system use [`OsString`] instead of plain strings. For example,
 //! [`env::var_os()`] is used to query environment variables; it
-//! returns an `Option<OsString>`. If the environment variable exists
-//! you will get a `Some(os_string)`, which you can *then* try to
+//! returns an [`Option`]`<`[`OsString`]`>`. If the environment variable
+//! exists you will get a [`Some`]`(os_string)`, which you can *then* try to
 //! convert to a Rust string. This yields a [`Result<>`], so that
 //! your code can detect errors in case the environment variable did
 //! not in fact contain valid Unicode data.
@@ -105,7 +105,7 @@
 //! * [`OsStr`] represents a borrowed reference to a string in a
 //! format that can be passed to the operating system. It can be
 //! converted into an UTF-8 Rust string slice in a similar way to
-//! `OsString`.
+//! [`OsString`].
 //!
 //! # Conversions
 //!
@@ -131,7 +131,7 @@
 //! Additionally, on Windows [`OsString`] implements the
 //! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
 //! trait, which provides a [`from_wide`] method. The result of this
-//! method is an `OsString` which can be round-tripped to a Windows
+//! method is an [`OsString`] which can be round-tripped to a Windows
 //! string losslessly.
 //!
 //! [`String`]: ../string/struct.String.html
@@ -160,6 +160,8 @@
 //! [`collect`]: ../iter/trait.Iterator.html#method.collect
 //! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
 //! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide
+//! [`Option`]: ../option/enum.Option.html
+//! [`Some`]: ../option/enum.Option.html#variant.Some
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index d581ba1de23f2..edcfdd9e53483 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -195,9 +195,10 @@ pub struct OpenOptions(fs_imp::OpenOptions);
 /// This module only currently provides one bit of information, [`readonly`],
 /// which is exposed on all currently supported platforms. Unix-specific
 /// functionality, such as mode bits, is available through the
-/// `os::unix::PermissionsExt` trait.
+/// [`PermissionsExt`] trait.
 ///
 /// [`readonly`]: struct.Permissions.html#method.readonly
+/// [`PermissionsExt`]: ../os/unix/fs/trait.PermissionsExt.html
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Permissions(fs_imp::FilePermissions);
diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr
index e2630b5b8ce47..ed6b325a01d4d 100644
--- a/src/test/ui/issues/issue-31173.stderr
+++ b/src/test/ui/issues/issue-31173.stderr
@@ -14,8 +14,8 @@ LL |         .collect(); //~ ERROR no method named `collect`
    |          ^^^^^^^
    |
    = note: the method `collect` exists but the following trait bounds were not satisfied:
-           `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
            `&mut std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
+           `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:16:39: 19:6 found_e:_]>> : std::iter::Iterator`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-35677.rs b/src/test/ui/issues/issue-35677.rs
new file mode 100644
index 0000000000000..46d3f7e4af00b
--- /dev/null
+++ b/src/test/ui/issues/issue-35677.rs
@@ -0,0 +1,5 @@
+use std::collections::HashMap;
+fn intersect_map<K, V>(this: &mut HashMap<K, V>, other: HashMap<K, V>) -> bool {
+    this.drain()
+    //~^ ERROR no method named
+}
diff --git a/src/test/ui/issues/issue-35677.stderr b/src/test/ui/issues/issue-35677.stderr
new file mode 100644
index 0000000000000..dca096b93f5f3
--- /dev/null
+++ b/src/test/ui/issues/issue-35677.stderr
@@ -0,0 +1,18 @@
+error[E0601]: `main` function not found in crate `issue_35677`
+   |
+   = note: consider adding a `main` function to `$DIR/issue-35677.rs`
+
+error[E0599]: no method named `drain` found for type `&mut std::collections::HashMap<K, V>` in the current scope
+  --> $DIR/issue-35677.rs:3:10
+   |
+LL |     this.drain()
+   |          ^^^^^
+   |
+   = note: the method `drain` exists but the following trait bounds were not satisfied:
+           `K : std::cmp::Eq`
+           `K : std::hash::Hash`
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0599, E0601.
+For more information about an error, try `rustc --explain E0599`.
diff --git a/src/test/ui/lint/lint-unexported-no-mangle.stderr b/src/test/ui/lint/lint-unexported-no-mangle.stderr
index 063915d5b5f9a..1df2d7babe91b 100644
--- a/src/test/ui/lint/lint-unexported-no-mangle.stderr
+++ b/src/test/ui/lint/lint-unexported-no-mangle.stderr
@@ -1,8 +1,8 @@
-warning: lint `private_no_mangle_fns` has been removed: `no longer an warning, #[no_mangle] functions always exported`
+warning: lint `private_no_mangle_fns` has been removed: `no longer a warning, #[no_mangle] functions always exported`
    |
    = note: requested on the command line with `-F private_no_mangle_fns`
 
-warning: lint `private_no_mangle_statics` has been removed: `no longer an warning, #[no_mangle] statics always exported`
+warning: lint `private_no_mangle_statics` has been removed: `no longer a warning, #[no_mangle] statics always exported`
    |
    = note: requested on the command line with `-F private_no_mangle_statics`
 
diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr
index 86a92a70287e9..1fbac9d688140 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.stderr
+++ b/src/test/ui/mismatched_types/issue-36053-2.stderr
@@ -5,8 +5,8 @@ LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
    |                                                       ^^^^^
    |
    = note: the method `count` exists but the following trait bounds were not satisfied:
-           `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
            `&mut std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
+           `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/issue-36053-2.rs:17:32
diff --git a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
new file mode 100644
index 0000000000000..24676fe5e5bd9
--- /dev/null
+++ b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
@@ -0,0 +1,74 @@
+// This is a collection of examples where a function's formal
+// parameter has an explicit lifetime and a closure within that
+// function returns that formal parameter. The closure's return type,
+// to be correctly inferred, needs to include the lifetime introduced
+// by the function.
+//
+// This works today, which precludes changing things so that closures
+// follow the same lifetime-elision rules used elsehwere. See
+// rust-lang/rust#56537
+
+// compile-pass
+// We are already testing NLL explicitly via the revision system below.
+// ignore-compare-mode-nll
+
+// revisions: ll nll migrate
+//[ll] compile-flags:-Zborrowck=ast
+//[nll] compile-flags:-Zborrowck=mir -Z two-phase-borrows
+//[migrate] compile-flags:-Zborrowck=migrate -Z two-phase-borrows
+
+fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x| { p }; // no type annotation at all
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x| -> &str { p }; // type annotation on the return type
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x| -> &'w str { p }; // type+region annotation on return type
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_arg_type_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x: &str| -> &str { p }; // type annotation on arg and return types
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn willy_arg_type_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str {
+    let free_dumb = |_x: &str| -> &'w str { p }; // fully annotated
+    let hello = format!("Hello");
+    free_dumb(&hello)
+}
+
+fn main() {
+    let world = format!("World");
+    let w1: &str = {
+        let hello = format!("He11o");
+        willy_no_annot(&world, &hello)
+    };
+    let w2: &str = {
+        let hello = format!("He22o");
+        willy_ret_type_annot(&world, &hello)
+    };
+    let w3: &str = {
+        let hello = format!("He33o");
+        willy_ret_region_annot(&world, &hello)
+    };
+    let w4: &str = {
+        let hello = format!("He44o");
+        willy_arg_type_ret_type_annot(&world, &hello)
+    };
+    let w5: &str = {
+        let hello = format!("He55o");
+        willy_arg_type_ret_region_annot(&world, &hello)
+    };
+    assert_eq!((w1, w2, w3, w4, w5),
+               ("World","World","World","World","World"));
+}
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
new file mode 100644
index 0000000000000..8592af1262e6f
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+
+use std::fmt::Debug;
+
+fn foo(d: impl Debug + 'static) {
+//~^ HELP consider adding an explicit lifetime bound  `'static` to `impl Debug`
+    bar(d);
+//~^ ERROR the parameter type `impl Debug` may not live long enough
+//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
+}
+
+fn bar(d: impl Debug + 'static) {
+    println!("{:?}", d)
+}
+
+fn main() {
+  foo("hi");
+}
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
new file mode 100644
index 0000000000000..c67d78ea4c73b
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
@@ -0,0 +1,18 @@
+// run-rustfix
+
+use std::fmt::Debug;
+
+fn foo(d: impl Debug) {
+//~^ HELP consider adding an explicit lifetime bound  `'static` to `impl Debug`
+    bar(d);
+//~^ ERROR the parameter type `impl Debug` may not live long enough
+//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
+}
+
+fn bar(d: impl Debug + 'static) {
+    println!("{:?}", d)
+}
+
+fn main() {
+  foo("hi");
+}
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
new file mode 100644
index 0000000000000..cba231d0e86e5
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
@@ -0,0 +1,19 @@
+error[E0310]: the parameter type `impl Debug` may not live long enough
+  --> $DIR/suggest-impl-trait-lifetime.rs:7:5
+   |
+LL |     bar(d);
+   |     ^^^
+   |
+note: ...so that the type `impl Debug` will meet its required lifetime bounds
+  --> $DIR/suggest-impl-trait-lifetime.rs:7:5
+   |
+LL |     bar(d);
+   |     ^^^
+help: consider adding an explicit lifetime bound  `'static` to `impl Debug`...
+   |
+LL | fn foo(d: impl Debug + 'static) {
+   |           ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 4ade87f5d65bd..a65d263d2e3a3 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -34,6 +34,16 @@
     'rust-by-example': '@steveklabnik @marioidival @projektir',
 }
 
+EMOJI = {
+    'miri': '🛰️',
+    'clippy-driver': '📎',
+    'rls': '💻',
+    'rustfmt': '📝',
+    'book': '📖',
+    'nomicon': '👿',
+    'reference': '📚',
+    'rust-by-example': '👩‍🏫',
+}
 
 def read_current_status(current_commit, path):
     '''Reads build status of `current_commit` from content of `history/*.tsv`
@@ -63,13 +73,12 @@ def update_latest(
         }
 
         slug = 'rust-lang/rust'
-        message = textwrap.dedent('''\
-            📣 Toolstate changed by {}!
-
+        long_message = textwrap.dedent('''\
             Tested on commit {}@{}.
             Direct link to PR: <{}>
 
-        ''').format(relevant_pr_number, slug, current_commit, relevant_pr_url)
+        ''').format(slug, current_commit, relevant_pr_url)
+        emoji_status = []
         anything_changed = False
         for status in latest:
             tool = status['tool']
@@ -81,12 +90,18 @@ def update_latest(
                 status[os] = new
                 if new > old:
                     changed = True
-                    message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
-                        .format(tool, os, old, new, MAINTAINERS.get(tool))
+                    long_message += '🎉 {} on {}: {} → {}.\n' \
+                        .format(tool, os, old, new)
+                    emoji = "{}🎉".format(EMOJI.get(tool))
+                    if msg not in emoji_status:
+                        emoji_status += [msg]
                 elif new < old:
                     changed = True
-                    message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
+                    long_message += '💔 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
                         .format(tool, os, old, new, MAINTAINERS.get(tool))
+                    emoji = "{}💔".format(EMOJI.get(tool))
+                    if msg not in emoji_status:
+                        emoji_status += [msg]
 
             if changed:
                 status['commit'] = current_commit
@@ -96,6 +111,9 @@ def update_latest(
         if not anything_changed:
             return ''
 
+        short_message = "📣 Toolstate changed by {}! ({})"
+            .format(relevant_pr_number, '/'.join(emoji_status))
+        message = short_message + "\n\n" + long_message
         f.seek(0)
         f.truncate(0)
         json.dump(latest, f, indent=4, separators=(',', ': '))