Auto merge of #82703 - iago-lito:nonzero_add_mul_pow, r=m-ou-se

Implement nonzero arithmetics for NonZero types.

Hello'all, this is my first PR to this repo.

Non-zero natural numbers are stable by addition/multiplication/exponentiation, so it makes sense to make this arithmetic possible with `NonZeroU*`.

The major pitfall is that overflowing underlying `u*` types possibly lead to underlying `0` values, which break the major invariant of `NonZeroU*`. To accommodate it, only `checked_` and `saturating_` operations are implemented.

Other variants allowing wrapped results like `wrapping_` or `overflowing_` are ruled out *de facto*.

`impl Add<u*> for NonZeroU* { .. }` was considered, as it panics on overflow which enforces the invariant, but it does not so in release mode. I considered forcing `NonZeroU*::add` to panic in release mode by deferring the check to `u*::checked_add`, but this is less explicit for the user than directly using `NonZeroU*::checked_add`.
Following `@Lokathor's` advice on zulip, I have dropped the idea.

`@poliorcetics` on Discord also suggested implementing `_sub` operations, but I'd postpone this to another PR if there is a need for it. My opinion is that it could be useful in some cases, but that it makes less sense because non-null natural numbers are not stable by subtraction even in theory, while the overflowing problem is just about technical implementation.

One thing I don't like is that the type of the `other` arg differs in every implementation: `_add` methods accept any raw positive integer, `_mul` methods only accept non-zero values otherwise the invariant is also broken, and `_pow` only seems to accept `u32` for a reason I ignore but that seems consistent throughout `std`. Maybe there is a better way to harmonize this?

This is it, Iope I haven't forgotten anything and I'll be happy to read your feedback.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index aa9d97b..3636263 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -259,6 +259,11 @@
           - name: x86_64-gnu
             os: ubuntu-latest-xl
             env: {}
+          - name: x86_64-gnu-stable
+            env:
+              IMAGE: x86_64-gnu
+              RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
+            os: ubuntu-latest-xl
           - name: x86_64-gnu-aux
             os: ubuntu-latest-xl
             env: {}
diff --git a/Cargo.lock b/Cargo.lock
index 2c29663..de110c5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3693,6 +3693,7 @@
  "rustc_incremental",
  "rustc_index",
  "rustc_llvm",
+ "rustc_metadata",
  "rustc_middle",
  "rustc_serialize",
  "rustc_session",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index b3bac1d..93d7a59 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -623,12 +623,13 @@
             PatKind::Ident(_, _, Some(p)) => p.walk(it),
 
             // Walk into each field of struct.
-            PatKind::Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
+            PatKind::Struct(_, _, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
 
             // Sequence of patterns.
-            PatKind::TupleStruct(_, s) | PatKind::Tuple(s) | PatKind::Slice(s) | PatKind::Or(s) => {
-                s.iter().for_each(|p| p.walk(it))
-            }
+            PatKind::TupleStruct(_, _, s)
+            | PatKind::Tuple(s)
+            | PatKind::Slice(s)
+            | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
 
             // Trivial wrappers over inner patterns.
             PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it),
@@ -701,10 +702,10 @@
 
     /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
     /// The `bool` is `true` in the presence of a `..`.
-    Struct(Path, Vec<PatField>, /* recovered */ bool),
+    Struct(Option<QSelf>, Path, Vec<PatField>, /* recovered */ bool),
 
     /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
-    TupleStruct(Path, Vec<P<Pat>>),
+    TupleStruct(Option<QSelf>, Path, Vec<P<Pat>>),
 
     /// An or-pattern `A | B | C`.
     /// Invariant: `pats.len() >= 2`.
@@ -1247,6 +1248,7 @@
 
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct StructExpr {
+    pub qself: Option<QSelf>,
     pub path: Path,
     pub fields: Vec<ExprField>,
     pub rest: StructRest,
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 071d41e..0b6099f 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1139,7 +1139,8 @@
             visit_opt(sub, |sub| vis.visit_pat(sub));
         }
         PatKind::Lit(e) => vis.visit_expr(e),
-        PatKind::TupleStruct(path, elems) => {
+        PatKind::TupleStruct(qself, path, elems) => {
+            vis.visit_qself(qself);
             vis.visit_path(path);
             visit_vec(elems, |elem| vis.visit_pat(elem));
         }
@@ -1147,7 +1148,8 @@
             vis.visit_qself(qself);
             vis.visit_path(path);
         }
-        PatKind::Struct(path, fields, _etc) => {
+        PatKind::Struct(qself, path, fields, _etc) => {
+            vis.visit_qself(qself);
             vis.visit_path(path);
             fields.flat_map_in_place(|field| vis.flat_map_pat_field(field));
         }
@@ -1333,7 +1335,8 @@
         }
         ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
         ExprKind::Struct(se) => {
-            let StructExpr { path, fields, rest } = se.deref_mut();
+            let StructExpr { qself, path, fields, rest } = se.deref_mut();
+            vis.visit_qself(qself);
             vis.visit_path(path);
             fields.flat_map_in_place(|field| vis.flat_map_expr_field(field));
             match rest {
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index f1a99bc..1ebfcf3 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -497,7 +497,10 @@
 
 pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
     match pattern.kind {
-        PatKind::TupleStruct(ref path, ref elems) => {
+        PatKind::TupleStruct(ref opt_qself, ref path, ref elems) => {
+            if let Some(ref qself) = *opt_qself {
+                visitor.visit_ty(&qself.ty);
+            }
             visitor.visit_path(path, pattern.id);
             walk_list!(visitor, visit_pat, elems);
         }
@@ -507,7 +510,10 @@
             }
             visitor.visit_path(path, pattern.id)
         }
-        PatKind::Struct(ref path, ref fields, _) => {
+        PatKind::Struct(ref opt_qself, ref path, ref fields, _) => {
+            if let Some(ref qself) = *opt_qself {
+                visitor.visit_ty(&qself.ty);
+            }
             visitor.visit_path(path, pattern.id);
             walk_list!(visitor, visit_pat_field, fields);
         }
@@ -740,6 +746,9 @@
             visitor.visit_anon_const(count)
         }
         ExprKind::Struct(ref se) => {
+            if let Some(ref qself) = se.qself {
+                visitor.visit_ty(&qself.ty);
+            }
             visitor.visit_path(&se.path, expression.id);
             walk_list!(visitor, visit_expr_field, &se.fields);
             match &se.rest {
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 866f218..b9dcd08 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -237,7 +237,7 @@
                     hir::ExprKind::Struct(
                         self.arena.alloc(self.lower_qpath(
                             e.id,
-                            &None,
+                            &se.qself,
                             &se.path,
                             ParamMode::Optional,
                             ImplTraitContext::disallowed(),
@@ -1041,10 +1041,12 @@
     /// It is not a complete check, but just tries to reject most paths early
     /// if they are not tuple structs.
     /// Type checking will take care of the full validation later.
-    fn extract_tuple_struct_path<'a>(&mut self, expr: &'a Expr) -> Option<&'a Path> {
-        // For tuple struct destructuring, it must be a non-qualified path (like in patterns).
-        if let ExprKind::Path(None, path) = &expr.kind {
-            // Does the path resolves to something disallowed in a tuple struct/variant pattern?
+    fn extract_tuple_struct_path<'a>(
+        &mut self,
+        expr: &'a Expr,
+    ) -> Option<(&'a Option<QSelf>, &'a Path)> {
+        if let ExprKind::Path(qself, path) = &expr.kind {
+            // Does the path resolve to something disallowed in a tuple struct/variant pattern?
             if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
                 if partial_res.unresolved_segments() == 0
                     && !partial_res.base_res().expected_in_tuple_struct_pat()
@@ -1052,7 +1054,7 @@
                     return None;
                 }
             }
-            return Some(path);
+            return Some((qself, path));
         }
         None
     }
@@ -1088,7 +1090,7 @@
             }
             // Tuple structs.
             ExprKind::Call(callee, args) => {
-                if let Some(path) = self.extract_tuple_struct_path(callee) {
+                if let Some((qself, path)) = self.extract_tuple_struct_path(callee) {
                     let (pats, rest) = self.destructure_sequence(
                         args,
                         "tuple struct or variant",
@@ -1097,7 +1099,7 @@
                     );
                     let qpath = self.lower_qpath(
                         callee.id,
-                        &None,
+                        qself,
                         path,
                         ParamMode::Optional,
                         ImplTraitContext::disallowed(),
@@ -1122,7 +1124,7 @@
                 }));
                 let qpath = self.lower_qpath(
                     lhs.id,
-                    &None,
+                    &se.qself,
                     &se.path,
                     ParamMode::Optional,
                     ImplTraitContext::disallowed(),
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2451409..66e6235 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -21,10 +21,10 @@
                         break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
                     }
                     PatKind::Lit(ref e) => break hir::PatKind::Lit(self.lower_expr(e)),
-                    PatKind::TupleStruct(ref path, ref pats) => {
+                    PatKind::TupleStruct(ref qself, ref path, ref pats) => {
                         let qpath = self.lower_qpath(
                             pattern.id,
-                            &None,
+                            qself,
                             path,
                             ParamMode::Optional,
                             ImplTraitContext::disallowed(),
@@ -47,10 +47,10 @@
                         );
                         break hir::PatKind::Path(qpath);
                     }
-                    PatKind::Struct(ref path, ref fields, etc) => {
+                    PatKind::Struct(ref qself, ref path, ref fields, etc) => {
                         let qpath = self.lower_qpath(
                             pattern.id,
-                            &None,
+                            qself,
                             path,
                             ParamMode::Optional,
                             ImplTraitContext::disallowed(),
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index ba2da76..30aa51a 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -938,8 +938,11 @@
                 }
                 GenericParamKind::Type { default: None } => (),
                 GenericParamKind::Lifetime => (),
-                // FIXME(const_generics_defaults)
-                GenericParamKind::Const { ty: _, kw_span: _, default: _ } => (),
+                GenericParamKind::Const { ty: _, kw_span: _, default: Some(default) } => {
+                    ordered_params += " = ";
+                    ordered_params += &pprust::expr_to_string(&*default.value);
+                }
+                GenericParamKind::Const { ty: _, kw_span: _, default: None } => (),
             }
             first = false;
         }
@@ -959,7 +962,7 @@
             span,
             &format!(
                 "reorder the parameters: lifetimes, {}",
-                if sess.features_untracked().const_generics {
+                if sess.features_untracked().unordered_const_ty_params() {
                     "then consts and types"
                 } else {
                     "then types, then consts"
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 664e138..3f98944 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -705,6 +705,7 @@
         "async closures are unstable",
         "to use an async block, remove the `||`: `async {`"
     );
+    gate_all!(more_qualified_paths, "usage of qualified paths in this context is experimental");
     gate_all!(generators, "yield syntax is experimental");
     gate_all!(raw_ref_op, "raw address of syntax is experimental");
     gate_all!(const_trait_bound_opt_out, "`?const` on trait bounds is experimental");
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index b7bb896..93facd2 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1713,11 +1713,16 @@
 
     fn print_expr_struct(
         &mut self,
+        qself: &Option<ast::QSelf>,
         path: &ast::Path,
         fields: &[ast::ExprField],
         rest: &ast::StructRest,
     ) {
-        self.print_path(path, true, 0);
+        if let Some(qself) = qself {
+            self.print_qpath(path, qself, true);
+        } else {
+            self.print_path(path, true, 0);
+        }
         self.s.word("{");
         self.commasep_cmnt(
             Consistent,
@@ -1874,7 +1879,7 @@
                 self.print_expr_repeat(element, count);
             }
             ast::ExprKind::Struct(ref se) => {
-                self.print_expr_struct(&se.path, &se.fields, &se.rest);
+                self.print_expr_struct(&se.qself, &se.path, &se.fields, &se.rest);
             }
             ast::ExprKind::Tup(ref exprs) => {
                 self.print_expr_tup(exprs);
@@ -2340,8 +2345,12 @@
                     self.print_pat(p);
                 }
             }
-            PatKind::TupleStruct(ref path, ref elts) => {
-                self.print_path(path, true, 0);
+            PatKind::TupleStruct(ref qself, ref path, ref elts) => {
+                if let Some(qself) = qself {
+                    self.print_qpath(path, qself, true);
+                } else {
+                    self.print_path(path, true, 0);
+                }
                 self.popen();
                 self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p));
                 self.pclose();
@@ -2355,8 +2364,12 @@
             PatKind::Path(Some(ref qself), ref path) => {
                 self.print_qpath(path, qself, false);
             }
-            PatKind::Struct(ref path, ref fields, etc) => {
-                self.print_path(path, true, 0);
+            PatKind::Struct(ref qself, ref path, ref fields, etc) => {
+                if let Some(qself) = qself {
+                    self.print_qpath(path, qself, true);
+                } else {
+                    self.print_path(path, true, 0);
+                }
                 self.nbsp();
                 self.word_space("{");
                 self.commasep_cmnt(
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index 904efed..6aadaf8 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -14,6 +14,7 @@
 extern crate rustc_hir;
 extern crate rustc_incremental;
 extern crate rustc_index;
+extern crate rustc_metadata;
 extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;
diff --git a/compiler/rustc_codegen_cranelift/src/metadata.rs b/compiler/rustc_codegen_cranelift/src/metadata.rs
index ab23824..db24bf6 100644
--- a/compiler/rustc_codegen_cranelift/src/metadata.rs
+++ b/compiler/rustc_codegen_cranelift/src/metadata.rs
@@ -10,7 +10,7 @@
     use std::io::Write;
 
     let metadata = tcx.encode_metadata();
-    let mut compressed = tcx.metadata_encoding_version();
+    let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
     FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
 
     object.add_rustc_section(
diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml
index 4999cb3..d0eb691 100644
--- a/compiler/rustc_codegen_llvm/Cargo.toml
+++ b/compiler/rustc_codegen_llvm/Cargo.toml
@@ -27,6 +27,7 @@
 rustc_incremental = { path = "../rustc_incremental" }
 rustc_index = { path = "../rustc_index" }
 rustc_llvm = { path = "../rustc_llvm" }
+rustc_metadata = { path = "../rustc_metadata" }
 rustc_session = { path = "../rustc_session" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_target = { path = "../rustc_target" }
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index 893c909..cc3cbea 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -63,7 +63,7 @@
     let section_name = if tcx.sess.target.is_like_osx { "__DATA,.rustc" } else { ".rustc" };
 
     let (metadata_llcx, metadata_llmod) = (&*llvm_module.llcx, llvm_module.llmod());
-    let mut compressed = tcx.metadata_encoding_version();
+    let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
     FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
 
     let llmeta = common::bytes_in_context(metadata_llcx, &compressed);
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 387062a..0dd3d2a 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -1,5 +1,5 @@
 use crate::back::write::create_informational_target_machine;
-use crate::llvm;
+use crate::{llvm, llvm_util};
 use libc::c_int;
 use rustc_codegen_ssa::target_features::supported_target_features;
 use rustc_data_structures::fx::FxHashSet;
@@ -84,6 +84,17 @@
         if !sess.opts.debugging_opts.no_generate_arange_section {
             add("-generate-arange-section", false);
         }
+
+        // FIXME(nagisa): disable the machine outliner by default in LLVM versions 11, where it was
+        // introduced and up.
+        //
+        // This should remain in place until https://reviews.llvm.org/D103167 is fixed. If LLVM
+        // has been upgraded since, consider adjusting the version check below to contain an upper
+        // bound.
+        if llvm_util::get_version() >= (11, 0, 0) {
+            add("-enable-machine-outliner=never", false);
+        }
+
         match sess.opts.debugging_opts.merge_functions.unwrap_or(sess.target.merge_functions) {
             MergeFunctions::Disabled | MergeFunctions::Trampolines => {}
             MergeFunctions::Aliases => {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 6a2005b..6c9ec9e 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -5,7 +5,7 @@
 use rustc_hir::def_id::CrateNum;
 use rustc_middle::middle::cstore::{DllImport, LibSource};
 use rustc_middle::middle::dependency_format::Linkage;
-use rustc_session::config::{self, CFGuard, CrateType, DebugInfo};
+use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
 use rustc_session::config::{OutputFilenames, OutputType, PrintRequest};
 use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
 use rustc_session::search_paths::PathKind;
@@ -907,14 +907,6 @@
         }
     }
 
-    fn escape_string(s: &[u8]) -> String {
-        str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
-            let mut x = "Non-UTF-8 output: ".to_string();
-            x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
-            x
-        })
-    }
-
     match prog {
         Ok(prog) => {
             if !prog.status.success() {
@@ -1056,6 +1048,47 @@
         // ... and otherwise we're processing a `*.dwp` packed dwarf file.
         SplitDebuginfo::Packed => link_dwarf_object(sess, &out_filename),
     }
+
+    if sess.target.is_like_osx {
+        if let Some(option) = osx_strip_opt(sess.opts.debugging_opts.strip) {
+            strip_symbols_in_osx(sess, &out_filename, option);
+        }
+    }
+}
+
+fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: &str) {
+    let prog = Command::new("strip").arg(option).arg(out_filename).output();
+    match prog {
+        Ok(prog) => {
+            if !prog.status.success() {
+                let mut output = prog.stderr.clone();
+                output.extend_from_slice(&prog.stdout);
+                sess.struct_warn(&format!(
+                    "stripping debug info with `strip` failed: {}",
+                    prog.status
+                ))
+                .note(&escape_string(&output))
+                .emit();
+            }
+        }
+        Err(e) => sess.fatal(&format!("unable to run `strip`: {}", e)),
+    }
+}
+
+fn osx_strip_opt<'a>(strip: Strip) -> Option<&'a str> {
+    match strip {
+        Strip::Debuginfo => Some("-S"),
+        Strip::Symbols => Some("-x"),
+        Strip::None => None,
+    }
+}
+
+fn escape_string(s: &[u8]) -> String {
+    str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
+        let mut x = "Non-UTF-8 output: ".to_string();
+        x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
+        x
+    })
 }
 
 fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) {
@@ -1894,6 +1927,8 @@
     out_filename: &Path,
     tmpdir: &Path,
 ) {
+    add_gcc_ld_path(cmd, sess, flavor);
+
     add_apple_sdk(cmd, sess, flavor);
 
     add_link_script(cmd, sess, tmpdir, crate_type);
@@ -2495,3 +2530,30 @@
         Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
     }
 }
+
+fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
+    if let Some(ld_impl) = sess.opts.debugging_opts.gcc_ld {
+        if let LinkerFlavor::Gcc = flavor {
+            match ld_impl {
+                LdImpl::Lld => {
+                    let tools_path =
+                        sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
+                    let lld_path = tools_path
+                        .into_iter()
+                        .map(|p| p.join("gcc-ld"))
+                        .find(|p| {
+                            p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()
+                        })
+                        .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found"));
+                    cmd.cmd().arg({
+                        let mut arg = OsString::from("-B");
+                        arg.push(lld_path);
+                        arg
+                    });
+                }
+            }
+        } else {
+            sess.fatal("option `-Z gcc-ld` is used even though linker flavor is not gcc");
+        }
+    }
+}
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 1d53e9a..43ff664 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -526,15 +526,18 @@
     fn control_flow_guard(&mut self) {}
 
     fn debuginfo(&mut self, strip: Strip) {
+        // MacOS linker doesn't support stripping symbols directly anymore.
+        if self.sess.target.is_like_osx {
+            return;
+        }
+
         match strip {
             Strip::None => {}
             Strip::Debuginfo => {
-                // MacOS linker does not support longhand argument --strip-debug
-                self.linker_arg("-S");
+                self.linker_arg("--strip-debug");
             }
             Strip::Symbols => {
-                // MacOS linker does not support longhand argument --strip-all
-                self.linker_arg("-s");
+                self.linker_arg("--strip-all");
             }
         }
     }
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 8a22a74..49b5e84 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -18,7 +18,10 @@
     let mir = fx.mir;
     let mut analyzer = LocalAnalyzer::new(fx);
 
-    for (bb, data) in mir.basic_blocks().iter_enumerated() {
+    // If there exists a local definition that dominates all uses of that local,
+    // the definition should be visited first. Traverse blocks in preorder which
+    // is a topological sort of dominance partial order.
+    for (bb, data) in traversal::preorder(&mir) {
         analyzer.visit_basic_block_data(bb, data);
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index b10de56..c89d42e 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -205,7 +205,7 @@
 ];
 
 const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
-    ("simd128", Some(sym::wasm_target_feature)),
+    ("simd128", None),
     ("atomics", Some(sym::wasm_target_feature)),
     ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
 ];
diff --git a/compiler/rustc_data_structures/src/box_region.rs b/compiler/rustc_data_structures/src/box_region.rs
deleted file mode 100644
index eb6f4e8..0000000
--- a/compiler/rustc_data_structures/src/box_region.rs
+++ /dev/null
@@ -1,169 +0,0 @@
-//! This module provides a way to deal with self-referential data.
-//!
-//! The main idea is to allocate such data in a generator frame and then
-//! give access to it by executing user-provided closures inside that generator.
-//! The module provides a safe abstraction for the latter task.
-//!
-//! The interface consists of two exported macros meant to be used together:
-//! * `declare_box_region_type` wraps a generator inside a struct with `access`
-//!   method which accepts closures.
-//! * `box_region_allow_access` is a helper which should be called inside
-//!   a generator to actually execute those closures.
-
-use std::marker::PhantomData;
-use std::ops::{Generator, GeneratorState};
-use std::pin::Pin;
-
-#[derive(Copy, Clone)]
-pub struct AccessAction(*mut dyn FnMut());
-
-impl AccessAction {
-    pub fn get(self) -> *mut dyn FnMut() {
-        self.0
-    }
-}
-
-#[derive(Copy, Clone)]
-pub enum Action {
-    Initial,
-    Access(AccessAction),
-    Complete,
-}
-
-pub struct PinnedGenerator<I, A, R> {
-    generator: Pin<Box<dyn Generator<Action, Yield = YieldType<I, A>, Return = R>>>,
-}
-
-impl<I, A, R> PinnedGenerator<I, A, R> {
-    pub fn new<T: Generator<Action, Yield = YieldType<I, A>, Return = R> + 'static>(
-        generator: T,
-    ) -> (I, Self) {
-        let mut result = PinnedGenerator { generator: Box::pin(generator) };
-
-        // Run it to the first yield to set it up
-        let init = match Pin::new(&mut result.generator).resume(Action::Initial) {
-            GeneratorState::Yielded(YieldType::Initial(y)) => y,
-            _ => panic!(),
-        };
-
-        (init, result)
-    }
-
-    pub unsafe fn access(&mut self, closure: *mut dyn FnMut()) {
-        // Call the generator, which in turn will call the closure
-        if let GeneratorState::Complete(_) =
-            Pin::new(&mut self.generator).resume(Action::Access(AccessAction(closure)))
-        {
-            panic!()
-        }
-    }
-
-    pub fn complete(&mut self) -> R {
-        // Tell the generator we want it to complete, consuming it and yielding a result
-        let result = Pin::new(&mut self.generator).resume(Action::Complete);
-        if let GeneratorState::Complete(r) = result { r } else { panic!() }
-    }
-}
-
-#[derive(PartialEq)]
-pub struct Marker<T>(PhantomData<T>);
-
-impl<T> Marker<T> {
-    pub unsafe fn new() -> Self {
-        Marker(PhantomData)
-    }
-}
-
-pub enum YieldType<I, A> {
-    Initial(I),
-    Accessor(Marker<A>),
-}
-
-#[macro_export]
-#[allow_internal_unstable(fn_traits)]
-macro_rules! declare_box_region_type {
-    (impl $v:vis
-     $name: ident,
-     $yield_type:ty,
-     for($($lifetimes:tt)*),
-     ($($args:ty),*) -> ($reti:ty, $retc:ty)
-    ) => {
-        $v struct $name($crate::box_region::PinnedGenerator<
-            $reti,
-            for<$($lifetimes)*> fn(($($args,)*)),
-            $retc
-        >);
-
-        impl $name {
-            fn new<T: ::std::ops::Generator<$crate::box_region::Action, Yield = $yield_type, Return = $retc> + 'static>(
-                generator: T
-            ) -> ($reti, Self) {
-                let (initial, pinned) = $crate::box_region::PinnedGenerator::new(generator);
-                (initial, $name(pinned))
-            }
-
-            $v fn access<F: for<$($lifetimes)*> FnOnce($($args,)*) -> R, R>(&mut self, f: F) -> R {
-                // Turn the FnOnce closure into *mut dyn FnMut()
-                // so we can pass it in to the generator
-                let mut r = None;
-                let mut f = Some(f);
-                let mut_f: &mut dyn for<$($lifetimes)*> FnMut(($($args,)*)) =
-                    &mut |args| {
-                        let f = f.take().unwrap();
-                        r = Some(FnOnce::call_once(f, args));
-                };
-                let mut_f = mut_f as *mut dyn for<$($lifetimes)*> FnMut(($($args,)*));
-
-                // Get the generator to call our closure
-                unsafe {
-                    self.0.access(::std::mem::transmute(mut_f));
-                }
-
-                // Unwrap the result
-                r.unwrap()
-            }
-
-            $v fn complete(mut self) -> $retc {
-                self.0.complete()
-            }
-
-            fn initial_yield(value: $reti) -> $yield_type {
-                $crate::box_region::YieldType::Initial(value)
-            }
-        }
-    };
-
-    ($v:vis $name: ident, for($($lifetimes:tt)*), ($($args:ty),*) -> ($reti:ty, $retc:ty)) => {
-        declare_box_region_type!(
-            impl $v $name,
-            $crate::box_region::YieldType<$reti, for<$($lifetimes)*> fn(($($args,)*))>,
-            for($($lifetimes)*),
-            ($($args),*) -> ($reti, $retc)
-        );
-    };
-}
-
-#[macro_export]
-#[allow_internal_unstable(fn_traits)]
-macro_rules! box_region_allow_access {
-    (for($($lifetimes:tt)*), ($($args:ty),*), ($($exprs:expr),*), $action:ident) => {
-        loop {
-            match $action {
-                $crate::box_region::Action::Access(accessor) => {
-                    let accessor: &mut dyn for<$($lifetimes)*> FnMut($($args),*) = unsafe {
-                        ::std::mem::transmute(accessor.get())
-                    };
-                    (*accessor)(($($exprs),*));
-                    unsafe {
-                        let marker = $crate::box_region::Marker::<
-                            for<$($lifetimes)*> fn(($($args,)*))
-                        >::new();
-                        $action = yield $crate::box_region::YieldType::Accessor(marker);
-                    };
-                }
-                $crate::box_region::Action::Complete => break,
-                $crate::box_region::Action::Initial => panic!("unexpected box_region action: Initial"),
-            }
-        }
-    }
-}
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index bbfe225..16151e9 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -10,7 +10,6 @@
 #![feature(array_windows)]
 #![feature(control_flow_enum)]
 #![feature(in_band_lifetimes)]
-#![feature(generator_trait)]
 #![feature(min_specialization)]
 #![feature(auto_traits)]
 #![feature(nll)]
@@ -63,7 +62,6 @@
 
 pub mod base_n;
 pub mod binary_search_util;
-pub mod box_region;
 pub mod captures;
 pub mod flock;
 pub mod functor;
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index cb8b939..ef5b97a 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -275,7 +275,12 @@
     ) -> P<ast::Expr> {
         self.expr(
             span,
-            ast::ExprKind::Struct(P(ast::StructExpr { path, fields, rest: ast::StructRest::None })),
+            ast::ExprKind::Struct(P(ast::StructExpr {
+                qself: None,
+                path,
+                fields,
+                rest: ast::StructRest::None,
+            })),
         )
     }
     pub fn expr_struct_ident(
@@ -405,7 +410,7 @@
         path: ast::Path,
         subpats: Vec<P<ast::Pat>>,
     ) -> P<ast::Pat> {
-        self.pat(span, PatKind::TupleStruct(path, subpats))
+        self.pat(span, PatKind::TupleStruct(None, path, subpats))
     }
     pub fn pat_struct(
         &self,
@@ -413,7 +418,7 @@
         path: ast::Path,
         field_pats: Vec<ast::PatField>,
     ) -> P<ast::Pat> {
-        self.pat(span, PatKind::Struct(path, field_pats, false))
+        self.pat(span, PatKind::Struct(None, path, field_pats, false))
     }
     pub fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
         self.pat(span, PatKind::Tuple(pats))
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 0359f50..56a320c 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -663,6 +663,9 @@
     /// Allows unnamed fields of struct and union type
     (active, unnamed_fields, "1.53.0", Some(49804), None),
 
+    /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
+    (active, more_qualified_paths, "1.54.0", Some(80080), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 49f418d..753b8c8 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -94,15 +94,6 @@
             .iter_enumerated()
             .map(move |(index, key)| (index, key, &self.def_path_hashes[index]))
     }
-
-    pub fn all_def_path_hashes_and_def_ids(
-        &self,
-        krate: CrateNum,
-    ) -> impl Iterator<Item = (DefPathHash, DefId)> + '_ {
-        self.def_path_hashes
-            .iter_enumerated()
-            .map(move |(index, hash)| (*hash, DefId { krate, index }))
-    }
 }
 
 /// The definition table containing node definitions.
@@ -440,6 +431,14 @@
     pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
         self.def_id_to_hir_id.iter_enumerated().map(|(k, _)| k)
     }
+
+    #[inline(always)]
+    pub fn local_def_path_hash_to_def_id(&self, hash: DefPathHash) -> Option<LocalDefId> {
+        self.table
+            .def_path_hash_to_index
+            .get(&hash)
+            .map(|&local_def_index| LocalDefId { local_def_index })
+    }
 }
 
 #[derive(Copy, Clone, PartialEq, Debug)]
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index 0232654..5606075 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -5,7 +5,7 @@
     TraitItem, TraitItemId, Ty, VisibilityKind,
 };
 use crate::hir_id::{HirId, ItemLocalId};
-use rustc_span::def_id::{DefPathHash, LocalDefId};
+use rustc_span::def_id::DefPathHash;
 
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
@@ -21,7 +21,6 @@
     fn hash_hir_ty(&mut self, _: &Ty<'_>, hasher: &mut StableHasher);
     fn hash_hir_visibility_kind(&mut self, _: &VisibilityKind<'_>, hasher: &mut StableHasher);
     fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, f: F);
-    fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash;
 }
 
 impl<HirCtx: crate::HashStableContext> ToStableHashKey<HirCtx> for HirId {
@@ -29,7 +28,7 @@
 
     #[inline]
     fn to_stable_hash_key(&self, hcx: &HirCtx) -> (DefPathHash, ItemLocalId) {
-        let def_path_hash = hcx.local_def_path_hash(self.owner);
+        let def_path_hash = self.owner.to_stable_hash_key(hcx);
         (def_path_hash, self.local_id)
     }
 }
@@ -39,7 +38,7 @@
 
     #[inline]
     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
-        hcx.local_def_path_hash(self.def_id)
+        self.def_id.to_stable_hash_key(hcx)
     }
 }
 
@@ -48,7 +47,7 @@
 
     #[inline]
     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
-        hcx.local_def_path_hash(self.def_id)
+        self.def_id.to_stable_hash_key(hcx)
     }
 }
 
@@ -57,7 +56,7 @@
 
     #[inline]
     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
-        hcx.local_def_path_hash(self.def_id)
+        self.def_id.to_stable_hash_key(hcx)
     }
 }
 
@@ -66,7 +65,7 @@
 
     #[inline]
     fn to_stable_hash_key(&self, hcx: &HirCtx) -> DefPathHash {
-        hcx.local_def_path_hash(self.def_id)
+        self.def_id.to_stable_hash_key(hcx)
     }
 }
 
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 303c39a..8539cc6 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -1,7 +1,6 @@
 //! Code to save/load the dep-graph from files.
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::definitions::DefPathTable;
 use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId};
 use rustc_middle::ty::query::OnDiskCache;
 use rustc_serialize::opaque::Decoder;
@@ -196,10 +195,7 @@
 /// If we are not in incremental compilation mode, returns `None`.
 /// Otherwise, tries to load the query result cache from disk,
 /// creating an empty cache if it could not be loaded.
-pub fn load_query_result_cache<'a>(
-    sess: &'a Session,
-    def_path_table: &DefPathTable,
-) -> Option<OnDiskCache<'a>> {
+pub fn load_query_result_cache<'a>(sess: &'a Session) -> Option<OnDiskCache<'a>> {
     if sess.opts.incremental.is_none() {
         return None;
     }
@@ -212,7 +208,7 @@
         sess.is_nightly_build(),
     ) {
         LoadResult::Ok { data: (bytes, start_pos) } => {
-            Some(OnDiskCache::new(sess, bytes, start_pos, def_path_table))
+            Some(OnDiskCache::new(sess, bytes, start_pos))
         }
         _ => Some(OnDiskCache::new_empty(sess.source_map())),
     }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index fb762d2..e3a79fe 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -64,6 +64,7 @@
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{Item, ItemKind, Node};
+use rustc_middle::dep_graph::DepContext;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{
     self,
@@ -1965,7 +1966,33 @@
                 struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str)
             }
             FailureCode::Error0308(failure_str) => {
-                struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str)
+                let mut err = struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str);
+                if let ValuePairs::Types(ty::error::ExpectedFound { expected, found }) =
+                    trace.values
+                {
+                    // If a tuple of length one was expected and the found expression has
+                    // parentheses around it, perhaps the user meant to write `(expr,)` to
+                    // build a tuple (issue #86100)
+                    match (expected.kind(), found.kind()) {
+                        (ty::Tuple(_), ty::Tuple(_)) => {}
+                        (ty::Tuple(_), _) if expected.tuple_fields().count() == 1 => {
+                            if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
+                                if let Some(code) =
+                                    code.strip_prefix('(').and_then(|s| s.strip_suffix(')'))
+                                {
+                                    err.span_suggestion(
+                                        span,
+                                        "use a trailing comma to create a tuple with one element",
+                                        format!("({},)", code),
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                }
+                            }
+                        }
+                        _ => {}
+                    }
+                }
+                err
             }
             FailureCode::Error0644(failure_str) => {
                 struct_span_err!(self.tcx.sess, span, E0644, "{}", failure_str)
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index b5af2bf..c7424b9 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -2,8 +2,6 @@
 #![feature(box_patterns)]
 #![feature(internal_output_capture)]
 #![feature(nll)]
-#![feature(generator_trait)]
-#![feature(generators)]
 #![feature(once_cell)]
 #![recursion_limit = "256"]
 
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index aa7af60..9e3e96d 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -6,10 +6,10 @@
 use rustc_ast::{self as ast, visit};
 use rustc_codegen_ssa::back::link::emit_metadata;
 use rustc_codegen_ssa::traits::CodegenBackend;
+use rustc_data_structures::parallel;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal};
 use rustc_data_structures::temp_dir::MaybeTempDir;
-use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
 use rustc_errors::{ErrorReported, PResult};
 use rustc_expand::base::ExtCtxt;
 use rustc_hir::def_id::LOCAL_CRATE;
@@ -47,7 +47,9 @@
 use std::ffi::OsString;
 use std::io::{self, BufWriter, Write};
 use std::lazy::SyncLazy;
+use std::marker::PhantomPinned;
 use std::path::PathBuf;
+use std::pin::Pin;
 use std::rc::Rc;
 use std::{env, fs, iter};
 
@@ -85,11 +87,83 @@
     counter.count
 }
 
-declare_box_region_type!(
-    pub BoxedResolver,
-    for(),
-    (&mut Resolver<'_>) -> (Result<ast::Crate>, ResolverOutputs)
-);
+pub use boxed_resolver::BoxedResolver;
+mod boxed_resolver {
+    use super::*;
+
+    pub struct BoxedResolver(Pin<Box<BoxedResolverInner>>);
+
+    struct BoxedResolverInner {
+        session: Lrc<Session>,
+        resolver_arenas: Option<ResolverArenas<'static>>,
+        resolver: Option<Resolver<'static>>,
+        _pin: PhantomPinned,
+    }
+
+    // Note: Drop order is important to prevent dangling references. Resolver must be dropped first,
+    // then resolver_arenas and finally session.
+    impl Drop for BoxedResolverInner {
+        fn drop(&mut self) {
+            self.resolver.take();
+            self.resolver_arenas.take();
+        }
+    }
+
+    impl BoxedResolver {
+        pub(super) fn new<F>(session: Lrc<Session>, make_resolver: F) -> Result<(ast::Crate, Self)>
+        where
+            F: for<'a> FnOnce(
+                &'a Session,
+                &'a ResolverArenas<'a>,
+            ) -> Result<(ast::Crate, Resolver<'a>)>,
+        {
+            let mut boxed_resolver = Box::new(BoxedResolverInner {
+                session,
+                resolver_arenas: Some(Resolver::arenas()),
+                resolver: None,
+                _pin: PhantomPinned,
+            });
+            // SAFETY: `make_resolver` takes a resolver arena with an arbitrary lifetime and
+            // returns a resolver with the same lifetime as the arena. We ensure that the arena
+            // outlives the resolver in the drop impl and elsewhere so these transmutes are sound.
+            unsafe {
+                let (crate_, resolver) = make_resolver(
+                    std::mem::transmute::<&Session, &Session>(&boxed_resolver.session),
+                    std::mem::transmute::<&ResolverArenas<'_>, &ResolverArenas<'_>>(
+                        boxed_resolver.resolver_arenas.as_ref().unwrap(),
+                    ),
+                )?;
+                boxed_resolver.resolver = Some(resolver);
+                Ok((crate_, BoxedResolver(Pin::new_unchecked(boxed_resolver))))
+            }
+        }
+
+        pub fn access<F: for<'a> FnOnce(&mut Resolver<'a>) -> R, R>(&mut self, f: F) -> R {
+            // SAFETY: The resolver doesn't need to be pinned.
+            let mut resolver = unsafe {
+                self.0.as_mut().map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
+            };
+            f((&mut *resolver).as_mut().unwrap())
+        }
+
+        pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ResolverOutputs {
+            match Rc::try_unwrap(resolver) {
+                Ok(resolver) => {
+                    let mut resolver = resolver.into_inner();
+                    // SAFETY: The resolver doesn't need to be pinned.
+                    let mut resolver = unsafe {
+                        resolver
+                            .0
+                            .as_mut()
+                            .map_unchecked_mut(|boxed_resolver| &mut boxed_resolver.resolver)
+                    };
+                    resolver.take().unwrap().into_outputs()
+                }
+                Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
+            }
+        }
+    }
+}
 
 /// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
 /// syntax expansion, secondary `cfg` expansion, synthesis of a test
@@ -111,41 +185,16 @@
     // its contents but the results of name resolution on those contents. Hopefully we'll push
     // this back at some point.
     let crate_name = crate_name.to_string();
-    let (result, resolver) = BoxedResolver::new(static move |mut action| {
-        let _ = action;
-        let sess = &*sess;
-        let resolver_arenas = Resolver::arenas();
-        let res = configure_and_expand_inner(
+    BoxedResolver::new(sess, move |sess, resolver_arenas| {
+        configure_and_expand_inner(
             sess,
             &lint_store,
             krate,
             &crate_name,
             &resolver_arenas,
-            &*metadata_loader,
-        );
-        let mut resolver = match res {
-            Err(v) => {
-                yield BoxedResolver::initial_yield(Err(v));
-                panic!()
-            }
-            Ok((krate, resolver)) => {
-                action = yield BoxedResolver::initial_yield(Ok(krate));
-                resolver
-            }
-        };
-        box_region_allow_access!(for(), (&mut Resolver<'_>), (&mut resolver), action);
-        resolver.into_outputs()
-    });
-    result.map(|k| (k, resolver))
-}
-
-impl BoxedResolver {
-    pub fn to_resolver_outputs(resolver: Rc<RefCell<BoxedResolver>>) -> ResolverOutputs {
-        match Rc::try_unwrap(resolver) {
-            Ok(resolver) => resolver.into_inner().complete(),
-            Err(resolver) => resolver.borrow_mut().access(|resolver| resolver.clone_outputs()),
-        }
-    }
+            metadata_loader,
+        )
+    })
 }
 
 pub fn register_plugins<'a>(
@@ -231,11 +280,11 @@
 
 fn configure_and_expand_inner<'a>(
     sess: &'a Session,
-    lint_store: &'a LintStore,
+    lint_store: &LintStore,
     mut krate: ast::Crate,
     crate_name: &str,
     resolver_arenas: &'a ResolverArenas<'a>,
-    metadata_loader: &'a MetadataLoaderDyn,
+    metadata_loader: Box<MetadataLoaderDyn>,
 ) -> Result<(ast::Crate, Resolver<'a>)> {
     tracing::trace!("configure_and_expand_inner");
     pre_expansion_lint(sess, lint_store, &krate, crate_name);
@@ -765,9 +814,7 @@
 ) -> QueryContext<'tcx> {
     let sess = &compiler.session();
 
-    let def_path_table = resolver_outputs.definitions.def_path_table();
-    let query_result_on_disk_cache =
-        rustc_incremental::load_query_result_cache(sess, def_path_table);
+    let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess);
 
     let codegen_backend = compiler.codegen_backend();
     let mut local_providers = *DEFAULT_QUERY_PROVIDERS;
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 67946df..44c2a55 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -858,10 +858,10 @@
             // The other cases do not contain sub-patterns.
             | Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
             // These are list-like patterns; parens can always be removed.
-            TupleStruct(_, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
+            TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
                 self.check_unused_parens_pat(cx, p, false, false);
             },
-            Struct(_, fps, _) => for f in fps {
+            Struct(_, _, fps, _) => for f in fps {
                 self.check_unused_parens_pat(cx, &f.pat, false, false);
             },
             // Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index e9ae22f..d73cfe3 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -54,7 +54,7 @@
 pub struct CrateLoader<'a> {
     // Immutable configuration.
     sess: &'a Session,
-    metadata_loader: &'a MetadataLoaderDyn,
+    metadata_loader: Box<MetadataLoaderDyn>,
     local_crate_name: Symbol,
     // Mutable output.
     cstore: CStore,
@@ -219,7 +219,7 @@
 impl<'a> CrateLoader<'a> {
     pub fn new(
         sess: &'a Session,
-        metadata_loader: &'a MetadataLoaderDyn,
+        metadata_loader: Box<MetadataLoaderDyn>,
         local_crate_name: &str,
     ) -> Self {
         let local_crate_stable_id =
@@ -544,7 +544,7 @@
             info!("falling back to a load");
             let mut locator = CrateLocator::new(
                 self.sess,
-                self.metadata_loader,
+                &*self.metadata_loader,
                 name,
                 hash,
                 host_hash,
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 27842ac..2c9bad7 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -29,3 +29,5 @@
 pub mod creader;
 pub mod dynamic_lib;
 pub mod locator;
+
+pub use rmeta::METADATA_HEADER;
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 7cec4ce..9a97835 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -1,7 +1,7 @@
 use crate::creader::{CStore, LoadedMacro};
 use crate::foreign_modules;
 use crate::native_libs;
-use crate::rmeta::{self, encoder};
+use crate::rmeta::encoder;
 
 use rustc_ast as ast;
 use rustc_ast::expand::allocator::AllocatorKind;
@@ -536,10 +536,6 @@
         encoder::encode_metadata(tcx)
     }
 
-    fn metadata_encoding_version(&self) -> &[u8] {
-        rmeta::METADATA_HEADER
-    }
-
     fn allocator_kind(&self) -> Option<AllocatorKind> {
         self.allocator_kind()
     }
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 04fe5cf..99ea0cc 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -52,7 +52,7 @@
 /// This header is followed by the position of the `CrateRoot`,
 /// which is encoded as a 32-bit big-endian unsigned integer,
 /// and further followed by the rustc version string.
-crate const METADATA_HEADER: &[u8; 8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
+pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
 
 /// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
 /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
diff --git a/compiler/rustc_middle/src/ich/hcx.rs b/compiler/rustc_middle/src/ich/hcx.rs
index b2fef73..91c81c3 100644
--- a/compiler/rustc_middle/src/ich/hcx.rs
+++ b/compiler/rustc_middle/src/ich/hcx.rs
@@ -14,7 +14,6 @@
 use rustc_span::symbol::Symbol;
 use rustc_span::{BytePos, CachingSourceMapView, SourceFile, SpanData};
 
-use rustc_span::def_id::{CrateNum, CRATE_DEF_INDEX};
 use smallvec::SmallVec;
 use std::cmp::Ord;
 use std::thread::LocalKey;
@@ -227,15 +226,8 @@
     }
 
     #[inline]
-    fn hash_crate_num(&mut self, cnum: CrateNum, hasher: &mut StableHasher) {
-        let hcx = self;
-        hcx.def_path_hash(DefId { krate: cnum, index: CRATE_DEF_INDEX }).hash_stable(hcx, hasher);
-    }
-
-    #[inline]
-    fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) {
-        let hcx = self;
-        hcx.def_path_hash(def_id).hash_stable(hcx, hasher);
+    fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
+        self.def_path_hash(def_id)
     }
 
     fn expn_id_cache() -> &'static LocalKey<rustc_span::ExpnIdCache> {
diff --git a/compiler/rustc_middle/src/ich/impls_hir.rs b/compiler/rustc_middle/src/ich/impls_hir.rs
index abf5683..5dfd00b 100644
--- a/compiler/rustc_middle/src/ich/impls_hir.rs
+++ b/compiler/rustc_middle/src/ich/impls_hir.rs
@@ -6,7 +6,6 @@
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
 use rustc_hir as hir;
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX};
 use rustc_hir::definitions::DefPathHash;
 use smallvec::SmallVec;
 use std::mem;
@@ -113,46 +112,6 @@
 
         self.node_id_hashing_mode = prev_hash_node_ids;
     }
-
-    #[inline]
-    fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash {
-        self.local_def_path_hash(def_id)
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
-    type KeyType = DefPathHash;
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
-        hcx.def_path_hash(*self)
-    }
-}
-
-impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
-    #[inline]
-    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
-        hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
-    type KeyType = DefPathHash;
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
-        hcx.def_path_hash(self.to_def_id())
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
-    type KeyType = DefPathHash;
-
-    #[inline]
-    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
-        let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
-        def_id.to_stable_hash_key(hcx)
-    }
 }
 
 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::ItemLocalId {
diff --git a/compiler/rustc_middle/src/middle/cstore.rs b/compiler/rustc_middle/src/middle/cstore.rs
index f09449a..a7ab43d 100644
--- a/compiler/rustc_middle/src/middle/cstore.rs
+++ b/compiler/rustc_middle/src/middle/cstore.rs
@@ -215,7 +215,6 @@
 
     // utility functions
     fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
-    fn metadata_encoding_version(&self) -> &[u8];
     fn allocator_kind(&self) -> Option<AllocatorKind>;
 }
 
diff --git a/compiler/rustc_middle/src/mir/abstract_const.rs b/compiler/rustc_middle/src/mir/abstract_const.rs
index 776a777..1ef1024 100644
--- a/compiler/rustc_middle/src/mir/abstract_const.rs
+++ b/compiler/rustc_middle/src/mir/abstract_const.rs
@@ -1,6 +1,6 @@
 //! A subset of a mir body used for const evaluatability checking.
-use crate::mir;
-use crate::ty;
+use crate::mir::{self, CastKind};
+use crate::ty::{self, Ty};
 
 rustc_index::newtype_index! {
     /// An index into an `AbstractConst`.
@@ -17,6 +17,7 @@
     Binop(mir::BinOp, NodeId, NodeId),
     UnaryOp(mir::UnOp, NodeId),
     FunctionCall(NodeId, &'tcx [NodeId]),
+    Cast(CastKind, NodeId, Ty<'tcx>),
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 62d1bc7..d13cbdd 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1288,10 +1288,6 @@
         )
     }
 
-    pub fn metadata_encoding_version(self) -> Vec<u8> {
-        self.cstore.metadata_encoding_version().to_vec()
-    }
-
     pub fn encode_metadata(self) -> EncodedMetadata {
         let _prof_timer = self.prof.verbose_generic_activity("generate_crate_metadata");
         self.cstore.encode_metadata(self)
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 982c8a3..bfb4c0c 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -54,7 +54,7 @@
     /// ADTs with no type arguments.
     pub fn is_simple_text(&self) -> bool {
         match self.kind() {
-            Adt(_, substs) => substs.types().next().is_none(),
+            Adt(_, substs) => substs.non_erasable_generics().next().is_none(),
             Ref(_, ty, _) => ty.is_simple_text(),
             _ => self.is_simple_ty(),
         }
diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
index ebb52d8..5c42625 100644
--- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
@@ -10,7 +10,7 @@
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_errors::Diagnostic;
 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
-use rustc_hir::definitions::{DefPathHash, DefPathTable};
+use rustc_hir::definitions::DefPathHash;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_query_system::dep_graph::DepContext;
 use rustc_query_system::query::QueryContext;
@@ -27,7 +27,6 @@
 use rustc_span::CachingSourceMapView;
 use rustc_span::{BytePos, ExpnData, SourceFile, Span, DUMMY_SP};
 use std::collections::hash_map::Entry;
-use std::iter::FromIterator;
 use std::mem;
 
 const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
@@ -103,12 +102,6 @@
     // during the next compilation session.
     latest_foreign_def_path_hashes: Lock<UnhashMap<DefPathHash, RawDefId>>,
 
-    // Maps `DefPathHashes` to their corresponding `LocalDefId`s for all
-    // local items in the current compilation session. This is only populated
-    // when we are in incremental mode and have loaded a pre-existing cache
-    // from disk, since this map is only used when deserializing a `DefPathHash`
-    // from the incremental cache.
-    local_def_path_hash_to_def_id: UnhashMap<DefPathHash, LocalDefId>,
     // Caches all lookups of `DefPathHashes`, both for local and foreign
     // definitions. A definition from the previous compilation session
     // may no longer exist in the current compilation session, so
@@ -168,12 +161,7 @@
 
 impl<'sess> OnDiskCache<'sess> {
     /// Creates a new `OnDiskCache` instance from the serialized data in `data`.
-    pub fn new(
-        sess: &'sess Session,
-        data: Vec<u8>,
-        start_pos: usize,
-        def_path_table: &DefPathTable,
-    ) -> Self {
+    pub fn new(sess: &'sess Session, data: Vec<u8>, start_pos: usize) -> Self {
         debug_assert!(sess.opts.incremental.is_some());
 
         // Wrap in a scope so we can borrow `data`.
@@ -210,11 +198,6 @@
             hygiene_context: Default::default(),
             foreign_def_path_hashes: footer.foreign_def_path_hashes,
             latest_foreign_def_path_hashes: Default::default(),
-            local_def_path_hash_to_def_id: UnhashMap::from_iter(
-                def_path_table
-                    .all_def_path_hashes_and_def_ids(LOCAL_CRATE)
-                    .map(|(hash, def_id)| (hash, def_id.as_local().unwrap())),
-            ),
             def_path_hash_to_def_id_cache: Default::default(),
         }
     }
@@ -236,7 +219,6 @@
             hygiene_context: Default::default(),
             foreign_def_path_hashes: Default::default(),
             latest_foreign_def_path_hashes: Default::default(),
-            local_def_path_hash_to_def_id: Default::default(),
             def_path_hash_to_def_id_cache: Default::default(),
         }
     }
@@ -616,7 +598,7 @@
                 debug!("def_path_hash_to_def_id({:?})", hash);
                 // Check if the `DefPathHash` corresponds to a definition in the current
                 // crate
-                if let Some(def_id) = self.local_def_path_hash_to_def_id.get(&hash).cloned() {
+                if let Some(def_id) = tcx.definitions.local_def_path_hash_to_def_id(hash) {
                     let def_id = def_id.to_def_id();
                     e.insert(Some(def_id));
                     return Some(def_id);
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 872d12c..3f426b1 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -112,7 +112,7 @@
 ///////////////////////////////////////////////////////////////////////////
 // Relate impls
 
-fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
+pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
     relation: &mut R,
     a: ty::TypeAndMut<'tcx>,
     b: ty::TypeAndMut<'tcx>,
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
index d2b1566..bf5f2c0 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
@@ -902,9 +902,13 @@
             {
                 let lt_name = &src[1..ws_pos];
                 let ty = &src[ws_pos..];
-                return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
+                if !ty.trim_start().starts_with("mut") {
+                    return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
+                }
             } else if let Some(stripped) = src.strip_prefix('&') {
-                return (assignment_rhs_span, format!("&mut {}", stripped));
+                if !stripped.trim_start().starts_with("mut") {
+                    return (assignment_rhs_span, format!("&mut {}", stripped));
+                }
             }
         }
     }
diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs
index 99622fb..4e4166d 100644
--- a/compiler/rustc_mir/src/interpret/intrinsics.rs
+++ b/compiler/rustc_mir/src/interpret/intrinsics.rs
@@ -56,8 +56,12 @@
             let alloc = type_name::alloc_type_name(tcx, tp_ty);
             ConstValue::Slice { data: alloc, start: 0, end: alloc.len() }
         }
-        sym::needs_drop => ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)),
+        sym::needs_drop => {
+            ensure_monomorphic_enough(tcx, tp_ty)?;
+            ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env))
+        }
         sym::min_align_of | sym::pref_align_of => {
+            // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
             let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?;
             let n = match name {
                 sym::pref_align_of => layout.align.pref.bytes(),
@@ -71,6 +75,7 @@
             ConstValue::from_u64(tcx.type_id_hash(tp_ty))
         }
         sym::variant_count => match tp_ty.kind() {
+            // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
             ty::Adt(ref adt, _) => ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx),
             ty::Projection(_)
             | ty::Opaque(_, _)
diff --git a/compiler/rustc_mir/src/interpret/traits.rs b/compiler/rustc_mir/src/interpret/traits.rs
index 11f8d38..d0c04b5 100644
--- a/compiler/rustc_mir/src/interpret/traits.rs
+++ b/compiler/rustc_mir/src/interpret/traits.rs
@@ -158,6 +158,8 @@
         let size = u64::try_from(self.force_bits(size, pointer_size)?).unwrap();
         let align = vtable.read_ptr_sized(pointer_size * 2)?.check_init()?;
         let align = u64::try_from(self.force_bits(align, pointer_size)?).unwrap();
+        let align = Align::from_bytes(align)
+            .map_err(|e| err_ub_format!("invalid vtable: alignment {}", e))?;
 
         if size >= self.tcx.data_layout.obj_size_bound() {
             throw_ub_format!(
@@ -165,6 +167,6 @@
                 size is bigger than largest supported object"
             );
         }
-        Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap()))
+        Ok((Size::from_bytes(size), align))
     }
 }
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index ee6ff4d..8b05038 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -32,7 +32,6 @@
         let mut just_parsed_doc_comment = false;
         let start_pos = self.token_cursor.num_next_calls;
         loop {
-            debug!("parse_outer_attributes: self.token={:?}", self.token);
             let attr = if self.check(&token::Pound) {
                 let inner_error_reason = if just_parsed_doc_comment {
                     "an inner attribute is not permitted following an outer doc comment"
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 72fdc78..b37caae 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -366,7 +366,7 @@
             let mut snapshot = self.clone();
             let path =
                 Path { segments: vec![], span: self.prev_token.span.shrink_to_lo(), tokens: None };
-            let struct_expr = snapshot.parse_struct_expr(path, AttrVec::new(), false);
+            let struct_expr = snapshot.parse_struct_expr(None, path, AttrVec::new(), false);
             let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No);
             return Some(match (struct_expr, block_tail) {
                 (Ok(expr), Err(mut err)) => {
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index a764cf6..c8789ab 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1108,9 +1108,6 @@
             self.parse_closure_expr(attrs)
         } else if self.check(&token::OpenDelim(token::Bracket)) {
             self.parse_array_or_repeat_expr(attrs)
-        } else if self.eat_lt() {
-            let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
-            Ok(self.mk_expr(lo.to(path.span), ExprKind::Path(Some(qself), path), attrs))
         } else if self.check_path() {
             self.parse_path_start_expr(attrs)
         } else if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
@@ -1262,12 +1259,20 @@
     }
 
     fn parse_path_start_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
-        let path = self.parse_path(PathStyle::Expr)?;
+        let (qself, path) = if self.eat_lt() {
+            let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
+            (Some(qself), path)
+        } else {
+            (None, self.parse_path(PathStyle::Expr)?)
+        };
         let lo = path.span;
 
         // `!`, as an operator, is prefix, so we know this isn't that.
         let (hi, kind) = if self.eat(&token::Not) {
             // MACRO INVOCATION expression
+            if qself.is_some() {
+                self.struct_span_err(path.span, "macros cannot use qualified paths").emit();
+            }
             let mac = MacCall {
                 path,
                 args: self.parse_mac_args()?,
@@ -1275,13 +1280,16 @@
             };
             (self.prev_token.span, ExprKind::MacCall(mac))
         } else if self.check(&token::OpenDelim(token::Brace)) {
-            if let Some(expr) = self.maybe_parse_struct_expr(&path, &attrs) {
+            if let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path, &attrs) {
+                if qself.is_some() {
+                    self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
+                }
                 return expr;
             } else {
-                (path.span, ExprKind::Path(None, path))
+                (path.span, ExprKind::Path(qself, path))
             }
         } else {
-            (path.span, ExprKind::Path(None, path))
+            (path.span, ExprKind::Path(qself, path))
         };
 
         let expr = self.mk_expr(lo.to(hi), kind, attrs);
@@ -2247,6 +2255,7 @@
 
     fn maybe_parse_struct_expr(
         &mut self,
+        qself: Option<&ast::QSelf>,
         path: &ast::Path,
         attrs: &AttrVec,
     ) -> Option<PResult<'a, P<Expr>>> {
@@ -2255,7 +2264,7 @@
             if let Err(err) = self.expect(&token::OpenDelim(token::Brace)) {
                 return Some(Err(err));
             }
-            let expr = self.parse_struct_expr(path.clone(), attrs.clone(), true);
+            let expr = self.parse_struct_expr(qself.cloned(), path.clone(), attrs.clone(), true);
             if let (Ok(expr), false) = (&expr, struct_allowed) {
                 // This is a struct literal, but we don't can't accept them here.
                 self.error_struct_lit_not_allowed_here(path.span, expr.span);
@@ -2278,6 +2287,7 @@
     /// Precondition: already parsed the '{'.
     pub(super) fn parse_struct_expr(
         &mut self,
+        qself: Option<ast::QSelf>,
         pth: ast::Path,
         attrs: AttrVec,
         recover: bool,
@@ -2375,7 +2385,7 @@
         let expr = if recover_async {
             ExprKind::Err
         } else {
-            ExprKind::Struct(P(ast::StructExpr { path: pth, fields, rest: base }))
+            ExprKind::Struct(P(ast::StructExpr { qself, path: pth, fields, rest: base }))
         };
         Ok(self.mk_expr(span, expr, attrs))
     }
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 0abefbd..4181222 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -859,7 +859,8 @@
     /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
     fn parse_pat_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
         if qself.is_some() {
-            return self.error_qpath_before_pat(&path, "{");
+            // Feature gate the use of qualified paths in patterns
+            self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
         }
         self.bump();
         let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
@@ -869,27 +870,17 @@
             (vec![], true)
         });
         self.bump();
-        Ok(PatKind::Struct(path, fields, etc))
+        Ok(PatKind::Struct(qself, path, fields, etc))
     }
 
     /// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`).
     fn parse_pat_tuple_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
-        if qself.is_some() {
-            return self.error_qpath_before_pat(&path, "(");
-        }
         let (fields, _) =
             self.parse_paren_comma_seq(|p| p.parse_pat_allow_top_alt(None, RecoverComma::No))?;
-        Ok(PatKind::TupleStruct(path, fields))
-    }
-
-    /// Error when there's a qualified path, e.g. `<Foo as Bar>::Baz`
-    /// as the path of e.g., a tuple or record struct pattern.
-    fn error_qpath_before_pat(&mut self, path: &Path, token: &str) -> PResult<'a, PatKind> {
-        let msg = &format!("unexpected `{}` after qualified path", token);
-        let mut err = self.struct_span_err(self.token.span, msg);
-        err.span_label(self.token.span, msg);
-        err.span_label(path.span, "the qualified path");
-        Err(err)
+        if qself.is_some() {
+            self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
+        }
+        Ok(PatKind::TupleStruct(qself, path, fields))
     }
 
     /// Parses the fields of a struct-like pattern.
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 4f0dcfe..9ef3f61 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -117,7 +117,7 @@
             }
 
             let expr = if this.eat(&token::OpenDelim(token::Brace)) {
-                this.parse_struct_expr(path, AttrVec::new(), true)?
+                this.parse_struct_expr(None, path, AttrVec::new(), true)?
             } else {
                 let hi = this.prev_token.span;
                 this.mk_expr(lo.to(hi), ExprKind::Path(None, path), AttrVec::new())
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index e64f12e..5a79a9c 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -156,6 +156,7 @@
                 let leaf = leaf.subst(tcx, ct.substs);
                 self.visit_const(leaf)
             }
+            ACNode::Cast(_, _, ty) => self.visit_ty(ty),
             ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => {
                 ControlFlow::CONTINUE
             }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 408d9b2..a21d819 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1613,10 +1613,10 @@
                     self.r.record_partial_res(pat.id, PartialRes::new(res));
                     self.r.record_pat_span(pat.id, pat.span);
                 }
-                PatKind::TupleStruct(ref path, ref sub_patterns) => {
+                PatKind::TupleStruct(ref qself, ref path, ref sub_patterns) => {
                     self.smart_resolve_path(
                         pat.id,
-                        None,
+                        qself.as_ref(),
                         path,
                         PathSource::TupleStruct(
                             pat.span,
@@ -1627,8 +1627,8 @@
                 PatKind::Path(ref qself, ref path) => {
                     self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat);
                 }
-                PatKind::Struct(ref path, ..) => {
-                    self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
+                PatKind::Struct(ref qself, ref path, ..) => {
+                    self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Struct);
                 }
                 PatKind::Or(ref ps) => {
                     // Add a new set of bindings to the stack. `Or` here records that when a
@@ -2288,7 +2288,7 @@
             }
 
             ExprKind::Struct(ref se) => {
-                self.smart_resolve_path(expr.id, None, &se.path, PathSource::Struct);
+                self.smart_resolve_path(expr.id, se.qself.as_ref(), &se.path, PathSource::Struct);
                 visit::walk_expr(self, expr);
             }
 
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index fd9b897..6d5531d 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1198,7 +1198,7 @@
         session: &'a Session,
         krate: &Crate,
         crate_name: &str,
-        metadata_loader: &'a MetadataLoaderDyn,
+        metadata_loader: Box<MetadataLoaderDyn>,
         arenas: &'a ResolverArenas<'a>,
     ) -> Resolver<'a> {
         let root_local_def_id = LocalDefId { local_def_index: CRATE_DEF_INDEX };
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 5752258..2b547f8 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2417,6 +2417,7 @@
 /// we have an opt-in scheme here, so one is hopefully forced to think about
 /// how the hash should be calculated when adding a new command-line argument.
 crate mod dep_tracking {
+    use super::LdImpl;
     use super::{
         CFGuard, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, LinkerPluginLto,
         LtoCli, OptLevel, OutputTypes, Passes, SourceFileHashAlgorithm, SwitchWithOptPath,
@@ -2497,6 +2498,7 @@
         SymbolManglingVersion,
         SourceFileHashAlgorithm,
         TrimmedDefPaths,
+        Option<LdImpl>,
     );
 
     impl<T1, T2> DepTrackingHash for (T1, T2)
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 58a53b3..1946bfd 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -370,6 +370,7 @@
     pub const parse_wasi_exec_model: &str = "either `command` or `reactor`";
     pub const parse_split_debuginfo: &str =
         "one of supported split-debuginfo modes (`off`, `packed`, or `unpacked`)";
+    pub const parse_gcc_ld: &str = "one of: no value, `lld`";
 }
 
 mod parse {
@@ -864,6 +865,15 @@
         }
         true
     }
+
+    crate fn parse_gcc_ld(slot: &mut Option<LdImpl>, v: Option<&str>) -> bool {
+        match v {
+            None => *slot = None,
+            Some("lld") => *slot = Some(LdImpl::Lld),
+            _ => return false,
+        }
+        true
+    }
 }
 
 options! {
@@ -1067,6 +1077,7 @@
         "set the optimization fuel quota for a crate"),
     function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "whether each function should go in its own section"),
+    gcc_ld: Option<LdImpl> = (None, parse_gcc_ld, [TRACKED], "implementation of ld used by cc"),
     graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
         "use dark-themed colors in graphviz output (default: no)"),
     graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED],
@@ -1321,3 +1332,8 @@
     Command,
     Reactor,
 }
+
+#[derive(Clone, Copy, Hash)]
+pub enum LdImpl {
+    Lld,
+}
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 6ee7537..bb4ac22 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -1,7 +1,7 @@
 use crate::crate_disambiguator::CrateDisambiguator;
 use crate::HashStableContext;
 use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
 use rustc_data_structures::AtomicRef;
 use rustc_index::vec::Idx;
 use rustc_macros::HashStable_Generic;
@@ -308,13 +308,49 @@
 rustc_data_structures::define_id_collections!(LocalDefIdMap, LocalDefIdSet, LocalDefId);
 
 impl<CTX: HashStableContext> HashStable<CTX> for DefId {
+    #[inline]
     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        hcx.hash_def_id(*self, hasher)
+        self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
+    }
+}
+
+impl<CTX: HashStableContext> HashStable<CTX> for LocalDefId {
+    #[inline]
+    fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
+        self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
     }
 }
 
 impl<CTX: HashStableContext> HashStable<CTX> for CrateNum {
+    #[inline]
     fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
-        hcx.hash_crate_num(*self, hasher)
+        self.to_stable_hash_key(hcx).hash_stable(hcx, hasher);
+    }
+}
+
+impl<CTX: HashStableContext> ToStableHashKey<CTX> for DefId {
+    type KeyType = DefPathHash;
+
+    #[inline]
+    fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash {
+        hcx.def_path_hash(*self)
+    }
+}
+
+impl<CTX: HashStableContext> ToStableHashKey<CTX> for LocalDefId {
+    type KeyType = DefPathHash;
+
+    #[inline]
+    fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash {
+        hcx.def_path_hash(self.to_def_id())
+    }
+}
+
+impl<CTX: HashStableContext> ToStableHashKey<CTX> for CrateNum {
+    type KeyType = DefPathHash;
+
+    #[inline]
+    fn to_stable_hash_key(&self, hcx: &CTX) -> DefPathHash {
+        self.as_def_id().to_stable_hash_key(hcx)
     }
 }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 8f3b8cc..23efaf6 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -29,7 +29,7 @@
 use crate::SESSION_GLOBALS;
 use crate::{BytePos, CachingSourceMapView, ExpnIdCache, SourceFile, Span, DUMMY_SP};
 
-use crate::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use crate::def_id::{CrateNum, DefId, DefPathHash, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -1330,9 +1330,12 @@
     }
 
     impl<'a> crate::HashStableContext for DummyHashStableContext<'a> {
-        fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) {
-            def_id.krate.as_u32().hash_stable(self, hasher);
-            def_id.index.as_u32().hash_stable(self, hasher);
+        #[inline]
+        fn def_path_hash(&self, def_id: DefId) -> DefPathHash {
+            DefPathHash(Fingerprint::new(
+                def_id.krate.as_u32().into(),
+                def_id.index.as_u32().into(),
+            ))
         }
 
         fn expn_id_cache() -> &'static LocalKey<ExpnIdCache> {
@@ -1345,9 +1348,6 @@
             &CACHE
         }
 
-        fn hash_crate_num(&mut self, krate: CrateNum, hasher: &mut StableHasher) {
-            krate.as_u32().hash_stable(self, hasher);
-        }
         fn hash_spans(&self) -> bool {
             true
         }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 9cf68cb..b4fe7c9 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -40,7 +40,7 @@
 use hygiene::Transparency;
 pub use hygiene::{DesugaringKind, ExpnData, ExpnId, ExpnKind, ForLoopLoc, MacroKind};
 pub mod def_id;
-use def_id::{CrateNum, DefId, LOCAL_CRATE};
+use def_id::{CrateNum, DefId, DefPathHash, LOCAL_CRATE};
 pub mod lev_distance;
 mod span_encoding;
 pub use span_encoding::{Span, DUMMY_SP};
@@ -1928,13 +1928,12 @@
 /// This is a hack to allow using the [`HashStable_Generic`] derive macro
 /// instead of implementing everything in rustc_middle.
 pub trait HashStableContext {
-    fn hash_def_id(&mut self, _: DefId, hasher: &mut StableHasher);
+    fn def_path_hash(&self, def_id: DefId) -> DefPathHash;
     /// Obtains a cache for storing the `Fingerprint` of an `ExpnId`.
     /// This method allows us to have multiple `HashStableContext` implementations
     /// that hash things in a different way, without the results of one polluting
     /// the cache of the other.
     fn expn_id_cache() -> &'static LocalKey<ExpnIdCache>;
-    fn hash_crate_num(&mut self, _: CrateNum, hasher: &mut StableHasher);
     fn hash_spans(&self) -> bool;
     fn span_data_to_lines_and_cols(
         &mut self,
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 0dadd41..1d45cd1 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -407,7 +407,7 @@
     }
 
     fn span_to_string(&self, sp: Span, prefer_local: bool) -> String {
-        if self.files.borrow().source_files.is_empty() && sp.is_dummy() {
+        if self.files.borrow().source_files.is_empty() || sp.is_dummy() {
             return "no-location".to_string();
         }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 31b425f..fb37c5e 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -756,6 +756,7 @@
         modifiers,
         module,
         module_path,
+        more_qualified_paths,
         more_struct_aliases,
         movbe_target_feature,
         move_ref_pattern,
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 8961cda..b1a9388 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -97,6 +97,16 @@
 
                         ControlFlow::CONTINUE
                     }
+                    Node::Cast(_, _, ty) => {
+                        let ty = ty.subst(tcx, ct.substs);
+                        if ty.has_infer_types_or_consts() {
+                            failure_kind = FailureKind::MentionsInfer;
+                        } else if ty.has_param_types_or_consts() {
+                            failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam);
+                        }
+
+                        ControlFlow::CONTINUE
+                    }
                     Node::Binop(_, _, _) | Node::UnaryOp(_, _) | Node::FunctionCall(_, _) => {
                         ControlFlow::CONTINUE
                     }
@@ -304,6 +314,9 @@
                 self.nodes[func].used = true;
                 nodes.iter().for_each(|&n| self.nodes[n].used = true);
             }
+            Node::Cast(_, operand, _) => {
+                self.nodes[operand].used = true;
+            }
         }
 
         // Nodes start as unused.
@@ -408,11 +421,19 @@
                         self.locals[local] = self.add_node(Node::UnaryOp(op, operand), span);
                         Ok(())
                     }
+                    Rvalue::Cast(cast_kind, ref operand, ty) => {
+                        let operand = self.operand_to_node(span, operand)?;
+                        self.locals[local] =
+                            self.add_node(Node::Cast(cast_kind, operand, ty), span);
+                        Ok(())
+                    }
                     _ => self.error(Some(span), "unsupported rvalue")?,
                 }
             }
             // These are not actually relevant for us here, so we can ignore them.
-            StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => Ok(()),
+            StatementKind::AscribeUserType(..)
+            | StatementKind::StorageLive(_)
+            | StatementKind::StorageDead(_) => Ok(()),
             _ => self.error(Some(stmt.source_info.span), "unsupported statement")?,
         }
     }
@@ -594,6 +615,7 @@
                 recurse(tcx, ct.subtree(func), f)?;
                 args.iter().try_for_each(|&arg| recurse(tcx, ct.subtree(arg), f))
             }
+            Node::Cast(_, operand, _) => recurse(tcx, ct.subtree(operand), f),
         }
     }
 
@@ -676,6 +698,11 @@
                 && iter::zip(a_args, b_args)
                     .all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn)))
         }
+        (Node::Cast(a_cast_kind, a_operand, a_ty), Node::Cast(b_cast_kind, b_operand, b_ty))
+            if (a_ty == b_ty) && (a_cast_kind == b_cast_kind) =>
+        {
+            try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand))
+        }
         _ => false,
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index d5e1bd3..7ebef7f 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -838,6 +838,7 @@
                         let leaf = leaf.subst(self.tcx, ct.substs);
                         self.visit_const(leaf)
                     }
+                    Node::Cast(_, _, ty) => self.visit_ty(ty),
                     Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
                         ControlFlow::CONTINUE
                     }
@@ -859,6 +860,7 @@
                             let leaf = leaf.subst(self.tcx, ct.substs);
                             self.visit_const(leaf)
                         }
+                        Node::Cast(_, _, ty) => self.visit_ty(ty),
                         Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
                             ControlFlow::CONTINUE
                         }
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 29a87b1..abe5d69 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -9,7 +9,7 @@
 use rustc_middle::hir::map::Map;
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
 use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable, TypeFolder};
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, DUMMY_SP};
 
@@ -749,6 +749,40 @@
     span: Span,
     item_ident: Ident,
 ) -> Ty<'_> {
+    // Attempts to make the type nameable by turning FnDefs into FnPtrs.
+    struct MakeNameable<'tcx> {
+        success: bool,
+        tcx: TyCtxt<'tcx>,
+    }
+
+    impl<'tcx> MakeNameable<'tcx> {
+        fn new(tcx: TyCtxt<'tcx>) -> Self {
+            MakeNameable { success: true, tcx }
+        }
+    }
+
+    impl TypeFolder<'tcx> for MakeNameable<'tcx> {
+        fn tcx(&self) -> TyCtxt<'tcx> {
+            self.tcx
+        }
+
+        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
+            if !self.success {
+                return ty;
+            }
+
+            match ty.kind() {
+                ty::FnDef(def_id, _) => self.tcx.mk_fn_ptr(self.tcx.fn_sig(*def_id)),
+                // FIXME: non-capturing closures should also suggest a function pointer
+                ty::Closure(..) | ty::Generator(..) => {
+                    self.success = false;
+                    ty
+                }
+                _ => ty.super_fold_with(self),
+            }
+        }
+    }
+
     let ty = tcx.diagnostic_only_typeck(def_id).node_type(body_id.hir_id);
 
     // If this came from a free `const` or `static mut?` item,
@@ -760,24 +794,47 @@
             // The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
             // We are typeck and have the real type, so remove that and suggest the actual type.
             err.suggestions.clear();
-            err.span_suggestion(
-                span,
-                "provide a type for the item",
-                format!("{}: {}", item_ident, ty),
-                Applicability::MachineApplicable,
-            )
-            .emit_unless(ty.references_error());
+
+            // Suggesting unnameable types won't help.
+            let mut mk_nameable = MakeNameable::new(tcx);
+            let ty = mk_nameable.fold_ty(ty);
+            let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
+            if let Some(sugg_ty) = sugg_ty {
+                err.span_suggestion(
+                    span,
+                    "provide a type for the item",
+                    format!("{}: {}", item_ident, sugg_ty),
+                    Applicability::MachineApplicable,
+                );
+            } else {
+                err.span_note(
+                    tcx.hir().body(body_id).value.span,
+                    &format!("however, the inferred type `{}` cannot be named", ty.to_string()),
+                );
+            }
+
+            err.emit_unless(ty.references_error());
         }
         None => {
             let mut diag = bad_placeholder_type(tcx, vec![span]);
 
             if !ty.references_error() {
-                diag.span_suggestion(
-                    span,
-                    "replace with the correct type",
-                    ty.to_string(),
-                    Applicability::MaybeIncorrect,
-                );
+                let mut mk_nameable = MakeNameable::new(tcx);
+                let ty = mk_nameable.fold_ty(ty);
+                let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
+                if let Some(sugg_ty) = sugg_ty {
+                    diag.span_suggestion(
+                        span,
+                        "replace with the correct type",
+                        sugg_ty.to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                } else {
+                    diag.span_note(
+                        tcx.hir().body(body_id).value.span,
+                        &format!("however, the inferred type `{}` cannot be named", ty.to_string()),
+                    );
+                }
             }
 
             diag.emit();
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index eb91af8..13b4244 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1209,7 +1209,7 @@
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "from_for_ptrs", since = "1.6.0")]
 impl<T> From<T> for Box<T> {
-    /// Converts a generic type `T` into a `Box<T>`
+    /// Converts a `T` into a `Box<T>`
     ///
     /// The conversion allocates on the heap and moves `t`
     /// from the stack into it.
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index 2da3d6a..80d0890 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -1,6 +1,5 @@
 //! impl char {}
 
-use crate::intrinsics::likely;
 use crate::slice;
 use crate::str::from_utf8_unchecked_mut;
 use crate::unicode::printable::is_printable;
@@ -332,21 +331,16 @@
     #[inline]
     pub fn to_digit(self, radix: u32) -> Option<u32> {
         assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
-        // the code is split up here to improve execution speed for cases where
-        // the `radix` is constant and 10 or smaller
-        let val = if likely(radix <= 10) {
-            // If not a digit, a number greater than radix will be created.
-            (self as u32).wrapping_sub('0' as u32)
-        } else {
-            match self {
-                '0'..='9' => self as u32 - '0' as u32,
-                'a'..='z' => self as u32 - 'a' as u32 + 10,
-                'A'..='Z' => self as u32 - 'A' as u32 + 10,
-                _ => return None,
+        // If not a digit, a number greater than radix will be created.
+        let mut digit = (self as u32).wrapping_sub('0' as u32);
+        if radix > 10 {
+            if digit < 10 {
+                return Some(digit);
             }
-        };
-
-        if val < radix { Some(val) } else { None }
+            // Force the 6th bit to be set to ensure ascii is lower case.
+            digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
+        }
+        (digit < radix).then_some(digit)
     }
 
     /// Returns an iterator that yields the hexadecimal Unicode escape of a
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 0034de9..70ab27c 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1742,157 +1742,6 @@
     /// Allocate at compile time. Should not be called at runtime.
     #[rustc_const_unstable(feature = "const_heap", issue = "79597")]
     pub fn const_allocate(size: usize, align: usize) -> *mut u8;
-
-    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
-    /// and destination must *not* overlap.
-    ///
-    /// For regions of memory which might overlap, use [`copy`] instead.
-    ///
-    /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
-    /// with the argument order swapped.
-    ///
-    /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
-    ///
-    /// # Safety
-    ///
-    /// Behavior is undefined if any of the following conditions are violated:
-    ///
-    /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
-    ///
-    /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
-    ///
-    /// * Both `src` and `dst` must be properly aligned.
-    ///
-    /// * The region of memory beginning at `src` with a size of `count *
-    ///   size_of::<T>()` bytes must *not* overlap with the region of memory
-    ///   beginning at `dst` with the same size.
-    ///
-    /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
-    /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
-    /// in the region beginning at `*src` and the region beginning at `*dst` can
-    /// [violate memory safety][read-ownership].
-    ///
-    /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
-    /// `0`, the pointers must be non-null and properly aligned.
-    ///
-    /// [`read`]: crate::ptr::read
-    /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
-    /// [valid]: crate::ptr#safety
-    ///
-    /// # Examples
-    ///
-    /// Manually implement [`Vec::append`]:
-    ///
-    /// ```
-    /// use std::ptr;
-    ///
-    /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
-    /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
-    ///     let src_len = src.len();
-    ///     let dst_len = dst.len();
-    ///
-    ///     // Ensure that `dst` has enough capacity to hold all of `src`.
-    ///     dst.reserve(src_len);
-    ///
-    ///     unsafe {
-    ///         // The call to offset is always safe because `Vec` will never
-    ///         // allocate more than `isize::MAX` bytes.
-    ///         let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
-    ///         let src_ptr = src.as_ptr();
-    ///
-    ///         // Truncate `src` without dropping its contents. We do this first,
-    ///         // to avoid problems in case something further down panics.
-    ///         src.set_len(0);
-    ///
-    ///         // The two regions cannot overlap because mutable references do
-    ///         // not alias, and two different vectors cannot own the same
-    ///         // memory.
-    ///         ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
-    ///
-    ///         // Notify `dst` that it now holds the contents of `src`.
-    ///         dst.set_len(dst_len + src_len);
-    ///     }
-    /// }
-    ///
-    /// let mut a = vec!['r'];
-    /// let mut b = vec!['u', 's', 't'];
-    ///
-    /// append(&mut a, &mut b);
-    ///
-    /// assert_eq!(a, &['r', 'u', 's', 't']);
-    /// assert!(b.is_empty());
-    /// ```
-    ///
-    /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
-    #[doc(alias = "memcpy")]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
-    pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
-
-    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
-    /// and destination may overlap.
-    ///
-    /// If the source and destination will *never* overlap,
-    /// [`copy_nonoverlapping`] can be used instead.
-    ///
-    /// `copy` is semantically equivalent to C's [`memmove`], but with the argument
-    /// order swapped. Copying takes place as if the bytes were copied from `src`
-    /// to a temporary array and then copied from the array to `dst`.
-    ///
-    /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
-    ///
-    /// # Safety
-    ///
-    /// Behavior is undefined if any of the following conditions are violated:
-    ///
-    /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
-    ///
-    /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
-    ///
-    /// * Both `src` and `dst` must be properly aligned.
-    ///
-    /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
-    /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
-    /// in the region beginning at `*src` and the region beginning at `*dst` can
-    /// [violate memory safety][read-ownership].
-    ///
-    /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
-    /// `0`, the pointers must be non-null and properly aligned.
-    ///
-    /// [`read`]: crate::ptr::read
-    /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
-    /// [valid]: crate::ptr#safety
-    ///
-    /// # Examples
-    ///
-    /// Efficiently create a Rust vector from an unsafe buffer:
-    ///
-    /// ```
-    /// use std::ptr;
-    ///
-    /// /// # Safety
-    /// ///
-    /// /// * `ptr` must be correctly aligned for its type and non-zero.
-    /// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
-    /// /// * Those elements must not be used after calling this function unless `T: Copy`.
-    /// # #[allow(dead_code)]
-    /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
-    ///     let mut dst = Vec::with_capacity(elts);
-    ///
-    ///     // SAFETY: Our precondition ensures the source is aligned and valid,
-    ///     // and `Vec::with_capacity` ensures that we have usable space to write them.
-    ///     ptr::copy(ptr, dst.as_mut_ptr(), elts);
-    ///
-    ///     // SAFETY: We created it with this much capacity earlier,
-    ///     // and the previous `copy` has initialized these elements.
-    ///     dst.set_len(elts);
-    ///     dst
-    /// }
-    /// ```
-    #[doc(alias = "memmove")]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
-    pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
 }
 
 // Some functions are defined here because they accidentally got made
@@ -1906,6 +1755,192 @@
     !ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
 }
 
+/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+/// and destination must *not* overlap.
+///
+/// For regions of memory which might overlap, use [`copy`] instead.
+///
+/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
+/// with the argument order swapped.
+///
+/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * Both `src` and `dst` must be properly aligned.
+///
+/// * The region of memory beginning at `src` with a size of `count *
+///   size_of::<T>()` bytes must *not* overlap with the region of memory
+///   beginning at `dst` with the same size.
+///
+/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
+/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
+/// in the region beginning at `*src` and the region beginning at `*dst` can
+/// [violate memory safety][read-ownership].
+///
+/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
+/// `0`, the pointers must be non-null and properly aligned.
+///
+/// [`read`]: crate::ptr::read
+/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
+/// [valid]: crate::ptr#safety
+///
+/// # Examples
+///
+/// Manually implement [`Vec::append`]:
+///
+/// ```
+/// use std::ptr;
+///
+/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
+/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
+///     let src_len = src.len();
+///     let dst_len = dst.len();
+///
+///     // Ensure that `dst` has enough capacity to hold all of `src`.
+///     dst.reserve(src_len);
+///
+///     unsafe {
+///         // The call to offset is always safe because `Vec` will never
+///         // allocate more than `isize::MAX` bytes.
+///         let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
+///         let src_ptr = src.as_ptr();
+///
+///         // Truncate `src` without dropping its contents. We do this first,
+///         // to avoid problems in case something further down panics.
+///         src.set_len(0);
+///
+///         // The two regions cannot overlap because mutable references do
+///         // not alias, and two different vectors cannot own the same
+///         // memory.
+///         ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
+///
+///         // Notify `dst` that it now holds the contents of `src`.
+///         dst.set_len(dst_len + src_len);
+///     }
+/// }
+///
+/// let mut a = vec!['r'];
+/// let mut b = vec!['u', 's', 't'];
+///
+/// append(&mut a, &mut b);
+///
+/// assert_eq!(a, &['r', 'u', 's', 't']);
+/// assert!(b.is_empty());
+/// ```
+///
+/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
+#[doc(alias = "memcpy")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+#[inline]
+pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
+    extern "rust-intrinsic" {
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+        pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+    }
+
+    // FIXME: Perform these checks only at run time
+    /*if cfg!(debug_assertions)
+        && !(is_aligned_and_not_null(src)
+            && is_aligned_and_not_null(dst)
+            && is_nonoverlapping(src, dst, count))
+    {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }*/
+
+    // SAFETY: the safety contract for `copy_nonoverlapping` must be
+    // upheld by the caller.
+    unsafe { copy_nonoverlapping(src, dst, count) }
+}
+
+/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+/// and destination may overlap.
+///
+/// If the source and destination will *never* overlap,
+/// [`copy_nonoverlapping`] can be used instead.
+///
+/// `copy` is semantically equivalent to C's [`memmove`], but with the argument
+/// order swapped. Copying takes place as if the bytes were copied from `src`
+/// to a temporary array and then copied from the array to `dst`.
+///
+/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * Both `src` and `dst` must be properly aligned.
+///
+/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
+/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
+/// in the region beginning at `*src` and the region beginning at `*dst` can
+/// [violate memory safety][read-ownership].
+///
+/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
+/// `0`, the pointers must be non-null and properly aligned.
+///
+/// [`read`]: crate::ptr::read
+/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
+/// [valid]: crate::ptr#safety
+///
+/// # Examples
+///
+/// Efficiently create a Rust vector from an unsafe buffer:
+///
+/// ```
+/// use std::ptr;
+///
+/// /// # Safety
+/// ///
+/// /// * `ptr` must be correctly aligned for its type and non-zero.
+/// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
+/// /// * Those elements must not be used after calling this function unless `T: Copy`.
+/// # #[allow(dead_code)]
+/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
+///     let mut dst = Vec::with_capacity(elts);
+///
+///     // SAFETY: Our precondition ensures the source is aligned and valid,
+///     // and `Vec::with_capacity` ensures that we have usable space to write them.
+///     ptr::copy(ptr, dst.as_mut_ptr(), elts);
+///
+///     // SAFETY: We created it with this much capacity earlier,
+///     // and the previous `copy` has initialized these elements.
+///     dst.set_len(elts);
+///     dst
+/// }
+/// ```
+#[doc(alias = "memmove")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+#[inline]
+pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
+    extern "rust-intrinsic" {
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
+        fn copy<T>(src: *const T, dst: *mut T, count: usize);
+    }
+
+    // FIXME: Perform these checks only at run time
+    /*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
+        // Not panicking to keep codegen impact smaller.
+        abort();
+    }*/
+
+    // SAFETY: the safety contract for `copy` must be upheld by the caller.
+    unsafe { copy(src, dst, count) }
+}
+
 /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
 /// `val`.
 ///
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 96b924f..11dea40 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -138,7 +138,7 @@
     /// A more complex example:
     ///
     /// ```
-    /// // The even numbers from zero to ten.
+    /// // The even numbers in the range of zero to nine.
     /// let iter = (0..10).filter(|x| x % 2 == 0);
     ///
     /// // We might iterate from zero to ten times. Knowing that it's five
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index d4e4c5b..949ef27 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -65,6 +65,7 @@
 #![feature(allow_internal_unstable)]
 #![feature(arbitrary_self_types)]
 #![feature(asm)]
+#![feature(bool_to_option)]
 #![feature(cfg_target_has_atomic)]
 #![feature(const_heap)]
 #![feature(const_alloc_layout)]
@@ -165,6 +166,7 @@
 #![feature(no_niche)] // rust-lang/rust#68303
 #![feature(no_coverage)] // rust-lang/rust#84605
 #![feature(int_error_matching)]
+#![cfg_attr(bootstrap, feature(target_feature_11))]
 #![deny(unsafe_op_in_unsafe_fn)]
 #![deny(or_patterns_back_compat)]
 
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 5bf47c3..c6750c5 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -682,8 +682,7 @@
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
-pub const fn swap<T>(x: &mut T, y: &mut T) {
+pub fn swap<T>(x: &mut T, y: &mut T) {
     // SAFETY: the raw pointers have been created from safe mutable references satisfying all the
     // constraints on `ptr::swap_nonoverlapping_one`
     unsafe {
@@ -813,8 +812,7 @@
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[must_use = "if you don't need the old value, you can just assign the new value directly"]
-#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
-pub const fn replace<T>(dest: &mut T, src: T) -> T {
+pub fn replace<T>(dest: &mut T, src: T) -> T {
     // SAFETY: We read from `dest` but directly write `src` into it afterwards,
     // such that the old value is not duplicated. Nothing is dropped and
     // nothing here can panic.
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 214d7c8..6a6cee0 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -430,8 +430,7 @@
 }
 
 #[inline]
-#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
-pub(crate) const unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
+pub(crate) unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
     // NOTE(eddyb) SPIR-V's Logical addressing model doesn't allow for arbitrary
     // reinterpretation of values as (chunkable) byte arrays, and the loop in the
     // block optimization in `swap_nonoverlapping_bytes` is hard to rewrite back
@@ -564,8 +563,7 @@
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
-pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
+pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
     // SAFETY: the caller must guarantee that `dst` is valid to be
     // cast to a mutable reference (valid for writes, aligned, initialized),
     // and cannot overlap `src` since `dst` must point to a distinct
@@ -871,14 +869,18 @@
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
-pub const unsafe fn write<T>(dst: *mut T, src: T) {
+pub unsafe fn write<T>(dst: *mut T, src: T) {
+    // We are calling the intrinsics directly to avoid function calls in the generated code
+    // as `intrinsics::copy_nonoverlapping` is a wrapper function.
+    extern "rust-intrinsic" {
+        fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+    }
+
     // SAFETY: the caller must guarantee that `dst` is valid for writes.
     // `dst` cannot overlap `src` because the caller has mutable access
     // to `dst` while `src` is owned by this function.
     unsafe {
         copy_nonoverlapping(&src as *const T, dst, 1);
-        // We are calling the intrinsic directly to avoid function calls in the generated code.
         intrinsics::forget(src);
     }
 }
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 750279a..a642404 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1002,9 +1002,8 @@
     ///
     /// [`ptr::write`]: crate::ptr::write()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
     #[inline(always)]
-    pub const unsafe fn write(self, val: T)
+    pub unsafe fn write(self, val: T)
     where
         T: Sized,
     {
diff --git a/library/core/tests/char.rs b/library/core/tests/char.rs
index c16f540..51eca1e 100644
--- a/library/core/tests/char.rs
+++ b/library/core/tests/char.rs
@@ -67,10 +67,20 @@
     assert_eq!('A'.to_digit(16), Some(10));
     assert_eq!('b'.to_digit(16), Some(11));
     assert_eq!('B'.to_digit(16), Some(11));
+    assert_eq!('A'.to_digit(36), Some(10));
     assert_eq!('z'.to_digit(36), Some(35));
     assert_eq!('Z'.to_digit(36), Some(35));
-    assert_eq!(' '.to_digit(10), None);
+    assert_eq!('['.to_digit(36), None);
+    assert_eq!('`'.to_digit(36), None);
+    assert_eq!('{'.to_digit(36), None);
     assert_eq!('$'.to_digit(36), None);
+    assert_eq!('@'.to_digit(16), None);
+    assert_eq!('G'.to_digit(16), None);
+    assert_eq!('g'.to_digit(16), None);
+    assert_eq!(' '.to_digit(10), None);
+    assert_eq!('/'.to_digit(10), None);
+    assert_eq!(':'.to_digit(10), None);
+    assert_eq!(':'.to_digit(11), None);
 }
 
 #[test]
diff --git a/library/core/tests/const_ptr.rs b/library/core/tests/const_ptr.rs
index 152fed8..4acd059 100644
--- a/library/core/tests/const_ptr.rs
+++ b/library/core/tests/const_ptr.rs
@@ -49,53 +49,3 @@
     const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
     assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
 }
-
-#[test]
-fn write() {
-    use core::ptr;
-
-    const fn write_aligned() -> i32 {
-        let mut res = 0;
-        unsafe {
-            ptr::write(&mut res as *mut _, 42);
-        }
-        res
-    }
-    const ALIGNED: i32 = write_aligned();
-    assert_eq!(ALIGNED, 42);
-
-    const fn write_unaligned() -> [u16; 2] {
-        let mut two_aligned = [0u16; 2];
-        unsafe {
-            let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
-            ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45]));
-        }
-        two_aligned
-    }
-    const UNALIGNED: [u16; 2] = write_unaligned();
-    assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
-}
-
-#[test]
-fn mut_ptr_write() {
-    const fn aligned() -> i32 {
-        let mut res = 0;
-        unsafe {
-            (&mut res as *mut i32).write(42);
-        }
-        res
-    }
-    const ALIGNED: i32 = aligned();
-    assert_eq!(ALIGNED, 42);
-
-    const fn write_unaligned() -> [u16; 2] {
-        let mut two_aligned = [0u16; 2];
-        unsafe {
-            let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
-            unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45]));
-        }
-        two_aligned
-    }
-    const UNALIGNED: [u16; 2] = write_unaligned();
-    assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
-}
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index ba2b8b6..5b8e837 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -987,13 +987,13 @@
 /// Capture a [closure]'s environment by value.
 ///
 /// `move` converts any variables captured by reference or mutable reference
-/// to owned by value variables.
+/// to variables captured by value.
 ///
 /// ```rust
-/// let capture = "hello";
-/// let closure = move || {
-///     println!("rust says {}", capture);
-/// };
+/// let data = vec![1, 2, 3];
+/// let closure = move || println!("captured {:?} by value", data);
+///
+/// // data is no longer available, it is owned by the closure
 /// ```
 ///
 /// Note: `move` closures may still implement [`Fn`] or [`FnMut`], even though
@@ -1004,31 +1004,29 @@
 /// ```rust
 /// fn create_fn() -> impl Fn() {
 ///     let text = "Fn".to_owned();
-///
 ///     move || println!("This is a: {}", text)
 /// }
 ///
 /// let fn_plain = create_fn();
-///
 /// fn_plain();
 /// ```
 ///
 /// `move` is often used when [threads] are involved.
 ///
 /// ```rust
-/// let x = 5;
+/// let data = vec![1, 2, 3];
 ///
 /// std::thread::spawn(move || {
-///     println!("captured {} by value", x)
+///     println!("captured {:?} by value", data)
 /// }).join().unwrap();
 ///
-/// // x is no longer available
+/// // data was moved to the spawned thread, so we cannot use it here
 /// ```
 ///
 /// `move` is also valid before an async block.
 ///
 /// ```rust
-/// let capture = "hello";
+/// let capture = "hello".to_owned();
 /// let block = async move {
 ///     println!("rust says {} from async block", capture);
 /// };
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index e591e07..0b9c9fb 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -19,7 +19,7 @@
 use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sys::stdio::panic_output;
 use crate::sys_common::backtrace::{self, RustBacktrace};
-use crate::sys_common::rwlock::RWLock;
+use crate::sys_common::rwlock::StaticRWLock;
 use crate::sys_common::thread_info;
 use crate::thread;
 
@@ -74,7 +74,7 @@
     Custom(*mut (dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send)),
 }
 
-static HOOK_LOCK: RWLock = RWLock::new();
+static HOOK_LOCK: StaticRWLock = StaticRWLock::new();
 static mut HOOK: Hook = Hook::Default;
 
 /// Registers a custom panic hook, replacing any that was previously registered.
@@ -117,10 +117,10 @@
     }
 
     unsafe {
-        HOOK_LOCK.write();
+        let guard = HOOK_LOCK.write();
         let old_hook = HOOK;
         HOOK = Hook::Custom(Box::into_raw(hook));
-        HOOK_LOCK.write_unlock();
+        drop(guard);
 
         if let Hook::Custom(ptr) = old_hook {
             #[allow(unused_must_use)]
@@ -165,10 +165,10 @@
     }
 
     unsafe {
-        HOOK_LOCK.write();
+        let guard = HOOK_LOCK.write();
         let hook = HOOK;
         HOOK = Hook::Default;
-        HOOK_LOCK.write_unlock();
+        drop(guard);
 
         match hook {
             Hook::Default => Box::new(default_hook),
@@ -608,7 +608,7 @@
 
     unsafe {
         let mut info = PanicInfo::internal_constructor(message, location);
-        HOOK_LOCK.read();
+        let _guard = HOOK_LOCK.read();
         match HOOK {
             // Some platforms (like wasm) know that printing to stderr won't ever actually
             // print anything, and if that's the case we can skip the default
@@ -626,7 +626,6 @@
                 (*ptr)(&info);
             }
         };
-        HOOK_LOCK.read_unlock();
     }
 
     if panics > 1 {
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 9d521ab..0d00f74 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -3,9 +3,7 @@
 
 use crate::cell::UnsafeCell;
 use crate::fmt;
-use crate::mem;
 use crate::ops::{Deref, DerefMut};
-use crate::ptr;
 use crate::sync::{poison, LockResult, TryLockError, TryLockResult};
 use crate::sys_common::rwlock as sys;
 
@@ -66,7 +64,7 @@
 /// [`Mutex`]: super::Mutex
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RwLock<T: ?Sized> {
-    inner: Box<sys::RWLock>,
+    inner: sys::MovableRWLock,
     poison: poison::Flag,
     data: UnsafeCell<T>,
 }
@@ -130,7 +128,7 @@
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> RwLock<T> {
         RwLock {
-            inner: box sys::RWLock::new(),
+            inner: sys::MovableRWLock::new(),
             poison: poison::Flag::new(),
             data: UnsafeCell::new(t),
         }
@@ -376,24 +374,8 @@
     where
         T: Sized,
     {
-        // We know statically that there are no outstanding references to
-        // `self` so there's no need to lock the inner lock.
-        //
-        // To get the inner value, we'd like to call `data.into_inner()`,
-        // but because `RwLock` impl-s `Drop`, we can't move out of it, so
-        // we'll have to destructure it manually instead.
-        unsafe {
-            // Like `let RwLock { inner, poison, data } = self`.
-            let (inner, poison, data) = {
-                let RwLock { ref inner, ref poison, ref data } = self;
-                (ptr::read(inner), ptr::read(poison), ptr::read(data))
-            };
-            mem::forget(self);
-            inner.destroy(); // Keep in sync with the `Drop` impl.
-            drop(inner);
-
-            poison::map_result(poison.borrow(), |_| data.into_inner())
-        }
+        let data = self.data.into_inner();
+        poison::map_result(self.poison.borrow(), |_| data)
     }
 
     /// Returns a mutable reference to the underlying data.
@@ -425,14 +407,6 @@
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<#[may_dangle] T: ?Sized> Drop for RwLock<T> {
-    fn drop(&mut self) {
-        // IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`.
-        unsafe { self.inner.destroy() }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut d = f.debug_struct("RwLock");
diff --git a/library/std/src/sys/hermit/rwlock.rs b/library/std/src/sys/hermit/rwlock.rs
index 06442e9..d205818 100644
--- a/library/std/src/sys/hermit/rwlock.rs
+++ b/library/std/src/sys/hermit/rwlock.rs
@@ -8,6 +8,8 @@
     state: UnsafeCell<State>,
 }
 
+pub type MovableRWLock = Box<RWLock>;
+
 enum State {
     Unlocked,
     Reading(usize),
diff --git a/library/std/src/sys/sgx/rwlock.rs b/library/std/src/sys/sgx/rwlock.rs
index 0c96e3f..2d038b5 100644
--- a/library/std/src/sys/sgx/rwlock.rs
+++ b/library/std/src/sys/sgx/rwlock.rs
@@ -13,6 +13,8 @@
     writer: SpinMutex<WaitVariable<bool>>,
 }
 
+pub type MovableRWLock = Box<RWLock>;
+
 // Check at compile time that RWLock size matches C definition (see test_c_rwlock_initializer below)
 //
 // # Safety
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs
index bbc4691..41ca976 100644
--- a/library/std/src/sys/unix/os.rs
+++ b/library/std/src/sys/unix/os.rs
@@ -20,8 +20,7 @@
 use crate::sys::cvt;
 use crate::sys::fd;
 use crate::sys::memchr;
-use crate::sys::rwlock::{RWLockReadGuard, StaticRWLock};
-use crate::sys_common::mutex::{StaticMutex, StaticMutexGuard};
+use crate::sys_common::rwlock::{StaticRWLock, StaticRWLockReadGuard};
 use crate::vec;
 
 use libc::{c_char, c_int, c_void};
@@ -490,8 +489,8 @@
 
 static ENV_LOCK: StaticRWLock = StaticRWLock::new();
 
-pub fn env_read_lock() -> RWLockReadGuard {
-    ENV_LOCK.read_with_guard()
+pub fn env_read_lock() -> StaticRWLockReadGuard {
+    ENV_LOCK.read()
 }
 
 /// Returns a vector of (variable, value) byte-vector pairs for all the
@@ -551,7 +550,7 @@
     let v = CString::new(v.as_bytes())?;
 
     unsafe {
-        let _guard = ENV_LOCK.write_with_guard();
+        let _guard = ENV_LOCK.write();
         cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
     }
 }
@@ -560,7 +559,7 @@
     let nbuf = CString::new(n.as_bytes())?;
 
     unsafe {
-        let _guard = ENV_LOCK.write_with_guard();
+        let _guard = ENV_LOCK.write();
         cvt(libc::unsetenv(nbuf.as_ptr())).map(drop)
     }
 }
diff --git a/library/std/src/sys/unix/rwlock.rs b/library/std/src/sys/unix/rwlock.rs
index d97d9d7..b1faf12 100644
--- a/library/std/src/sys/unix/rwlock.rs
+++ b/library/std/src/sys/unix/rwlock.rs
@@ -7,6 +7,8 @@
     num_readers: AtomicUsize,
 }
 
+pub type MovableRWLock = Box<RWLock>;
+
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {}
 
@@ -139,55 +141,3 @@
         }
     }
 }
-
-pub struct StaticRWLock(RWLock);
-
-impl StaticRWLock {
-    pub const fn new() -> StaticRWLock {
-        StaticRWLock(RWLock::new())
-    }
-
-    /// Acquires shared access to the underlying lock, blocking the current
-    /// thread to do so.
-    ///
-    /// The lock is automatically unlocked when the returned guard is dropped.
-    #[inline]
-    pub fn read_with_guard(&'static self) -> RWLockReadGuard {
-        // SAFETY: All methods require static references, therefore self
-        // cannot be moved between invocations.
-        unsafe {
-            self.0.read();
-        }
-        RWLockReadGuard(&self.0)
-    }
-
-    /// Acquires write access to the underlying lock, blocking the current thread
-    /// to do so.
-    ///
-    /// The lock is automatically unlocked when the returned guard is dropped.
-    #[inline]
-    pub fn write_with_guard(&'static self) -> RWLockWriteGuard {
-        // SAFETY: All methods require static references, therefore self
-        // cannot be moved between invocations.
-        unsafe {
-            self.0.write();
-        }
-        RWLockWriteGuard(&self.0)
-    }
-}
-
-pub struct RWLockReadGuard(&'static RWLock);
-
-impl Drop for RWLockReadGuard {
-    fn drop(&mut self) {
-        unsafe { self.0.read_unlock() }
-    }
-}
-
-pub struct RWLockWriteGuard(&'static RWLock);
-
-impl Drop for RWLockWriteGuard {
-    fn drop(&mut self) {
-        unsafe { self.0.write_unlock() }
-    }
-}
diff --git a/library/std/src/sys/unsupported/rwlock.rs b/library/std/src/sys/unsupported/rwlock.rs
index 6982b2b..8438ade 100644
--- a/library/std/src/sys/unsupported/rwlock.rs
+++ b/library/std/src/sys/unsupported/rwlock.rs
@@ -5,6 +5,8 @@
     mode: Cell<isize>,
 }
 
+pub type MovableRWLock = RWLock;
+
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {} // no threads on this platform
 
diff --git a/library/std/src/sys/wasm/atomics/rwlock.rs b/library/std/src/sys/wasm/atomics/rwlock.rs
index 06442e9..64eaa2f 100644
--- a/library/std/src/sys/wasm/atomics/rwlock.rs
+++ b/library/std/src/sys/wasm/atomics/rwlock.rs
@@ -8,6 +8,8 @@
     state: UnsafeCell<State>,
 }
 
+pub type MovableRWLock = RWLock;
+
 enum State {
     Unlocked,
     Reading(usize),
diff --git a/library/std/src/sys/windows/rwlock.rs b/library/std/src/sys/windows/rwlock.rs
index a769326..b7a5b1e 100644
--- a/library/std/src/sys/windows/rwlock.rs
+++ b/library/std/src/sys/windows/rwlock.rs
@@ -5,6 +5,8 @@
     inner: UnsafeCell<c::SRWLOCK>,
 }
 
+pub type MovableRWLock = RWLock;
+
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {}
 
diff --git a/library/std/src/sys_common/rwlock.rs b/library/std/src/sys_common/rwlock.rs
index 3705d64..07ec20f 100644
--- a/library/std/src/sys_common/rwlock.rs
+++ b/library/std/src/sys_common/rwlock.rs
@@ -1,63 +1,112 @@
 use crate::sys::rwlock as imp;
 
-/// An OS-based reader-writer lock.
+/// An OS-based reader-writer lock, meant for use in static variables.
 ///
-/// This structure is entirely unsafe and serves as the lowest layer of a
-/// cross-platform binding of system rwlocks. It is recommended to use the
-/// safer types at the top level of this crate instead of this type.
-pub struct RWLock(imp::RWLock);
+/// This rwlock does not implement poisoning.
+///
+/// This rwlock has a const constructor ([`StaticRWLock::new`]), does not
+/// implement `Drop` to cleanup resources.
+pub struct StaticRWLock(imp::RWLock);
 
-impl RWLock {
-    /// Creates a new reader-writer lock for use.
-    ///
-    /// Behavior is undefined if the reader-writer lock is moved after it is
-    /// first used with any of the functions below.
-    pub const fn new() -> RWLock {
-        RWLock(imp::RWLock::new())
+impl StaticRWLock {
+    /// Creates a new rwlock for use.
+    pub const fn new() -> Self {
+        Self(imp::RWLock::new())
     }
 
     /// Acquires shared access to the underlying lock, blocking the current
     /// thread to do so.
     ///
-    /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous method call.
+    /// The lock is automatically unlocked when the returned guard is dropped.
     #[inline]
-    pub unsafe fn read(&self) {
-        self.0.read()
+    pub fn read(&'static self) -> StaticRWLockReadGuard {
+        unsafe { self.0.read() };
+        StaticRWLockReadGuard(&self.0)
+    }
+
+    /// Acquires write access to the underlying lock, blocking the current thread
+    /// to do so.
+    ///
+    /// The lock is automatically unlocked when the returned guard is dropped.
+    #[inline]
+    pub fn write(&'static self) -> StaticRWLockWriteGuard {
+        unsafe { self.0.write() };
+        StaticRWLockWriteGuard(&self.0)
+    }
+}
+
+#[must_use]
+pub struct StaticRWLockReadGuard(&'static imp::RWLock);
+
+impl Drop for StaticRWLockReadGuard {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            self.0.read_unlock();
+        }
+    }
+}
+
+#[must_use]
+pub struct StaticRWLockWriteGuard(&'static imp::RWLock);
+
+impl Drop for StaticRWLockWriteGuard {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            self.0.write_unlock();
+        }
+    }
+}
+
+/// An OS-based reader-writer lock.
+///
+/// This rwlock does *not* have a const constructor, cleans up its resources in
+/// its `Drop` implementation and may safely be moved (when not borrowed).
+///
+/// This rwlock does not implement poisoning.
+///
+/// This is either a wrapper around `Box<imp::RWLock>` or `imp::RWLock`,
+/// depending on the platform. It is boxed on platforms where `imp::RWLock` may
+/// not be moved.
+pub struct MovableRWLock(imp::MovableRWLock);
+
+impl MovableRWLock {
+    /// Creates a new reader-writer lock for use.
+    pub fn new() -> Self {
+        Self(imp::MovableRWLock::from(imp::RWLock::new()))
+    }
+
+    /// Acquires shared access to the underlying lock, blocking the current
+    /// thread to do so.
+    #[inline]
+    pub fn read(&self) {
+        unsafe { self.0.read() }
     }
 
     /// Attempts to acquire shared access to this lock, returning whether it
     /// succeeded or not.
     ///
     /// This function does not block the current thread.
-    ///
-    /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous method call.
     #[inline]
-    pub unsafe fn try_read(&self) -> bool {
-        self.0.try_read()
+    pub fn try_read(&self) -> bool {
+        unsafe { self.0.try_read() }
     }
 
     /// Acquires write access to the underlying lock, blocking the current thread
     /// to do so.
-    ///
-    /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous method call.
     #[inline]
-    pub unsafe fn write(&self) {
-        self.0.write()
+    pub fn write(&self) {
+        unsafe { self.0.write() }
     }
 
     /// Attempts to acquire exclusive access to this lock, returning whether it
     /// succeeded or not.
     ///
     /// This function does not block the current thread.
-    ///
-    /// Behavior is undefined if the rwlock has been moved between this and any
-    /// previous method call.
     #[inline]
-    pub unsafe fn try_write(&self) -> bool {
-        self.0.try_write()
+    pub fn try_write(&self) -> bool {
+        unsafe { self.0.try_write() }
     }
 
     /// Unlocks previously acquired shared access to this lock.
@@ -76,13 +125,10 @@
     pub unsafe fn write_unlock(&self) {
         self.0.write_unlock()
     }
+}
 
-    /// Destroys OS-related resources with this RWLock.
-    ///
-    /// Behavior is undefined if there are any currently active users of this
-    /// lock.
-    #[inline]
-    pub unsafe fn destroy(&self) {
-        self.0.destroy()
+impl Drop for MovableRWLock {
+    fn drop(&mut self) {
+        unsafe { self.0.destroy() };
     }
 }
diff --git a/library/stdarch b/library/stdarch
index 37d6e18..1e05dff 160000
--- a/library/stdarch
+++ b/library/stdarch
@@ -1 +1 @@
-Subproject commit 37d6e1886369ea0176356286dc7fbd42ee5aa79c
+Subproject commit 1e05dffbeeb80ba61bf59cc63b222d538d7825ed
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index cba17c8..e4396d5 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -41,7 +41,12 @@
         cmd.arg(arg);
     }
     if env::var_os("RUSTDOC_FUSE_LD_LLD").is_some() {
-        cmd.arg("-Clink-args=-fuse-ld=lld");
+        cmd.arg("-Clink-arg=-fuse-ld=lld");
+        if cfg!(windows) {
+            cmd.arg("-Clink-arg=-Wl,/threads:1");
+        } else {
+            cmd.arg("-Clink-arg=-Wl,--threads=1");
+        }
     }
 
     // Needed to be able to run all rustdoc tests.
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 06f8bf8..bc499fd 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1142,6 +1142,7 @@
         }
         if self.is_fuse_ld_lld(compiler.host) {
             cargo.env("RUSTC_HOST_FUSE_LD_LLD", "1");
+            cargo.env("RUSTDOC_FUSE_LD_LLD", "1");
         }
 
         if let Some(target_linker) = self.linker(target) {
@@ -1151,6 +1152,9 @@
         if self.is_fuse_ld_lld(target) {
             rustflags.arg("-Clink-args=-fuse-ld=lld");
         }
+        self.lld_flags(target).for_each(|flag| {
+            rustdocflags.arg(&flag);
+        });
 
         if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
             cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index ed311e2..112a6ea 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -1108,6 +1108,13 @@
             let src_exe = exe("lld", target_compiler.host);
             let dst_exe = exe("rust-lld", target_compiler.host);
             builder.copy(&lld_install.join("bin").join(&src_exe), &libdir_bin.join(&dst_exe));
+            // for `-Z gcc-ld=lld`
+            let gcc_ld_dir = libdir_bin.join("gcc-ld");
+            t!(fs::create_dir(&gcc_ld_dir));
+            builder.copy(
+                &lld_install.join("bin").join(&src_exe),
+                &gcc_ld_dir.join(exe("ld", target_compiler.host)),
+            );
         }
 
         // Similarly, copy `llvm-dwp` into libdir for Split DWARF. Only copy it when the LLVM
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index aee3c83..71ed0af 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -402,6 +402,10 @@
             if builder.config.lld_enabled {
                 let exe = exe("rust-lld", compiler.host);
                 builder.copy(&src_dir.join(&exe), &dst_dir.join(&exe));
+                // for `-Z gcc-ld=lld`
+                let gcc_lld_dir = dst_dir.join("gcc-ld");
+                t!(fs::create_dir(&gcc_lld_dir));
+                builder.copy(&src_dir.join(&exe), &gcc_lld_dir.join(&exe));
             }
 
             // Copy over llvm-dwp if it's there
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 21c7dd1..347236c 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -923,6 +923,21 @@
         self.config.use_lld && !target.contains("msvc")
     }
 
+    fn lld_flags(&self, target: TargetSelection) -> impl Iterator<Item = String> {
+        let mut options = [None, None];
+
+        if self.config.use_lld {
+            if self.is_fuse_ld_lld(target) {
+                options[0] = Some("-Clink-arg=-fuse-ld=lld".to_string());
+            }
+
+            let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" };
+            options[1] = Some(format!("-Clink-arg=-Wl,{}", threads));
+        }
+
+        std::array::IntoIter::new(options).flatten()
+    }
+
     /// Returns if this target should statically link the C runtime, if specified
     fn crt_static(&self, target: TargetSelection) -> Option<bool> {
         if target.contains("pc-windows-msvc") {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index cc7c143..fe4666e 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1131,19 +1131,6 @@
     compare_mode: Option<&'static str>,
 }
 
-impl Compiletest {
-    fn add_lld_flags(builder: &Builder<'_>, target: TargetSelection, flags: &mut Vec<String>) {
-        if builder.config.use_lld {
-            if builder.is_fuse_ld_lld(target) {
-                flags.push("-Clink-arg=-fuse-ld=lld".to_string());
-            }
-
-            let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" };
-            flags.push(format!("-Clink-arg=-Wl,{}", threads));
-        }
-    }
-}
-
 impl Step for Compiletest {
     type Output = ();
 
@@ -1280,7 +1267,6 @@
             }
         }
         flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
-        flags.push("-Zunstable-options".to_string());
         flags.push(builder.config.cmd.rustc_args().join(" "));
 
         if let Some(linker) = builder.linker(target) {
@@ -1289,12 +1275,12 @@
 
         let mut hostflags = flags.clone();
         hostflags.push(format!("-Lnative={}", builder.test_helpers_out(compiler.host).display()));
-        Self::add_lld_flags(builder, compiler.host, &mut hostflags);
+        hostflags.extend(builder.lld_flags(compiler.host));
         cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
 
         let mut targetflags = flags;
         targetflags.push(format!("-Lnative={}", builder.test_helpers_out(target).display()));
-        Self::add_lld_flags(builder, target, &mut targetflags);
+        targetflags.extend(builder.lld_flags(target));
         cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
 
         cmd.arg("--docck-python").arg(builder.python());
@@ -1517,6 +1503,8 @@
 
         cmd.env("BOOTSTRAP_CARGO", &builder.initial_cargo);
 
+        cmd.arg("--channel").arg(&builder.config.channel);
+
         builder.ci_env.force_coloring_in_ci(&mut cmd);
 
         builder.info(&format!(
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index c2ff62e..3a47076 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -235,6 +235,7 @@
   --env TOOLSTATE_REPO_ACCESS_TOKEN \
   --env TOOLSTATE_REPO \
   --env TOOLSTATE_PUBLISH \
+  --env RUST_CI_OVERRIDE_RELEASE_CHANNEL \
   --env CI_JOB_NAME="${CI_JOB_NAME-$IMAGE}" \
   --init \
   --rm \
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 343091c..e704071 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -407,6 +407,17 @@
           - name: x86_64-gnu
             <<: *job-linux-xl
 
+          # This job ensures commits landing on nightly still pass the full
+          # test suite on the stable channel. There are some UI tests that
+          # depend on the channel being built (for example if they include the
+          # channel name on the output), and this builder prevents landing
+          # changes that would result in broken builds after a promotion.
+          - name: x86_64-gnu-stable
+            env:
+              IMAGE: x86_64-gnu
+              RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
+            <<: *job-linux-xl
+
           - name: x86_64-gnu-aux
             <<: *job-linux-xl
 
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 35f80a9..c5e225c 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -65,7 +65,11 @@
 # Always set the release channel for bootstrap; this is normally not important (i.e., only dist
 # builds would seem to matter) but in practice bootstrap wants to know whether we're targeting
 # master, beta, or stable with a build to determine whether to run some checks (notably toolstate).
-export RUST_RELEASE_CHANNEL="$(cat "${ci_dir}/channel")"
+if [[ -z "${RUST_CI_OVERRIDE_RELEASE_CHANNEL+x}" ]]; then
+    export RUST_RELEASE_CHANNEL="$(cat "${ci_dir}/channel")"
+else
+    export RUST_RELEASE_CHANNEL="${RUST_CI_OVERRIDE_RELEASE_CHANNEL}"
+fi
 RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL"
 
 if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then
diff --git a/src/doc/unstable-book/src/language-features/more-qualified-paths.md b/src/doc/unstable-book/src/language-features/more-qualified-paths.md
new file mode 100644
index 0000000..857af57
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/more-qualified-paths.md
@@ -0,0 +1,29 @@
+# `more_qualified_paths`
+
+The `more_qualified_paths` feature can be used in order to enable the
+use of qualified paths in patterns.
+
+## Example
+
+```rust
+#![feature(more_qualified_paths)]
+
+fn main() {
+    // destructure through a qualified path
+    let <Foo as A>::Assoc { br } = StructStruct { br: 2 };
+}
+
+struct StructStruct {
+    br: i8,
+}
+
+struct Foo;
+
+trait A {
+    type Assoc;
+}
+
+impl A for Foo {
+    type Assoc = StructStruct;
+}
+```
diff --git "a/src/test/mir-opt/generator_storage_dead_unwind.main-\173closure\0430\175.StateTransform.before.mir" "b/src/test/mir-opt/generator_storage_dead_unwind.main-\173closure\0430\175.StateTransform.before.mir"
index 42b95b5..296a459 100644
--- "a/src/test/mir-opt/generator_storage_dead_unwind.main-\173closure\0430\175.StateTransform.before.mir"
+++ "b/src/test/mir-opt/generator_storage_dead_unwind.main-\173closure\0430\175.StateTransform.before.mir"
@@ -85,13 +85,13 @@
     bb8 (cleanup): {
         StorageDead(_10);                // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:15: 27:16
         StorageDead(_9);                 // scope 2 at $DIR/generator-storage-dead-unwind.rs:27:16: 27:17
-        goto -> bb10;                    // scope 2 at $DIR/generator-storage-dead-unwind.rs:1:1: 1:1
+        goto -> bb10;                    // scope 2 at no-location
     }
 
     bb9 (cleanup): {
         StorageDead(_8);                 // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:15: 26:16
         StorageDead(_7);                 // scope 2 at $DIR/generator-storage-dead-unwind.rs:26:16: 26:17
-        goto -> bb10;                    // scope 2 at $DIR/generator-storage-dead-unwind.rs:1:1: 1:1
+        goto -> bb10;                    // scope 2 at no-location
     }
 
     bb10 (cleanup): {
diff --git a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir
index 99c7ac8..db88f77 100644
--- a/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir
+++ b/src/test/mir-opt/loop_test.main.SimplifyCfg-promote-consts.after.mir
@@ -43,7 +43,7 @@
         _6 = const 1_i32;                // scope 0 at $DIR/loop_test.rs:14:17: 14:18
         FakeRead(ForLet(None), _6);      // scope 0 at $DIR/loop_test.rs:14:13: 14:14
         StorageDead(_6);                 // scope 0 at $DIR/loop_test.rs:16:5: 16:6
-        goto -> bb3;                     // scope 0 at $DIR/loop_test.rs:1:1: 1:1
+        goto -> bb3;                     // scope 0 at no-location
     }
 
     bb5 (cleanup): {
diff --git a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 3395cbf..feb2503 100644
--- a/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/src/test/mir-opt/match_arm_scopes.complicated_match.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -94,8 +94,8 @@
           _0 = const 3_i32;                // scope 0 at $DIR/match-arm-scopes.rs:15:59: 15:60
           StorageDead(_10);                // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
           StorageDead(_9);                 // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
--         goto -> bb23;                    // scope 0 at $DIR/match-arm-scopes.rs:1:1: 1:1
-+         goto -> bb20;                    // scope 0 at $DIR/match-arm-scopes.rs:1:1: 1:1
+-         goto -> bb23;                    // scope 0 at no-location
++         goto -> bb20;                    // scope 0 at no-location
       }
   
 -     bb10: {
@@ -150,8 +150,8 @@
           _0 = const 3_i32;                // scope 0 at $DIR/match-arm-scopes.rs:15:59: 15:60
           StorageDead(_13);                // scope 0 at $DIR/match-arm-scopes.rs:15:72: 15:73
           StorageDead(_12);                // scope 0 at $DIR/match-arm-scopes.rs:15:77: 15:78
--         goto -> bb23;                    // scope 0 at $DIR/match-arm-scopes.rs:1:1: 1:1
-+         goto -> bb20;                    // scope 0 at $DIR/match-arm-scopes.rs:1:1: 1:1
+-         goto -> bb23;                    // scope 0 at no-location
++         goto -> bb20;                    // scope 0 at no-location
       }
   
 -     bb15: {
diff --git a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
index b91aae0..bf9c2d1 100644
--- a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
+++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir
@@ -40,7 +40,7 @@
 
     bb4: {
         StorageDead(_4);                 // scope 0 at $DIR/while-storage.rs:13:9: 13:10
-        goto -> bb6;                     // scope 0 at $DIR/while-storage.rs:1:1: 1:1
+        goto -> bb6;                     // scope 0 at no-location
     }
 
     bb5: {
diff --git a/src/test/run-make/issue-71519/Makefile b/src/test/run-make/issue-71519/Makefile
new file mode 100644
index 0000000..636665e
--- /dev/null
+++ b/src/test/run-make/issue-71519/Makefile
@@ -0,0 +1,6 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# needs-rust-lld
+all:
+	RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Z gcc-ld=lld -C link-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt
+	$(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt
diff --git a/src/test/run-make/issue-71519/main.rs b/src/test/run-make/issue-71519/main.rs
new file mode 100644
index 0000000..f8d09e8
--- /dev/null
+++ b/src/test/run-make/issue-71519/main.rs
@@ -0,0 +1,4 @@
+// test linking using cc with rust-lld injected into search path as ld
+// see rust-lang/rust#71519 for more info
+
+fn main() {}
diff --git a/src/test/rustdoc-ui/run-directory.rs b/src/test/rustdoc-ui/run-directory.rs
index 78431c0..0d432c1 100644
--- a/src/test/rustdoc-ui/run-directory.rs
+++ b/src/test/rustdoc-ui/run-directory.rs
@@ -2,8 +2,8 @@
 
 // revisions: correct incorrect
 // check-pass
-// [correct]compile-flags:--test --test-run-directory={{src-base}}
-// [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage
+// [correct]compile-flags:--test --test-run-directory={{src-base}} -Zunstable-options
+// [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage -Zunstable-options
 // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
 // normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
 
diff --git a/src/test/rustdoc-ui/wasm-safe.rs b/src/test/rustdoc-ui/wasm-safe.rs
index 80b15ac..ba97134 100644
--- a/src/test/rustdoc-ui/wasm-safe.rs
+++ b/src/test/rustdoc-ui/wasm-safe.rs
@@ -1,7 +1,5 @@
 // check-pass
 
-#![feature(wasm_target_feature)]
-
 #[cfg(any(target_arch = "wasm32", doc))]
 #[target_feature(enable = "simd128")]
 pub fn foo() {}
diff --git a/src/test/rustdoc/intra-doc/field.rs b/src/test/rustdoc/intra-doc/field.rs
index c67c40a..0011434 100644
--- a/src/test/rustdoc/intra-doc/field.rs
+++ b/src/test/rustdoc/intra-doc/field.rs
@@ -1,4 +1,4 @@
-// @has field/index.html '//a[@href="https://doc.rust-lang.org/nightly/core/ops/range/struct.Range.html#structfield.start"]' 'start'
-// @has field/index.html '//a[@href="https://doc.rust-lang.org/nightly/std/io/error/enum.ErrorKind.html#variant.NotFound"]' 'not_found'
+// @has field/index.html '//a[@href="{{channel}}/core/ops/range/struct.Range.html#structfield.start"]' 'start'
+// @has field/index.html '//a[@href="{{channel}}/std/io/error/enum.ErrorKind.html#variant.NotFound"]' 'not_found'
 //! [start][std::ops::Range::start]
 //! [not_found][std::io::ErrorKind::NotFound]
diff --git a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
index f58446d..25f6490 100644
--- a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
+++ b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.rs
@@ -1,3 +1,4 @@
+// compile-flags: -Z unstable-options
 // NOTE: This test doesn't actually require `fulldeps`
 // so we could instead use it as an `ui` test.
 //
diff --git a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr
index b846b30..15a06e7 100644
--- a/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr
+++ b/src/test/ui-fulldeps/internal-lints/pass_ty_by_ref_self.stderr
@@ -1,17 +1,17 @@
 error: passing `TyCtxt<'tcx>` by reference
-  --> $DIR/pass_ty_by_ref_self.rs:17:15
+  --> $DIR/pass_ty_by_ref_self.rs:18:15
    |
 LL |     fn by_ref(&self) {}
    |               ^^^^^ help: try passing by value: `TyCtxt<'tcx>`
    |
 note: the lint level is defined here
-  --> $DIR/pass_ty_by_ref_self.rs:7:9
+  --> $DIR/pass_ty_by_ref_self.rs:8:9
    |
 LL | #![deny(rustc::ty_pass_by_reference)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: passing `Ty<'tcx>` by reference
-  --> $DIR/pass_ty_by_ref_self.rs:30:21
+  --> $DIR/pass_ty_by_ref_self.rs:31:21
    |
 LL |     fn by_ref(self: &Ty<'tcx>) {}
    |                     ^^^^^^^^^ help: try passing by value: `Ty<'tcx>`
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index ac2d29c..091c834 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -19,45 +19,35 @@
 
 #![feature(rustc_private)]
 
+extern crate rustc_ast;
 extern crate rustc_ast_pretty;
 extern crate rustc_data_structures;
-extern crate rustc_ast;
 extern crate rustc_parse;
 extern crate rustc_session;
 extern crate rustc_span;
 
+use rustc_ast::mut_visit::{self, visit_clobber, MutVisitor};
+use rustc_ast::ptr::P;
+use rustc_ast::*;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_parse::new_parser_from_source_str;
 use rustc_session::parse::ParseSess;
-use rustc_span::source_map::{Spanned, DUMMY_SP, FileName};
 use rustc_span::source_map::FilePathMapping;
+use rustc_span::source_map::{FileName, Spanned, DUMMY_SP};
 use rustc_span::symbol::Ident;
-use rustc_ast::*;
-use rustc_ast::mut_visit::{self, MutVisitor, visit_clobber};
-use rustc_ast::ptr::P;
 
 fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
     let src_as_string = src.to_string();
 
-    let mut p = new_parser_from_source_str(
-        ps,
-        FileName::Custom(src_as_string.clone()),
-        src_as_string,
-    );
+    let mut p =
+        new_parser_from_source_str(ps, FileName::Custom(src_as_string.clone()), src_as_string);
     p.parse_expr().map_err(|mut e| e.cancel()).ok()
 }
 
-
 // Helper functions for building exprs
 fn expr(kind: ExprKind) -> P<Expr> {
-    P(Expr {
-        id: DUMMY_NODE_ID,
-        kind,
-        span: DUMMY_SP,
-        attrs: ThinVec::new(),
-        tokens: None
-    })
+    P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: ThinVec::new(), tokens: None })
 }
 
 fn make_x() -> P<Expr> {
@@ -83,11 +73,13 @@
             1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))),
             2 => {
                 let seg = PathSegment::from_ident(Ident::from_str("x"));
-                iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall(
-                            seg.clone(), vec![e, make_x()], DUMMY_SP)));
-                iter_exprs(depth - 1, &mut |e| g(ExprKind::MethodCall(
-                            seg.clone(), vec![make_x(), e], DUMMY_SP)));
-            },
+                iter_exprs(depth - 1, &mut |e| {
+                    g(ExprKind::MethodCall(seg.clone(), vec![e, make_x()], DUMMY_SP))
+                });
+                iter_exprs(depth - 1, &mut |e| {
+                    g(ExprKind::MethodCall(seg.clone(), vec![make_x(), e], DUMMY_SP))
+                });
+            }
             3..=8 => {
                 let op = Spanned {
                     span: DUMMY_SP,
@@ -99,14 +91,14 @@
                         7 => BinOpKind::Or,
                         8 => BinOpKind::Lt,
                         _ => unreachable!(),
-                    }
+                    },
                 };
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, e, make_x())));
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Binary(op, make_x(), e)));
-            },
+            }
             9 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e)));
-            },
+            }
             10 => {
                 let block = P(Block {
                     stmts: Vec::new(),
@@ -116,67 +108,66 @@
                     tokens: None,
                 });
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None)));
-            },
+            }
             11 => {
-                let decl = P(FnDecl {
-                    inputs: vec![],
-                    output: FnRetTy::Default(DUMMY_SP),
+                let decl = P(FnDecl { inputs: vec![], output: FnRetTy::Default(DUMMY_SP) });
+                iter_exprs(depth - 1, &mut |e| {
+                    g(ExprKind::Closure(
+                        CaptureBy::Value,
+                        Async::No,
+                        Movability::Movable,
+                        decl.clone(),
+                        e,
+                        DUMMY_SP,
+                    ))
                 });
-                iter_exprs(depth - 1, &mut |e| g(
-                        ExprKind::Closure(CaptureBy::Value,
-                                          Async::No,
-                                          Movability::Movable,
-                                          decl.clone(),
-                                          e,
-                                          DUMMY_SP)));
-            },
+            }
             12 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(e, make_x(), DUMMY_SP)));
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Assign(make_x(), e, DUMMY_SP)));
-            },
+            }
             13 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Field(e, Ident::from_str("f"))));
-            },
+            }
             14 => {
-                iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
-                            Some(e), Some(make_x()), RangeLimits::HalfOpen)));
-                iter_exprs(depth - 1, &mut |e| g(ExprKind::Range(
-                            Some(make_x()), Some(e), RangeLimits::HalfOpen)));
-            },
+                iter_exprs(depth - 1, &mut |e| {
+                    g(ExprKind::Range(Some(e), Some(make_x()), RangeLimits::HalfOpen))
+                });
+                iter_exprs(depth - 1, &mut |e| {
+                    g(ExprKind::Range(Some(make_x()), Some(e), RangeLimits::HalfOpen))
+                });
+            }
             15 => {
-                iter_exprs(
-                    depth - 1,
-                    &mut |e| g(ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, e)),
-                );
-            },
+                iter_exprs(depth - 1, &mut |e| {
+                    g(ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, e))
+                });
+            }
             16 => {
                 g(ExprKind::Ret(None));
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Ret(Some(e))));
-            },
+            }
             17 => {
                 let path = Path::from_ident(Ident::from_str("S"));
                 g(ExprKind::Struct(P(StructExpr {
-                    path, fields: vec![], rest: StructRest::Base(make_x())
+                    qself: None,
+                    path,
+                    fields: vec![],
+                    rest: StructRest::Base(make_x()),
                 })));
-            },
+            }
             18 => {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
-            },
+            }
             19 => {
-                let pat = P(Pat {
-                    id: DUMMY_NODE_ID,
-                    kind: PatKind::Wild,
-                    span: DUMMY_SP,
-                    tokens: None,
-                });
+                let pat =
+                    P(Pat { id: DUMMY_NODE_ID, kind: PatKind::Wild, span: DUMMY_SP, tokens: None });
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(pat.clone(), e)))
-            },
+            }
             _ => panic!("bad counter value in iter_exprs"),
         }
     }
 }
 
-
 // Folders for manipulating the placement of `Paren` nodes. See below for why this is needed.
 
 /// `MutVisitor` that removes all `ExprKind::Paren` nodes.
@@ -192,7 +183,6 @@
     }
 }
 
-
 /// `MutVisitor` that inserts `ExprKind::Paren` nodes around every `Expr`.
 struct AddParens;
 
@@ -205,7 +195,7 @@
                 kind: ExprKind::Paren(e),
                 span: DUMMY_SP,
                 attrs: ThinVec::new(),
-                tokens: None
+                tokens: None,
             })
         });
     }
@@ -238,9 +228,12 @@
             RemoveParens.visit_expr(&mut parsed);
             AddParens.visit_expr(&mut parsed);
             let text2 = pprust::expr_to_string(&parsed);
-            assert!(text1 == text2,
-                    "exprs are not equal:\n  e =      {:?}\n  parsed = {:?}",
-                    text1, text2);
+            assert!(
+                text1 == text2,
+                "exprs are not equal:\n  e =      {:?}\n  parsed = {:?}",
+                text1,
+                text2
+            );
         }
     });
 }
diff --git a/src/test/ui-fulldeps/session-derive-errors.rs b/src/test/ui-fulldeps/session-derive-errors.rs
index 7967b32..140aaad 100644
--- a/src/test/ui-fulldeps/session-derive-errors.rs
+++ b/src/test/ui-fulldeps/session-derive-errors.rs
@@ -1,6 +1,12 @@
 // check-fail
 // Tests error conditions for specifying diagnostics using #[derive(SessionDiagnostic)]
 
+// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
+// changing the output of this test. Since SessionDiagnostic is strictly internal to the compiler
+// the test is just ignored on stable and beta:
+// ignore-beta
+// ignore-stable
+
 #![feature(rustc_private)]
 #![crate_type = "lib"]
 
diff --git a/src/test/ui-fulldeps/session-derive-errors.stderr b/src/test/ui-fulldeps/session-derive-errors.stderr
index c6c3765..2f1debe 100644
--- a/src/test/ui-fulldeps/session-derive-errors.stderr
+++ b/src/test/ui-fulldeps/session-derive-errors.stderr
@@ -1,5 +1,5 @@
 error: `#[derive(SessionDiagnostic)]` can only be used on structs
-  --> $DIR/session-derive-errors.rs:28:1
+  --> $DIR/session-derive-errors.rs:34:1
    |
 LL | / #[error = "E0123"]
 LL | |
@@ -10,31 +10,31 @@
    | |_^
 
 error: `#[label = ...]` is not a valid SessionDiagnostic struct attribute
-  --> $DIR/session-derive-errors.rs:37:1
+  --> $DIR/session-derive-errors.rs:43:1
    |
 LL | #[label = "This is in the wrong place"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[suggestion = ...]` is not a valid SessionDiagnostic field attribute
-  --> $DIR/session-derive-errors.rs:44:5
+  --> $DIR/session-derive-errors.rs:50:5
    |
 LL |     #[suggestion = "this is the wrong kind of attribute"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `error` specified multiple times
-  --> $DIR/session-derive-errors.rs:52:11
+  --> $DIR/session-derive-errors.rs:58:11
    |
 LL | #[error = "E0456"]
    |           ^^^^^^^
 
 error: `lint` specified when `error` was already specified
-  --> $DIR/session-derive-errors.rs:58:10
+  --> $DIR/session-derive-errors.rs:64:10
    |
 LL | #[lint = "some_useful_lint"]
    |          ^^^^^^^^^^^^^^^^^^
 
 error: `code` not specified
-  --> $DIR/session-derive-errors.rs:67:1
+  --> $DIR/session-derive-errors.rs:73:1
    |
 LL | struct ErrorCodeNotProvided {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,19 +42,19 @@
    = help: use the [code = "..."] attribute to set this diagnostic's error code 
 
 error: the `#[message = "..."]` attribute can only be applied to fields of type Span
-  --> $DIR/session-derive-errors.rs:95:5
+  --> $DIR/session-derive-errors.rs:101:5
    |
 LL |     #[message = "this message is applied to a String field"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `name` doesn't refer to a field on this type
-  --> $DIR/session-derive-errors.rs:102:1
+  --> $DIR/session-derive-errors.rs:108:1
    |
 LL | #[message = "This error has a field, and references {name}"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: invalid format string: expected `'}'` but string was terminated
-  --> $DIR/session-derive-errors.rs:110:1
+  --> $DIR/session-derive-errors.rs:116:1
    |
 LL | #[error = "E0123"]
    |               - because of this opening brace
@@ -65,7 +65,7 @@
    = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: invalid format string: unmatched `}` found
-  --> $DIR/session-derive-errors.rs:119:1
+  --> $DIR/session-derive-errors.rs:125:1
    |
 LL | #[message = "This is missing an opening brace: name}"]
    | ^ unmatched `}` in format string
@@ -74,25 +74,25 @@
    = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: The `#[label = ...]` attribute can only be applied to fields of type Span
-  --> $DIR/session-derive-errors.rs:138:5
+  --> $DIR/session-derive-errors.rs:144:5
    |
 LL |     #[label = "See here"]
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: `nonsense` is not a valid key for `#[suggestion(...)]`
-  --> $DIR/session-derive-errors.rs:163:18
+  --> $DIR/session-derive-errors.rs:169:18
    |
 LL |     #[suggestion(nonsense = "This is nonsense")]
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `msg` is not a valid key for `#[suggestion(...)]`
-  --> $DIR/session-derive-errors.rs:171:18
+  --> $DIR/session-derive-errors.rs:177:18
    |
 LL |     #[suggestion(msg = "This is a suggestion")]
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: missing suggestion message
-  --> $DIR/session-derive-errors.rs:179:7
+  --> $DIR/session-derive-errors.rs:185:7
    |
 LL |     #[suggestion(code = "This is suggested code")]
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +100,7 @@
    = help: provide a suggestion message using #[suggestion(message = "...")]
 
 error: wrong field type for suggestion
-  --> $DIR/session-derive-errors.rs:194:5
+  --> $DIR/session-derive-errors.rs:200:5
    |
 LL | /     #[suggestion(message = "This is a message", code = "This is suggested code")]
 LL | |
@@ -110,7 +110,7 @@
    = help: #[suggestion(...)] should be applied to fields of type Span or (Span, Applicability)
 
 error: type of field annotated with `#[suggestion(...)]` contains more than one Span
-  --> $DIR/session-derive-errors.rs:209:5
+  --> $DIR/session-derive-errors.rs:215:5
    |
 LL | /     #[suggestion(message = "This is a message", code = "This is suggested code")]
 LL | |
@@ -118,7 +118,7 @@
    | |___________________________________________^
 
 error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability
-  --> $DIR/session-derive-errors.rs:217:5
+  --> $DIR/session-derive-errors.rs:223:5
    |
 LL | /     #[suggestion(message = "This is a message", code = "This is suggested code")]
 LL | |
@@ -126,7 +126,7 @@
    | |____________________________________________________^
 
 error: invalid annotation list `#[label(...)]`
-  --> $DIR/session-derive-errors.rs:225:7
+  --> $DIR/session-derive-errors.rs:231:7
    |
 LL |     #[label("wrong kind of annotation for label")]
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/annotate-snippet/missing-type.rs b/src/test/ui/annotate-snippet/missing-type.rs
index d0814a9..b0d8b5f 100644
--- a/src/test/ui/annotate-snippet/missing-type.rs
+++ b/src/test/ui/annotate-snippet/missing-type.rs
@@ -1,4 +1,4 @@
-// compile-flags: --error-format human-annotate-rs
+// compile-flags: --error-format human-annotate-rs -Z unstable-options
 
 pub fn main() {
     let x: Iter; //~ ERROR cannot find type `Iter` in this scope
diff --git a/src/test/ui/annotate-snippet/multispan.rs b/src/test/ui/annotate-snippet/multispan.rs
index 325252d..69d7e1a 100644
--- a/src/test/ui/annotate-snippet/multispan.rs
+++ b/src/test/ui/annotate-snippet/multispan.rs
@@ -1,5 +1,5 @@
 // aux-build:multispan.rs
-// compile-flags: --error-format human-annotate-rs
+// compile-flags: --error-format human-annotate-rs -Z unstable-options
 
 #![feature(proc_macro_hygiene)]
 
diff --git a/src/test/ui/associated-types/associated-type-destructuring-assignment.rs b/src/test/ui/associated-types/associated-type-destructuring-assignment.rs
new file mode 100644
index 0000000..fea7c7a
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-destructuring-assignment.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+#![feature(destructuring_assignment)]
+#![feature(more_qualified_paths)]
+
+enum E { V() }
+
+fn main() {
+    <E>::V() = E::V(); // OK, destructuring assignment
+    <E>::V {} = E::V(); // OK, destructuring assignment
+}
diff --git a/src/test/ui/associated-types/associated-type-macro.rs b/src/test/ui/associated-types/associated-type-macro.rs
new file mode 100644
index 0000000..22b5bca
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-macro.rs
@@ -0,0 +1,4 @@
+fn main() {
+    #[cfg(FALSE)]
+    <() as module>::mac!(); //~ ERROR macros cannot use qualified paths
+}
diff --git a/src/test/ui/associated-types/associated-type-macro.stderr b/src/test/ui/associated-types/associated-type-macro.stderr
new file mode 100644
index 0000000..6a4cf99
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-macro.stderr
@@ -0,0 +1,8 @@
+error: macros cannot use qualified paths
+  --> $DIR/associated-type-macro.rs:3:5
+   |
+LL |     <() as module>::mac!();
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/associated-type-struct-construction.rs b/src/test/ui/associated-types/associated-type-struct-construction.rs
new file mode 100644
index 0000000..f8f8048
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-struct-construction.rs
@@ -0,0 +1,24 @@
+// Make sure that users can construct structs through associated types
+// in both expressions and patterns
+
+#![feature(more_qualified_paths)]
+
+// check-pass
+fn main() {
+    let <Foo as A>::Assoc { br } = <Foo as A>::Assoc { br: 2 };
+    assert!(br == 2);
+}
+
+struct StructStruct {
+    br: i8,
+}
+
+struct Foo;
+
+trait A {
+    type Assoc;
+}
+
+impl A for Foo {
+    type Assoc = StructStruct;
+}
diff --git a/src/test/ui/associated-types/associated-type-tuple-struct-construction.rs b/src/test/ui/associated-types/associated-type-tuple-struct-construction.rs
new file mode 100644
index 0000000..d5809ec
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-tuple-struct-construction.rs
@@ -0,0 +1,24 @@
+// Users cannot yet construct structs through associated types
+// in both expressions and patterns
+
+#![feature(more_qualified_paths)]
+
+fn main() {
+    let <Foo as A>::Assoc(n) = <Foo as A>::Assoc(2);
+    //~^ ERROR expected method or associated constant, found associated type
+    //~| ERROR expected method or associated constant, found associated type
+    assert!(n == 2);
+}
+
+struct TupleStruct(i8);
+
+struct Foo;
+
+
+trait A {
+    type Assoc;
+}
+
+impl A for Foo {
+    type Assoc = TupleStruct;
+}
diff --git a/src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr b/src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr
new file mode 100644
index 0000000..bca7dee
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr
@@ -0,0 +1,19 @@
+error[E0575]: expected method or associated constant, found associated type `A::Assoc`
+  --> $DIR/associated-type-tuple-struct-construction.rs:7:32
+   |
+LL |     let <Foo as A>::Assoc(n) = <Foo as A>::Assoc(2);
+   |                                ^^^^^^^^^^^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+error[E0575]: expected method or associated constant, found associated type `A::Assoc`
+  --> $DIR/associated-type-tuple-struct-construction.rs:7:9
+   |
+LL |     let <Foo as A>::Assoc(n) = <Foo as A>::Assoc(2);
+   |         ^^^^^^^^^^^^^^^^^
+   |
+   = note: can't use a type alias as a constructor
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0575`.
diff --git a/src/test/ui/borrowck/issue-85765.rs b/src/test/ui/borrowck/issue-85765.rs
new file mode 100644
index 0000000..b82e029
--- /dev/null
+++ b/src/test/ui/borrowck/issue-85765.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let mut test = Vec::new();
+    let rofl: &Vec<Vec<i32>> = &mut test;
+    //~^ HELP consider changing this to be a mutable reference
+    rofl.push(Vec::new());
+    //~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference
+    //~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+}
diff --git a/src/test/ui/borrowck/issue-85765.stderr b/src/test/ui/borrowck/issue-85765.stderr
new file mode 100644
index 0000000..863c2e8
--- /dev/null
+++ b/src/test/ui/borrowck/issue-85765.stderr
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow `*rofl` as mutable, as it is behind a `&` reference
+  --> $DIR/issue-85765.rs:5:5
+   |
+LL |     let rofl: &Vec<Vec<i32>> = &mut test;
+   |         ---- help: consider changing this to be a mutable reference: `&mut Vec<Vec<i32>>`
+LL |
+LL |     rofl.push(Vec::new());
+   |     ^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-1.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-1.rs
new file mode 100644
index 0000000..744a1c4
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-1.rs
@@ -0,0 +1,18 @@
+// check-pass
+#![feature(const_evaluatable_checked, const_generics)]
+#![allow(incomplete_features)]
+
+struct Foo<const N: u8>([u8; N as usize])
+where
+    [(); N as usize]:;
+
+struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 2) as usize]:;
+
+// unifying with subtrees
+struct Evaluatable<const N: u16>;
+fn foo<const N: u8>() where Evaluatable<{N as usize as u16 }>: {
+    let _ = Foo::<N>([1; N as usize]);
+}
+
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs
new file mode 100644
index 0000000..5437746
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs
@@ -0,0 +1,20 @@
+#![feature(const_evaluatable_checked, const_generics)]
+#![allow(incomplete_features)]
+
+struct Evaluatable<const N: u128> {}
+
+struct Foo<const N: u8>([u8; N as usize])
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); N as usize]:`
+where
+    Evaluatable<{N as u128}>:;
+
+struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+
+struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr
new file mode 100644
index 0000000..5ca04d2
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr
@@ -0,0 +1,26 @@
+error: unconstrained generic constant
+  --> $DIR/abstract-const-as-cast-2.rs:6:25
+   |
+LL | struct Foo<const N: u8>([u8; N as usize])
+   |                         ^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); N as usize]:`
+
+error: unconstrained generic constant
+  --> $DIR/abstract-const-as-cast-2.rs:12:26
+   |
+LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+
+error: unconstrained generic constant
+  --> $DIR/abstract-const-as-cast-2.rs:16:25
+   |
+LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
+   |                         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.rs
new file mode 100644
index 0000000..2ca06bd
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.rs
@@ -0,0 +1,47 @@
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+trait Trait {}
+pub struct EvaluatableU128<const N: u128>;
+
+struct HasCastInTraitImpl<const N: usize, const M: u128>;
+impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+
+pub fn use_trait_impl<const N: usize>()
+where
+    [(); { N + 1}]:,
+    EvaluatableU128<{N as u128}>:, {
+    fn assert_impl<T: Trait>() {}
+
+    // errors are bad but seems to be pre-existing issue #86198
+    assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+    //~^ Error: mismatched types
+    //~^^ Error: unconstrained generic constant
+    assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+    //~^ Error: mismatched types
+    //~^^ Error: unconstrained generic constant
+    assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+    //~^ Error: mismatched types
+    assert_impl::<HasCastInTraitImpl<14, 13>>();
+    //~^ Error: mismatched types
+}
+pub fn use_trait_impl_2<const N: usize>()
+where
+    [(); { N + 1}]:,
+    EvaluatableU128<{N as _}>:, {
+    fn assert_impl<T: Trait>() {}
+
+    // errors are bad but seems to be pre-existing issue #86198
+    assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+    //~^ Error: mismatched types
+    //~^^ Error: unconstrained generic constant
+    assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+    //~^ Error: mismatched types
+    //~^^ Error: unconstrained generic constant
+    assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+    //~^ Error: mismatched types
+    assert_impl::<HasCastInTraitImpl<14, 13>>();
+    //~^ Error: mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr
new file mode 100644
index 0000000..c5237fc
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-3.stderr
@@ -0,0 +1,139 @@
+error: unconstrained generic constant
+  --> $DIR/abstract-const-as-cast-3.rs:17:5
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ----- required by this bound in `use_trait_impl::assert_impl`
+...
+LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+  --> $DIR/abstract-const-as-cast-3.rs:8:22
+   |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+   |                      ^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/abstract-const-as-cast-3.rs:17:5
+   |
+LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
+   |
+   = note: expected type `{ N as u128 }`
+              found type `{ O as u128 }`
+
+error: unconstrained generic constant
+  --> $DIR/abstract-const-as-cast-3.rs:20:5
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ----- required by this bound in `use_trait_impl::assert_impl`
+...
+LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+  --> $DIR/abstract-const-as-cast-3.rs:8:22
+   |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+   |                      ^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/abstract-const-as-cast-3.rs:20:5
+   |
+LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
+   |
+   = note: expected type `{ N as _ }`
+              found type `{ O as u128 }`
+
+error[E0308]: mismatched types
+  --> $DIR/abstract-const-as-cast-3.rs:23:5
+   |
+LL |     assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128`
+   |
+   = note: expected type `12_u128`
+              found type `13_u128`
+
+error[E0308]: mismatched types
+  --> $DIR/abstract-const-as-cast-3.rs:25:5
+   |
+LL |     assert_impl::<HasCastInTraitImpl<14, 13>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128`
+   |
+   = note: expected type `13_u128`
+              found type `14_u128`
+
+error: unconstrained generic constant
+  --> $DIR/abstract-const-as-cast-3.rs:35:5
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ----- required by this bound in `use_trait_impl_2::assert_impl`
+...
+LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
+  --> $DIR/abstract-const-as-cast-3.rs:8:22
+   |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+   |                      ^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/abstract-const-as-cast-3.rs:35:5
+   |
+LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
+   |
+   = note: expected type `{ N as u128 }`
+              found type `{ O as u128 }`
+
+error: unconstrained generic constant
+  --> $DIR/abstract-const-as-cast-3.rs:38:5
+   |
+LL |     fn assert_impl<T: Trait>() {}
+   |                       ----- required by this bound in `use_trait_impl_2::assert_impl`
+...
+LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
+note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
+  --> $DIR/abstract-const-as-cast-3.rs:8:22
+   |
+LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+   |                      ^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/abstract-const-as-cast-3.rs:38:5
+   |
+LL |     assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
+   |
+   = note: expected type `{ N as _ }`
+              found type `{ O as u128 }`
+
+error[E0308]: mismatched types
+  --> $DIR/abstract-const-as-cast-3.rs:41:5
+   |
+LL |     assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128`
+   |
+   = note: expected type `12_u128`
+              found type `13_u128`
+
+error[E0308]: mismatched types
+  --> $DIR/abstract-const-as-cast-3.rs:43:5
+   |
+LL |     assert_impl::<HasCastInTraitImpl<14, 13>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128`
+   |
+   = note: expected type `13_u128`
+              found type `14_u128`
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs
new file mode 100644
index 0000000..0bb4fcf
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-4.rs
@@ -0,0 +1,29 @@
+// check-pass
+#![feature(const_evaluatable_checked, const_generics)]
+#![allow(incomplete_features)]
+
+trait Trait {}
+pub struct EvaluatableU128<const N: u128>;
+
+struct HasCastInTraitImpl<const N: usize, const M: u128>;
+impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
+
+pub fn use_trait_impl<const N: usize>() where EvaluatableU128<{N as u128}>:, {
+    fn assert_impl<T: Trait>() {}
+
+    assert_impl::<HasCastInTraitImpl<N, { N as u128 }>>();
+    assert_impl::<HasCastInTraitImpl<N, { N as _ }>>();
+    assert_impl::<HasCastInTraitImpl<12, { 12 as u128 }>>();
+    assert_impl::<HasCastInTraitImpl<13, 13>>();
+}
+pub fn use_trait_impl_2<const N: usize>() where EvaluatableU128<{N as _}>:, {
+    fn assert_impl<T: Trait>() {}
+
+    assert_impl::<HasCastInTraitImpl<N, { N as u128 }>>();
+    assert_impl::<HasCastInTraitImpl<N, { N as _ }>>();
+    assert_impl::<HasCastInTraitImpl<12, { 12 as u128 }>>();
+    assert_impl::<HasCastInTraitImpl<13, 13>>();
+}
+
+
+fn main() {}
diff --git a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
index 985e7b6..29d835e 100644
--- a/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
+++ b/src/test/ui/const-generics/defaults/intermixed-lifetime.min.stderr
@@ -2,13 +2,13 @@
   --> $DIR/intermixed-lifetime.rs:7:28
    |
 LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
-   |           -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const N: usize, T = u32>`
+   |           -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
 
 error: lifetime parameters must be declared prior to type parameters
   --> $DIR/intermixed-lifetime.rs:10:37
    |
 LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
-   |           --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const N: usize, T = u32>`
+   |           --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/defaults/mismatch.full.stderr b/src/test/ui/const-generics/defaults/mismatch.full.stderr
index be4f364..4aa8401 100644
--- a/src/test/ui/const-generics/defaults/mismatch.full.stderr
+++ b/src/test/ui/const-generics/defaults/mismatch.full.stderr
@@ -5,9 +5,12 @@
    |            -------------   ^^ expected struct `Example`, found `()`
    |            |
    |            expected due to this
+   |
+   = note: expected struct `Example`
+           found unit type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/mismatch.rs:14:34
+  --> $DIR/mismatch.rs:15:34
    |
 LL |     let e: Example2::<u32, 13> = ();
    |            -------------------   ^^ expected struct `Example2`, found `()`
@@ -18,7 +21,7 @@
            found unit type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/mismatch.rs:16:34
+  --> $DIR/mismatch.rs:18:34
    |
 LL |     let e: Example3::<13, u32> = ();
    |            -------------------   ^^ expected struct `Example3`, found `()`
@@ -29,7 +32,7 @@
            found unit type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/mismatch.rs:18:28
+  --> $DIR/mismatch.rs:21:28
    |
 LL |     let e: Example3::<7> = ();
    |            -------------   ^^ expected struct `Example3`, found `()`
@@ -40,12 +43,15 @@
            found unit type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/mismatch.rs:22:28
+  --> $DIR/mismatch.rs:24:28
    |
 LL |     let e: Example4::<7> = ();
    |            -------------   ^^ expected struct `Example4`, found `()`
    |            |
    |            expected due to this
+   |
+   = note: expected struct `Example4<7_usize>`
+           found unit type `()`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/const-generics/defaults/mismatch.min.stderr b/src/test/ui/const-generics/defaults/mismatch.min.stderr
index be4f364..4aa8401 100644
--- a/src/test/ui/const-generics/defaults/mismatch.min.stderr
+++ b/src/test/ui/const-generics/defaults/mismatch.min.stderr
@@ -5,9 +5,12 @@
    |            -------------   ^^ expected struct `Example`, found `()`
    |            |
    |            expected due to this
+   |
+   = note: expected struct `Example`
+           found unit type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/mismatch.rs:14:34
+  --> $DIR/mismatch.rs:15:34
    |
 LL |     let e: Example2::<u32, 13> = ();
    |            -------------------   ^^ expected struct `Example2`, found `()`
@@ -18,7 +21,7 @@
            found unit type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/mismatch.rs:16:34
+  --> $DIR/mismatch.rs:18:34
    |
 LL |     let e: Example3::<13, u32> = ();
    |            -------------------   ^^ expected struct `Example3`, found `()`
@@ -29,7 +32,7 @@
            found unit type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/mismatch.rs:18:28
+  --> $DIR/mismatch.rs:21:28
    |
 LL |     let e: Example3::<7> = ();
    |            -------------   ^^ expected struct `Example3`, found `()`
@@ -40,12 +43,15 @@
            found unit type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/mismatch.rs:22:28
+  --> $DIR/mismatch.rs:24:28
    |
 LL |     let e: Example4::<7> = ();
    |            -------------   ^^ expected struct `Example4`, found `()`
    |            |
    |            expected due to this
+   |
+   = note: expected struct `Example4<7_usize>`
+           found unit type `()`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/const-generics/defaults/mismatch.rs b/src/test/ui/const-generics/defaults/mismatch.rs
index 68a640c..9d9a879 100644
--- a/src/test/ui/const-generics/defaults/mismatch.rs
+++ b/src/test/ui/const-generics/defaults/mismatch.rs
@@ -11,14 +11,17 @@
 fn main() {
     let e: Example::<13> = ();
     //~^ Error: mismatched types
+    //~| expected struct `Example`
     let e: Example2::<u32, 13> = ();
     //~^ Error: mismatched types
+    //~| expected struct `Example2`
     let e: Example3::<13, u32> = ();
     //~^ Error: mismatched types
+    //~| expected struct `Example3`
     let e: Example3::<7> = ();
     //~^ Error: mismatched types
-    // FIXME(const_generics_defaults): There should be a note for the error below, but it is
-    // missing.
+    //~| expected struct `Example3<7_usize>`
     let e: Example4::<7> = ();
     //~^ Error: mismatched types
+    //~| expected struct `Example4<7_usize>`
 }
diff --git a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs
new file mode 100644
index 0000000..933eacb
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.rs
@@ -0,0 +1,5 @@
+#![feature(const_generics_defaults)]
+struct Foo<const M: usize = 10, 'a>(&'a u32);
+//~^ Error lifetime parameters must be declared prior to const parameters
+
+fn main() {}
diff --git a/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr
new file mode 100644
index 0000000..f50653f
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/param-order-err-pretty-prints-default.stderr
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to const parameters
+  --> $DIR/param-order-err-pretty-prints-default.rs:2:33
+   |
+LL | struct Foo<const M: usize = 10, 'a>(&'a u32);
+   |           ----------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const M: usize = 10>`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs b/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs
deleted file mode 100644
index 560795a..0000000
--- a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-struct Const<const P: &'static ()>;
-//~^ ERROR `&'static ()` is forbidden as the type of a const generic parameter
-
-fn main() {
-    const A: &'static () = unsafe {
-        std::mem::transmute(10 as *const ())
-    };
-
-    let _ = Const::<{A}>;
-}
diff --git a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr b/src/test/ui/const-generics/transmute-const-param-static-reference.min.stderr
similarity index 85%
rename from src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr
rename to src/test/ui/const-generics/transmute-const-param-static-reference.min.stderr
index d612e0c..f735be9 100644
--- a/src/test/ui/const-generics/min_const_generics/transmute-const-param-static-reference.stderr
+++ b/src/test/ui/const-generics/transmute-const-param-static-reference.min.stderr
@@ -1,5 +1,5 @@
 error: `&'static ()` is forbidden as the type of a const generic parameter
-  --> $DIR/transmute-const-param-static-reference.rs:1:23
+  --> $DIR/transmute-const-param-static-reference.rs:7:23
    |
 LL | struct Const<const P: &'static ()>;
    |                       ^^^^^^^^^^^
diff --git a/src/test/ui/const-generics/transmute-const-param-static-reference.rs b/src/test/ui/const-generics/transmute-const-param-static-reference.rs
new file mode 100644
index 0000000..3147d61
--- /dev/null
+++ b/src/test/ui/const-generics/transmute-const-param-static-reference.rs
@@ -0,0 +1,16 @@
+// revisions: full min
+//[full] check-pass
+
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+
+struct Const<const P: &'static ()>;
+//[min]~^ ERROR `&'static ()` is forbidden as the type of a const generic parameter
+
+fn main() {
+    const A: &'static () = unsafe {
+        std::mem::transmute(10 as *const ())
+    };
+
+    let _ = Const::<{A}>;
+}
diff --git a/src/test/ui/const-ptr/out_of_bounds_read.rs b/src/test/ui/const-ptr/out_of_bounds_read.rs
deleted file mode 100644
index 183aa9e..0000000
--- a/src/test/ui/const-ptr/out_of_bounds_read.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// error-pattern: any use of this value will cause an error
-
-#![feature(const_ptr_read)]
-#![feature(const_ptr_offset)]
-
-fn main() {
-    use std::ptr;
-
-    const DATA: [u32; 1] = [42];
-
-    const PAST_END_PTR: *const u32 = unsafe { DATA.as_ptr().add(1) };
-
-    const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
-    const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
-    const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
-}
diff --git a/src/test/ui/const-ptr/out_of_bounds_read.stderr b/src/test/ui/const-ptr/out_of_bounds_read.stderr
deleted file mode 100644
index 6c4092e..0000000
--- a/src/test/ui/const-ptr/out_of_bounds_read.stderr
+++ /dev/null
@@ -1,59 +0,0 @@
-error: any use of this value will cause an error
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |
-LL |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |         |
-   |         memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
-   |         inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |         inside `_READ` at $DIR/out_of_bounds_read.rs:13:33
-   | 
-  ::: $DIR/out_of_bounds_read.rs:13:5
-   |
-LL |     const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
-   |     ------------------------------------------------------
-   |
-   = note: `#[deny(const_err)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |
-LL |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |         |
-   |         memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
-   |         inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |         inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
-   |         inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39
-   | 
-  ::: $DIR/out_of_bounds_read.rs:14:5
-   |
-LL |     const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
-   |     --------------------------------------------------------
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
-  --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |
-LL |         copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |         |
-   |         memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
-   |         inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
-   |         inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
-   |         inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37
-   | 
-  ::: $DIR/out_of_bounds_read.rs:15:5
-   |
-LL |     const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
-   |     --------------------------------------------------------------------
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: aborting due to 3 previous errors
-
diff --git a/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs b/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs
new file mode 100644
index 0000000..0c0e368
--- /dev/null
+++ b/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs
@@ -0,0 +1,21 @@
+// This test contains code with incorrect vtables in a const context:
+// - from issue 86132: a trait object with invalid alignment caused an ICE in const eval, and now
+//   triggers an error
+// - a similar test that triggers a previously-untested const UB error: emitted close to the above
+//   error, it checks the correctness of the size
+
+trait Trait {}
+
+const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
+    unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
+//~^ ERROR any use of this value will cause an error
+//~| WARNING this was previously accepted by the compiler
+//~| invalid vtable: alignment `1000` is not a power of 2
+
+const INVALID_VTABLE_SIZE: &dyn Trait =
+    unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
+//~^ ERROR any use of this value will cause an error
+//~| WARNING this was previously accepted by the compiler
+//~| invalid vtable: size is bigger than largest supported object
+
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr b/src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr
new file mode 100644
index 0000000..c937d03
--- /dev/null
+++ b/src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr
@@ -0,0 +1,27 @@
+error: any use of this value will cause an error
+  --> $DIR/ub-incorrect-vtable.rs:10:14
+   |
+LL | / const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
+LL | |     unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
+   | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__-
+   |                |
+   |                invalid vtable: alignment `1000` is not a power of 2
+   |
+   = note: `#[deny(const_err)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: any use of this value will cause an error
+  --> $DIR/ub-incorrect-vtable.rs:16:14
+   |
+LL | / const INVALID_VTABLE_SIZE: &dyn Trait =
+LL | |     unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
+   | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__-
+   |                |
+   |                invalid vtable: size is bigger than largest supported object
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/consts/const-needs_drop-monomorphic.rs b/src/test/ui/consts/const-needs_drop-monomorphic.rs
new file mode 100644
index 0000000..9f66e3c
--- /dev/null
+++ b/src/test/ui/consts/const-needs_drop-monomorphic.rs
@@ -0,0 +1,17 @@
+// Check that evaluation of needs_drop<T> fails when T is not monomorphic.
+#![feature(const_generics)]
+#![allow(const_evaluatable_unchecked)]
+#![allow(incomplete_features)]
+
+struct Bool<const B: bool> {}
+impl Bool<true> {
+    fn assert() {}
+}
+fn f<T>() {
+    Bool::<{ std::mem::needs_drop::<T>() }>::assert();
+    //~^ ERROR no function or associated item named `assert` found
+    //~| ERROR constant expression depends on a generic parameter
+}
+fn main() {
+    f::<u32>();
+}
diff --git a/src/test/ui/consts/const-needs_drop-monomorphic.stderr b/src/test/ui/consts/const-needs_drop-monomorphic.stderr
new file mode 100644
index 0000000..0770d06
--- /dev/null
+++ b/src/test/ui/consts/const-needs_drop-monomorphic.stderr
@@ -0,0 +1,20 @@
+error[E0599]: no function or associated item named `assert` found for struct `Bool<{ std::mem::needs_drop::<T>() }>` in the current scope
+  --> $DIR/const-needs_drop-monomorphic.rs:11:46
+   |
+LL | struct Bool<const B: bool> {}
+   | -------------------------- function or associated item `assert` not found for this
+...
+LL |     Bool::<{ std::mem::needs_drop::<T>() }>::assert();
+   |                                              ^^^^^^ function or associated item cannot be called on `Bool<{ std::mem::needs_drop::<T>() }>` due to unsatisfied trait bounds
+
+error: constant expression depends on a generic parameter
+  --> $DIR/const-needs_drop-monomorphic.rs:11:5
+   |
+LL |     Bool::<{ std::mem::needs_drop::<T>() }>::assert();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/consts/copy-intrinsic.rs b/src/test/ui/consts/copy-intrinsic.rs
deleted file mode 100644
index 9dc595f..0000000
--- a/src/test/ui/consts/copy-intrinsic.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// ignore-tidy-linelength
-#![feature(const_mut_refs, const_intrinsic_copy, const_ptr_offset)]
-use std::{ptr, mem};
-
-const COPY_ZERO: () = unsafe {
-    // Since we are not copying anything, this should be allowed.
-    let src = ();
-    let mut dst = ();
-    ptr::copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0);
-};
-
-const COPY_OOB_1: () = unsafe {
-    let mut x = 0i32;
-    let dangle = (&mut x as *mut i32).wrapping_add(10);
-    // Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs.
-    ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0); //~ ERROR any use of this value will cause an error
-    //~| memory access failed: pointer must be in-bounds
-    //~| previously accepted
-};
-const COPY_OOB_2: () = unsafe {
-    let x = 0i32;
-    let dangle = (&x as *const i32).wrapping_add(10);
-    // Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs.
-    ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0); //~ ERROR any use of this value will cause an error
-    //~| memory access failed: pointer must be in-bounds
-    //~| previously accepted
-};
-
-const COPY_SIZE_OVERFLOW: () = unsafe {
-    let x = 0;
-    let mut y = 0;
-    ptr::copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ ERROR any use of this value will cause an error
-    //~| overflow computing total size of `copy`
-    //~| previously accepted
-};
-const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe {
-    let x = 0;
-    let mut y = 0;
-    ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ ERROR any use of this value will cause an error
-    //~| overflow computing total size of `copy_nonoverlapping`
-    //~| previously accepted
-};
-
-fn main() {
-}
diff --git a/src/test/ui/consts/copy-intrinsic.stderr b/src/test/ui/consts/copy-intrinsic.stderr
deleted file mode 100644
index 2736cde..0000000
--- a/src/test/ui/consts/copy-intrinsic.stderr
+++ /dev/null
@@ -1,69 +0,0 @@
-error: any use of this value will cause an error
-  --> $DIR/copy-intrinsic.rs:16:5
-   |
-LL | / const COPY_OOB_1: () = unsafe {
-LL | |     let mut x = 0i32;
-LL | |     let dangle = (&mut x as *mut i32).wrapping_add(10);
-LL | |     // Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs.
-LL | |     ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0);
-   | |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc4 which has size 4
-LL | |
-LL | |
-LL | | };
-   | |__-
-   |
-   = note: `#[deny(const_err)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
-  --> $DIR/copy-intrinsic.rs:24:5
-   |
-LL | / const COPY_OOB_2: () = unsafe {
-LL | |     let x = 0i32;
-LL | |     let dangle = (&x as *const i32).wrapping_add(10);
-LL | |     // Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs.
-LL | |     ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0);
-   | |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc6 which has size 4
-LL | |
-LL | |
-LL | | };
-   | |__-
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
-  --> $DIR/copy-intrinsic.rs:32:5
-   |
-LL | / const COPY_SIZE_OVERFLOW: () = unsafe {
-LL | |     let x = 0;
-LL | |     let mut y = 0;
-LL | |     ptr::copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
-   | |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy`
-LL | |
-LL | |
-LL | | };
-   | |__-
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: any use of this value will cause an error
-  --> $DIR/copy-intrinsic.rs:39:5
-   |
-LL | / const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe {
-LL | |     let x = 0;
-LL | |     let mut y = 0;
-LL | |     ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
-   | |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping`
-LL | |
-LL | |
-LL | | };
-   | |__-
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-
-error: aborting due to 4 previous errors
-
diff --git a/src/test/ui/deduplicate-diagnostics.duplicate.stderr b/src/test/ui/deduplicate-diagnostics.duplicate.stderr
index 3b100b5..cd4700c 100644
--- a/src/test/ui/deduplicate-diagnostics.duplicate.stderr
+++ b/src/test/ui/deduplicate-diagnostics.duplicate.stderr
@@ -22,12 +22,6 @@
 LL | #[deny("literal")]
    |        ^^^^^^^^^ bad attribute argument
 
-error[E0452]: malformed lint attribute input
-  --> $DIR/deduplicate-diagnostics.rs:8:8
-   |
-LL | #[deny("literal")]
-   |        ^^^^^^^^^ bad attribute argument
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0452`.
diff --git a/src/test/ui/deduplicate-diagnostics.rs b/src/test/ui/deduplicate-diagnostics.rs
index c5d41ff..7d1c4f5 100644
--- a/src/test/ui/deduplicate-diagnostics.rs
+++ b/src/test/ui/deduplicate-diagnostics.rs
@@ -7,5 +7,4 @@
 
 #[deny("literal")] //~ ERROR malformed lint attribute input
                    //[duplicate]~| ERROR malformed lint attribute input
-                   //[duplicate]~| ERROR malformed lint attribute input
 fn main() {}
diff --git a/src/test/ui/error-codes/E0452.rs b/src/test/ui/error-codes/E0452.rs
index 4e5a6c9..5066cd9 100644
--- a/src/test/ui/error-codes/E0452.rs
+++ b/src/test/ui/error-codes/E0452.rs
@@ -2,7 +2,5 @@
                     //~| ERROR E0452
                     //~| ERROR E0452
                     //~| ERROR E0452
-                    //~| ERROR E0452
-                    //~| ERROR E0452
 fn main() {
 }
diff --git a/src/test/ui/error-codes/E0452.stderr b/src/test/ui/error-codes/E0452.stderr
index 30c11e3..f67b740 100644
--- a/src/test/ui/error-codes/E0452.stderr
+++ b/src/test/ui/error-codes/E0452.stderr
@@ -22,18 +22,6 @@
 LL | #![allow(foo = "")]
    |          ^^^^^^^^ bad attribute argument
 
-error[E0452]: malformed lint attribute input
-  --> $DIR/E0452.rs:1:10
-   |
-LL | #![allow(foo = "")]
-   |          ^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/E0452.rs:1:10
-   |
-LL | #![allow(foo = "")]
-   |          ^^^^^^^^ bad attribute argument
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0452`.
diff --git a/src/test/ui/error-codes/E0453.rs b/src/test/ui/error-codes/E0453.rs
index 6fa8dd9..ca9573c 100644
--- a/src/test/ui/error-codes/E0453.rs
+++ b/src/test/ui/error-codes/E0453.rs
@@ -3,6 +3,5 @@
 #[allow(non_snake_case)]
 //~^ ERROR allow(non_snake_case) incompatible
 //~| ERROR allow(non_snake_case) incompatible
-//~| ERROR allow(non_snake_case) incompatible
 fn main() {
 }
diff --git a/src/test/ui/error-codes/E0453.stderr b/src/test/ui/error-codes/E0453.stderr
index 21c43cc..6d60dc8 100644
--- a/src/test/ui/error-codes/E0453.stderr
+++ b/src/test/ui/error-codes/E0453.stderr
@@ -16,15 +16,6 @@
 LL | #[allow(non_snake_case)]
    |         ^^^^^^^^^^^^^^ overruled by previous forbid
 
-error[E0453]: allow(non_snake_case) incompatible with previous forbid
-  --> $DIR/E0453.rs:3:9
-   |
-LL | #![forbid(non_snake_case)]
-   |           -------------- `forbid` level set here
-LL | 
-LL | #[allow(non_snake_case)]
-   |         ^^^^^^^^^^^^^^ overruled by previous forbid
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui/error-codes/E0602.stderr b/src/test/ui/error-codes/E0602.stderr
index 70137cb..2b37226 100644
--- a/src/test/ui/error-codes/E0602.stderr
+++ b/src/test/ui/error-codes/E0602.stderr
@@ -6,10 +6,6 @@
    |
    = note: requested on the command line with `-D bogus`
 
-error[E0602]: unknown lint: `bogus`
-   |
-   = note: requested on the command line with `-D bogus`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0602`.
diff --git a/src/test/ui/feature-gates/feature-gate-lint-reasons.rs b/src/test/ui/feature-gates/feature-gate-lint-reasons.rs
index b124e9b..7756074 100644
--- a/src/test/ui/feature-gates/feature-gate-lint-reasons.rs
+++ b/src/test/ui/feature-gates/feature-gate-lint-reasons.rs
@@ -1,6 +1,5 @@
 #![warn(nonstandard_style, reason = "the standard should be respected")]
 //~^ ERROR lint reasons are experimental
 //~| ERROR lint reasons are experimental
-//~| ERROR lint reasons are experimental
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr
index a7d5ea6..12793c7 100644
--- a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr
+++ b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr
@@ -16,15 +16,6 @@
    = note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information
    = help: add `#![feature(lint_reasons)]` to the crate attributes to enable
 
-error[E0658]: lint reasons are experimental
-  --> $DIR/feature-gate-lint-reasons.rs:1:28
-   |
-LL | #![warn(nonstandard_style, reason = "the standard should be respected")]
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #54503 <https://github.com/rust-lang/rust/issues/54503> for more information
-   = help: add `#![feature(lint_reasons)]` to the crate attributes to enable
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-more-qualified-paths.rs b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.rs
new file mode 100644
index 0000000..2e05acb
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.rs
@@ -0,0 +1,27 @@
+fn main() {
+    // destructure through a qualified path
+    let <Foo as A>::Assoc { br } = StructStruct { br: 2 };
+    //~^ ERROR usage of qualified paths in this context is experimental
+    let _ = <Foo as A>::Assoc { br: 2 };
+    //~^ ERROR usage of qualified paths in this context is experimental
+    let <E>::V(..) = E::V(0);
+    //~^ ERROR usage of qualified paths in this context is experimental
+}
+
+struct StructStruct {
+    br: i8,
+}
+
+struct Foo;
+
+trait A {
+    type Assoc;
+}
+
+impl A for Foo {
+    type Assoc = StructStruct;
+}
+
+enum E {
+    V(u8)
+}
diff --git a/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr
new file mode 100644
index 0000000..b49cc40
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr
@@ -0,0 +1,30 @@
+error[E0658]: usage of qualified paths in this context is experimental
+  --> $DIR/feature-gate-more-qualified-paths.rs:3:9
+   |
+LL |     let <Foo as A>::Assoc { br } = StructStruct { br: 2 };
+   |         ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80080 <https://github.com/rust-lang/rust/issues/80080> for more information
+   = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
+
+error[E0658]: usage of qualified paths in this context is experimental
+  --> $DIR/feature-gate-more-qualified-paths.rs:5:13
+   |
+LL |     let _ = <Foo as A>::Assoc { br: 2 };
+   |             ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80080 <https://github.com/rust-lang/rust/issues/80080> for more information
+   = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
+
+error[E0658]: usage of qualified paths in this context is experimental
+  --> $DIR/feature-gate-more-qualified-paths.rs:7:9
+   |
+LL |     let <E>::V(..) = E::V(0);
+   |         ^^^^^^
+   |
+   = note: see issue #80080 <https://github.com/rust-lang/rust/issues/80080> for more information
+   = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/intrinsics/issue-84297-reifying-copy.rs b/src/test/ui/intrinsics/issue-84297-reifying-copy.rs
new file mode 100644
index 0000000..08ba9ce
--- /dev/null
+++ b/src/test/ui/intrinsics/issue-84297-reifying-copy.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+fn main() {
+    let _unused = if true {
+        core::ptr::copy::<i32>
+    } else {
+        core::ptr::copy_nonoverlapping::<i32>
+    };
+}
diff --git a/src/test/ui/lint/crate_level_only_lint.rs b/src/test/ui/lint/crate_level_only_lint.rs
index d9673fa..38c5487 100644
--- a/src/test/ui/lint/crate_level_only_lint.rs
+++ b/src/test/ui/lint/crate_level_only_lint.rs
@@ -4,12 +4,10 @@
 #![allow(uncommon_codepoints)]
 //~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
 //~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
-//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
 
 #[allow(uncommon_codepoints)]
 //~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
 //~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
-//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
 const BAR: f64 = 0.000001;
 
 }
@@ -17,6 +15,5 @@
 #[allow(uncommon_codepoints)]
 //~^ ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
 //~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
-//~| ERROR allow(uncommon_codepoints) is ignored unless specified at crate level [unused_attributes]
 fn main() {
 }
diff --git a/src/test/ui/lint/crate_level_only_lint.stderr b/src/test/ui/lint/crate_level_only_lint.stderr
index 8fb06df..83bea04 100644
--- a/src/test/ui/lint/crate_level_only_lint.stderr
+++ b/src/test/ui/lint/crate_level_only_lint.stderr
@@ -11,13 +11,13 @@
    |                              ^^^^^^^^^^^^^^^^^
 
 error: allow(uncommon_codepoints) is ignored unless specified at crate level
-  --> $DIR/crate_level_only_lint.rs:9:9
+  --> $DIR/crate_level_only_lint.rs:8:9
    |
 LL | #[allow(uncommon_codepoints)]
    |         ^^^^^^^^^^^^^^^^^^^
 
 error: allow(uncommon_codepoints) is ignored unless specified at crate level
-  --> $DIR/crate_level_only_lint.rs:17:9
+  --> $DIR/crate_level_only_lint.rs:15:9
    |
 LL | #[allow(uncommon_codepoints)]
    |         ^^^^^^^^^^^^^^^^^^^
@@ -29,34 +29,16 @@
    |          ^^^^^^^^^^^^^^^^^^^
 
 error: allow(uncommon_codepoints) is ignored unless specified at crate level
-  --> $DIR/crate_level_only_lint.rs:9:9
+  --> $DIR/crate_level_only_lint.rs:8:9
    |
 LL | #[allow(uncommon_codepoints)]
    |         ^^^^^^^^^^^^^^^^^^^
 
 error: allow(uncommon_codepoints) is ignored unless specified at crate level
-  --> $DIR/crate_level_only_lint.rs:17:9
+  --> $DIR/crate_level_only_lint.rs:15:9
    |
 LL | #[allow(uncommon_codepoints)]
    |         ^^^^^^^^^^^^^^^^^^^
 
-error: allow(uncommon_codepoints) is ignored unless specified at crate level
-  --> $DIR/crate_level_only_lint.rs:4:10
-   |
-LL | #![allow(uncommon_codepoints)]
-   |          ^^^^^^^^^^^^^^^^^^^
-
-error: allow(uncommon_codepoints) is ignored unless specified at crate level
-  --> $DIR/crate_level_only_lint.rs:9:9
-   |
-LL | #[allow(uncommon_codepoints)]
-   |         ^^^^^^^^^^^^^^^^^^^
-
-error: allow(uncommon_codepoints) is ignored unless specified at crate level
-  --> $DIR/crate_level_only_lint.rs:17:9
-   |
-LL | #[allow(uncommon_codepoints)]
-   |         ^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 9 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/lint/forbid-group-group-2.rs b/src/test/ui/lint/forbid-group-group-2.rs
index b12fd72..7d8a398 100644
--- a/src/test/ui/lint/forbid-group-group-2.rs
+++ b/src/test/ui/lint/forbid-group-group-2.rs
@@ -17,10 +17,4 @@
 //~| WARNING previously accepted by the compiler
 //~| ERROR incompatible with previous
 //~| WARNING previously accepted by the compiler
-//~| ERROR incompatible with previous
-//~| WARNING previously accepted by the compiler
-//~| ERROR incompatible with previous
-//~| WARNING previously accepted by the compiler
-//~| ERROR incompatible with previous
-//~| WARNING previously accepted by the compiler
 fn main() {}
diff --git a/src/test/ui/lint/forbid-group-group-2.stderr b/src/test/ui/lint/forbid-group-group-2.stderr
index 214e949..d8c09e6 100644
--- a/src/test/ui/lint/forbid-group-group-2.stderr
+++ b/src/test/ui/lint/forbid-group-group-2.stderr
@@ -75,41 +75,5 @@
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
 
-error: allow(nonstandard_style) incompatible with previous forbid
-  --> $DIR/forbid-group-group-2.rs:7:9
-   |
-LL | #![forbid(warnings)]
-   |           -------- `forbid` level set here
-...
-LL | #[allow(nonstandard_style)]
-   |         ^^^^^^^^^^^^^^^^^ overruled by previous forbid
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-error: allow(nonstandard_style) incompatible with previous forbid
-  --> $DIR/forbid-group-group-2.rs:7:9
-   |
-LL | #![forbid(warnings)]
-   |           -------- `forbid` level set here
-...
-LL | #[allow(nonstandard_style)]
-   |         ^^^^^^^^^^^^^^^^^ overruled by previous forbid
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-error: allow(nonstandard_style) incompatible with previous forbid
-  --> $DIR/forbid-group-group-2.rs:7:9
-   |
-LL | #![forbid(warnings)]
-   |           -------- `forbid` level set here
-...
-LL | #[allow(nonstandard_style)]
-   |         ^^^^^^^^^^^^^^^^^ overruled by previous forbid
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-error: aborting due to 9 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/lint/forbid-group-member.rs b/src/test/ui/lint/forbid-group-member.rs
index 6f1b2e9..664edea 100644
--- a/src/test/ui/lint/forbid-group-member.rs
+++ b/src/test/ui/lint/forbid-group-member.rs
@@ -12,8 +12,6 @@
 //~| WARNING previously accepted
 //~| WARNING incompatible with previous forbid
 //~| WARNING previously accepted
-//~| WARNING incompatible with previous forbid
-//~| WARNING previously accepted
 fn main() {
     let a: ();
 }
diff --git a/src/test/ui/lint/forbid-group-member.stderr b/src/test/ui/lint/forbid-group-member.stderr
index c818d7f..72772a4 100644
--- a/src/test/ui/lint/forbid-group-member.stderr
+++ b/src/test/ui/lint/forbid-group-member.stderr
@@ -35,17 +35,5 @@
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
 
-warning: allow(unused_variables) incompatible with previous forbid
-  --> $DIR/forbid-group-member.rs:8:9
-   |
-LL | #![forbid(unused)]
-   |           ------ `forbid` level set here
-LL | 
-LL | #[allow(unused_variables)]
-   |         ^^^^^^^^^^^^^^^^ overruled by previous forbid
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-warning: 4 warnings emitted
+warning: 3 warnings emitted
 
diff --git a/src/test/ui/lint/forbid-member-group.rs b/src/test/ui/lint/forbid-member-group.rs
index 3279029..e2f7682 100644
--- a/src/test/ui/lint/forbid-member-group.rs
+++ b/src/test/ui/lint/forbid-member-group.rs
@@ -6,7 +6,6 @@
 #[allow(unused)]
 //~^ ERROR incompatible with previous forbid
 //~| ERROR incompatible with previous forbid
-//~| ERROR incompatible with previous forbid
 fn main() {
     let a: ();
 }
diff --git a/src/test/ui/lint/forbid-member-group.stderr b/src/test/ui/lint/forbid-member-group.stderr
index 1d8ab4d..39700af 100644
--- a/src/test/ui/lint/forbid-member-group.stderr
+++ b/src/test/ui/lint/forbid-member-group.stderr
@@ -16,15 +16,6 @@
 LL | #[allow(unused)]
    |         ^^^^^^ overruled by previous forbid
 
-error[E0453]: allow(unused) incompatible with previous forbid
-  --> $DIR/forbid-member-group.rs:6:9
-   |
-LL | #![forbid(unused_variables)]
-   |           ---------------- `forbid` level set here
-LL | 
-LL | #[allow(unused)]
-   |         ^^^^^^ overruled by previous forbid
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui/lint/force-warn/force-allowed-by-default-lint.rs b/src/test/ui/lint/force-warn/force-allowed-by-default-lint.rs
index d4a5056..0a3e20b 100644
--- a/src/test/ui/lint/force-warn/force-allowed-by-default-lint.rs
+++ b/src/test/ui/lint/force-warn/force-allowed-by-default-lint.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns elided_lifetimes_in_paths
+// compile-flags: --force-warns elided_lifetimes_in_paths -Zunstable-options
 // check-pass
 
 struct Foo<'a> {
diff --git a/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.rs b/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.rs
index afd2d6e..0abc491 100644
--- a/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.rs
+++ b/src/test/ui/lint/force-warn/force-allowed-deny-by-default-lint.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns const_err
+// compile-flags: --force-warns const_err -Zunstable-options
 // check-pass
 
 #![allow(const_err)]
diff --git a/src/test/ui/lint/force-warn/force-allowed-warning.rs b/src/test/ui/lint/force-warn/force-allowed-warning.rs
index 5c83c52..bac0e4f 100644
--- a/src/test/ui/lint/force-warn/force-allowed-warning.rs
+++ b/src/test/ui/lint/force-warn/force-allowed-warning.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns dead_code
+// compile-flags: --force-warns dead_code -Zunstable-options
 // check-pass
 
 #![allow(dead_code)]
diff --git a/src/test/ui/lint/force-warn/force-deny-by-default-lint.rs b/src/test/ui/lint/force-warn/force-deny-by-default-lint.rs
index 4f267f0..e721760 100644
--- a/src/test/ui/lint/force-warn/force-deny-by-default-lint.rs
+++ b/src/test/ui/lint/force-warn/force-deny-by-default-lint.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns const_err
+// compile-flags: --force-warns const_err -Zunstable-options
 // check-pass
 
 const C: i32 = 1 / 0;
diff --git a/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.rs b/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.rs
index 5501faa..0dc1ce2 100644
--- a/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.rs
+++ b/src/test/ui/lint/force-warn/force-lint-allow-all-warnings.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns dead_code
+// compile-flags: --force-warns dead_code -Zunstable-options
 // check-pass
 
 #![allow(warnings)]
diff --git a/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.rs b/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.rs
index 9009971..4f637c7 100644
--- a/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.rs
+++ b/src/test/ui/lint/force-warn/force-lint-group-allow-all-warnings.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns nonstandard_style
+// compile-flags: --force-warns nonstandard_style -Zunstable-options
 // check-pass
 
 #![allow(warnings)]
diff --git a/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs b/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
index b68b979..bb2f394a 100644
--- a/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
+++ b/src/test/ui/lint/force-warn/force-lint-in-allowed-group.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns bare_trait_objects
+// compile-flags: --force-warns bare_trait_objects -Zunstable-options
 // check-pass
 
 #![allow(rust_2018_idioms)]
diff --git a/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs b/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
index 357a79b..fd029a3 100644
--- a/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
+++ b/src/test/ui/lint/force-warn/force-warn-group-allow-warning.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns rust_2018_idioms
+// compile-flags: --force-warns rust_2018_idioms -Zunstable-options
 // check-pass
 
 #![allow(bare_trait_objects)]
diff --git a/src/test/ui/lint/force-warn/force-warn-group.rs b/src/test/ui/lint/force-warn/force-warn-group.rs
index a4615df..c97eeab 100644
--- a/src/test/ui/lint/force-warn/force-warn-group.rs
+++ b/src/test/ui/lint/force-warn/force-warn-group.rs
@@ -1,4 +1,4 @@
-// compile-flags: --force-warns rust_2018_idioms
+// compile-flags: --force-warns rust_2018_idioms -Zunstable-options
 // check-pass
 
 #![allow(rust_2018_idioms)]
diff --git a/src/test/ui/lint/issue-80988.rs b/src/test/ui/lint/issue-80988.rs
index 16a0419..1e11620 100644
--- a/src/test/ui/lint/issue-80988.rs
+++ b/src/test/ui/lint/issue-80988.rs
@@ -11,6 +11,4 @@
 //~| WARNING being phased out
 //~| WARNING incompatible with previous forbid
 //~| WARNING being phased out
-//~| WARNING incompatible with previous forbid
-//~| WARNING being phased out
 fn main() {}
diff --git a/src/test/ui/lint/issue-80988.stderr b/src/test/ui/lint/issue-80988.stderr
index 4cae11f..deee267 100644
--- a/src/test/ui/lint/issue-80988.stderr
+++ b/src/test/ui/lint/issue-80988.stderr
@@ -35,17 +35,5 @@
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
 
-warning: deny(warnings) incompatible with previous forbid
-  --> $DIR/issue-80988.rs:7:8
-   |
-LL | #![forbid(warnings)]
-   |           -------- `forbid` level set here
-LL | 
-LL | #[deny(warnings)]
-   |        ^^^^^^^^ overruled by previous forbid
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
-
-warning: 4 warnings emitted
+warning: 3 warnings emitted
 
diff --git a/src/test/ui/lint/issue-83477.rs b/src/test/ui/lint/issue-83477.rs
index 0eba52a..ab62f0c 100644
--- a/src/test/ui/lint/issue-83477.rs
+++ b/src/test/ui/lint/issue-83477.rs
@@ -1,3 +1,4 @@
+// compile-flags: -Zunstable-options
 // check-pass
 #![warn(rustc::internal)]
 
diff --git a/src/test/ui/lint/issue-83477.stderr b/src/test/ui/lint/issue-83477.stderr
index dbe0c9e..028890f 100644
--- a/src/test/ui/lint/issue-83477.stderr
+++ b/src/test/ui/lint/issue-83477.stderr
@@ -1,5 +1,5 @@
 warning: unknown lint: `rustc::foo::bar::default_hash_types`
-  --> $DIR/issue-83477.rs:4:9
+  --> $DIR/issue-83477.rs:5:9
    |
 LL | #[allow(rustc::foo::bar::default_hash_types)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
@@ -7,19 +7,19 @@
    = note: `#[warn(unknown_lints)]` on by default
 
 warning: unknown lint: `rustc::foo::default_hash_types`
-  --> $DIR/issue-83477.rs:8:9
+  --> $DIR/issue-83477.rs:9:9
    |
 LL | #[allow(rustc::foo::default_hash_types)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
 
 warning: Prefer FxHashMap over HashMap, it has better performance
-  --> $DIR/issue-83477.rs:13:31
+  --> $DIR/issue-83477.rs:14:31
    |
 LL |     let _ = std::collections::HashMap::<String, String>::new();
    |                               ^^^^^^^ help: use: `FxHashMap`
    |
 note: the lint level is defined here
-  --> $DIR/issue-83477.rs:2:9
+  --> $DIR/issue-83477.rs:3:9
    |
 LL | #![warn(rustc::internal)]
    |         ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/lint/lint-forbid-attr.rs b/src/test/ui/lint/lint-forbid-attr.rs
index 13ebb6d..6d4cfd8 100644
--- a/src/test/ui/lint/lint-forbid-attr.rs
+++ b/src/test/ui/lint/lint-forbid-attr.rs
@@ -3,6 +3,5 @@
 #[allow(deprecated)]
 //~^ ERROR allow(deprecated) incompatible
 //~| ERROR allow(deprecated) incompatible
-//~| ERROR allow(deprecated) incompatible
 fn main() {
 }
diff --git a/src/test/ui/lint/lint-forbid-attr.stderr b/src/test/ui/lint/lint-forbid-attr.stderr
index cb0b25d..48228c5 100644
--- a/src/test/ui/lint/lint-forbid-attr.stderr
+++ b/src/test/ui/lint/lint-forbid-attr.stderr
@@ -16,15 +16,6 @@
 LL | #[allow(deprecated)]
    |         ^^^^^^^^^^ overruled by previous forbid
 
-error[E0453]: allow(deprecated) incompatible with previous forbid
-  --> $DIR/lint-forbid-attr.rs:3:9
-   |
-LL | #![forbid(deprecated)]
-   |           ---------- `forbid` level set here
-LL | 
-LL | #[allow(deprecated)]
-   |         ^^^^^^^^^^ overruled by previous forbid
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui/lint/lint-forbid-cmdline.rs b/src/test/ui/lint/lint-forbid-cmdline.rs
index 38bb8d2..5246ccb 100644
--- a/src/test/ui/lint/lint-forbid-cmdline.rs
+++ b/src/test/ui/lint/lint-forbid-cmdline.rs
@@ -2,6 +2,5 @@
 
 #[allow(deprecated)] //~ ERROR allow(deprecated) incompatible
                      //~| ERROR allow(deprecated) incompatible
-                     //~| ERROR allow(deprecated) incompatible
 fn main() {
 }
diff --git a/src/test/ui/lint/lint-forbid-cmdline.stderr b/src/test/ui/lint/lint-forbid-cmdline.stderr
index 5b1b015..0a92e58 100644
--- a/src/test/ui/lint/lint-forbid-cmdline.stderr
+++ b/src/test/ui/lint/lint-forbid-cmdline.stderr
@@ -14,14 +14,6 @@
    |
    = note: `forbid` lint level was set on command line
 
-error[E0453]: allow(deprecated) incompatible with previous forbid
-  --> $DIR/lint-forbid-cmdline.rs:3:9
-   |
-LL | #[allow(deprecated)]
-   |         ^^^^^^^^^^ overruled by previous forbid
-   |
-   = note: `forbid` lint level was set on command line
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0453`.
diff --git a/src/test/ui/lint/lint-malformed.rs b/src/test/ui/lint/lint-malformed.rs
index cf55707..188e702 100644
--- a/src/test/ui/lint/lint-malformed.rs
+++ b/src/test/ui/lint/lint-malformed.rs
@@ -3,6 +3,4 @@
                        //~| ERROR malformed lint attribute
                        //~| ERROR malformed lint attribute
                        //~| ERROR malformed lint attribute
-                       //~| ERROR malformed lint attribute
-                       //~| ERROR malformed lint attribute
 fn main() { }
diff --git a/src/test/ui/lint/lint-malformed.stderr b/src/test/ui/lint/lint-malformed.stderr
index 6dc8d49..b3a41a7 100644
--- a/src/test/ui/lint/lint-malformed.stderr
+++ b/src/test/ui/lint/lint-malformed.stderr
@@ -28,18 +28,6 @@
 LL | #![allow(bar = "baz")]
    |          ^^^^^^^^^^^ bad attribute argument
 
-error[E0452]: malformed lint attribute input
-  --> $DIR/lint-malformed.rs:2:10
-   |
-LL | #![allow(bar = "baz")]
-   |          ^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/lint-malformed.rs:2:10
-   |
-LL | #![allow(bar = "baz")]
-   |          ^^^^^^^^^^^ bad attribute argument
-
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0452`.
diff --git a/src/test/ui/lint/lint-removed-cmdline.stderr b/src/test/ui/lint/lint-removed-cmdline.stderr
index fc2ba92..9be532e 100644
--- a/src/test/ui/lint/lint-removed-cmdline.stderr
+++ b/src/test/ui/lint/lint-removed-cmdline.stderr
@@ -10,10 +10,6 @@
    |
    = note: requested on the command line with `-D raw_pointer_derive`
 
-warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok
-   |
-   = note: requested on the command line with `-D raw_pointer_derive`
-
 error: unused variable: `unused`
   --> $DIR/lint-removed-cmdline.rs:12:17
    |
@@ -27,5 +23,5 @@
    |        ^^^^^^^^
    = note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]`
 
-error: aborting due to previous error; 4 warnings emitted
+error: aborting due to previous error; 3 warnings emitted
 
diff --git a/src/test/ui/lint/lint-renamed-cmdline.stderr b/src/test/ui/lint/lint-renamed-cmdline.stderr
index 1c37a5b..8dfd61a 100644
--- a/src/test/ui/lint/lint-renamed-cmdline.stderr
+++ b/src/test/ui/lint/lint-renamed-cmdline.stderr
@@ -10,10 +10,6 @@
    |
    = note: requested on the command line with `-D bare_trait_object`
 
-warning: lint `bare_trait_object` has been renamed to `bare_trait_objects`
-   |
-   = note: requested on the command line with `-D bare_trait_object`
-
 error: unused variable: `unused`
   --> $DIR/lint-renamed-cmdline.rs:8:17
    |
@@ -27,5 +23,5 @@
    |        ^^^^^^
    = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]`
 
-error: aborting due to previous error; 4 warnings emitted
+error: aborting due to previous error; 3 warnings emitted
 
diff --git a/src/test/ui/lint/lint-unexported-no-mangle.stderr b/src/test/ui/lint/lint-unexported-no-mangle.stderr
index 66d64e8..a11ee76 100644
--- a/src/test/ui/lint/lint-unexported-no-mangle.stderr
+++ b/src/test/ui/lint/lint-unexported-no-mangle.stderr
@@ -22,14 +22,6 @@
    |
    = note: requested on the command line with `-F private_no_mangle_statics`
 
-warning: lint `private_no_mangle_fns` has been removed: no longer a warning, `#[no_mangle]` functions always exported
-   |
-   = note: requested on the command line with `-F private_no_mangle_fns`
-
-warning: lint `private_no_mangle_statics` has been removed: no longer a warning, `#[no_mangle]` statics always exported
-   |
-   = note: requested on the command line with `-F private_no_mangle_statics`
-
 error: const items should never be `#[no_mangle]`
   --> $DIR/lint-unexported-no-mangle.rs:9:1
    |
@@ -48,5 +40,5 @@
    | |
    | help: try a static value: `pub static`
 
-error: aborting due to 2 previous errors; 8 warnings emitted
+error: aborting due to 2 previous errors; 6 warnings emitted
 
diff --git a/src/test/ui/lint/lint-unknown-lint-cmdline.stderr b/src/test/ui/lint/lint-unknown-lint-cmdline.stderr
index 27e7ee7..3855d55 100644
--- a/src/test/ui/lint/lint-unknown-lint-cmdline.stderr
+++ b/src/test/ui/lint/lint-unknown-lint-cmdline.stderr
@@ -16,15 +16,6 @@
    = help: did you mean: `dead_code`
    = note: requested on the command line with `-D dead_cod`
 
-error[E0602]: unknown lint: `bogus`
-   |
-   = note: requested on the command line with `-D bogus`
-
-error[E0602]: unknown lint: `dead_cod`
-   |
-   = help: did you mean: `dead_code`
-   = note: requested on the command line with `-D dead_cod`
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0602`.
diff --git a/src/test/ui/lint/reasons-erroneous.rs b/src/test/ui/lint/reasons-erroneous.rs
index 03cf067..cd693ae 100644
--- a/src/test/ui/lint/reasons-erroneous.rs
+++ b/src/test/ui/lint/reasons-erroneous.rs
@@ -3,15 +3,11 @@
 #![warn(absolute_paths_not_starting_with_crate, reason = 0)]
 //~^ ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE reason must be a string literal
 //~| NOTE reason must be a string literal
 //~| NOTE reason must be a string literal
 #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
 //~^ ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE reason must be a string literal
 //~| NOTE reason must be a string literal
 //~| NOTE reason must be a string literal
 #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
@@ -19,10 +15,6 @@
 //~| ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE bad attribute argument
-//~| NOTE bad attribute argument
 //~| NOTE bad attribute argument
 //~| NOTE bad attribute argument
 //~| NOTE bad attribute argument
@@ -32,10 +24,6 @@
 //~| ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE bad attribute argument
-//~| NOTE bad attribute argument
 //~| NOTE bad attribute argument
 //~| NOTE bad attribute argument
 //~| NOTE bad attribute argument
@@ -45,10 +33,6 @@
 //~| ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE bad attribute argument
-//~| NOTE bad attribute argument
 //~| NOTE bad attribute argument
 //~| NOTE bad attribute argument
 //~| NOTE bad attribute argument
@@ -56,15 +40,11 @@
 #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
 //~^ ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE reason in lint attribute must come last
 //~| NOTE reason in lint attribute must come last
 //~| NOTE reason in lint attribute must come last
 #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
 //~^ ERROR malformed lint attribute
 //~| ERROR malformed lint attribute
-//~| ERROR malformed lint attribute
-//~| NOTE reason in lint attribute must come last
 //~| NOTE reason in lint attribute must come last
 //~| NOTE reason in lint attribute must come last
 #![warn(missing_copy_implementations, reason)]
diff --git a/src/test/ui/lint/reasons-erroneous.stderr b/src/test/ui/lint/reasons-erroneous.stderr
index d7926b7..f65ca08 100644
--- a/src/test/ui/lint/reasons-erroneous.stderr
+++ b/src/test/ui/lint/reasons-erroneous.stderr
@@ -5,61 +5,61 @@
    |                                                          ^ reason must be a string literal
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:10:40
+  --> $DIR/reasons-erroneous.rs:8:40
    |
 LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:17:29
+  --> $DIR/reasons-erroneous.rs:13:29
    |
 LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:17:29
+  --> $DIR/reasons-erroneous.rs:13:29
    |
 LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:30:23
+  --> $DIR/reasons-erroneous.rs:22:23
    |
 LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:30:23
+  --> $DIR/reasons-erroneous.rs:22:23
    |
 LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:43:36
+  --> $DIR/reasons-erroneous.rs:31:36
    |
 LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:43:36
+  --> $DIR/reasons-erroneous.rs:31:36
    |
 LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:56:44
+  --> $DIR/reasons-erroneous.rs:40:44
    |
 LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
    |                                            ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:63:25
+  --> $DIR/reasons-erroneous.rs:45:25
    |
 LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
 
 warning: unknown lint: `reason`
-  --> $DIR/reasons-erroneous.rs:70:39
+  --> $DIR/reasons-erroneous.rs:50:39
    |
 LL | #![warn(missing_copy_implementations, reason)]
    |                                       ^^^^^^
@@ -73,119 +73,59 @@
    |                                                          ^ reason must be a string literal
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:10:40
+  --> $DIR/reasons-erroneous.rs:8:40
    |
 LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:17:29
+  --> $DIR/reasons-erroneous.rs:13:29
    |
 LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:17:29
+  --> $DIR/reasons-erroneous.rs:13:29
    |
 LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:30:23
+  --> $DIR/reasons-erroneous.rs:22:23
    |
 LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:30:23
+  --> $DIR/reasons-erroneous.rs:22:23
    |
 LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:43:36
+  --> $DIR/reasons-erroneous.rs:31:36
    |
 LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:43:36
+  --> $DIR/reasons-erroneous.rs:31:36
    |
 LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:56:44
+  --> $DIR/reasons-erroneous.rs:40:44
    |
 LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
    |                                            ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
 
 error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:63:25
+  --> $DIR/reasons-erroneous.rs:45:25
    |
 LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
 
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:3:58
-   |
-LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)]
-   |                                                          ^ reason must be a string literal
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:10:40
-   |
-LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")]
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:17:29
-   |
-LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:17:29
-   |
-LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")]
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:30:23
-   |
-LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:30:23
-   |
-LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")]
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:43:36
-   |
-LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:43:36
-   |
-LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))]
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:56:44
-   |
-LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")]
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
-
-error[E0452]: malformed lint attribute input
-  --> $DIR/reasons-erroneous.rs:63:25
-   |
-LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)]
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last
-
-error: aborting due to 30 previous errors; 1 warning emitted
+error: aborting due to 20 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0452`.
diff --git a/src/test/ui/lint/register-tool-lint.rs b/src/test/ui/lint/register-tool-lint.rs
index 0ba5a37..17d3afb 100644
--- a/src/test/ui/lint/register-tool-lint.rs
+++ b/src/test/ui/lint/register-tool-lint.rs
@@ -7,5 +7,3 @@
 //~| HELP add `#![register_tool(abc)]`
 //~| ERROR unknown tool name `abc`
 //~| HELP add `#![register_tool(abc)]`
-//~| ERROR unknown tool name `abc`
-//~| HELP add `#![register_tool(abc)]`
diff --git a/src/test/ui/lint/register-tool-lint.stderr b/src/test/ui/lint/register-tool-lint.stderr
index 750c74c..842d845 100644
--- a/src/test/ui/lint/register-tool-lint.stderr
+++ b/src/test/ui/lint/register-tool-lint.stderr
@@ -14,14 +14,6 @@
    |
    = help: add `#![register_tool(abc)]` to the crate root
 
-error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
-  --> $DIR/register-tool-lint.rs:5:9
-   |
-LL | #![warn(abc::my_lint)]
-   |         ^^^
-   |
-   = help: add `#![register_tool(abc)]` to the crate root
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0710`.
diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr
index 21342e2..d175143 100644
--- a/src/test/ui/lint/use_suggestion_json.stderr
+++ b/src/test/ui/lint/use_suggestion_json.stderr
@@ -1,420 +1,3 @@
-{
-  "message": "cannot find type `Iter` in this scope",
-  "code": {
-    "code": "E0412",
-    "explanation": "A used type name is not in scope.
+{"message":"`--error-format=pretty-json` is unstable","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: `--error-format=pretty-json` is unstable\u001b[0m
 
-Erroneous code examples:
-
-```compile_fail,E0412
-impl Something {} // error: type name `Something` is not in scope
-
-// or:
-
-trait Foo {
-    fn bar(N); // error: type name `N` is not in scope
-}
-
-// or:
-
-fn foo(x: T) {} // type name `T` is not in scope
-```
-
-To fix this error, please verify you didn't misspell the type name, you did
-declare it or imported it into the scope. Examples:
-
-```
-struct Something;
-
-impl Something {} // ok!
-
-// or:
-
-trait Foo {
-    type N;
-
-    fn bar(_: Self::N); // ok!
-}
-
-// or:
-
-fn foo<T>(x: T) {} // ok!
-```
-
-Another case that causes this error is when a type is imported into a parent
-module. To fix this, you can follow the suggestion and use File directly or
-`use super::File;` which will import the types from the parent namespace. An
-example that causes this error is below:
-
-```compile_fail,E0412
-use std::fs::File;
-
-mod foo {
-    fn some_function(f: File) {}
-}
-```
-
-```
-use std::fs::File;
-
-mod foo {
-    // either
-    use super::File;
-    // or
-    // use std::fs::File;
-    fn foo(f: File) {}
-}
-# fn main() {} // don't insert it for us; that'll break imports
-```
-"
-  },
-  "level": "error",
-  "spans": [
-    {
-      "file_name": "$DIR/use_suggestion_json.rs",
-      "byte_start": 541,
-      "byte_end": 545,
-      "line_start": 12,
-      "line_end": 12,
-      "column_start": 12,
-      "column_end": 16,
-      "is_primary": true,
-      "text": [
-        {
-          "text": "    let x: Iter;",
-          "highlight_start": 12,
-          "highlight_end": 16
-        }
-      ],
-      "label": "not found in this scope",
-      "suggested_replacement": null,
-      "suggestion_applicability": null,
-      "expansion": null
-    }
-  ],
-  "children": [
-    {
-      "message": "consider importing one of these items",
-      "code": null,
-      "level": "help",
-      "spans": [
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::collections::binary_heap::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::collections::btree_map::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::collections::btree_set::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::collections::hash_map::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::collections::hash_set::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::collections::linked_list::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::collections::vec_deque::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::option::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::path::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::result::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::slice::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        },
-        {
-          "file_name": "$DIR/use_suggestion_json.rs",
-          "byte_start": 518,
-          "byte_end": 518,
-          "line_start": 11,
-          "line_end": 11,
-          "column_start": 1,
-          "column_end": 1,
-          "is_primary": true,
-          "text": [
-            {
-              "text": "fn main() {",
-              "highlight_start": 1,
-              "highlight_end": 1
-            }
-          ],
-          "label": null,
-          "suggested_replacement": "use std::sync::mpsc::Iter;
-
-",
-          "suggestion_applicability": "Unspecified",
-          "expansion": null
-        }
-      ],
-      "children": [],
-      "rendered": null
-    }
-  ],
-  "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror[E0412]\u001b[0m\u001b[0m\u001b[1m: cannot find type `Iter` in this scope\u001b[0m
-\u001b[0m  \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0m$DIR/use_suggestion_json.rs:12:12\u001b[0m
-\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m    let x: Iter;\u001b[0m
-\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0m           \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mnot found in this scope\u001b[0m
-\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;14mhelp\u001b[0m\u001b[0m: consider importing one of these items\u001b[0m
-\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::binary_heap::Iter;\u001b[0m
-\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::btree_map::Iter;\u001b[0m
-\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::btree_set::Iter;\u001b[0m
-\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::hash_map::Iter;\u001b[0m
-\u001b[0m   \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0m     and 8 other candidates\u001b[0m
-
-"
-}
-{
-  "message": "aborting due to previous error",
-  "code": null,
-  "level": "error",
-  "spans": [],
-  "children": [],
-  "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: aborting due to previous error\u001b[0m
-
-"
-}
-{
-  "message": "For more information about this error, try `rustc --explain E0412`.",
-  "code": null,
-  "level": "failure-note",
-  "spans": [],
-  "children": [],
-  "rendered": "\u001b[0m\u001b[1mFor more information about this error, try `rustc --explain E0412`.\u001b[0m
-"
-}
+"}
diff --git a/src/test/ui/parser/brace-after-qualified-path-in-match.rs b/src/test/ui/parser/brace-after-qualified-path-in-match.rs
deleted file mode 100644
index f415208..0000000
--- a/src/test/ui/parser/brace-after-qualified-path-in-match.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-fn main() {
-    match 10 {
-        <T as Trait>::Type{key: value} => (),
-        //~^ ERROR unexpected `{` after qualified path
-        _ => (),
-    }
-}
diff --git a/src/test/ui/parser/brace-after-qualified-path-in-match.stderr b/src/test/ui/parser/brace-after-qualified-path-in-match.stderr
deleted file mode 100644
index d6fdf35..0000000
--- a/src/test/ui/parser/brace-after-qualified-path-in-match.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: unexpected `{` after qualified path
-  --> $DIR/brace-after-qualified-path-in-match.rs:3:27
-   |
-LL |         <T as Trait>::Type{key: value} => (),
-   |         ------------------^ unexpected `{` after qualified path
-   |         |
-   |         the qualified path
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/paren-after-qualified-path-in-match.rs b/src/test/ui/parser/paren-after-qualified-path-in-match.rs
deleted file mode 100644
index 68b1c2b..0000000
--- a/src/test/ui/parser/paren-after-qualified-path-in-match.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-fn main() {
-    match 10 {
-        <T as Trait>::Type(2) => (),
-        //~^ ERROR unexpected `(` after qualified path
-        _ => (),
-    }
-}
diff --git a/src/test/ui/parser/paren-after-qualified-path-in-match.stderr b/src/test/ui/parser/paren-after-qualified-path-in-match.stderr
deleted file mode 100644
index af21f91..0000000
--- a/src/test/ui/parser/paren-after-qualified-path-in-match.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: unexpected `(` after qualified path
-  --> $DIR/paren-after-qualified-path-in-match.rs:3:27
-   |
-LL |         <T as Trait>::Type(2) => (),
-   |         ------------------^ unexpected `(` after qualified path
-   |         |
-   |         the qualified path
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/reify-intrinsic.rs b/src/test/ui/reify-intrinsic.rs
index 05535b9..9eb2f72 100644
--- a/src/test/ui/reify-intrinsic.rs
+++ b/src/test/ui/reify-intrinsic.rs
@@ -1,6 +1,6 @@
 // check-fail
 
-#![feature(intrinsics)]
+#![feature(core_intrinsics, intrinsics)]
 
 fn a() {
     let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute;
@@ -14,8 +14,8 @@
 
 fn c() {
     let _ = [
-        std::intrinsics::copy_nonoverlapping::<i32>,
-        std::intrinsics::copy::<i32>,
+        std::intrinsics::likely,
+        std::intrinsics::unlikely,
         //~^ ERROR cannot coerce
     ];
 }
diff --git a/src/test/ui/reify-intrinsic.stderr b/src/test/ui/reify-intrinsic.stderr
index 5d82fdb..69c11b5 100644
--- a/src/test/ui/reify-intrinsic.stderr
+++ b/src/test/ui/reify-intrinsic.stderr
@@ -22,11 +22,11 @@
 error[E0308]: cannot coerce intrinsics to function pointers
   --> $DIR/reify-intrinsic.rs:18:9
    |
-LL |         std::intrinsics::copy::<i32>,
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
+LL |         std::intrinsics::unlikely,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
    |
-   = note: expected type `unsafe extern "rust-intrinsic" fn(_, _, _) {copy_nonoverlapping::<i32>}`
-           found fn item `unsafe extern "rust-intrinsic" fn(_, _, _) {std::intrinsics::copy::<i32>}`
+   = note: expected type `extern "rust-intrinsic" fn(_) -> _ {likely}`
+           found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/simd/wasm-simd-indirect.rs b/src/test/ui/simd/wasm-simd-indirect.rs
index deac593..88f92fc 100644
--- a/src/test/ui/simd/wasm-simd-indirect.rs
+++ b/src/test/ui/simd/wasm-simd-indirect.rs
@@ -1,7 +1,5 @@
 // build-pass
 
-#![cfg_attr(target_arch = "wasm32", feature(wasm_simd, wasm_target_feature))]
-
 #[cfg(target_arch = "wasm32")]
 fn main() {
     unsafe {
diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.rs b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.rs
new file mode 100644
index 0000000..fa9d1a8
--- /dev/null
+++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.rs
@@ -0,0 +1,25 @@
+// Tests that a suggestion is issued for type mismatch errors when a
+// 1-tuple is expected and a parenthesized expression of non-tuple
+// type is supplied.
+
+fn foo<T>(_t: (T,)) {}
+struct S { _s: (String,) }
+
+fn main() {
+    let _x: (i32,) = (5);
+    //~^ ERROR: mismatched types [E0308]
+    //~| HELP: use a trailing comma to create a tuple with one element
+
+    foo((Some(3)));
+    //~^ ERROR: mismatched types [E0308]
+    //~| HELP: use a trailing comma to create a tuple with one element
+
+    let _s = S { _s: ("abc".to_string()) };
+    //~^ ERROR: mismatched types [E0308]
+    //~| HELP: use a trailing comma to create a tuple with one element
+
+    // Do not issue the suggestion if the found type is already a tuple.
+    let t = (1, 2);
+    let _x: (i32,) = (t);
+    //~^ ERROR: mismatched types [E0308]
+}
diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
new file mode 100644
index 0000000..5753796
--- /dev/null
+++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
@@ -0,0 +1,55 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-86100-tuple-paren-comma.rs:9:22
+   |
+LL |     let _x: (i32,) = (5);
+   |             ------   ^^^ expected tuple, found integer
+   |             |
+   |             expected due to this
+   |
+   = note: expected tuple `(i32,)`
+               found type `{integer}`
+help: use a trailing comma to create a tuple with one element
+   |
+LL |     let _x: (i32,) = (5,);
+   |                      ^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/issue-86100-tuple-paren-comma.rs:13:9
+   |
+LL |     foo((Some(3)));
+   |         ^^^^^^^^^ expected tuple, found enum `Option`
+   |
+   = note: expected tuple `(_,)`
+               found enum `Option<{integer}>`
+help: use a trailing comma to create a tuple with one element
+   |
+LL |     foo((Some(3),));
+   |         ^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/issue-86100-tuple-paren-comma.rs:17:22
+   |
+LL |     let _s = S { _s: ("abc".to_string()) };
+   |                      ^^^^^^^^^^^^^^^^^^^ expected tuple, found struct `String`
+   |
+   = note: expected tuple `(String,)`
+             found struct `String`
+help: use a trailing comma to create a tuple with one element
+   |
+LL |     let _s = S { _s: ("abc".to_string(),) };
+   |                      ^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/issue-86100-tuple-paren-comma.rs:23:22
+   |
+LL |     let _x: (i32,) = (t);
+   |             ------   ^^^ expected a tuple with 1 element, found one with 2 elements
+   |             |
+   |             expected due to this
+   |
+   = note: expected tuple `(i32,)`
+              found tuple `({integer}, {integer})`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/unnamable-types.rs b/src/test/ui/suggestions/unnamable-types.rs
new file mode 100644
index 0000000..5d06164
--- /dev/null
+++ b/src/test/ui/suggestions/unnamable-types.rs
@@ -0,0 +1,39 @@
+// Test that we do not suggest to add type annotations for unnamable types.
+
+#![crate_type="lib"]
+#![feature(generators)]
+
+const A = 5;
+//~^ ERROR: missing type for `const` item
+//~| HELP: provide a type for the item
+
+static B: _ = "abc";
+//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE: not allowed in type signatures
+//~| HELP: replace with the correct type
+
+
+// FIXME: this should also suggest a function pointer, as the closure is non-capturing
+const C: _ = || 42;
+//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures
+//~| NOTE: not allowed in type signatures
+//~| NOTE: however, the inferred type
+
+struct S<T> { t: T }
+const D = S { t: { let i = 0; move || -> i32 { i } } };
+//~^ ERROR: missing type for `const` item
+//~| NOTE: however, the inferred type
+
+
+fn foo() -> i32 { 42 }
+const E = foo;
+//~^ ERROR: missing type for `const` item
+//~| HELP: provide a type for the item
+const F = S { t: foo };
+//~^ ERROR: missing type for `const` item
+//~| HELP: provide a type for the item
+
+
+const G = || -> i32 { yield 0; return 1; };
+//~^ ERROR: missing type for `const` item
+//~| NOTE: however, the inferred type
diff --git a/src/test/ui/suggestions/unnamable-types.stderr b/src/test/ui/suggestions/unnamable-types.stderr
new file mode 100644
index 0000000..2c81667
--- /dev/null
+++ b/src/test/ui/suggestions/unnamable-types.stderr
@@ -0,0 +1,66 @@
+error: missing type for `const` item
+  --> $DIR/unnamable-types.rs:6:7
+   |
+LL | const A = 5;
+   |       ^ help: provide a type for the item: `A: i32`
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/unnamable-types.rs:10:11
+   |
+LL | static B: _ = "abc";
+   |           ^
+   |           |
+   |           not allowed in type signatures
+   |           help: replace with the correct type: `&str`
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/unnamable-types.rs:17:10
+   |
+LL | const C: _ = || 42;
+   |          ^ not allowed in type signatures
+   |
+note: however, the inferred type `[closure@$DIR/unnamable-types.rs:17:14: 17:19]` cannot be named
+  --> $DIR/unnamable-types.rs:17:14
+   |
+LL | const C: _ = || 42;
+   |              ^^^^^
+
+error: missing type for `const` item
+  --> $DIR/unnamable-types.rs:23:7
+   |
+LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
+   |       ^
+   |
+note: however, the inferred type `S<[closure@$DIR/unnamable-types.rs:23:31: 23:51]>` cannot be named
+  --> $DIR/unnamable-types.rs:23:11
+   |
+LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: missing type for `const` item
+  --> $DIR/unnamable-types.rs:29:7
+   |
+LL | const E = foo;
+   |       ^ help: provide a type for the item: `E: fn() -> i32`
+
+error: missing type for `const` item
+  --> $DIR/unnamable-types.rs:32:7
+   |
+LL | const F = S { t: foo };
+   |       ^ help: provide a type for the item: `F: S<fn() -> i32>`
+
+error: missing type for `const` item
+  --> $DIR/unnamable-types.rs:37:7
+   |
+LL | const G = || -> i32 { yield 0; return 1; };
+   |       ^
+   |
+note: however, the inferred type `[generator@$DIR/unnamable-types.rs:37:11: 37:43 {i32, ()}]` cannot be named
+  --> $DIR/unnamable-types.rs:37:11
+   |
+LL | const G = || -> i32 { yield 0; return 1; };
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/thread-local-static.rs b/src/test/ui/thread-local-static.rs
index c7fee9e..dc542fe 100644
--- a/src/test/ui/thread-local-static.rs
+++ b/src/test/ui/thread-local-static.rs
@@ -11,6 +11,7 @@
     //~| ERROR mutable references are not allowed
     //~| ERROR use of mutable static is unsafe
     //~| constant functions cannot refer to statics
+    //~| ERROR calls in constant functions are limited to constant functions
 }
 
 fn main() {}
diff --git a/src/test/ui/thread-local-static.stderr b/src/test/ui/thread-local-static.stderr
index 08bf593..a213282 100644
--- a/src/test/ui/thread-local-static.stderr
+++ b/src/test/ui/thread-local-static.stderr
@@ -30,6 +30,12 @@
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
+error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+  --> $DIR/thread-local-static.rs:9:5
+   |
+LL |     std::mem::swap(x, &mut STATIC_VAR_2)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
   --> $DIR/thread-local-static.rs:9:23
    |
@@ -38,7 +44,7 @@
    |
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0013, E0133, E0658.
+Some errors have detailed explanations: E0013, E0015, E0133, E0658.
 For more information about an error, try `rustc --explain E0013`.
diff --git a/src/test/ui/tool_lints.rs b/src/test/ui/tool_lints.rs
index 9e4aa7a..ef27532 100644
--- a/src/test/ui/tool_lints.rs
+++ b/src/test/ui/tool_lints.rs
@@ -1,5 +1,4 @@
 #[warn(foo::bar)]
 //~^ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
 //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
-//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
 fn main() {}
diff --git a/src/test/ui/tool_lints.stderr b/src/test/ui/tool_lints.stderr
index e06f6dd..d36cd19 100644
--- a/src/test/ui/tool_lints.stderr
+++ b/src/test/ui/tool_lints.stderr
@@ -14,14 +14,6 @@
    |
    = help: add `#![register_tool(foo)]` to the crate root
 
-error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
-  --> $DIR/tool_lints.rs:1:8
-   |
-LL | #[warn(foo::bar)]
-   |        ^^^
-   |
-   = help: add `#![register_tool(foo)]` to the crate root
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0710`.
diff --git a/src/test/ui/unknown-lint-tool-name.rs b/src/test/ui/unknown-lint-tool-name.rs
index 84ab7c1..cd5d2f0 100644
--- a/src/test/ui/unknown-lint-tool-name.rs
+++ b/src/test/ui/unknown-lint-tool-name.rs
@@ -1,8 +1,6 @@
 #![deny(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
                    //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
-                   //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
 
 #[allow(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
                    //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
-                   //~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
 fn main() {}
diff --git a/src/test/ui/unknown-lint-tool-name.stderr b/src/test/ui/unknown-lint-tool-name.stderr
index 1d14551..5f8349c 100644
--- a/src/test/ui/unknown-lint-tool-name.stderr
+++ b/src/test/ui/unknown-lint-tool-name.stderr
@@ -7,7 +7,7 @@
    = help: add `#![register_tool(foo)]` to the crate root
 
 error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
-  --> $DIR/unknown-lint-tool-name.rs:5:9
+  --> $DIR/unknown-lint-tool-name.rs:4:9
    |
 LL | #[allow(foo::bar)]
    |         ^^^
@@ -23,29 +23,13 @@
    = help: add `#![register_tool(foo)]` to the crate root
 
 error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
-  --> $DIR/unknown-lint-tool-name.rs:5:9
+  --> $DIR/unknown-lint-tool-name.rs:4:9
    |
 LL | #[allow(foo::bar)]
    |         ^^^
    |
    = help: add `#![register_tool(foo)]` to the crate root
 
-error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
-  --> $DIR/unknown-lint-tool-name.rs:1:9
-   |
-LL | #![deny(foo::bar)]
-   |         ^^^
-   |
-   = help: add `#![register_tool(foo)]` to the crate root
-
-error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
-  --> $DIR/unknown-lint-tool-name.rs:5:9
-   |
-LL | #[allow(foo::bar)]
-   |         ^^^
-   |
-   = help: add `#![register_tool(foo)]` to the crate root
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0710`.
diff --git a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs b/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs
index 3e1527e..e69df03 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs
@@ -1,7 +1,7 @@
 // --extern-location with bad location type
 
 // aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=badloc:in-the-test-file
+// compile-flags:--extern-location bar=badloc:in-the-test-file -Z unstable-options
 
 #![warn(unused_crate_dependencies)]
 
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs
index 6fdf710..aee6233 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs
@@ -1,7 +1,7 @@
 // --extern-location with a raw reference
 
 // aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=json:[{"malformed
+// compile-flags:--extern-location bar=json:[{"malformed -Z unstable-options
 
 #![warn(unused_crate_dependencies)]
 
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json-json.rs
index 02a9869..c7988cd 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-json-json.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-json-json.rs
@@ -2,7 +2,7 @@
 
 // check-pass
 // aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=json:{"key":123,"value":{}} --error-format json
+// compile-flags:--extern-location bar=json:{"key":123,"value":{}} --error-format json -Z unstable-options
 
 #![warn(unused_crate_dependencies)]
 //~^ WARNING external crate `bar` unused in
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr
index 5fc8397..001ec6a 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr
+++ b/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr
@@ -1,4 +1,4 @@
-{"message":"external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":169,"byte_end":169,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":177,"byte_end":202,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":{"key":123,"value":{}}}],"rendered":"warning: external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`
+{"message":"external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":189,"byte_end":189,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":197,"byte_end":222,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":{"key":123,"value":{}}}],"rendered":"warning: external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`
   --> $DIR/extern-loc-json-json.rs:7:1
    |
 LL | #![warn(unused_crate_dependencies)]
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json.rs
index 212610d..c0d76c8 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-json.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-json.rs
@@ -2,7 +2,7 @@
 
 // check-pass
 // aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=json:{"key":123,"value":{}}
+// compile-flags:--extern-location bar=json:{"key":123,"value":{}} -Z unstable-options
 
 #![warn(unused_crate_dependencies)]
 //~^ WARNING external crate `bar` unused in
diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs b/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs
index 4768365..3590b9c 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs
@@ -1,7 +1,7 @@
 // --extern-location with no type
 
 // aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=missing-loc-type
+// compile-flags:--extern-location bar=missing-loc-type -Z unstable-options
 
 #![warn(unused_crate_dependencies)]
 
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs b/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs
index 207615c..64c3d77 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs
@@ -2,7 +2,7 @@
 
 // check-pass
 // aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=raw:in-the-test-file --error-format json
+// compile-flags:--extern-location bar=raw:in-the-test-file --error-format json -Z unstable-options
 
 #![warn(unused_crate_dependencies)]
 //~^ WARNING external crate `bar` unused in
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr
index 25f0999..4083bd5 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr
+++ b/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr
@@ -1,4 +1,4 @@
-{"message":"external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":162,"byte_end":162,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":170,"byte_end":195,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar` at `in-the-test-file`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"raw extern location","code":null,"level":"help","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":0,"byte_end":0,"line_start":1,"line_end":1,"column_start":1,"column_end":1,"is_primary":true,"text":[],"label":null,"suggested_replacement":"in-the-test-file","suggestion_applicability":"Unspecified","expansion":null}],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":"in-the-test-file"}],"rendered":"warning: external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`
+{"message":"external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":182,"byte_end":182,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":190,"byte_end":215,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar` at `in-the-test-file`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"raw extern location","code":null,"level":"help","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":0,"byte_end":0,"line_start":1,"line_end":1,"column_start":1,"column_end":1,"is_primary":true,"text":[],"label":null,"suggested_replacement":"in-the-test-file","suggestion_applicability":"Unspecified","expansion":null}],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":"in-the-test-file"}],"rendered":"warning: external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`
   --> $DIR/extern-loc-raw-json.rs:7:1
    |
 LL | #![warn(unused_crate_dependencies)]
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs b/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs
index 65b6426..a9e7afb 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs
@@ -1,7 +1,7 @@
 // --extern-location with a raw reference
 
 // aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=raw
+// compile-flags:--extern-location bar=raw -Z unstable-options
 
 #![warn(unused_crate_dependencies)]
 
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw.rs b/src/test/ui/unused-crate-deps/extern-loc-raw.rs
index fc3fed1..27d0975 100644
--- a/src/test/ui/unused-crate-deps/extern-loc-raw.rs
+++ b/src/test/ui/unused-crate-deps/extern-loc-raw.rs
@@ -2,7 +2,7 @@
 
 // check-pass
 // aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=raw:in-the-test-file
+// compile-flags:--extern-location bar=raw:in-the-test-file -Z unstable-options
 
 #![warn(unused_crate_dependencies)]
 //~^ WARNING external crate `bar` unused in
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
index 329a000..2201cf5 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
@@ -5,7 +5,7 @@
 use super::UNNEEDED_FIELD_PATTERN;
 
 pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
-    if let PatKind::Struct(ref npat, ref pfields, _) = pat.kind {
+    if let PatKind::Struct(_, ref npat, ref pfields, _) = pat.kind {
         let mut wilds = 0;
         let type_name = npat
             .segments
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs
index 4dd032d..df04453 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs
@@ -7,7 +7,7 @@
 use super::UNNEEDED_WILDCARD_PATTERN;
 
 pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
-    if let PatKind::TupleStruct(_, ref patterns) | PatKind::Tuple(ref patterns) = pat.kind {
+    if let PatKind::TupleStruct(_, _, ref patterns) | PatKind::Tuple(ref patterns) = pat.kind {
         if let Some(rest_index) = patterns.iter().position(|pat| pat.is_rest()) {
             if let Some((left_index, left_pat)) = patterns[..rest_index]
                 .iter()
diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
index 5292af5..1a23e6a 100644
--- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
+++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
@@ -139,7 +139,7 @@
                     self.check_ident(ident);
                 }
             },
-            PatKind::Struct(_, ref fields, _) => {
+            PatKind::Struct(_, _, ref fields, _) => {
                 for field in fields {
                     if !field.is_shorthand {
                         self.visit_pat(&field.pat);
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 3e985fa..1b3c457 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
 
-use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_pat, eq_path};
+use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_pat, eq_path, eq_maybe_qself};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::{meets_msrv, msrvs, over};
 use rustc_ast::mut_visit::*;
@@ -273,16 +273,16 @@
             |k| always_pat!(k, Tuple(ps) => ps),
         ),
         // Transform `S(pre, x, post) | ... | S(pre, y, post)` into `S(pre, x | y, post)`.
-        TupleStruct(path1, ps1) => extend_with_matching_product(
+        TupleStruct(qself1, path1, ps1) => extend_with_matching_product(
             ps1, start, alternatives,
             |k, ps1, idx| matches!(
                 k,
-                TupleStruct(path2, ps2) if eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
+                TupleStruct(qself2, path2, ps2) if eq_maybe_qself(qself1, qself2) && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
             ),
-            |k| always_pat!(k, TupleStruct(_, ps) => ps),
+            |k| always_pat!(k, TupleStruct(_, _, ps) => ps),
         ),
         // Transform a record pattern `S { fp_0, ..., fp_n }`.
-        Struct(path1, fps1, rest1) => extend_with_struct_pat(path1, fps1, *rest1, start, alternatives),
+        Struct(qself1, path1, fps1, rest1) => extend_with_struct_pat(qself1, path1, fps1, *rest1, start, alternatives),
     };
 
     alternatives[focus_idx].kind = focus_kind;
@@ -294,6 +294,7 @@
 /// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
 /// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
 fn extend_with_struct_pat(
+    qself1: &Option<ast::QSelf>,
     path1: &ast::Path,
     fps1: &mut Vec<ast::PatField>,
     rest1: bool,
@@ -306,8 +307,9 @@
             start,
             alternatives,
             |k| {
-                matches!(k, Struct(path2, fps2, rest2)
+                matches!(k, Struct(qself2, path2, fps2, rest2)
                 if rest1 == *rest2 // If one struct pattern has `..` so must the other.
+                && eq_maybe_qself(qself1, qself2)
                 && eq_path(path1, path2)
                 && fps1.len() == fps2.len()
                 && fps1.iter().enumerate().all(|(idx_1, fp1)| {
@@ -323,7 +325,7 @@
                 }))
             },
             // Extract `p2_k`.
-            |k| always_pat!(k, Struct(_, mut fps, _) => fps.swap_remove(pos_in_2.take().unwrap()).pat),
+            |k| always_pat!(k, Struct(_, _, mut fps, _) => fps.swap_remove(pos_in_2.take().unwrap()).pat),
         );
         extend_with_tail_or(&mut fps1[idx].pat, tail_or)
     })
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 93e10c8..e6d84bc 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -47,9 +47,9 @@
         | (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r),
         (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, |l, r| eq_pat(l, r)),
         (Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
-        (TupleStruct(lp, lfs), TupleStruct(rp, rfs)) => eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)),
-        (Struct(lp, lfs, lr), Struct(rp, rfs, rr)) => {
-            lr == rr && eq_path(lp, rp) && unordered_over(lfs, rfs, |lf, rf| eq_field_pat(lf, rf))
+        (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)),
+        (Struct(lqself, lp, lfs, lr), Struct(rqself, rp, rfs, rr)) => {
+            lr == rr && eq_maybe_qself(lqself, rqself) &&eq_path(lp, rp) && unordered_over(lfs, rfs, |lf, rf| eq_field_pat(lf, rf))
         },
         (Or(ls), Or(rs)) => unordered_over(ls, rs, |l, r| eq_pat(l, r)),
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
@@ -78,6 +78,14 @@
     l.position == r.position && eq_ty(&l.ty, &r.ty)
 }
 
+pub fn eq_maybe_qself(l: &Option<QSelf>, r: &Option<QSelf>) -> bool {
+    match (l, r) {
+        (Some(l), Some(r)) => eq_qself(l, r),
+        (None, None) => true,
+        _ => false
+    }
+}
+
 pub fn eq_path(l: &Path, r: &Path) -> bool {
     over(&l.segments, &r.segments, |l, r| eq_path_seg(l, r))
 }
@@ -170,7 +178,8 @@
         (Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
         (Struct(lse), Struct(rse)) => {
-            eq_path(&lse.path, &rse.path)
+            eq_maybe_qself(&lse.qself, &rse.qself) 
+                && eq_path(&lse.path, &rse.path)
                 && eq_struct_rest(&lse.rest, &rse.rest)
                 && unordered_over(&lse.fields, &rse.fields, |l, r| eq_field(l, r))
         },
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 8037d67..b913d1c 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -116,8 +116,8 @@
 pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
 pub const POLL_PENDING: [&str; 5] = ["core", "task", "poll", "Poll", "Pending"];
 pub const POLL_READY: [&str; 5] = ["core", "task", "poll", "Poll", "Ready"];
-pub const PTR_COPY: [&str; 4] = ["core", "intrinsics", "", "copy"];
-pub const PTR_COPY_NONOVERLAPPING: [&str; 4] = ["core", "intrinsics", "", "copy_nonoverlapping"];
+pub const PTR_COPY: [&str; 3] = ["core", "intrinsics", "copy"];
+pub const PTR_COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"];
 pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
 pub const PTR_NULL: [&str; 3] = ["core", "ptr", "null"];
 pub const PTR_NULL_MUT: [&str; 3] = ["core", "ptr", "null_mut"];
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 408c0b8..a5b526b 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -346,6 +346,9 @@
     /// whether to run `tidy` when a rustdoc test fails
     pub has_tidy: bool,
 
+    /// The current Rust channel
+    pub channel: String,
+
     // Configuration for various run-make tests frobbing things like C compilers
     // or querying about various LLVM component information.
     pub cc: String,
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 983934d..26c1710 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -50,6 +50,15 @@
         let has_msan = util::MSAN_SUPPORTED_TARGETS.contains(&&*config.target);
         let has_tsan = util::TSAN_SUPPORTED_TARGETS.contains(&&*config.target);
         let has_hwasan = util::HWASAN_SUPPORTED_TARGETS.contains(&&*config.target);
+        // for `-Z gcc-ld=lld`
+        let has_rust_lld = config
+            .compile_lib_path
+            .join("rustlib")
+            .join(&config.target)
+            .join("bin")
+            .join("gcc-ld")
+            .join(if config.host.contains("windows") { "ld.exe" } else { "ld" })
+            .exists();
 
         iter_header(testfile, None, rdr, &mut |ln| {
             // we should check if any only-<platform> exists and if it exists
@@ -136,6 +145,10 @@
                 if config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln) {
                     props.ignore = true;
                 }
+
+                if !has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld") {
+                    props.ignore = true;
+                }
             }
 
             if let Some(s) = config.parse_aux_build(ln) {
@@ -438,6 +451,9 @@
 
                 if let Some(edition) = config.parse_edition(ln) {
                     self.compile_flags.push(format!("--edition={}", edition));
+                    if edition == "2021" {
+                        self.compile_flags.push("-Zunstable-options".to_string());
+                    }
                 }
 
                 config.parse_and_update_revisions(ln, &mut self.revisions);
@@ -876,6 +892,7 @@
             name == util::get_arch(&self.target) ||             // architecture
             name == util::get_pointer_width(&self.target) ||    // pointer width
             name == self.stage_id.split('-').next().unwrap() || // stage
+            name == self.channel ||                             // channel
             (self.target != self.host && name == "cross-compile") ||
             (name == "endian-big" && util::is_big_endian(&self.target)) ||
             (self.remote_test_client.is_some() && name == "remote") ||
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index ca7458d..2c607b6 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -55,6 +55,7 @@
         "--llvm-components=",
         "--android-cross-path=",
         "--target=x86_64-unknown-linux-gnu",
+        "--channel=nightly",
     ];
     let args = args.iter().map(ToString::to_string).collect();
     crate::parse_config(args)
@@ -235,6 +236,20 @@
 }
 
 #[test]
+fn channel() {
+    let mut config = config();
+    config.channel = "beta".into();
+
+    assert!(parse_rs(&config, "// ignore-beta").ignore);
+    assert!(parse_rs(&config, "// only-nightly").ignore);
+    assert!(parse_rs(&config, "// only-stable").ignore);
+
+    assert!(!parse_rs(&config, "// only-beta").ignore);
+    assert!(!parse_rs(&config, "// ignore-nightly").ignore);
+    assert!(!parse_rs(&config, "// ignore-stable").ignore);
+}
+
+#[test]
 fn test_extract_version_range() {
     use super::{extract_llvm_version, extract_version_range};
 
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 08ee8fc..c854663 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -144,7 +144,8 @@
             "enable this to generate a Rustfix coverage file, which is saved in \
                 `./<build_base>/rustfix_missing_coverage.txt`",
         )
-        .optflag("h", "help", "show this message");
+        .optflag("h", "help", "show this message")
+        .reqopt("", "channel", "current Rust channel", "CHANNEL");
 
     let (argv0, args_) = args.split_first().unwrap();
     if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
@@ -278,6 +279,7 @@
         compare_mode: matches.opt_str("compare-mode").map(CompareMode::parse),
         rustfix_coverage: matches.opt_present("rustfix-coverage"),
         has_tidy,
+        channel: matches.opt_str("channel").unwrap(),
 
         cc: matches.opt_str("cc").unwrap(),
         cxx: matches.opt_str("cxx").unwrap(),
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 931c822..02dffaa 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1785,6 +1785,9 @@
                 get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), is_dylib);
             rustc.arg("--extern").arg(format!("{}={}/{}", aux_name, aux_dir.display(), lib_name));
         }
+        if !self.props.aux_crates.is_empty() {
+            rustc.arg("-Zunstable-options");
+        }
 
         aux_dir
     }
@@ -2488,6 +2491,7 @@
 
         {
             let mut diff_output = File::create(&diff_filename).unwrap();
+            let mut wrote_data = false;
             for entry in walkdir::WalkDir::new(out_dir) {
                 let entry = entry.expect("failed to read file");
                 let extension = entry.path().extension().and_then(|p| p.to_str());
@@ -2500,17 +2504,28 @@
                         if let Ok(s) = std::fs::read(&expected_path) { s } else { continue };
                     let actual_path = entry.path();
                     let actual = std::fs::read(&actual_path).unwrap();
-                    diff_output
-                        .write_all(&unified_diff::diff(
-                            &expected,
-                            &expected_path.to_string_lossy(),
-                            &actual,
-                            &actual_path.to_string_lossy(),
-                            3,
-                        ))
-                        .unwrap();
+                    let diff = unified_diff::diff(
+                        &expected,
+                        &expected_path.to_string_lossy(),
+                        &actual,
+                        &actual_path.to_string_lossy(),
+                        3,
+                    );
+                    wrote_data |= !diff.is_empty();
+                    diff_output.write_all(&diff).unwrap();
                 }
             }
+
+            if !wrote_data {
+                println!("note: diff is identical to nightly rustdoc");
+                assert!(diff_output.metadata().unwrap().len() == 0);
+                return;
+            } else if self.config.verbose {
+                eprintln!("printing diff:");
+                let mut buf = Vec::new();
+                diff_output.read_to_end(&mut buf).unwrap();
+                std::io::stderr().lock().write_all(&mut buf).unwrap();
+            }
         }
 
         match self.config.color {
diff --git a/src/tools/miri b/src/tools/miri
index c8713c2..e5c3af6 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit c8713c2f9fc1e28c90876b9ec9557d8c5729757b
+Subproject commit e5c3af6f516311cc4b1fc017c58d83b7442cbc34
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index ced382c..bca9f77 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -107,7 +107,9 @@
         }
         ast::ExprKind::Unary(op, ref subexpr) => rewrite_unary_op(context, op, subexpr, shape),
         ast::ExprKind::Struct(ref struct_expr) => {
-            let ast::StructExpr { fields, path, rest } = &**struct_expr;
+            let ast::StructExpr {
+                fields, path, rest, ..
+            } = &**struct_expr;
             rewrite_struct_lit(context, path, fields, rest, &expr.attrs, expr.span, shape)
         }
         ast::ExprKind::Tup(ref items) => {
diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs
index 6824fc6..fa0ef26 100644
--- a/src/tools/rustfmt/src/patterns.rs
+++ b/src/tools/rustfmt/src/patterns.rs
@@ -45,7 +45,7 @@
         | ast::PatKind::Path(..)
         | ast::PatKind::Range(..) => false,
         ast::PatKind::Tuple(ref subpats) => subpats.len() <= 1,
-        ast::PatKind::TupleStruct(ref path, ref subpats) => {
+        ast::PatKind::TupleStruct(_, ref path, ref subpats) => {
             path.segments.len() <= 1 && subpats.len() <= 1
         }
         ast::PatKind::Box(ref p) | ast::PatKind::Ref(ref p, _) | ast::PatKind::Paren(ref p) => {
@@ -226,7 +226,7 @@
             PatKind::Path(ref q_self, ref path) => {
                 rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)
             }
-            PatKind::TupleStruct(ref path, ref pat_vec) => {
+            PatKind::TupleStruct(_, ref path, ref pat_vec) => {
                 let path_str = rewrite_path(context, PathContext::Expr, None, path, shape)?;
                 rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape)
             }
@@ -244,7 +244,7 @@
                     .collect();
                 Some(format!("[{}]", rw.join(", ")))
             }
-            PatKind::Struct(ref path, ref fields, ellipsis) => {
+            PatKind::Struct(_, ref path, ref fields, ellipsis) => {
                 rewrite_struct_pat(path, fields, ellipsis, self.span, context, shape)
             }
             PatKind::MacCall(ref mac) => {
diff --git a/src/version b/src/version
index b7921ae..094d6ad 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.54.0
+1.55.0