about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/builder.rs5
-rw-r--r--src/bootstrap/check.rs29
-rw-r--r--src/bootstrap/compile.rs10
-rw-r--r--src/bootstrap/doc.rs5
-rw-r--r--src/bootstrap/lib.rs19
-rw-r--r--src/bootstrap/test.rs6
-rw-r--r--src/bootstrap/tool.rs19
-rw-r--r--src/doc/unstable-book/src/library-features/asm.md8
-rw-r--r--src/liballoc/benches/lib.rs3
-rw-r--r--src/libcore/slice/mod.rs2
-rw-r--r--src/librustc_ast/ast.rs2
-rw-r--r--src/librustc_ast/attr/mod.rs2
-rw-r--r--src/librustc_ast/mut_visit.rs4
-rw-r--r--src/librustc_ast/token.rs31
-rw-r--r--src/librustc_ast/util/literal.rs2
-rw-r--r--src/librustc_ast/util/parser.rs2
-rw-r--r--src/librustc_ast_lowering/expr.rs1
-rw-r--r--src/librustc_ast_lowering/lib.rs4
-rw-r--r--src/librustc_ast_passes/ast_validation.rs6
-rw-r--r--src/librustc_ast_pretty/pprust.rs4
-rw-r--r--src/librustc_builtin_macros/deriving/mod.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs12
-rw-r--r--src/librustc_codegen_llvm/debuginfo/mod.rs6
-rw-r--r--src/librustc_codegen_llvm/llvm_util.rs4
-rw-r--r--src/librustc_errors/emitter.rs10
-rw-r--r--src/librustc_expand/base.rs6
-rw-r--r--src/librustc_expand/mbe/macro_parser.rs10
-rw-r--r--src/librustc_expand/mbe/transcribe.rs7
-rw-r--r--src/librustc_expand/proc_macro.rs4
-rw-r--r--src/librustc_expand/proc_macro_server.rs38
-rw-r--r--src/librustc_llvm/build.rs6
-rw-r--r--src/librustc_middle/Cargo.toml2
-rw-r--r--src/librustc_middle/traits/chalk.rs2
-rw-r--r--src/librustc_middle/ty/subst.rs2
-rw-r--r--src/librustc_parse/parser/attr.rs4
-rw-r--r--src/librustc_parse/parser/expr.rs2
-rw-r--r--src/librustc_parse/parser/generics.rs6
-rw-r--r--src/librustc_parse/parser/item.rs2
-rw-r--r--src/librustc_parse/parser/mod.rs6
-rw-r--r--src/librustc_parse/parser/pat.rs2
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs2
-rw-r--r--src/librustc_resolve/def_collector.rs2
-rw-r--r--src/librustc_resolve/late.rs6
-rw-r--r--src/librustc_target/asm/arm.rs40
-rw-r--r--src/librustc_target/asm/mod.rs35
-rw-r--r--src/librustc_target/asm/riscv.rs2
-rw-r--r--src/librustc_target/asm/x86.rs3
-rw-r--r--src/librustc_trait_selection/traits/chalk_fulfill.rs15
-rw-r--r--src/librustc_traits/Cargo.toml4
-rw-r--r--src/librustc_traits/chalk/db.rs180
-rw-r--r--src/librustc_traits/chalk/lowering.rs42
-rw-r--r--src/librustc_traits/chalk/mod.rs1
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/utils.rs4
-rw-r--r--src/librustdoc/doctree.rs2
-rw-r--r--src/librustdoc/html/static/main.js2
-rw-r--r--src/librustdoc/test.rs18
-rw-r--r--src/librustdoc/visit_ast.rs43
-rw-r--r--src/test/codegen/debug-linkage-name.rs42
-rw-r--r--src/test/ui/chalkify/closure.rs39
-rw-r--r--src/test/ui/chalkify/closure.stderr18
-rw-r--r--src/test/ui/chalkify/impl_wf.rs7
-rw-r--r--src/test/ui/chalkify/impl_wf.stderr15
-rw-r--r--src/test/ui/chalkify/inherent_impl.rs17
-rw-r--r--src/test/ui/chalkify/recursive_where_clause_on_type.rs11
-rw-r--r--src/test/ui/chalkify/recursive_where_clause_on_type.stderr16
-rw-r--r--src/tools/build-manifest/src/main.rs2
-rw-r--r--src/tools/cargotest/main.rs2
-rwxr-xr-xsrc/tools/clippy/clippy_lints/src/utils/ast_utils.rs2
-rw-r--r--src/tools/compiletest/src/main.rs1
-rw-r--r--src/tools/error_index_generator/main.rs1
-rw-r--r--src/tools/expand-yaml-anchors/src/main.rs4
-rw-r--r--src/tools/linkchecker/main.rs2
-rw-r--r--src/tools/remote-test-client/src/main.rs2
-rw-r--r--src/tools/remote-test-server/src/main.rs2
-rw-r--r--src/tools/tidy/src/main.rs2
-rw-r--r--src/tools/tidy/src/pal.rs1
-rw-r--r--src/tools/unstable-book-gen/src/main.rs2
78 files changed, 603 insertions, 285 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 8f0a245a565..0735ba8869a 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -23,7 +23,7 @@ use crate::install;
 use crate::native;
 use crate::run;
 use crate::test;
-use crate::tool;
+use crate::tool::{self, SourceType};
 use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir};
 use crate::{Build, DocTests, GitRepo, Mode};
 
@@ -759,6 +759,7 @@ impl<'a> Builder<'a> {
         &self,
         compiler: Compiler,
         mode: Mode,
+        source_type: SourceType,
         target: Interned<String>,
         cmd: &str,
     ) -> Cargo {
@@ -1125,7 +1126,7 @@ impl<'a> Builder<'a> {
 
         cargo.env("RUSTC_VERBOSE", self.verbosity.to_string());
 
-        if !mode.is_tool() {
+        if source_type == SourceType::InTree {
             // When extending this list, add the new lints to the RUSTFLAGS of the
             // build_bootstrap function of src/bootstrap/bootstrap.py as well as
             // some code doesn't go through this `rustc` wrapper.
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 7a8bfb2d5d8..0d38d2eebe7 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -44,7 +44,13 @@ impl Step for Std {
         let target = self.target;
         let compiler = builder.compiler(0, builder.config.build);
 
-        let mut cargo = builder.cargo(compiler, Mode::Std, target, cargo_subcommand(builder.kind));
+        let mut cargo = builder.cargo(
+            compiler,
+            Mode::Std,
+            SourceType::InTree,
+            target,
+            cargo_subcommand(builder.kind),
+        );
         std_cargo(builder, target, compiler.stage, &mut cargo);
 
         builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
@@ -92,8 +98,13 @@ impl Step for Rustc {
 
         builder.ensure(Std { target });
 
-        let mut cargo =
-            builder.cargo(compiler, Mode::Rustc, target, cargo_subcommand(builder.kind));
+        let mut cargo = builder.cargo(
+            compiler,
+            Mode::Rustc,
+            SourceType::InTree,
+            target,
+            cargo_subcommand(builder.kind),
+        );
         rustc_cargo(builder, &mut cargo, target);
 
         builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
@@ -113,7 +124,7 @@ impl Step for Rustc {
 }
 
 macro_rules! tool_check_step {
-    ($name:ident, $path:expr) => {
+    ($name:ident, $path:expr, $source_type:expr) => {
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub struct $name {
             pub target: Interned<String>,
@@ -145,7 +156,7 @@ macro_rules! tool_check_step {
                     target,
                     cargo_subcommand(builder.kind),
                     $path,
-                    SourceType::InTree,
+                    $source_type,
                     &[],
                 );
 
@@ -184,8 +195,12 @@ macro_rules! tool_check_step {
     };
 }
 
-tool_check_step!(Rustdoc, "src/tools/rustdoc");
-tool_check_step!(Clippy, "src/tools/clippy");
+tool_check_step!(Rustdoc, "src/tools/rustdoc", SourceType::InTree);
+// Clippy is a hybrid. It is an external tool, but uses a git subtree instead
+// of a submodule. Since the SourceType only drives the deny-warnings
+// behavior, treat it as in-tree so that any new warnings in clippy will be
+// rejected.
+tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);
 
 /// Cargo's output path for the standard library in a given stage, compiled
 /// by a particular compiler for the specified target.
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index afcf0dcac7e..0208dc8ba5e 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -20,14 +20,14 @@ use filetime::FileTime;
 use serde::Deserialize;
 
 use crate::builder::Cargo;
+use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
+use crate::cache::{Interned, INTERNER};
 use crate::dist;
 use crate::native;
+use crate::tool::SourceType;
 use crate::util::{exe, is_dylib, symlink_dir};
 use crate::{Compiler, DependencyType, GitRepo, Mode};
 
-use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
-use crate::cache::{Interned, INTERNER};
-
 #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Std {
     pub target: Interned<String>,
@@ -87,7 +87,7 @@ impl Step for Std {
         target_deps.extend(copy_third_party_objects(builder, &compiler, target));
         target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
 
-        let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build");
         std_cargo(builder, target, compiler.stage, &mut cargo);
 
         builder.info(&format!(
@@ -513,7 +513,7 @@ impl Step for Rustc {
             target: builder.config.build,
         });
 
-        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "build");
         rustc_cargo(builder, &mut cargo, target);
 
         builder.info(&format!(
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 6d7fb7acfcb..8b76158f9e5 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -435,7 +435,8 @@ impl Step for Std {
         t!(fs::copy(builder.src.join("src/doc/rust.css"), out.join("rust.css")));
 
         let run_cargo_rustdoc_for = |package: &str| {
-            let mut cargo = builder.cargo(compiler, Mode::Std, target, "rustdoc");
+            let mut cargo =
+                builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc");
             compile::std_cargo(builder, target, compiler.stage, &mut cargo);
 
             // Keep a whitelist so we do not build internal stdlib crates, these will be
@@ -534,7 +535,7 @@ impl Step for Rustc {
         t!(symlink_dir_force(&builder.config, &out, &out_dir));
 
         // Build cargo command.
-        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "doc");
         cargo.env(
             "RUSTDOCFLAGS",
             "--document-private-items \
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index e7aeb08643c..5728b9d24de 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -301,16 +301,21 @@ pub enum Mode {
     /// Build codegen libraries, placing output in the "stageN-codegen" directory
     Codegen,
 
-    /// Build some tools, placing output in the "stageN-tools" directory. The
-    /// "other" here is for miscellaneous sets of tools that are built using the
-    /// bootstrap compiler in its entirety (target libraries and all).
-    /// Typically these tools compile with stable Rust.
+    /// Build a tool, placing output in the "stage0-bootstrap-tools"
+    /// directory. This is for miscellaneous sets of tools that are built
+    /// using the bootstrap stage0 compiler in its entirety (target libraries
+    /// and all). Typically these tools compile with stable Rust.
     ToolBootstrap,
 
-    /// Compile a tool which uses all libraries we compile (up to rustc).
-    /// Doesn't use the stage0 compiler libraries like "other", and includes
-    /// tools like rustdoc, cargo, rls, etc.
+    /// Build a tool which uses the locally built std, placing output in the
+    /// "stageN-tools" directory. Its usage is quite rare, mainly used by
+    /// compiletest which needs libtest.
     ToolStd,
+
+    /// Build a tool which uses the locally built rustc and the target std,
+    /// placing the output in the "stageN-tools" directory. This is used for
+    /// anything that needs a fully functional rustc, such as rustdoc, clippy,
+    /// cargo, rls, rustfmt, miri, etc.
     ToolRustc,
 }
 
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index bb35203c826..12ab6b1636c 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -367,7 +367,8 @@ impl Step for Miri {
             extra_features: Vec::new(),
         });
         if let (Some(miri), Some(_cargo_miri)) = (miri, cargo_miri) {
-            let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "install");
+            let mut cargo =
+                builder.cargo(compiler, Mode::ToolRustc, SourceType::Submodule, host, "install");
             cargo.arg("xargo");
             // Configure `cargo install` path. cargo adds a `bin/`.
             cargo.env("CARGO_INSTALL_ROOT", &builder.out);
@@ -1696,7 +1697,8 @@ impl Step for Crate {
         // we're working with automatically.
         let compiler = builder.compiler_for(compiler.stage, compiler.host, target);
 
-        let mut cargo = builder.cargo(compiler, mode, target, test_kind.subcommand());
+        let mut cargo =
+            builder.cargo(compiler, mode, SourceType::InTree, target, test_kind.subcommand());
         match mode {
             Mode::Std => {
                 compile::std_cargo(builder, target, compiler.stage, &mut cargo);
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index c92082a9423..0055dee6092 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -16,7 +16,7 @@ use crate::util::{add_dylib_path, exe, CiEnv};
 use crate::Compiler;
 use crate::Mode;
 
-#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub enum SourceType {
     InTree,
     Submodule,
@@ -226,14 +226,10 @@ pub fn prepare_tool_cargo(
     source_type: SourceType,
     extra_features: &[String],
 ) -> CargoCommand {
-    let mut cargo = builder.cargo(compiler, mode, target, command);
+    let mut cargo = builder.cargo(compiler, mode, source_type, target, command);
     let dir = builder.src.join(path);
     cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
 
-    if source_type == SourceType::Submodule {
-        cargo.env("RUSTC_EXTERNAL_TOOL", "1");
-    }
-
     let mut features = extra_features.to_vec();
     if builder.build.config.cargo_native_static {
         if path.ends_with("cargo")
@@ -596,6 +592,7 @@ macro_rules! tool_extended {
        $path:expr,
        $tool_name:expr,
        stable = $stable:expr,
+       $(in_tree = $in_tree:expr,)*
        $extra_deps:block;)+) => {
         $(
             #[derive(Debug, Clone, Hash, PartialEq, Eq)]
@@ -647,7 +644,11 @@ macro_rules! tool_extended {
                     path: $path,
                     extra_features: $sel.extra_features,
                     is_optional_tool: true,
-                    source_type: SourceType::Submodule,
+                    source_type: if false $(|| $in_tree)* {
+                        SourceType::InTree
+                    } else {
+                        SourceType::Submodule
+                    },
                 })
             }
         }
@@ -659,8 +660,8 @@ macro_rules! tool_extended {
 // to make `./x.py build <tool>` work.
 tool_extended!((self, builder),
     Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", stable=true, {};
-    CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, {};
-    Clippy, clippy, "src/tools/clippy", "clippy-driver", stable=true, {};
+    CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
+    Clippy, clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {};
     Miri, miri, "src/tools/miri", "miri", stable=false, {};
     CargoMiri, miri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {};
     Rls, rls, "src/tools/rls", "rls", stable=true, {
diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md
index a941bc9348f..c4c985dd134 100644
--- a/src/doc/unstable-book/src/library-features/asm.md
+++ b/src/doc/unstable-book/src/library-features/asm.md
@@ -474,7 +474,7 @@ Here is the list of currently supported register classes:
 | AArch64 | `reg` | `x[0-28]`, `x30` | `r` |
 | AArch64 | `vreg` | `v[0-31]` | `w` |
 | AArch64 | `vreg_low16` | `v[0-15]` | `x` |
-| ARM | `reg` | `r[0-r10]`, `r12`, `r14` | `r` |
+| ARM | `reg` | `r[0-5]` `r7`\*, `r[8-10]`, `r11`\*, `r12`, `r14` | `r` |
 | ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` |
 | ARM (ARM) | `reg_thumb` | `r[0-r10]`, `r12`, `r14` | `l` |
 | ARM | `sreg` | `s[0-31]` | `t` |
@@ -497,6 +497,8 @@ Here is the list of currently supported register classes:
 > Note #2: On x86-64 the high byte registers (e.g. `ah`) are only available when used as an explicit register. Specifying the `reg_byte` register class for an operand will always allocate a low byte register.
 >
 > Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported.
+>
+> Note #4: On ARM the frame pointer is either `r7` or `r11` depending on the platform.
 
 Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc).
 
@@ -591,7 +593,9 @@ Some registers cannot be used for input or output operands:
 | Architecture | Unsupported register | Reason |
 | ------------ | -------------------- | ------ |
 | All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. |
-| All | `bp` (x86), `r11` (ARM), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon) | The frame pointer cannot be used as an input or output. |
+| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon) | The frame pointer cannot be used as an input or output. |
+| ARM | `r7` or `r11` | On ARM the frame pointer can be either `r7` or `r11` depending on the target. The frame pointer cannot be used as an input or output. |
+| ARM | `r6` | `r6` is used internally by LLVM as a base pointer and therefore cannot be used as an input or output. |
 | x86 | `k0` | This is a constant zero register which can't be modified. |
 | x86 | `ip` | This is the program counter, not a real register. |
 | x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). |
diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs
index f31717d9fd5..608eafc88d2 100644
--- a/src/liballoc/benches/lib.rs
+++ b/src/liballoc/benches/lib.rs
@@ -1,3 +1,6 @@
+// Disabling on android for the time being
+// See https://github.com/rust-lang/rust/issues/73535#event-3477699747
+#![cfg(not(target_os = "android"))]
 #![feature(btree_drain_filter)]
 #![feature(map_first_last)]
 #![feature(repr_simd)]
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index c69aafe687c..57bacdd99ef 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -2817,6 +2817,7 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
     /// performing any bounds checking.
     /// Calling this method with an out-of-bounds index is *[undefined behavior]*
     /// even if the resulting reference is not used.
+    ///
     /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
     #[unstable(feature = "slice_index_methods", issue = "none")]
     unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
@@ -2825,6 +2826,7 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
     /// performing any bounds checking.
     /// Calling this method with an out-of-bounds index is *[undefined behavior]*
     /// even if the resulting reference is not used.
+    ///
     /// [undefined behavior]: ../../reference/behavior-considered-undefined.html
     #[unstable(feature = "slice_index_methods", issue = "none")]
     unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs
index e98d709539d..99fbb1ee3ea 100644
--- a/src/librustc_ast/ast.rs
+++ b/src/librustc_ast/ast.rs
@@ -335,6 +335,8 @@ pub enum GenericParamKind {
     },
     Const {
         ty: P<Ty>,
+        /// Span of the `const` keyword.
+        kw_span: Span,
     },
 }
 
diff --git a/src/librustc_ast/attr/mod.rs b/src/librustc_ast/attr/mod.rs
index b812f2dadf6..6c128f0176f 100644
--- a/src/librustc_ast/attr/mod.rs
+++ b/src/librustc_ast/attr/mod.rs
@@ -475,7 +475,7 @@ impl MetaItem {
                 let span = span.with_hi(segments.last().unwrap().ident.span.hi());
                 Path { span, segments }
             }
-            Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
+            Some(TokenTree::Token(Token { kind: token::Interpolated(nt, _), .. })) => match *nt {
                 token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
                 token::Nonterminal::NtPath(ref path) => path.clone(),
                 _ => return None,
diff --git a/src/librustc_ast/mut_visit.rs b/src/librustc_ast/mut_visit.rs
index 2ffef9d48c1..3fd2815daa1 100644
--- a/src/librustc_ast/mut_visit.rs
+++ b/src/librustc_ast/mut_visit.rs
@@ -656,7 +656,7 @@ pub fn noop_visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
             *span = ident.span;
             return; // Avoid visiting the span for the second time.
         }
-        token::Interpolated(nt) => {
+        token::Interpolated(nt, _) => {
             let mut nt = Lrc::make_mut(nt);
             vis.visit_interpolated(&mut nt);
         }
@@ -762,7 +762,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
         GenericParamKind::Type { default } => {
             visit_opt(default, |default| vis.visit_ty(default));
         }
-        GenericParamKind::Const { ty } => {
+        GenericParamKind::Const { ty, kw_span: _ } => {
             vis.visit_ty(ty);
         }
     }
diff --git a/src/librustc_ast/token.rs b/src/librustc_ast/token.rs
index a5b9c2a95bb..89be3e6e212 100644
--- a/src/librustc_ast/token.rs
+++ b/src/librustc_ast/token.rs
@@ -182,6 +182,15 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool {
             .contains(&name)
 }
 
+/// A hack used to pass AST fragments to attribute and derive macros
+/// as a single nonterminal token instead of a token stream.
+/// FIXME: It needs to be removed, but there are some compatibility issues (see #73345).
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
+pub enum FlattenGroup {
+    Yes,
+    No,
+}
+
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
 pub enum TokenKind {
     /* Expression-operator symbols. */
@@ -236,7 +245,7 @@ pub enum TokenKind {
     /// treat regular and interpolated lifetime identifiers in the same way.
     Lifetime(Symbol),
 
-    Interpolated(Lrc<Nonterminal>),
+    Interpolated(Lrc<Nonterminal>, FlattenGroup),
 
     // Can be expanded into several tokens.
     /// A doc comment.
@@ -343,7 +352,7 @@ impl Token {
     /// if they keep spans or perform edition checks.
     pub fn uninterpolated_span(&self) -> Span {
         match &self.kind {
-            Interpolated(nt) => nt.span(),
+            Interpolated(nt, _) => nt.span(),
             _ => self.span,
         }
     }
@@ -382,7 +391,7 @@ impl Token {
             ModSep                            | // global path
             Lifetime(..)                      | // labeled loop
             Pound                             => true, // expression attributes
-            Interpolated(ref nt) => match **nt {
+            Interpolated(ref nt, _) => match **nt {
                 NtLiteral(..) |
                 NtExpr(..)    |
                 NtBlock(..)   |
@@ -408,7 +417,7 @@ impl Token {
             Lifetime(..)                | // lifetime bound in trait object
             Lt | BinOp(Shl)             | // associated path
             ModSep                      => true, // global path
-            Interpolated(ref nt) => match **nt {
+            Interpolated(ref nt, _) => match **nt {
                 NtTy(..) | NtPath(..) => true,
                 _ => false,
             },
@@ -420,7 +429,7 @@ impl Token {
     pub fn can_begin_const_arg(&self) -> bool {
         match self.kind {
             OpenDelim(Brace) => true,
-            Interpolated(ref nt) => match **nt {
+            Interpolated(ref nt, _) => match **nt {
                 NtExpr(..) | NtBlock(..) | NtLiteral(..) => true,
                 _ => false,
             },
@@ -455,7 +464,7 @@ impl Token {
         match self.uninterpolate().kind {
             Literal(..) | BinOp(Minus) => true,
             Ident(name, false) if name.is_bool_lit() => true,
-            Interpolated(ref nt) => match &**nt {
+            Interpolated(ref nt, _) => match &**nt {
                 NtLiteral(_) => true,
                 NtExpr(e) => match &e.kind {
                     ast::ExprKind::Lit(_) => true,
@@ -476,7 +485,7 @@ impl Token {
     // otherwise returns the original token.
     pub fn uninterpolate(&self) -> Cow<'_, Token> {
         match &self.kind {
-            Interpolated(nt) => match **nt {
+            Interpolated(nt, _) => match **nt {
                 NtIdent(ident, is_raw) => {
                     Cow::Owned(Token::new(Ident(ident.name, is_raw), ident.span))
                 }
@@ -523,7 +532,7 @@ impl Token {
 
     /// Returns `true` if the token is an interpolated path.
     fn is_path(&self) -> bool {
-        if let Interpolated(ref nt) = self.kind {
+        if let Interpolated(ref nt, _) = self.kind {
             if let NtPath(..) = **nt {
                 return true;
             }
@@ -535,7 +544,7 @@ impl Token {
     /// That is, is this a pre-parsed expression dropped into the token stream
     /// (which happens while parsing the result of macro expansion)?
     pub fn is_whole_expr(&self) -> bool {
-        if let Interpolated(ref nt) = self.kind {
+        if let Interpolated(ref nt, _) = self.kind {
             if let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtIdent(..) | NtBlock(_) = **nt {
                 return true;
             }
@@ -546,7 +555,7 @@ impl Token {
 
     // Is the token an interpolated block (`$b:block`)?
     pub fn is_whole_block(&self) -> bool {
-        if let Interpolated(ref nt) = self.kind {
+        if let Interpolated(ref nt, _) = self.kind {
             if let NtBlock(..) = **nt {
                 return true;
             }
@@ -724,7 +733,7 @@ impl Token {
                 b == d && (a == c || a == kw::DollarCrate || c == kw::DollarCrate)
             }
 
-            (&Interpolated(_), &Interpolated(_)) => false,
+            (&Interpolated(..), &Interpolated(..)) => false,
 
             _ => panic!("forgot to add a token?"),
         }
diff --git a/src/librustc_ast/util/literal.rs b/src/librustc_ast/util/literal.rs
index 4428d09902b..ea59f867c59 100644
--- a/src/librustc_ast/util/literal.rs
+++ b/src/librustc_ast/util/literal.rs
@@ -205,7 +205,7 @@ impl Lit {
                 token::Lit::new(token::Bool, name, None)
             }
             token::Literal(lit) => lit,
-            token::Interpolated(ref nt) => {
+            token::Interpolated(ref nt, _) => {
                 if let token::NtExpr(expr) | token::NtLiteral(expr) = &**nt {
                     if let ast::ExprKind::Lit(lit) = &expr.kind {
                         return Ok(lit.clone());
diff --git a/src/librustc_ast/util/parser.rs b/src/librustc_ast/util/parser.rs
index d8b44a22f2c..e5bcc571d41 100644
--- a/src/librustc_ast/util/parser.rs
+++ b/src/librustc_ast/util/parser.rs
@@ -5,7 +5,7 @@ use rustc_span::symbol::kw;
 /// Associative operator with precedence.
 ///
 /// This is the enum which specifies operator precedence and fixity to the parser.
-#[derive(PartialEq, Debug)]
+#[derive(Copy, Clone, PartialEq, Debug)]
 pub enum AssocOp {
     /// `+`
     Add,
diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs
index b7894eb145b..d2c4478ccfe 100644
--- a/src/librustc_ast_lowering/expr.rs
+++ b/src/librustc_ast_lowering/expr.rs
@@ -1001,6 +1001,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             asm::InlineAsmReg::parse(
                                 sess.asm_arch?,
                                 |feature| sess.target_features.contains(&Symbol::intern(feature)),
+                                &sess.target.target,
                                 s,
                             )
                             .map_err(|e| {
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 39b14ac4588..863f525bdc8 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -1027,7 +1027,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
     fn lower_token(&mut self, token: Token) -> TokenStream {
         match token.kind {
-            token::Interpolated(nt) => {
+            token::Interpolated(nt, _) => {
                 let tts = (self.nt_to_tokenstream)(&nt, &self.sess.parse_sess, token.span);
                 self.lower_token_stream(tts)
             }
@@ -2230,7 +2230,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
                 (hir::ParamName::Plain(param.ident), kind)
             }
-            GenericParamKind::Const { ref ty } => {
+            GenericParamKind::Const { ref ty, kw_span: _ } => {
                 let ty = self
                     .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
                         this.lower_ty(&ty, ImplTraitContext::disallowed())
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index 8eb125e4440..975881d9a0a 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -1135,9 +1135,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             generics.params.iter().map(|param| {
                 let ident = Some(param.ident.to_string());
                 let (kind, ident) = match &param.kind {
-                    GenericParamKind::Lifetime { .. } => (ParamKindOrd::Lifetime, ident),
-                    GenericParamKind::Type { .. } => (ParamKindOrd::Type, ident),
-                    GenericParamKind::Const { ref ty } => {
+                    GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident),
+                    GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident),
+                    GenericParamKind::Const { ref ty, kw_span: _ } => {
                         let ty = pprust::ty_to_string(ty);
                         (ParamKindOrd::Const, Some(format!("const {}: {}", param.ident, ty)))
                     }
diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs
index b1abc08aa67..86faa1f086c 100644
--- a/src/librustc_ast_pretty/pprust.rs
+++ b/src/librustc_ast_pretty/pprust.rs
@@ -266,7 +266,7 @@ fn token_kind_to_string_ext(tok: &TokenKind, convert_dollar_crate: Option<Span>)
         token::Shebang(s) => format!("/* shebang: {}*/", s),
         token::Unknown(s) => s.to_string(),
 
-        token::Interpolated(ref nt) => nonterminal_to_string(nt),
+        token::Interpolated(ref nt, _) => nonterminal_to_string(nt),
     }
 }
 
@@ -2578,7 +2578,7 @@ impl<'a> State<'a> {
                         s.print_type(default)
                     }
                 }
-                ast::GenericParamKind::Const { ref ty } => {
+                ast::GenericParamKind::Const { ref ty, kw_span: _ } => {
                     s.word_space("const");
                     s.print_ident(param.ident);
                     s.s.space();
diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs
index 9660cade382..dc21be3b296 100644
--- a/src/librustc_builtin_macros/deriving/mod.rs
+++ b/src/librustc_builtin_macros/deriving/mod.rs
@@ -123,7 +123,7 @@ fn inject_impl_of_structural_trait(
                 *default = None;
                 ast::GenericArg::Type(cx.ty_ident(span, param.ident))
             }
-            ast::GenericParamKind::Const { ty: _ } => {
+            ast::GenericParamKind::Const { ty: _, kw_span: _ } => {
                 ast::GenericArg::Const(cx.const_ident(span, param.ident))
             }
         })
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 33351c06d27..dab85b8fb86 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::ich::NodeIdHashingMode;
-use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::truncate;
 use rustc_middle::mir::{self, Field, GeneratorLayout};
 use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout};
@@ -2382,9 +2381,7 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
     }
 
     let tcx = cx.tcx;
-    let attrs = tcx.codegen_fn_attrs(def_id);
 
-    let no_mangle = attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE);
     // We may want to remove the namespace scope if we're in an extern block (see
     // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952).
     let var_scope = get_namespace_for_item(cx, def_id);
@@ -2401,14 +2398,11 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
     let variable_type = Instance::mono(cx.tcx, def_id).monomorphic_ty(cx.tcx);
     let type_metadata = type_metadata(cx, variable_type, span);
     let var_name = tcx.item_name(def_id).as_str();
-    let linkage_name = if no_mangle {
-        None
-    } else {
-        Some(mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name.as_str())
-    };
+    let linkage_name: &str =
+        &mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name.as_str();
     // When empty, linkage_name field is omitted,
     // which is what we want for no_mangle statics
-    let linkage_name = linkage_name.as_deref().unwrap_or("");
+    let linkage_name = if var_name == linkage_name { "" } else { linkage_name };
 
     let global_align = cx.align_of(variable_type);
 
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 8c580847ef8..b5434298805 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -267,9 +267,9 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         let substs = instance.substs.truncate_to(self.tcx(), generics);
         let template_parameters = get_template_parameters(self, &generics, substs, &mut name);
 
-        // Get the linkage_name, which is just the symbol name
-        let linkage_name = mangled_name_of_instance(self, instance);
-        let linkage_name = linkage_name.name.as_str();
+        let linkage_name: &str = &mangled_name_of_instance(self, instance).name.as_str();
+        // Omit the linkage_name if it is the same as subprogram name.
+        let linkage_name = if &name == linkage_name { "" } else { linkage_name };
 
         // FIXME(eddyb) does this need to be separate from `loc.line` for some reason?
         let scope_line = loc.line;
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 67a2251e859..80278bb9f53 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -156,6 +156,10 @@ const ARM_WHITELIST: &[(&str, Option<Symbol>)] = &[
     ("vfp2", Some(sym::arm_target_feature)),
     ("vfp3", Some(sym::arm_target_feature)),
     ("vfp4", Some(sym::arm_target_feature)),
+    // This is needed for inline assembly, but shouldn't be stabilized as-is
+    // since it should be enabled per-function using #[instruction_set], not
+    // #[target_feature].
+    ("thumb-mode", Some(sym::arm_target_feature)),
 ];
 
 const AARCH64_WHITELIST: &[(&str, Option<Symbol>)] = &[
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index b22da86c091..1362a1155bc 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -31,6 +31,9 @@ use std::path::Path;
 use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream};
 use termcolor::{Buffer, Color, WriteColor};
 
+/// Default column width, used in tests and when terminal dimensions cannot be determined.
+const DEFAULT_COLUMN_WIDTH: usize = 140;
+
 /// Describes the way the content of the `rendered` field of the json output is generated
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum HumanReadableErrorType {
@@ -74,7 +77,8 @@ struct Margin {
     pub computed_left: usize,
     /// The end of the line to be displayed.
     pub computed_right: usize,
-    /// The current width of the terminal. 140 by default and in tests.
+    /// The current width of the terminal. Uses value of `DEFAULT_COLUMN_WIDTH` constant by default
+    /// and in tests.
     pub column_width: usize,
     /// The end column of a span label, including the span. Doesn't account for labels not in the
     /// same line as the span.
@@ -1414,11 +1418,11 @@ impl EmitterWriter {
                 let column_width = if let Some(width) = self.terminal_width {
                     width.saturating_sub(code_offset)
                 } else if self.ui_testing {
-                    140
+                    DEFAULT_COLUMN_WIDTH
                 } else {
                     termize::dimensions()
                         .map(|(w, _)| w.saturating_sub(code_offset))
-                        .unwrap_or(usize::MAX)
+                        .unwrap_or(DEFAULT_COLUMN_WIDTH)
                 };
 
                 let margin = Margin::new(
diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs
index a57ae798ffc..d4c756c9ec7 100644
--- a/src/librustc_expand/base.rs
+++ b/src/librustc_expand/base.rs
@@ -4,7 +4,7 @@ use crate::module::DirectoryOwnership;
 use rustc_ast::ast::{self, Attribute, NodeId, PatKind};
 use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::ptr::P;
-use rustc_ast::token;
+use rustc_ast::token::{self, FlattenGroup};
 use rustc_ast::tokenstream::{self, TokenStream, TokenTree};
 use rustc_ast::visit::{AssocCtxt, Visitor};
 use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
@@ -142,7 +142,7 @@ impl Annotatable {
             | Annotatable::StructField(..)
             | Annotatable::Variant(..) => panic!("unexpected annotatable"),
         };
-        TokenTree::token(token::Interpolated(Lrc::new(nt)), DUMMY_SP).into()
+        TokenTree::token(token::Interpolated(Lrc::new(nt), FlattenGroup::Yes), DUMMY_SP).into()
     }
 
     pub fn expect_item(self) -> P<ast::Item> {
@@ -374,7 +374,7 @@ where
         impl MutVisitor for AvoidInterpolatedIdents {
             fn visit_tt(&mut self, tt: &mut tokenstream::TokenTree) {
                 if let tokenstream::TokenTree::Token(token) = tt {
-                    if let token::Interpolated(nt) = &token.kind {
+                    if let token::Interpolated(nt, _) = &token.kind {
                         if let token::NtIdent(ident, is_raw) = **nt {
                             *tt = tokenstream::TokenTree::token(
                                 token::Ident(ident.name, is_raw),
diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs
index 968f7c8e273..c90a438c25e 100644
--- a/src/librustc_expand/mbe/macro_parser.rs
+++ b/src/librustc_expand/mbe/macro_parser.rs
@@ -785,12 +785,12 @@ fn may_begin_with(token: &Token, name: Symbol) -> bool {
         sym::literal => token.can_begin_literal_maybe_minus(),
         sym::vis => match token.kind {
             // The follow-set of :vis + "priv" keyword + interpolated
-            token::Comma | token::Ident(..) | token::Interpolated(_) => true,
+            token::Comma | token::Ident(..) | token::Interpolated(..) => true,
             _ => token.can_begin_type(),
         },
         sym::block => match token.kind {
             token::OpenDelim(token::Brace) => true,
-            token::Interpolated(ref nt) => match **nt {
+            token::Interpolated(ref nt, _) => match **nt {
                 token::NtItem(_)
                 | token::NtPat(_)
                 | token::NtTy(_)
@@ -804,7 +804,7 @@ fn may_begin_with(token: &Token, name: Symbol) -> bool {
         },
         sym::path | sym::meta => match token.kind {
             token::ModSep | token::Ident(..) => true,
-            token::Interpolated(ref nt) => match **nt {
+            token::Interpolated(ref nt, _) => match **nt {
                 token::NtPath(_) | token::NtMeta(_) => true,
                 _ => may_be_ident(&nt),
             },
@@ -823,12 +823,12 @@ fn may_begin_with(token: &Token, name: Symbol) -> bool {
             token::ModSep |                     // path
             token::Lt |                         // path (UFCS constant)
             token::BinOp(token::Shl) => true,   // path (double UFCS)
-            token::Interpolated(ref nt) => may_be_ident(nt),
+            token::Interpolated(ref nt, _) => may_be_ident(nt),
             _ => false,
         },
         sym::lifetime => match token.kind {
             token::Lifetime(_) => true,
-            token::Interpolated(ref nt) => match **nt {
+            token::Interpolated(ref nt, _) => match **nt {
                 token::NtLifetime(_) | token::NtTT(_) => true,
                 _ => false,
             },
diff --git a/src/librustc_expand/mbe/transcribe.rs b/src/librustc_expand/mbe/transcribe.rs
index e2d3d5c4d64..486f0a6420d 100644
--- a/src/librustc_expand/mbe/transcribe.rs
+++ b/src/librustc_expand/mbe/transcribe.rs
@@ -4,7 +4,7 @@ use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
 
 use rustc_ast::ast::MacCall;
 use rustc_ast::mut_visit::{self, MutVisitor};
-use rustc_ast::token::{self, NtTT, Token};
+use rustc_ast::token::{self, FlattenGroup, NtTT, Token};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
@@ -240,7 +240,10 @@ pub(super) fn transcribe<'a>(
                             result.push(tt.clone().into());
                         } else {
                             marker.visit_span(&mut sp);
-                            let token = TokenTree::token(token::Interpolated(nt.clone()), sp);
+                            let token = TokenTree::token(
+                                token::Interpolated(nt.clone(), FlattenGroup::No),
+                                sp,
+                            );
                             result.push(token.into());
                         }
                     } else {
diff --git a/src/librustc_expand/proc_macro.rs b/src/librustc_expand/proc_macro.rs
index df7bf9438c3..1e26c832a26 100644
--- a/src/librustc_expand/proc_macro.rs
+++ b/src/librustc_expand/proc_macro.rs
@@ -2,7 +2,7 @@ use crate::base::{self, *};
 use crate::proc_macro_server;
 
 use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem};
-use rustc_ast::token;
+use rustc_ast::token::{self, FlattenGroup};
 use rustc_ast::tokenstream::{self, TokenStream};
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, ErrorReported};
@@ -102,7 +102,7 @@ impl MultiItemModifier for ProcMacroDerive {
             }
         }
 
-        let token = token::Interpolated(Lrc::new(token::NtItem(item)));
+        let token = token::Interpolated(Lrc::new(token::NtItem(item)), FlattenGroup::Yes);
         let input = tokenstream::TokenTree::token(token, DUMMY_SP).into();
 
         let server = proc_macro_server::Rustc::new(ecx);
diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs
index ea55674045c..c88b5a37f71 100644
--- a/src/librustc_expand/proc_macro_server.rs
+++ b/src/librustc_expand/proc_macro_server.rs
@@ -1,7 +1,7 @@
 use crate::base::ExtCtxt;
 
 use rustc_ast::ast;
-use rustc_ast::token;
+use rustc_ast::token::{self, FlattenGroup};
 use rustc_ast::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
 use rustc_ast::util::comments;
 use rustc_ast_pretty::pprust;
@@ -60,7 +60,12 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
         let Token { kind, span } = match tree {
             tokenstream::TokenTree::Delimited(span, delim, tts) => {
                 let delimiter = Delimiter::from_internal(delim);
-                return TokenTree::Group(Group { delimiter, stream: tts, span });
+                return TokenTree::Group(Group {
+                    delimiter,
+                    stream: tts,
+                    span,
+                    flatten: FlattenGroup::No,
+                });
             }
             tokenstream::TokenTree::Token(token) => token,
         };
@@ -167,6 +172,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
                     delimiter: Delimiter::Bracket,
                     stream,
                     span: DelimSpan::from_single(span),
+                    flatten: FlattenGroup::No,
                 }));
                 if style == ast::AttrStyle::Inner {
                     stack.push(tt!(Punct::new('!', false)));
@@ -174,12 +180,13 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
                 tt!(Punct::new('#', false))
             }
 
-            Interpolated(nt) => {
+            Interpolated(nt, flatten) => {
                 let stream = nt_to_tokenstream(&nt, sess, span);
                 TokenTree::Group(Group {
                     delimiter: Delimiter::None,
                     stream,
                     span: DelimSpan::from_single(span),
+                    flatten,
                 })
             }
 
@@ -195,7 +202,7 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
 
         let (ch, joint, span) = match self {
             TokenTree::Punct(Punct { ch, joint, span }) => (ch, joint, span),
-            TokenTree::Group(Group { delimiter, stream, span }) => {
+            TokenTree::Group(Group { delimiter, stream, span, .. }) => {
                 return tokenstream::TokenTree::Delimited(span, delimiter.to_internal(), stream)
                     .into();
             }
@@ -283,6 +290,10 @@ pub struct Group {
     delimiter: Delimiter,
     stream: TokenStream,
     span: DelimSpan,
+    /// A hack used to pass AST fragments to attribute and derive macros
+    /// as a single nonterminal token instead of a token stream.
+    /// FIXME: It needs to be removed, but there are some compatibility issues (see #73345).
+    flatten: FlattenGroup,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
@@ -437,14 +448,12 @@ impl server::TokenStreamIter for Rustc<'_> {
                 let next = iter.cursor.next_with_joint()?;
                 Some(TokenTree::from_internal((next, self.sess, &mut iter.stack)))
             })?;
-            // HACK: The condition "dummy span + group with empty delimiter" represents an AST
-            // fragment approximately converted into a token stream. This may happen, for
-            // example, with inputs to proc macro attributes, including derives. Such "groups"
-            // need to flattened during iteration over stream's token trees.
-            // Eventually this needs to be removed in favor of keeping original token trees
-            // and not doing the roundtrip through AST.
+            // A hack used to pass AST fragments to attribute and derive macros
+            // as a single nonterminal token instead of a token stream.
+            // Such token needs to be "unwrapped" and not represented as a delimited group.
+            // FIXME: It needs to be removed, but there are some compatibility issues (see #73345).
             if let TokenTree::Group(ref group) = tree {
-                if group.delimiter == Delimiter::None && group.span.entire().is_dummy() {
+                if matches!(group.flatten, FlattenGroup::Yes) {
                     iter.cursor.append(group.stream.clone());
                     continue;
                 }
@@ -456,7 +465,12 @@ impl server::TokenStreamIter for Rustc<'_> {
 
 impl server::Group for Rustc<'_> {
     fn new(&mut self, delimiter: Delimiter, stream: Self::TokenStream) -> Self::Group {
-        Group { delimiter, stream, span: DelimSpan::from_single(server::Span::call_site(self)) }
+        Group {
+            delimiter,
+            stream,
+            span: DelimSpan::from_single(server::Span::call_site(self)),
+            flatten: FlattenGroup::No,
+        }
     }
     fn delimiter(&mut self, group: &Self::Group) -> Delimiter {
         group.delimiter
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index ada48bc147e..d25f8bd1b8c 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -293,11 +293,9 @@ fn main() {
         }
     }
 
-    // LLVM requires symbols from this library, but apparently they're not printed
-    // during llvm-config?
+    // Libstdc++ depends on pthread which Rust doesn't link on MinGW
+    // since nothing else requires it.
     if target.contains("windows-gnu") {
-        println!("cargo:rustc-link-lib=static-nobundle=gcc_s");
         println!("cargo:rustc-link-lib=static-nobundle=pthread");
-        println!("cargo:rustc-link-lib=dylib=uuid");
     }
 }
diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml
index 21d0b102a4a..02d82c67933 100644
--- a/src/librustc_middle/Cargo.toml
+++ b/src/librustc_middle/Cargo.toml
@@ -30,7 +30,7 @@ rustc_serialize = { path = "../librustc_serialize" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
 byteorder = { version = "1.3" }
-chalk-ir = "0.11.0"
+chalk-ir = "0.14.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 measureme = "0.7.1"
 rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs
index a49a0045812..405af8cb240 100644
--- a/src/librustc_middle/traits/chalk.rs
+++ b/src/librustc_middle/traits/chalk.rs
@@ -10,6 +10,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
 
 use rustc_hir::def_id::DefId;
+use rustc_target::spec::abi::Abi;
 
 use smallvec::SmallVec;
 
@@ -77,6 +78,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
     type DefId = DefId;
     type InternedAdtId = &'tcx AdtDef;
     type Identifier = ();
+    type FnAbi = Abi;
 
     fn debug_program_clause_implication(
         pci: &chalk_ir::ProgramClauseImplication<Self>,
diff --git a/src/librustc_middle/ty/subst.rs b/src/librustc_middle/ty/subst.rs
index fd31adae499..e9fd67a748c 100644
--- a/src/librustc_middle/ty/subst.rs
+++ b/src/librustc_middle/ty/subst.rs
@@ -336,8 +336,10 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
     ///
     /// For example given:
     ///
+    /// ```no_run
     /// trait X<S> { fn f<T>(); }
     /// impl<U> X<U> for U { fn f<V>() {} }
+    /// ```
     ///
     /// * If `self` is `[Self, S, T]`: the identity substs of `f` in the trait.
     /// * If `source_ancestor` is the def_id of the trait.
diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs
index 803f14a2a22..b8cb146145b 100644
--- a/src/librustc_parse/parser/attr.rs
+++ b/src/librustc_parse/parser/attr.rs
@@ -155,7 +155,7 @@ impl<'a> Parser<'a> {
     /// The delimiters or `=` are still put into the resulting token stream.
     pub fn parse_attr_item(&mut self) -> PResult<'a, ast::AttrItem> {
         let item = match self.token.kind {
-            token::Interpolated(ref nt) => match **nt {
+            token::Interpolated(ref nt, _) => match **nt {
                 Nonterminal::NtMeta(ref item) => Some(item.clone().into_inner()),
                 _ => None,
             },
@@ -254,7 +254,7 @@ impl<'a> Parser<'a> {
     ///     meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
     pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
         let nt_meta = match self.token.kind {
-            token::Interpolated(ref nt) => match **nt {
+            token::Interpolated(ref nt, _) => match **nt {
                 token::NtMeta(ref e) => Some(e.clone()),
                 _ => None,
             },
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 49a5c880176..2745b18a8cd 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -26,7 +26,7 @@ use std::mem;
 /// `token::Interpolated` tokens.
 macro_rules! maybe_whole_expr {
     ($p:expr) => {
-        if let token::Interpolated(nt) = &$p.token.kind {
+        if let token::Interpolated(nt, _) = &$p.token.kind {
             match &**nt {
                 token::NtExpr(e) | token::NtLiteral(e) => {
                     let e = e.clone();
diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs
index 04b64d93c70..47794746126 100644
--- a/src/librustc_parse/parser/generics.rs
+++ b/src/librustc_parse/parser/generics.rs
@@ -47,21 +47,21 @@ impl<'a> Parser<'a> {
     }
 
     fn parse_const_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, GenericParam> {
-        let lo = self.token.span;
+        let const_span = self.token.span;
 
         self.expect_keyword(kw::Const)?;
         let ident = self.parse_ident()?;
         self.expect(&token::Colon)?;
         let ty = self.parse_ty()?;
 
-        self.sess.gated_spans.gate(sym::const_generics, lo.to(self.prev_token.span));
+        self.sess.gated_spans.gate(sym::const_generics, const_span.to(self.prev_token.span));
 
         Ok(GenericParam {
             ident,
             id: ast::DUMMY_NODE_ID,
             attrs: preceding_attrs.into(),
             bounds: Vec::new(),
-            kind: GenericParamKind::Const { ty },
+            kind: GenericParamKind::Const { ty, kw_span: const_span },
             is_placeholder: false,
         })
     }
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 6f13d7994d1..10df16964da 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -1780,7 +1780,7 @@ impl<'a> Parser<'a> {
 
     fn is_named_param(&self) -> bool {
         let offset = match self.token.kind {
-            token::Interpolated(ref nt) => match **nt {
+            token::Interpolated(ref nt, _) => match **nt {
                 token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
                 _ => 0,
             },
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index 7811d5fb741..04074479a21 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -54,7 +54,7 @@ enum BlockMode {
 #[macro_export]
 macro_rules! maybe_whole {
     ($p:expr, $constructor:ident, |$x:ident| $e:expr) => {
-        if let token::Interpolated(nt) = &$p.token.kind {
+        if let token::Interpolated(nt, _) = &$p.token.kind {
             if let token::$constructor(x) = &**nt {
                 let $x = x.clone();
                 $p.bump();
@@ -69,7 +69,7 @@ macro_rules! maybe_whole {
 macro_rules! maybe_recover_from_interpolated_ty_qpath {
     ($self: expr, $allow_qpath_recovery: expr) => {
         if $allow_qpath_recovery && $self.look_ahead(1, |t| t == &token::ModSep) {
-            if let token::Interpolated(nt) = &$self.token.kind {
+            if let token::Interpolated(nt, _) = &$self.token.kind {
                 if let token::NtTy(ty) = &**nt {
                     let ty = ty.clone();
                     $self.bump();
@@ -922,7 +922,7 @@ impl<'a> Parser<'a> {
                 if self.eat(&token::Eq) {
                     let eq_span = self.prev_token.span;
                     let mut is_interpolated_expr = false;
-                    if let token::Interpolated(nt) = &self.token.kind {
+                    if let token::Interpolated(nt, _) = &self.token.kind {
                         if let token::NtExpr(..) = **nt {
                             is_interpolated_expr = true;
                         }
diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs
index 6603d0afc02..742183d3697 100644
--- a/src/librustc_parse/parser/pat.rs
+++ b/src/librustc_parse/parser/pat.rs
@@ -515,7 +515,7 @@ impl<'a> Parser<'a> {
         self.recover_additional_muts();
 
         // Make sure we don't allow e.g. `let mut $p;` where `$p:pat`.
-        if let token::Interpolated(ref nt) = self.token.kind {
+        if let token::Interpolated(ref nt, _) = self.token.kind {
             if let token::NtPat(_) = **nt {
                 self.expected_ident_found().emit();
             }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index ef43f597eab..72faa68d0b2 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -1325,7 +1325,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
     }
 
     fn visit_token(&mut self, t: Token) {
-        if let token::Interpolated(nt) = t.kind {
+        if let token::Interpolated(nt, _) = t.kind {
             if let token::NtExpr(ref expr) = *nt {
                 if let ast::ExprKind::MacCall(..) = expr.kind {
                     self.visit_invoc(expr.id);
diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs
index f1063f42c91..dc8d1a8d3fd 100644
--- a/src/librustc_resolve/def_collector.rs
+++ b/src/librustc_resolve/def_collector.rs
@@ -256,7 +256,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
     }
 
     fn visit_token(&mut self, t: Token) {
-        if let token::Interpolated(nt) = t.kind {
+        if let token::Interpolated(nt, _) = t.kind {
             if let token::NtExpr(ref expr) = *nt {
                 if let ExprKind::MacCall(..) = expr.kind {
                     self.visit_macro_invoc(expr.id);
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 6f769c3c59c..b8fb813ea15 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -536,8 +536,8 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
 
         for param in &generics.params {
             match param.kind {
-                GenericParamKind::Lifetime { .. } => self.visit_generic_param(param),
-                GenericParamKind::Type { ref default, .. } => {
+                GenericParamKind::Lifetime => self.visit_generic_param(param),
+                GenericParamKind::Type { ref default } => {
                     for bound in &param.bounds {
                         self.visit_param_bound(bound);
                     }
@@ -551,7 +551,7 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                     // Allow all following defaults to refer to this type parameter.
                     default_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name));
                 }
-                GenericParamKind::Const { ref ty } => {
+                GenericParamKind::Const { ref ty, kw_span: _ } => {
                     for bound in &param.bounds {
                         self.visit_param_bound(bound);
                     }
diff --git a/src/librustc_target/asm/arm.rs b/src/librustc_target/asm/arm.rs
index 1798b2a0949..85a136b94aa 100644
--- a/src/librustc_target/asm/arm.rs
+++ b/src/librustc_target/asm/arm.rs
@@ -1,4 +1,5 @@
 use super::{InlineAsmArch, InlineAsmType};
+use crate::spec::Target;
 use rustc_macros::HashStable_Generic;
 use std::fmt;
 
@@ -58,6 +59,37 @@ impl ArmInlineAsmRegClass {
     }
 }
 
+// This uses the same logic as useR7AsFramePointer in LLVM
+fn frame_pointer_is_r7(mut has_feature: impl FnMut(&str) -> bool, target: &Target) -> bool {
+    target.options.is_like_osx || (!target.options.is_like_windows && has_feature("thumb-mode"))
+}
+
+fn frame_pointer_r11(
+    _arch: InlineAsmArch,
+    has_feature: impl FnMut(&str) -> bool,
+    target: &Target,
+    _allocating: bool,
+) -> Result<(), &'static str> {
+    if !frame_pointer_is_r7(has_feature, target) {
+        Err("the frame pointer (r11) cannot be used as an operand for inline asm")
+    } else {
+        Ok(())
+    }
+}
+
+fn frame_pointer_r7(
+    _arch: InlineAsmArch,
+    has_feature: impl FnMut(&str) -> bool,
+    target: &Target,
+    _allocating: bool,
+) -> Result<(), &'static str> {
+    if frame_pointer_is_r7(has_feature, target) {
+        Err("the frame pointer (r7) cannot be used as an operand for inline asm")
+    } else {
+        Ok(())
+    }
+}
+
 def_regs! {
     Arm ArmInlineAsmReg ArmInlineAsmRegClass {
         r0: reg, reg_thumb = ["r0", "a1"],
@@ -66,11 +98,11 @@ def_regs! {
         r3: reg, reg_thumb = ["r3", "a4"],
         r4: reg, reg_thumb = ["r4", "v1"],
         r5: reg, reg_thumb = ["r5", "v2"],
-        r6: reg, reg_thumb = ["r6", "v3"],
-        r7: reg, reg_thumb = ["r7", "v4"],
+        r7: reg, reg_thumb = ["r7", "v4"] % frame_pointer_r7,
         r8: reg = ["r8", "v5"],
         r9: reg = ["r9", "v6", "rfp"],
         r10: reg = ["r10", "sl"],
+        r11: reg = ["r11", "fp"] % frame_pointer_r11,
         r12: reg = ["r12", "ip"],
         r14: reg = ["r14", "lr"],
         s0: sreg, sreg_low16 = ["s0"],
@@ -153,8 +185,8 @@ def_regs! {
         q13: qreg = ["q13"],
         q14: qreg = ["q14"],
         q15: qreg = ["q15"],
-        #error = ["r11", "fp"] =>
-            "the frame pointer cannot be used as an operand for inline asm",
+        #error = ["r6", "v3"] =>
+            "r6 is used internally by LLVM and cannot be used as an operand for inline asm",
         #error = ["r13", "sp"] =>
             "the stack pointer cannot be used as an operand for inline asm",
         #error = ["r15", "pc"] =>
diff --git a/src/librustc_target/asm/mod.rs b/src/librustc_target/asm/mod.rs
index 834d7c6d381..ccec17817d3 100644
--- a/src/librustc_target/asm/mod.rs
+++ b/src/librustc_target/asm/mod.rs
@@ -1,4 +1,5 @@
 use crate::abi::Size;
+use crate::spec::Target;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_macros::HashStable_Generic;
 use rustc_span::Symbol;
@@ -83,12 +84,13 @@ macro_rules! def_regs {
             pub fn parse(
                 _arch: super::InlineAsmArch,
                 mut _has_feature: impl FnMut(&str) -> bool,
+                _target: &crate::spec::Target,
                 name: &str,
             ) -> Result<Self, &'static str> {
                 match name {
                     $(
                         $($alias)|* | $reg_name => {
-                            $($filter(_arch, &mut _has_feature, false)?;)?
+                            $($filter(_arch, &mut _has_feature, _target, false)?;)?
                             Ok(Self::$reg)
                         }
                     )*
@@ -103,6 +105,7 @@ macro_rules! def_regs {
         pub(super) fn fill_reg_map(
             _arch: super::InlineAsmArch,
             mut _has_feature: impl FnMut(&str) -> bool,
+            _target: &crate::spec::Target,
             _map: &mut rustc_data_structures::fx::FxHashMap<
                 super::InlineAsmRegClass,
                 rustc_data_structures::fx::FxHashSet<super::InlineAsmReg>,
@@ -111,7 +114,7 @@ macro_rules! def_regs {
             #[allow(unused_imports)]
             use super::{InlineAsmReg, InlineAsmRegClass};
             $(
-                if $($filter(_arch, &mut _has_feature, true).is_ok() &&)? true {
+                if $($filter(_arch, &mut _has_feature, _target, true).is_ok() &&)? true {
                     if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
                         set.insert(InlineAsmReg::$arch($arch_reg::$reg));
                     }
@@ -234,6 +237,7 @@ impl InlineAsmReg {
     pub fn parse(
         arch: InlineAsmArch,
         has_feature: impl FnMut(&str) -> bool,
+        target: &Target,
         name: Symbol,
     ) -> Result<Self, &'static str> {
         // FIXME: use direct symbol comparison for register names
@@ -241,20 +245,22 @@ impl InlineAsmReg {
         let name = name.as_str();
         Ok(match arch {
             InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
-                Self::X86(X86InlineAsmReg::parse(arch, has_feature, &name)?)
+                Self::X86(X86InlineAsmReg::parse(arch, has_feature, target, &name)?)
+            }
+            InlineAsmArch::Arm => {
+                Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
-            InlineAsmArch::Arm => Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, &name)?),
             InlineAsmArch::AArch64 => {
-                Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, &name)?)
+                Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
             InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
-                Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, &name)?)
+                Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
             InlineAsmArch::Nvptx64 => {
-                Self::Nvptx(NvptxInlineAsmReg::parse(arch, has_feature, &name)?)
+                Self::Nvptx(NvptxInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
             InlineAsmArch::Hexagon => {
-                Self::Hexagon(HexagonInlineAsmReg::parse(arch, has_feature, &name)?)
+                Self::Hexagon(HexagonInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
         })
     }
@@ -536,36 +542,37 @@ impl fmt::Display for InlineAsmType {
 pub fn allocatable_registers(
     arch: InlineAsmArch,
     has_feature: impl FnMut(&str) -> bool,
+    target: &crate::spec::Target,
 ) -> FxHashMap<InlineAsmRegClass, FxHashSet<InlineAsmReg>> {
     match arch {
         InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
             let mut map = x86::regclass_map();
-            x86::fill_reg_map(arch, has_feature, &mut map);
+            x86::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
         InlineAsmArch::Arm => {
             let mut map = arm::regclass_map();
-            arm::fill_reg_map(arch, has_feature, &mut map);
+            arm::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
         InlineAsmArch::AArch64 => {
             let mut map = aarch64::regclass_map();
-            aarch64::fill_reg_map(arch, has_feature, &mut map);
+            aarch64::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
         InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
             let mut map = riscv::regclass_map();
-            riscv::fill_reg_map(arch, has_feature, &mut map);
+            riscv::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
         InlineAsmArch::Nvptx64 => {
             let mut map = nvptx::regclass_map();
-            nvptx::fill_reg_map(arch, has_feature, &mut map);
+            nvptx::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
         InlineAsmArch::Hexagon => {
             let mut map = hexagon::regclass_map();
-            hexagon::fill_reg_map(arch, has_feature, &mut map);
+            hexagon::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
     }
diff --git a/src/librustc_target/asm/riscv.rs b/src/librustc_target/asm/riscv.rs
index 3ff542247ff..ced7483b005 100644
--- a/src/librustc_target/asm/riscv.rs
+++ b/src/librustc_target/asm/riscv.rs
@@ -1,4 +1,5 @@
 use super::{InlineAsmArch, InlineAsmType};
+use crate::spec::Target;
 use rustc_macros::HashStable_Generic;
 use std::fmt;
 
@@ -50,6 +51,7 @@ impl RiscVInlineAsmRegClass {
 fn not_e(
     _arch: InlineAsmArch,
     mut has_feature: impl FnMut(&str) -> bool,
+    _target: &Target,
     _allocating: bool,
 ) -> Result<(), &'static str> {
     if has_feature("e") {
diff --git a/src/librustc_target/asm/x86.rs b/src/librustc_target/asm/x86.rs
index ed51b526414..0f62c19e1a3 100644
--- a/src/librustc_target/asm/x86.rs
+++ b/src/librustc_target/asm/x86.rs
@@ -1,4 +1,5 @@
 use super::{InlineAsmArch, InlineAsmType};
+use crate::spec::Target;
 use rustc_macros::HashStable_Generic;
 use std::fmt;
 
@@ -131,6 +132,7 @@ impl X86InlineAsmRegClass {
 fn x86_64_only(
     arch: InlineAsmArch,
     _has_feature: impl FnMut(&str) -> bool,
+    _target: &Target,
     _allocating: bool,
 ) -> Result<(), &'static str> {
     match arch {
@@ -143,6 +145,7 @@ fn x86_64_only(
 fn high_byte(
     arch: InlineAsmArch,
     _has_feature: impl FnMut(&str) -> bool,
+    _target: &Target,
     allocating: bool,
 ) -> Result<(), &'static str> {
     match arch {
diff --git a/src/librustc_trait_selection/traits/chalk_fulfill.rs b/src/librustc_trait_selection/traits/chalk_fulfill.rs
index cbbff82d35f..2ade4892752 100644
--- a/src/librustc_trait_selection/traits/chalk_fulfill.rs
+++ b/src/librustc_trait_selection/traits/chalk_fulfill.rs
@@ -7,17 +7,17 @@ use crate::traits::{
     ChalkEnvironmentAndGoal, ChalkEnvironmentClause, FulfillmentError, FulfillmentErrorCode,
     ObligationCause, PredicateObligation, SelectionError, TraitEngine,
 };
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 
 pub struct FulfillmentContext<'tcx> {
-    obligations: FxHashSet<PredicateObligation<'tcx>>,
+    obligations: FxIndexSet<PredicateObligation<'tcx>>,
 }
 
 impl FulfillmentContext<'tcx> {
     crate fn new() -> Self {
-        FulfillmentContext { obligations: FxHashSet::default() }
+        FulfillmentContext { obligations: FxIndexSet::default() }
     }
 }
 
@@ -79,7 +79,7 @@ fn environment<'tcx>(
     };
 
     // FIXME(eddyb) isn't the unordered nature of this a hazard?
-    let mut inputs = FxHashSet::default();
+    let mut inputs = FxIndexSet::default();
 
     match node_kind {
         // In a trait impl, we assume that the header trait ref and all its
@@ -140,7 +140,8 @@ fn in_environment(
         None if obligation.param_env.caller_bounds.is_empty() => ty::List::empty(),
         // FIXME(chalk): this is hit in ui/where-clauses/where-clause-constraints-are-local-for-trait-impl
         // and ui/generics/generic-static-methods
-        _ => bug!("non-empty `ParamEnv` with no def-id"),
+        //_ => bug!("non-empty `ParamEnv` with no def-id"),
+        _ => ty::List::empty(),
     };
 
     ChalkEnvironmentAndGoal { environment, goal: obligation.predicate }
@@ -195,7 +196,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
         infcx: &InferCtxt<'_, 'tcx>,
     ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
         let mut errors = Vec::new();
-        let mut next_round = FxHashSet::default();
+        let mut next_round = FxIndexSet::default();
         let mut making_progress;
 
         loop {
@@ -203,7 +204,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
 
             // We iterate over all obligations, and record if we are able
             // to unambiguously prove at least one obligation.
-            for obligation in self.obligations.drain() {
+            for obligation in self.obligations.drain(..) {
                 let goal_in_environment = in_environment(infcx, &obligation);
                 let mut orig_values = OriginalQueryValues::default();
                 let canonical_goal =
diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml
index 8def98a9603..079b9b10fd0 100644
--- a/src/librustc_traits/Cargo.toml
+++ b/src/librustc_traits/Cargo.toml
@@ -16,8 +16,8 @@ rustc_hir = { path = "../librustc_hir" }
 rustc_index = { path = "../librustc_index" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
-chalk-ir = "0.11.0"
-chalk-solve = "0.11.0"
+chalk-ir = "0.14.0"
+chalk-solve = "0.14.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc_infer = { path = "../librustc_infer" }
 rustc_trait_selection = { path = "../librustc_trait_selection" }
diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs
index 235497d3740..715e5299a37 100644
--- a/src/librustc_traits/chalk/db.rs
+++ b/src/librustc_traits/chalk/db.rs
@@ -8,7 +8,7 @@
 
 use rustc_middle::traits::ChalkRustInterner as RustInterner;
 use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
-use rustc_middle::ty::{self, AssocItemContainer, AssocKind, Binder, TyCtxt};
+use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt};
 
 use rustc_hir::def_id::DefId;
 
@@ -85,14 +85,29 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             .iter()
             .map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
             .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
+        let associated_ty_ids: Vec<_> = self
+            .tcx
+            .associated_items(def_id)
+            .in_definition_order()
+            .filter(|i| i.kind == AssocKind::Type)
+            .map(|i| chalk_ir::AssocTypeId(i.def_id))
+            .collect();
 
         let well_known =
             if self.tcx.lang_items().sized_trait().map(|t| def_id == t).unwrap_or(false) {
-                Some(chalk_solve::rust_ir::WellKnownTrait::SizedTrait)
+                Some(chalk_solve::rust_ir::WellKnownTrait::Sized)
             } else if self.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false) {
-                Some(chalk_solve::rust_ir::WellKnownTrait::CopyTrait)
+                Some(chalk_solve::rust_ir::WellKnownTrait::Copy)
             } else if self.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false) {
-                Some(chalk_solve::rust_ir::WellKnownTrait::CloneTrait)
+                Some(chalk_solve::rust_ir::WellKnownTrait::Clone)
+            } else if self.tcx.lang_items().drop_trait().map(|t| def_id == t).unwrap_or(false) {
+                Some(chalk_solve::rust_ir::WellKnownTrait::Drop)
+            } else if self.tcx.lang_items().fn_trait().map(|t| def_id == t).unwrap_or(false) {
+                Some(chalk_solve::rust_ir::WellKnownTrait::Fn)
+            } else if self.tcx.lang_items().fn_once_trait().map(|t| def_id == t).unwrap_or(false) {
+                Some(chalk_solve::rust_ir::WellKnownTrait::FnOnce)
+            } else if self.tcx.lang_items().fn_mut_trait().map(|t| def_id == t).unwrap_or(false) {
+                Some(chalk_solve::rust_ir::WellKnownTrait::FnMut)
             } else {
                 None
             };
@@ -110,7 +125,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
                 non_enumerable: true,
                 coinductive: false,
             },
-            associated_ty_ids: vec![],
+            associated_ty_ids,
             well_known,
         })
     }
@@ -156,6 +171,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             flags: chalk_solve::rust_ir::AdtFlags {
                 upstream: !adt_def.did.is_local(),
                 fundamental: adt_def.is_fundamental(),
+                phantom_data: adt_def.is_phantom_data(),
             },
         });
         return struct_datum;
@@ -176,28 +192,32 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
 
         let sig = self.tcx.fn_sig(def_id);
-        // FIXME(chalk): collect into an intermediate SmallVec here since
-        // we need `TypeFoldable` for `no_bound_vars`
-        let argument_types: Binder<Vec<_>> =
-            sig.map_bound(|i| i.inputs().iter().copied().collect());
-        let argument_types = argument_types
-            .no_bound_vars()
-            .expect("FIXME(chalk): late-bound fn parameters not supported in chalk")
+        let inputs_and_output = sig.inputs_and_output();
+        let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars(
+            &self.interner,
+            self.tcx,
+            &inputs_and_output,
+        );
+
+        let argument_types = inputs_and_output[..inputs_and_output.len() - 1]
             .iter()
             .map(|t| t.subst(self.tcx, &bound_vars).lower_into(&self.interner))
             .collect();
 
-        let return_type = sig
-            .output()
-            .no_bound_vars()
-            .expect("FIXME(chalk): late-bound fn parameters not supported in chalk")
+        let return_type = inputs_and_output[inputs_and_output.len() - 1]
             .subst(self.tcx, &bound_vars)
             .lower_into(&self.interner);
 
-        let bound =
-            chalk_solve::rust_ir::FnDefDatumBound { argument_types, where_clauses, return_type };
+        let bound = chalk_solve::rust_ir::FnDefDatumBound {
+            inputs_and_output: chalk_ir::Binders::new(
+                iobinders,
+                chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type },
+            ),
+            where_clauses,
+        };
         Arc::new(chalk_solve::rust_ir::FnDefDatum {
             id: fn_def_id,
+            abi: sig.abi(),
             binders: chalk_ir::Binders::new(binders, bound),
         })
     }
@@ -326,9 +346,16 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
         &self,
         opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
     ) -> Arc<chalk_solve::rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> {
-        // FIXME(chalk): actually lower opaque ty
+        let bound_vars = bound_vars_for_item(self.tcx, opaque_ty_id.0);
+        let binders = binders_for(&self.interner, bound_vars);
+        let predicates = self.tcx.predicates_defined_on(opaque_ty_id.0).predicates;
+        let where_clauses: Vec<_> = predicates
+            .iter()
+            .map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
+            .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
+
         let value = chalk_solve::rust_ir::OpaqueTyDatumBound {
-            bounds: chalk_ir::Binders::new(chalk_ir::VariableKinds::new(&self.interner), vec![]),
+            bounds: chalk_ir::Binders::new(binders, where_clauses),
         };
         Arc::new(chalk_solve::rust_ir::OpaqueTyDatum {
             opaque_ty_id,
@@ -346,7 +373,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
     ) -> Option<bool> {
         use chalk_ir::TyData::*;
         match well_known {
-            chalk_solve::rust_ir::WellKnownTrait::SizedTrait => match ty {
+            chalk_solve::rust_ir::WellKnownTrait::Sized => match ty {
                 Apply(apply) => match apply.name {
                     chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() {
                         ty::AdtKind::Struct | ty::AdtKind::Union => None,
@@ -364,8 +391,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
                 | InferenceVar(_, _)
                 | BoundVar(_) => None,
             },
-            chalk_solve::rust_ir::WellKnownTrait::CopyTrait
-            | chalk_solve::rust_ir::WellKnownTrait::CloneTrait => match ty {
+            chalk_solve::rust_ir::WellKnownTrait::Copy
+            | chalk_solve::rust_ir::WellKnownTrait::Clone => match ty {
                 Apply(apply) => match apply.name {
                     chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() {
                         ty::AdtKind::Struct | ty::AdtKind::Union => None,
@@ -383,7 +410,11 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
                 | InferenceVar(_, _)
                 | BoundVar(_) => None,
             },
-            chalk_solve::rust_ir::WellKnownTrait::DropTrait => None,
+            chalk_solve::rust_ir::WellKnownTrait::Drop => None,
+            chalk_solve::rust_ir::WellKnownTrait::Fn => None,
+            chalk_solve::rust_ir::WellKnownTrait::FnMut => None,
+            chalk_solve::rust_ir::WellKnownTrait::FnOnce => None,
+            chalk_solve::rust_ir::WellKnownTrait::Unsize => None,
         }
     }
 
@@ -399,17 +430,17 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
         well_known_trait: chalk_solve::rust_ir::WellKnownTrait,
     ) -> Option<chalk_ir::TraitId<RustInterner<'tcx>>> {
         use chalk_solve::rust_ir::WellKnownTrait::*;
-        let t = match well_known_trait {
-            SizedTrait => {
-                self.tcx.lang_items().sized_trait().map(|t| chalk_ir::TraitId(t)).unwrap()
-            }
-            CopyTrait => self.tcx.lang_items().copy_trait().map(|t| chalk_ir::TraitId(t)).unwrap(),
-            CloneTrait => {
-                self.tcx.lang_items().clone_trait().map(|t| chalk_ir::TraitId(t)).unwrap()
-            }
-            DropTrait => self.tcx.lang_items().drop_trait().map(|t| chalk_ir::TraitId(t)).unwrap(),
+        let def_id = match well_known_trait {
+            Sized => self.tcx.lang_items().sized_trait(),
+            Copy => self.tcx.lang_items().copy_trait(),
+            Clone => self.tcx.lang_items().clone_trait(),
+            Drop => self.tcx.lang_items().drop_trait(),
+            Fn => self.tcx.lang_items().fn_trait(),
+            FnMut => self.tcx.lang_items().fn_mut_trait(),
+            FnOnce => self.tcx.lang_items().fn_once_trait(),
+            Unsize => self.tcx.lang_items().unsize_trait(),
         };
-        Some(t)
+        def_id.map(|t| chalk_ir::TraitId(t))
     }
 
     fn is_object_safe(&self, trait_id: chalk_ir::TraitId<RustInterner<'tcx>>) -> bool {
@@ -423,6 +454,87 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
         // FIXME(chalk): actually get hidden ty
         self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner)
     }
+
+    fn closure_kind(
+        &self,
+        _closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
+        substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
+    ) -> chalk_solve::rust_ir::ClosureKind {
+        let kind = &substs.parameters(&self.interner)[substs.len(&self.interner) - 3];
+        match kind.assert_ty_ref(&self.interner).data(&self.interner) {
+            chalk_ir::TyData::Apply(apply) => match apply.name {
+                chalk_ir::TypeName::Scalar(scalar) => match scalar {
+                    chalk_ir::Scalar::Int(int_ty) => match int_ty {
+                        chalk_ir::IntTy::I8 => chalk_solve::rust_ir::ClosureKind::Fn,
+                        chalk_ir::IntTy::I16 => chalk_solve::rust_ir::ClosureKind::FnMut,
+                        chalk_ir::IntTy::I32 => chalk_solve::rust_ir::ClosureKind::FnOnce,
+                        _ => bug!("bad closure kind"),
+                    },
+                    _ => bug!("bad closure kind"),
+                },
+                _ => bug!("bad closure kind"),
+            },
+            _ => bug!("bad closure kind"),
+        }
+    }
+
+    fn closure_inputs_and_output(
+        &self,
+        _closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
+        substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
+    ) -> chalk_ir::Binders<chalk_solve::rust_ir::FnDefInputsAndOutputDatum<RustInterner<'tcx>>>
+    {
+        let sig = &substs.parameters(&self.interner)[substs.len(&self.interner) - 2];
+        match sig.assert_ty_ref(&self.interner).data(&self.interner) {
+            chalk_ir::TyData::Function(f) => {
+                let substitution = f.substitution.parameters(&self.interner);
+                let return_type =
+                    substitution.last().unwrap().assert_ty_ref(&self.interner).clone();
+                // Closure arguments are tupled
+                let argument_tuple = substitution[0].assert_ty_ref(&self.interner);
+                let argument_types = match argument_tuple.data(&self.interner) {
+                    chalk_ir::TyData::Apply(apply) => match apply.name {
+                        chalk_ir::TypeName::Tuple(_) => apply
+                            .substitution
+                            .iter(&self.interner)
+                            .map(|arg| arg.assert_ty_ref(&self.interner))
+                            .cloned()
+                            .collect(),
+                        _ => bug!("Expecting closure FnSig args to be tupled."),
+                    },
+                    _ => bug!("Expecting closure FnSig args to be tupled."),
+                };
+
+                chalk_ir::Binders::new(
+                    chalk_ir::VariableKinds::from(
+                        &self.interner,
+                        (0..f.num_binders).map(|_| chalk_ir::VariableKind::Lifetime),
+                    ),
+                    chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type },
+                )
+            }
+            _ => panic!("Invalid sig."),
+        }
+    }
+
+    fn closure_upvars(
+        &self,
+        _closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
+        substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
+    ) -> chalk_ir::Binders<chalk_ir::Ty<RustInterner<'tcx>>> {
+        let inputs_and_output = self.closure_inputs_and_output(_closure_id, substs);
+        let tuple = substs.parameters(&self.interner).last().unwrap().assert_ty_ref(&self.interner);
+        inputs_and_output.map_ref(|_| tuple.clone())
+    }
+
+    fn closure_fn_substitution(
+        &self,
+        _closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
+        substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
+    ) -> chalk_ir::Substitution<RustInterner<'tcx>> {
+        let substitution = &substs.parameters(&self.interner)[0..substs.len(&self.interner) - 3];
+        chalk_ir::Substitution::from(&self.interner, substitution)
+    }
 }
 
 /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs
index 5546a8db533..e09359b8b3f 100644
--- a/src/librustc_traits/chalk/lowering.rs
+++ b/src/librustc_traits/chalk/lowering.rs
@@ -43,6 +43,8 @@ use rustc_span::def_id::DefId;
 
 use std::collections::btree_map::{BTreeMap, Entry};
 
+use chalk_ir::fold::shift::Shift;
+
 /// Essentially an `Into` with a `&RustInterner` parameter
 crate trait LowerInto<'tcx, T> {
     /// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk type, consuming `self`.
@@ -82,7 +84,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
                             collect_bound_vars(interner, interner.tcx, predicate);
 
                         Some(
-                            chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
+                            chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
                                 binders,
                                 chalk_ir::ProgramClauseImplication {
                                     consequence: chalk_ir::DomainGoal::FromEnv(
@@ -102,7 +104,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
                             collect_bound_vars(interner, interner.tcx, predicate);
 
                         Some(
-                            chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
+                            chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
                                 binders,
                                 chalk_ir::ProgramClauseImplication {
                                     consequence: chalk_ir::DomainGoal::Holds(
@@ -127,7 +129,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
                             collect_bound_vars(interner, interner.tcx, predicate);
 
                         Some(
-                            chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
+                            chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
                                 binders,
                                 chalk_ir::ProgramClauseImplication {
                                     consequence: chalk_ir::DomainGoal::Holds(
@@ -153,13 +155,16 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
                 }
             }
             ChalkEnvironmentClause::TypeFromEnv(ty) => Some(
-                chalk_ir::ProgramClauseData::Implies(chalk_ir::ProgramClauseImplication {
-                    consequence: chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(
-                        ty.lower_into(interner),
-                    )),
-                    conditions: chalk_ir::Goals::new(interner),
-                    priority: chalk_ir::ClausePriority::High,
-                })
+                chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
+                    chalk_ir::VariableKinds::new(interner),
+                    chalk_ir::ProgramClauseImplication {
+                        consequence: chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(
+                            ty.lower_into(interner).shifted_in(interner),
+                        )),
+                        conditions: chalk_ir::Goals::new(interner),
+                        priority: chalk_ir::ClausePriority::High,
+                    },
+                ))
                 .intern(interner),
             ),
         });
@@ -416,12 +421,15 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
                 })
                 .intern(interner)
             }
-            // FIXME(chalk): add region
-            Dynamic(predicates, _region) => {
-                TyData::Dyn(chalk_ir::DynTy { bounds: predicates.lower_into(interner) })
-                    .intern(interner)
-            }
-            Closure(_def_id, _) => unimplemented!(),
+            Dynamic(predicates, region) => TyData::Dyn(chalk_ir::DynTy {
+                bounds: predicates.lower_into(interner),
+                lifetime: region.lower_into(interner),
+            })
+            .intern(interner),
+            Closure(def_id, substs) => apply(
+                chalk_ir::TypeName::Closure(chalk_ir::ClosureId(def_id)),
+                substs.lower_into(interner),
+            ),
             Generator(_def_id, _substs, _) => unimplemented!(),
             GeneratorWitness(_) => unimplemented!(),
             Never => apply(chalk_ir::TypeName::Never, empty()),
@@ -624,7 +632,7 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>(
     }
 
     (0..parameters.len()).for_each(|i| {
-        parameters.get(&(i as u32)).expect("Skipped bound var index.");
+        parameters.get(&(i as u32)).expect(&format!("Skipped bound var index `{:?}`.", i));
     });
 
     let binders = chalk_ir::VariableKinds::from(interner, parameters.into_iter().map(|(_, v)| v));
diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs
index 6f657be0908..52ec0f2409d 100644
--- a/src/librustc_traits/chalk/mod.rs
+++ b/src/librustc_traits/chalk/mod.rs
@@ -133,6 +133,7 @@ crate fn evaluate_goal<'tcx>(
                             },
                             chalk_ir::TypeName::Array => unimplemented!(),
                             chalk_ir::TypeName::FnDef(_) => unimplemented!(),
+                            chalk_ir::TypeName::Closure(_) => unimplemented!(),
                             chalk_ir::TypeName::Never => unimplemented!(),
                             chalk_ir::TypeName::Tuple(_size) => unimplemented!(),
                             chalk_ir::TypeName::Slice => unimplemented!(),
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 08e04f719e9..78628b198a3 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -278,7 +278,7 @@ fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type>
     type_.def_id().and_then(|did| build_ty(cx, did))
 }
 
-pub fn build_ty(cx: &DocContext, did: DefId) -> Option<clean::Type> {
+pub fn build_ty(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type> {
     match cx.tcx.def_kind(did) {
         DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Const | DefKind::Static => {
             Some(cx.tcx.type_of(did).clean(cx))
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index c4e4802db6c..2d99b2fd134 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -328,7 +328,7 @@ pub fn strip_path(path: &Path) -> Path {
     Path { global: path.global, res: path.res, segments }
 }
 
-pub fn qpath_to_string(p: &hir::QPath) -> String {
+pub fn qpath_to_string(p: &hir::QPath<'_>) -> String {
     let segments = match *p {
         hir::QPath::Resolved(_, ref path) => &path.segments,
         hir::QPath::TypeRelative(_, ref segment) => return segment.ident.to_string(),
@@ -417,7 +417,7 @@ impl ToSource for rustc_span::Span {
     }
 }
 
-pub fn name_from_pat(p: &hir::Pat) -> String {
+pub fn name_from_pat(p: &hir::Pat<'_>) -> String {
     use rustc_hir::*;
     debug!("trying to get a name from pattern: {:?}", p);
 
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 5b138327427..943729a74ab 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -262,7 +262,7 @@ pub struct ProcMacro<'hir> {
     pub whence: Span,
 }
 
-pub fn struct_type_from_def(vdata: &hir::VariantData) -> StructType {
+pub fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType {
     match *vdata {
         hir::VariantData::Struct(..) => Plain,
         hir::VariantData::Tuple(..) => Tuple,
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 59bb206678f..62a23298c1b 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -1408,6 +1408,7 @@ function defocusSearchBar() {
 
                     addClass(actives[currentTab][0].previousElementSibling, "highlighted");
                     removeClass(actives[currentTab][0], "highlighted");
+                    e.preventDefault();
                 } else if (e.which === 40) { // down
                     if (!actives[currentTab].length) {
                         var results = document.getElementById("results").childNodes;
@@ -1421,6 +1422,7 @@ function defocusSearchBar() {
                         addClass(actives[currentTab][0].nextElementSibling, "highlighted");
                         removeClass(actives[currentTab][0], "highlighted");
                     }
+                    e.preventDefault();
                 } else if (e.which === 13) { // return
                     if (actives[currentTab].length) {
                         document.location.href =
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 21aa0ded5a4..e9504aa3af1 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -166,7 +166,7 @@ pub fn run(options: Options) -> Result<(), String> {
 }
 
 // Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
-fn scrape_test_config(krate: &::rustc_hir::Crate) -> TestOptions {
+fn scrape_test_config(krate: &::rustc_hir::Crate<'_>) -> TestOptions {
     use rustc_ast_pretty::pprust;
 
     let mut opts =
@@ -973,7 +973,7 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
         intravisit::NestedVisitorMap::All(self.map)
     }
 
-    fn visit_item(&mut self, item: &'hir hir::Item) {
+    fn visit_item(&mut self, item: &'hir hir::Item<'_>) {
         let name = if let hir::ItemKind::Impl { ref self_ty, .. } = item.kind {
             rustc_hir_pretty::id_to_string(&self.map, self_ty.hir_id)
         } else {
@@ -985,19 +985,19 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
         });
     }
 
-    fn visit_trait_item(&mut self, item: &'hir hir::TraitItem) {
+    fn visit_trait_item(&mut self, item: &'hir hir::TraitItem<'_>) {
         self.visit_testable(item.ident.to_string(), &item.attrs, item.hir_id, item.span, |this| {
             intravisit::walk_trait_item(this, item);
         });
     }
 
-    fn visit_impl_item(&mut self, item: &'hir hir::ImplItem) {
+    fn visit_impl_item(&mut self, item: &'hir hir::ImplItem<'_>) {
         self.visit_testable(item.ident.to_string(), &item.attrs, item.hir_id, item.span, |this| {
             intravisit::walk_impl_item(this, item);
         });
     }
 
-    fn visit_foreign_item(&mut self, item: &'hir hir::ForeignItem) {
+    fn visit_foreign_item(&mut self, item: &'hir hir::ForeignItem<'_>) {
         self.visit_testable(item.ident.to_string(), &item.attrs, item.hir_id, item.span, |this| {
             intravisit::walk_foreign_item(this, item);
         });
@@ -1005,8 +1005,8 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
 
     fn visit_variant(
         &mut self,
-        v: &'hir hir::Variant,
-        g: &'hir hir::Generics,
+        v: &'hir hir::Variant<'_>,
+        g: &'hir hir::Generics<'_>,
         item_id: hir::HirId,
     ) {
         self.visit_testable(v.ident.to_string(), &v.attrs, v.id, v.span, |this| {
@@ -1014,13 +1014,13 @@ impl<'a, 'hir, 'tcx> intravisit::Visitor<'hir> for HirCollector<'a, 'hir, 'tcx>
         });
     }
 
-    fn visit_struct_field(&mut self, f: &'hir hir::StructField) {
+    fn visit_struct_field(&mut self, f: &'hir hir::StructField<'_>) {
         self.visit_testable(f.ident.to_string(), &f.attrs, f.hir_id, f.span, |this| {
             intravisit::walk_struct_field(this, f);
         });
     }
 
-    fn visit_macro_def(&mut self, macro_def: &'hir hir::MacroDef) {
+    fn visit_macro_def(&mut self, macro_def: &'hir hir::MacroDef<'_>) {
         self.visit_testable(
             macro_def.ident.to_string(),
             &macro_def.attrs,
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index d2a950027cf..c18f417e4f8 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -62,7 +62,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         self.exact_paths.entry(did).or_insert_with(|| def_id_to_path(tcx, did));
     }
 
-    pub fn visit(mut self, krate: &'tcx hir::Crate) -> Module<'tcx> {
+    pub fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> {
         let mut module = self.visit_mod_contents(
             krate.item.span,
             krate.item.attrs,
@@ -84,10 +84,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
     fn visit_variant_data(
         &mut self,
-        item: &'tcx hir::Item,
+        item: &'tcx hir::Item<'_>,
         name: Symbol,
-        sd: &'tcx hir::VariantData,
-        generics: &'tcx hir::Generics,
+        sd: &'tcx hir::VariantData<'_>,
+        generics: &'tcx hir::Generics<'_>,
     ) -> Struct<'tcx> {
         debug!("visiting struct");
         let struct_type = struct_type_from_def(&*sd);
@@ -105,10 +105,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
     fn visit_union_data(
         &mut self,
-        item: &'tcx hir::Item,
+        item: &'tcx hir::Item<'_>,
         name: Symbol,
-        sd: &'tcx hir::VariantData,
-        generics: &'tcx hir::Generics,
+        sd: &'tcx hir::VariantData<'_>,
+        generics: &'tcx hir::Generics<'_>,
     ) -> Union<'tcx> {
         debug!("visiting union");
         let struct_type = struct_type_from_def(&*sd);
@@ -126,10 +126,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
     fn visit_enum_def(
         &mut self,
-        it: &'tcx hir::Item,
+        it: &'tcx hir::Item<'_>,
         name: Symbol,
-        def: &'tcx hir::EnumDef,
-        generics: &'tcx hir::Generics,
+        def: &'tcx hir::EnumDef<'_>,
+        generics: &'tcx hir::Generics<'_>,
     ) -> Enum<'tcx> {
         debug!("visiting enum");
         Enum {
@@ -156,11 +156,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     fn visit_fn(
         &mut self,
         om: &mut Module<'tcx>,
-        item: &'tcx hir::Item,
+        item: &'tcx hir::Item<'_>,
         name: Symbol,
-        decl: &'tcx hir::FnDecl,
+        decl: &'tcx hir::FnDecl<'_>,
         header: hir::FnHeader,
-        generics: &'tcx hir::Generics,
+        generics: &'tcx hir::Generics<'_>,
         body: hir::BodyId,
     ) {
         debug!("visiting fn");
@@ -231,7 +231,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         &mut self,
         span: Span,
         attrs: &'tcx [ast::Attribute],
-        vis: &'tcx hir::Visibility,
+        vis: &'tcx hir::Visibility<'_>,
         id: hir::HirId,
         m: &'tcx hir::Mod<'tcx>,
         name: Option<Symbol>,
@@ -375,7 +375,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         ret
     }
 
-    fn visit_item(&mut self, item: &'tcx hir::Item, renamed: Option<Ident>, om: &mut Module<'tcx>) {
+    fn visit_item(
+        &mut self,
+        item: &'tcx hir::Item<'_>,
+        renamed: Option<Ident>,
+        om: &mut Module<'tcx>,
+    ) {
         debug!("visiting item {:?}", item);
         let ident = renamed.unwrap_or(item.ident);
 
@@ -587,7 +592,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
     fn visit_foreign_item(
         &mut self,
-        item: &'tcx hir::ForeignItem,
+        item: &'tcx hir::ForeignItem<'_>,
         renamed: Option<Ident>,
         om: &mut Module<'tcx>,
     ) {
@@ -607,7 +612,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     }
 
     // Convert each `exported_macro` into a doc item.
-    fn visit_local_macro(&self, def: &'tcx hir::MacroDef, renamed: Option<Symbol>) -> Macro<'tcx> {
+    fn visit_local_macro(
+        &self,
+        def: &'tcx hir::MacroDef<'_>,
+        renamed: Option<Symbol>,
+    ) -> Macro<'tcx> {
         debug!("visit_local_macro: {}", def.ident);
         let tts = def.ast.body.inner_tokens().trees().collect::<Vec<_>>();
         // Extract the spans of all matchers. They represent the "interface" of the macro.
diff --git a/src/test/codegen/debug-linkage-name.rs b/src/test/codegen/debug-linkage-name.rs
new file mode 100644
index 00000000000..0d7dca3aba3
--- /dev/null
+++ b/src/test/codegen/debug-linkage-name.rs
@@ -0,0 +1,42 @@
+// Verifies that linkage name is omitted when it is
+// the same as variable / function name.
+//
+// compile-flags: -C no-prepopulate-passes
+// compile-flags: -C debuginfo=2
+#![crate_type = "lib"]
+
+pub mod xyz {
+    // CHECK: !DIGlobalVariable(name: "A",
+    // CHECK:                   linkageName:
+    // CHECK-SAME:              line: 12,
+    pub static A: u32 = 1;
+
+    // CHECK: !DIGlobalVariable(name: "B",
+    // CHECK-NOT:               linkageName:
+    // CHECK-SAME:              line: 18,
+    #[no_mangle]
+    pub static B: u32 = 2;
+
+    // CHECK: !DIGlobalVariable(name: "C",
+    // CHECK-NOT:               linkageName:
+    // CHECK-SAME:              line: 24,
+    #[export_name = "C"]
+    pub static C: u32 = 2;
+
+    // CHECK: !DISubprogram(name: "e",
+    // CHECK:               linkageName:
+    // CHECK-SAME:          line: 29,
+    pub extern fn e() {}
+
+    // CHECK: !DISubprogram(name: "f",
+    // CHECK-NOT:           linkageName:
+    // CHECK-SAME:          line: 35,
+    #[no_mangle]
+    pub extern fn f() {}
+
+    // CHECK: !DISubprogram(name: "g",
+    // CHECK-NOT:           linkageName:
+    // CHECK-SAME:          line: 41,
+    #[export_name = "g"]
+    pub extern fn g() {}
+}
diff --git a/src/test/ui/chalkify/closure.rs b/src/test/ui/chalkify/closure.rs
new file mode 100644
index 00000000000..81114d491d7
--- /dev/null
+++ b/src/test/ui/chalkify/closure.rs
@@ -0,0 +1,39 @@
+// check-fail
+// compile-flags: -Z chalk
+
+fn main() -> () {
+    let t = || {};
+    t();
+
+    let mut a = 0;
+    let mut b = move || {
+        a = 1;
+    };
+    b();
+
+    let mut c = b;
+
+    c();
+    b();
+
+    let mut a = 0;
+    let mut b = || {
+        a = 1;
+    };
+    b();
+
+    let mut c = b;
+
+    c();
+    b(); //~ ERROR
+
+    // FIXME(chalk): this doesn't quite work
+    /*
+    let b = |c| {
+        c
+    };
+
+    let a = &32;
+    b(a);
+    */
+}
diff --git a/src/test/ui/chalkify/closure.stderr b/src/test/ui/chalkify/closure.stderr
new file mode 100644
index 00000000000..d5a48a7dc6f
--- /dev/null
+++ b/src/test/ui/chalkify/closure.stderr
@@ -0,0 +1,18 @@
+error[E0382]: borrow of moved value: `b`
+  --> $DIR/closure.rs:28:5
+   |
+LL |     let mut c = b;
+   |                 - value moved here
+...
+LL |     b();
+   |     ^ value borrowed here after move
+   |
+note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment
+  --> $DIR/closure.rs:21:9
+   |
+LL |         a = 1;
+   |         ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/chalkify/impl_wf.rs b/src/test/ui/chalkify/impl_wf.rs
index fdc94f69bf2..465eb10241e 100644
--- a/src/test/ui/chalkify/impl_wf.rs
+++ b/src/test/ui/chalkify/impl_wf.rs
@@ -23,15 +23,10 @@ impl<T> Bar for Option<T> {
     type Item = Option<T>;
 }
 
-// FIXME(chalk): the ordering of these two errors differs between CI and local
-// We need to figure out why its non-deterministic
-/*
 impl Bar for f32 {
-//^ ERROR the trait bound `f32: Foo` is not satisfied
     type Item = f32;
-    //^ ERROR the trait bound `f32: Foo` is not satisfied
+    //~^ ERROR the trait bound `f32: Foo` is not satisfied
 }
-*/
 
 trait Baz<U: ?Sized> where U: Foo { }
 
diff --git a/src/test/ui/chalkify/impl_wf.stderr b/src/test/ui/chalkify/impl_wf.stderr
index 5293bbaecd3..e5d7615e43e 100644
--- a/src/test/ui/chalkify/impl_wf.stderr
+++ b/src/test/ui/chalkify/impl_wf.stderr
@@ -11,7 +11,18 @@ LL | impl Foo for str { }
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
 
 error[E0277]: the trait bound `f32: Foo` is not satisfied
-  --> $DIR/impl_wf.rs:40:6
+  --> $DIR/impl_wf.rs:27:17
+   |
+LL | trait Bar {
+   |       --- required by a bound in this
+LL |     type Item: Foo;
+   |                --- required by this bound in `Bar`
+...
+LL |     type Item = f32;
+   |                 ^^^ the trait `Foo` is not implemented for `f32`
+
+error[E0277]: the trait bound `f32: Foo` is not satisfied
+  --> $DIR/impl_wf.rs:35:6
    |
 LL | trait Baz<U: ?Sized> where U: Foo { }
    |                               --- required by this bound in `Baz`
@@ -19,6 +30,6 @@ LL | trait Baz<U: ?Sized> where U: Foo { }
 LL | impl Baz<f32> for f32 { }
    |      ^^^^^^^^ the trait `Foo` is not implemented for `f32`
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/chalkify/inherent_impl.rs b/src/test/ui/chalkify/inherent_impl.rs
index 9dd9eb320dd..a2730219fbe 100644
--- a/src/test/ui/chalkify/inherent_impl.rs
+++ b/src/test/ui/chalkify/inherent_impl.rs
@@ -1,7 +1,5 @@
 // run-pass
 // compile-flags: -Z chalk
-// FIXME(chalk): remove when uncommented
-#![allow(dead_code, unused_variables)]
 
 trait Foo { }
 
@@ -11,8 +9,6 @@ struct S<T: Foo> {
     x: T,
 }
 
-// FIXME(chalk): need late-bound regions on FnDefs
-/*
 fn only_foo<T: Foo>(_x: &T) { }
 
 impl<T> S<T> {
@@ -21,7 +17,6 @@ impl<T> S<T> {
         only_foo(&self.x)
     }
 }
-*/
 
 trait Bar { }
 impl Bar for u32 { }
@@ -31,16 +26,10 @@ fn only_bar<T: Bar>() { }
 impl<T> S<T> {
     // Test that the environment of `dummy_bar` adds up with the environment
     // of the inherent impl.
-    // FIXME(chalk): need late-bound regions on FnDefs
-    /*
     fn dummy_bar<U: Bar>(&self) {
         only_foo(&self.x);
         only_bar::<U>();
     }
-    */
-    fn dummy_bar<U: Bar>() {
-        only_bar::<U>();
-    }
 }
 
 fn main() {
@@ -48,10 +37,6 @@ fn main() {
         x: 5,
     };
 
-    // FIXME(chalk): need late-bound regions on FnDefs
-    /*
-    s.dummy_foo();
     s.dummy_bar::<u32>();
-    */
-    S::<i32>::dummy_bar::<u32>();
+    s.dummy_foo();
 }
diff --git a/src/test/ui/chalkify/recursive_where_clause_on_type.rs b/src/test/ui/chalkify/recursive_where_clause_on_type.rs
index 6ee13f5e7a1..87324a5f79b 100644
--- a/src/test/ui/chalkify/recursive_where_clause_on_type.rs
+++ b/src/test/ui/chalkify/recursive_where_clause_on_type.rs
@@ -1,5 +1,5 @@
 // FIXME(chalk): should fail, see comments
-// check-pass
+// check-fail
 // compile-flags: -Z chalk
 
 #![feature(trivial_bounds)]
@@ -10,7 +10,6 @@ trait Bar {
 trait Foo: Bar { }
 
 struct S where S: Foo;
-//~^ WARN Trait bound S: Foo does not depend on any type or lifetime parameters
 
 impl Foo for S {
 }
@@ -26,10 +25,6 @@ fn foo<T: Foo>() {
 fn main() {
     // For some reason, the error is duplicated...
 
-    // FIXME(chalk): this order of this duplicate error seems non-determistic
-    // and causes test to fail
-    /*
-    foo::<S>() // ERROR the type `S` is not well-formed (chalk)
-    //^ ERROR the type `S` is not well-formed (chalk)
-    */
+    foo::<S>() //~ ERROR the type `S` is not well-formed (chalk)
+    //~^ ERROR the type `S` is not well-formed (chalk)
 }
diff --git a/src/test/ui/chalkify/recursive_where_clause_on_type.stderr b/src/test/ui/chalkify/recursive_where_clause_on_type.stderr
index a5b7ef7fdb2..fddd5895927 100644
--- a/src/test/ui/chalkify/recursive_where_clause_on_type.stderr
+++ b/src/test/ui/chalkify/recursive_where_clause_on_type.stderr
@@ -1,10 +1,14 @@
-warning: Trait bound S: Foo does not depend on any type or lifetime parameters
-  --> $DIR/recursive_where_clause_on_type.rs:12:19
+error: the type `S` is not well-formed (chalk)
+  --> $DIR/recursive_where_clause_on_type.rs:28:11
    |
-LL | struct S where S: Foo;
-   |                   ^^^
+LL |     foo::<S>()
+   |           ^
+
+error: the type `S` is not well-formed (chalk)
+  --> $DIR/recursive_where_clause_on_type.rs:28:5
    |
-   = note: `#[warn(trivial_bounds)]` on by default
+LL |     foo::<S>()
+   |     ^^^^^^^^
 
-warning: 1 warning emitted
+error: aborting due to 2 previous errors
 
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 9eb43eb2df4..614e2558960 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -4,8 +4,6 @@
 //! via `x.py dist hash-and-sign`; the cmdline arguments are set up
 //! by rustbuild (in `src/bootstrap/dist.rs`).
 
-#![deny(warnings)]
-
 use serde::Serialize;
 
 use std::collections::BTreeMap;
diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs
index 6968822c1b8..ecaeda68695 100644
--- a/src/tools/cargotest/main.rs
+++ b/src/tools/cargotest/main.rs
@@ -1,5 +1,3 @@
-#![deny(warnings)]
-
 use std::env;
 use std::fs;
 use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
index e60e2a81e07..e19a79dd8da 100755
--- a/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/ast_utils.rs
@@ -476,7 +476,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
         && match (&l.kind, &r.kind) {
             (Lifetime, Lifetime) => true,
             (Type { default: l }, Type { default: r }) => both(l, r, |l, r| eq_ty(l, r)),
-            (Const { ty: l }, Const { ty: r }) => eq_ty(l, r),
+            (Const { ty: l, kw_span: _ }, Const { ty: r, kw_span: _ }) => eq_ty(l, r),
             _ => false,
         }
         && over(&l.attrs, &r.attrs, |l, r| eq_attr(l, r))
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 134ac66b7d1..2aea4d22700 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -1,5 +1,4 @@
 #![crate_name = "compiletest"]
-#![deny(warnings)]
 // The `test` crate is the only unstable feature
 // allowed here, just to share similar code.
 #![feature(test)]
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 3335816f09f..097fb1f985a 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -1,5 +1,4 @@
 #![feature(rustc_private)]
-#![deny(warnings)]
 
 extern crate env_logger;
 extern crate rustc_ast;
diff --git a/src/tools/expand-yaml-anchors/src/main.rs b/src/tools/expand-yaml-anchors/src/main.rs
index f2ed8aa409a..d8dad8fc789 100644
--- a/src/tools/expand-yaml-anchors/src/main.rs
+++ b/src/tools/expand-yaml-anchors/src/main.rs
@@ -165,7 +165,7 @@ struct StrError(String);
 impl Error for StrError {}
 
 impl std::fmt::Display for StrError {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.0, f)
     }
 }
@@ -177,7 +177,7 @@ struct WithContext {
 }
 
 impl std::fmt::Display for WithContext {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         write!(f, "{}", self.context)
     }
 }
diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs
index 570ffd5d306..9e4e2c433fb 100644
--- a/src/tools/linkchecker/main.rs
+++ b/src/tools/linkchecker/main.rs
@@ -14,8 +14,6 @@
 //! A few whitelisted exceptions are allowed as there's known bugs in rustdoc,
 //! but this should catch the majority of "broken link" cases.
 
-#![deny(warnings)]
-
 use std::collections::hash_map::Entry;
 use std::collections::{HashMap, HashSet};
 use std::env;
diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs
index 1fafe109d34..6245b76fd6e 100644
--- a/src/tools/remote-test-client/src/main.rs
+++ b/src/tools/remote-test-client/src/main.rs
@@ -5,8 +5,6 @@
 //! Here is also where we bake in the support to spawn the QEMU emulator as
 //! well.
 
-#![deny(warnings)]
-
 use std::env;
 use std::fs::{self, File};
 use std::io::prelude::*;
diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs
index 8c56910e2df..d92758eb747 100644
--- a/src/tools/remote-test-server/src/main.rs
+++ b/src/tools/remote-test-server/src/main.rs
@@ -10,8 +10,6 @@
 //! themselves having support libraries. All data over the TCP sockets is in a
 //! basically custom format suiting our needs.
 
-#![deny(warnings)]
-
 #[cfg(not(windows))]
 use std::fs::Permissions;
 #[cfg(not(windows))]
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index e2856c69055..2d105c7f33a 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -4,8 +4,6 @@
 //! etc. This is run by default on `./x.py test` and as part of the auto
 //! builders. The tidy checks can be executed with `./x.py test tidy`.
 
-#![deny(warnings)]
-
 use tidy::*;
 
 use std::env;
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 247e85603cf..7e77ae1db0d 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -67,6 +67,7 @@ const EXCEPTION_PATHS: &[&str] = &[
     // std testing crates, okay for now at least
     "src/libcore/tests",
     "src/liballoc/tests/lib.rs",
+    "src/liballoc/benches/lib.rs",
     // The `VaList` implementation must have platform specific code.
     // The Windows implementation of a `va_list` is always a character
     // pointer regardless of the target architecture. As a result,
diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs
index c9d1561a9d3..aa24881ac6b 100644
--- a/src/tools/unstable-book-gen/src/main.rs
+++ b/src/tools/unstable-book-gen/src/main.rs
@@ -1,7 +1,5 @@
 //! Auto-generate stub docs for the unstable book
 
-#![deny(warnings)]
-
 use std::collections::BTreeSet;
 use std::env;
 use std::fs::{self, File};