diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 63dccf8b0ce04..91ea34eb54d35 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -364,7 +364,7 @@ fn report_unexpected_variant_res(
         .with_code(err_code);
     match res {
         Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == E0164 => {
-            let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html";
+            let patterns_url = "https://doc.rust-lang.org/book/ch19-00-patterns.html";
             err.with_span_label(span, "`fn` calls are not allowed in patterns")
                 .with_help(format!("for more information, visit {patterns_url}"))
         }
diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
index b20673fe8daf5..7a91bfad4836c 100644
--- a/compiler/rustc_middle/src/middle/lang_items.rs
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
@@ -68,6 +68,17 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
+    /// Given a [`ty::ClosureKind`], get the [`DefId`] of its corresponding `Fn`-family
+    /// trait, if it is defined.
+    pub fn async_fn_trait_kind_to_def_id(self, kind: ty::ClosureKind) -> Option<DefId> {
+        let items = self.lang_items();
+        match kind {
+            ty::ClosureKind::Fn => items.async_fn_trait(),
+            ty::ClosureKind::FnMut => items.async_fn_mut_trait(),
+            ty::ClosureKind::FnOnce => items.async_fn_once_trait(),
+        }
+    }
+
     /// Returns `true` if `id` is a `DefId` of [`Fn`], [`FnMut`] or [`FnOnce`] traits.
     pub fn is_fn_trait(self, id: DefId) -> bool {
         self.fn_trait_kind_from_def_id(id).is_some()
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 039c988f5c972..cd4123f0a3f56 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -16,8 +16,8 @@ use rustc_hir::definitions::{DefKey, DefPathDataName};
 use rustc_macros::{Lift, extension};
 use rustc_session::Limit;
 use rustc_session::cstore::{ExternCrate, ExternCrateSource};
-use rustc_span::FileNameDisplayPreference;
 use rustc_span::symbol::{Ident, Symbol, kw};
+use rustc_span::{FileNameDisplayPreference, sym};
 use rustc_type_ir::{Upcast as _, elaborate};
 use smallvec::SmallVec;
 
@@ -26,8 +26,8 @@ use super::*;
 use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
 use crate::query::{IntoQueryParam, Providers};
 use crate::ty::{
-    ConstInt, Expr, GenericArgKind, ParamConst, ScalarInt, Term, TermKind, TypeFoldable,
-    TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
+    ConstInt, Expr, GenericArgKind, ParamConst, ScalarInt, Term, TermKind, TraitPredicate,
+    TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
 };
 
 macro_rules! p {
@@ -993,10 +993,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
 
             match bound_predicate.skip_binder() {
                 ty::ClauseKind::Trait(pred) => {
-                    let trait_ref = bound_predicate.rebind(pred.trait_ref);
-
                     // Don't print `+ Sized`, but rather `+ ?Sized` if absent.
-                    if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) {
+                    if tcx.is_lang_item(pred.def_id(), LangItem::Sized) {
                         match pred.polarity {
                             ty::PredicatePolarity::Positive => {
                                 has_sized_bound = true;
@@ -1007,24 +1005,22 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                     }
 
                     self.insert_trait_and_projection(
-                        trait_ref,
-                        pred.polarity,
+                        bound_predicate.rebind(pred),
                         None,
                         &mut traits,
                         &mut fn_traits,
                     );
                 }
                 ty::ClauseKind::Projection(pred) => {
-                    let proj_ref = bound_predicate.rebind(pred);
-                    let trait_ref = proj_ref.required_poly_trait_ref(tcx);
-
-                    // Projection type entry -- the def-id for naming, and the ty.
-                    let proj_ty = (proj_ref.projection_def_id(), proj_ref.term());
+                    let proj = bound_predicate.rebind(pred);
+                    let trait_ref = proj.map_bound(|proj| TraitPredicate {
+                        trait_ref: proj.projection_term.trait_ref(tcx),
+                        polarity: ty::PredicatePolarity::Positive,
+                    });
 
                     self.insert_trait_and_projection(
                         trait_ref,
-                        ty::PredicatePolarity::Positive,
-                        Some(proj_ty),
+                        Some((proj.projection_def_id(), proj.term())),
                         &mut traits,
                         &mut fn_traits,
                     );
@@ -1042,88 +1038,66 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
         let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !has_sized_bound;
 
-        for (fn_once_trait_ref, entry) in fn_traits {
+        for ((bound_args, is_async), entry) in fn_traits {
             write!(self, "{}", if first { "" } else { " + " })?;
             write!(self, "{}", if paren_needed { "(" } else { "" })?;
 
-            self.wrap_binder(&fn_once_trait_ref, |trait_ref, cx| {
-                define_scoped_cx!(cx);
-                // Get the (single) generic ty (the args) of this FnOnce trait ref.
-                let generics = tcx.generics_of(trait_ref.def_id);
-                let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
-
-                match (entry.return_ty, own_args[0].expect_ty()) {
-                    // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
-                    // a return type.
-                    (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
-                        let name = if entry.fn_trait_ref.is_some() {
-                            "Fn"
-                        } else if entry.fn_mut_trait_ref.is_some() {
-                            "FnMut"
-                        } else {
-                            "FnOnce"
-                        };
-
-                        p!(write("{}(", name));
+            let trait_def_id = if is_async {
+                tcx.async_fn_trait_kind_to_def_id(entry.kind).expect("expected AsyncFn lang items")
+            } else {
+                tcx.fn_trait_kind_to_def_id(entry.kind).expect("expected Fn lang items")
+            };
 
-                        for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() {
-                            if idx > 0 {
-                                p!(", ");
-                            }
-                            p!(print(ty));
-                        }
+            if let Some(return_ty) = entry.return_ty {
+                self.wrap_binder(&bound_args, |args, cx| {
+                    define_scoped_cx!(cx);
+                    p!(write("{}", tcx.item_name(trait_def_id)));
+                    p!("(");
 
-                        p!(")");
-                        if let Some(ty) = return_ty.skip_binder().as_type() {
-                            if !ty.is_unit() {
-                                p!(" -> ", print(return_ty));
-                            }
+                    for (idx, ty) in args.iter().enumerate() {
+                        if idx > 0 {
+                            p!(", ");
                         }
-                        p!(write("{}", if paren_needed { ")" } else { "" }));
-
-                        first = false;
+                        p!(print(ty));
                     }
-                    // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
-                    // trait_refs we collected in the OpaqueFnEntry as normal trait refs.
-                    _ => {
-                        if entry.has_fn_once {
-                            traits
-                                .entry((fn_once_trait_ref, ty::PredicatePolarity::Positive))
-                                .or_default()
-                                .extend(
-                                    // Group the return ty with its def id, if we had one.
-                                    entry.return_ty.map(|ty| {
-                                        (tcx.require_lang_item(LangItem::FnOnceOutput, None), ty)
-                                    }),
-                                );
-                        }
-                        if let Some(trait_ref) = entry.fn_mut_trait_ref {
-                            traits.entry((trait_ref, ty::PredicatePolarity::Positive)).or_default();
-                        }
-                        if let Some(trait_ref) = entry.fn_trait_ref {
-                            traits.entry((trait_ref, ty::PredicatePolarity::Positive)).or_default();
+
+                    p!(")");
+                    if let Some(ty) = return_ty.skip_binder().as_type() {
+                        if !ty.is_unit() {
+                            p!(" -> ", print(return_ty));
                         }
                     }
-                }
+                    p!(write("{}", if paren_needed { ")" } else { "" }));
 
-                Ok(())
-            })?;
+                    first = false;
+                    Ok(())
+                })?;
+            } else {
+                // Otherwise, render this like a regular trait.
+                traits.insert(
+                    bound_args.map_bound(|args| ty::TraitPredicate {
+                        polarity: ty::PredicatePolarity::Positive,
+                        trait_ref: ty::TraitRef::new(tcx, trait_def_id, [Ty::new_tup(tcx, args)]),
+                    }),
+                    FxIndexMap::default(),
+                );
+            }
         }
 
         // Print the rest of the trait types (that aren't Fn* family of traits)
-        for ((trait_ref, polarity), assoc_items) in traits {
+        for (trait_pred, assoc_items) in traits {
             write!(self, "{}", if first { "" } else { " + " })?;
 
-            self.wrap_binder(&trait_ref, |trait_ref, cx| {
+            self.wrap_binder(&trait_pred, |trait_pred, cx| {
                 define_scoped_cx!(cx);
 
-                if polarity == ty::PredicatePolarity::Negative {
+                if trait_pred.polarity == ty::PredicatePolarity::Negative {
                     p!("!");
                 }
-                p!(print(trait_ref.print_only_trait_name()));
+                p!(print(trait_pred.trait_ref.print_only_trait_name()));
 
-                let generics = tcx.generics_of(trait_ref.def_id);
-                let own_args = generics.own_args_no_defaults(tcx, trait_ref.args);
+                let generics = tcx.generics_of(trait_pred.def_id());
+                let own_args = generics.own_args_no_defaults(tcx, trait_pred.trait_ref.args);
 
                 if !own_args.is_empty() || !assoc_items.is_empty() {
                     let mut first = true;
@@ -1230,51 +1204,48 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
     /// traits map or fn_traits map, depending on if the trait is in the Fn* family of traits.
     fn insert_trait_and_projection(
         &mut self,
-        trait_ref: ty::PolyTraitRef<'tcx>,
-        polarity: ty::PredicatePolarity,
+        trait_pred: ty::PolyTraitPredicate<'tcx>,
         proj_ty: Option<(DefId, ty::Binder<'tcx, Term<'tcx>>)>,
         traits: &mut FxIndexMap<
-            (ty::PolyTraitRef<'tcx>, ty::PredicatePolarity),
+            ty::PolyTraitPredicate<'tcx>,
             FxIndexMap<DefId, ty::Binder<'tcx, Term<'tcx>>>,
         >,
-        fn_traits: &mut FxIndexMap<ty::PolyTraitRef<'tcx>, OpaqueFnEntry<'tcx>>,
+        fn_traits: &mut FxIndexMap<
+            (ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>>, bool),
+            OpaqueFnEntry<'tcx>,
+        >,
     ) {
-        let trait_def_id = trait_ref.def_id();
-
-        // If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce
-        // super-trait ref and record it there.
-        // We skip negative Fn* bounds since they can't use parenthetical notation anyway.
-        if polarity == ty::PredicatePolarity::Positive
-            && let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait()
-        {
-            // If we have a FnOnce, then insert it into
-            if trait_def_id == fn_once_trait {
-                let entry = fn_traits.entry(trait_ref).or_default();
-                // Optionally insert the return_ty as well.
-                if let Some((_, ty)) = proj_ty {
-                    entry.return_ty = Some(ty);
-                }
-                entry.has_fn_once = true;
-                return;
-            } else if self.tcx().is_lang_item(trait_def_id, LangItem::FnMut) {
-                let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref)
-                    .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
-                    .unwrap();
+        let tcx = self.tcx();
+        let trait_def_id = trait_pred.def_id();
 
-                fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref);
-                return;
-            } else if self.tcx().is_lang_item(trait_def_id, LangItem::Fn) {
-                let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref)
-                    .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
-                    .unwrap();
+        let fn_trait_and_async = if let Some(kind) = tcx.fn_trait_kind_from_def_id(trait_def_id) {
+            Some((kind, false))
+        } else if let Some(kind) = tcx.async_fn_trait_kind_from_def_id(trait_def_id) {
+            Some((kind, true))
+        } else {
+            None
+        };
 
-                fn_traits.entry(super_trait_ref).or_default().fn_trait_ref = Some(trait_ref);
-                return;
+        if trait_pred.polarity() == ty::PredicatePolarity::Positive
+            && let Some((kind, is_async)) = fn_trait_and_async
+            && let ty::Tuple(types) = *trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
+        {
+            let entry = fn_traits
+                .entry((trait_pred.rebind(types), is_async))
+                .or_insert_with(|| OpaqueFnEntry { kind, return_ty: None });
+            if kind.extends(entry.kind) {
+                entry.kind = kind;
+            }
+            if let Some((proj_def_id, proj_ty)) = proj_ty
+                && tcx.item_name(proj_def_id) == sym::Output
+            {
+                entry.return_ty = Some(proj_ty);
             }
+            return;
         }
 
         // Otherwise, just group our traits and projection types.
-        traits.entry((trait_ref, polarity)).or_default().extend(proj_ty);
+        traits.entry(trait_pred).or_default().extend(proj_ty);
     }
 
     fn pretty_print_inherent_projection(
@@ -3189,10 +3160,10 @@ define_print_and_forward_display! {
 
     TraitRefPrintSugared<'tcx> {
         if !with_reduced_queries()
-            && let Some(kind) = cx.tcx().fn_trait_kind_from_def_id(self.0.def_id)
+            && cx.tcx().trait_def(self.0.def_id).paren_sugar
             && let ty::Tuple(args) = self.0.args.type_at(1).kind()
         {
-            p!(write("{}", kind.as_str()), "(");
+            p!(write("{}", cx.tcx().item_name(self.0.def_id)), "(");
             for (i, arg) in args.iter().enumerate() {
                 if i > 0 {
                     p!(", ");
@@ -3415,11 +3386,7 @@ pub fn provide(providers: &mut Providers) {
     *providers = Providers { trimmed_def_paths, ..*providers };
 }
 
-#[derive(Default)]
 pub struct OpaqueFnEntry<'tcx> {
-    // The trait ref is already stored as a key, so just track if we have it as a real predicate
-    has_fn_once: bool,
-    fn_mut_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
-    fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
+    kind: ty::ClosureKind,
     return_ty: Option<ty::Binder<'tcx, Term<'tcx>>>,
 }
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 55149570dbc4d..673a9bceb2718 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -203,7 +203,7 @@ mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper =
 
 mir_build_lower_range_bound_must_be_less_than_upper = lower range bound must be less than upper
 
-mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+mir_build_more_information = for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 
 mir_build_moved = value is moved into `{$name}` here
 
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index cafd4b6dca28f..8c4f669c332b2 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -827,7 +827,7 @@ parse_unexpected_expr_in_pat =
     }, found an expression
 
     .label = not a pattern
-    .note = arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+    .note = arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 parse_unexpected_expr_in_pat_const_sugg = consider extracting the expression into a `const`
 
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 26b345f5941c4..02cb9da6e9ab2 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3940,12 +3940,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             }
             Res::SelfCtor(_) => {
                 // We resolve `Self` in pattern position as an ident sometimes during recovery,
-                // so delay a bug instead of ICEing. (Note: is this no longer true? We now ICE. If
-                // this triggers, please convert to a delayed bug and add a test.)
-                self.r.dcx().span_bug(
+                // so delay a bug instead of ICEing.
+                self.r.dcx().span_delayed_bug(
                     ident.span,
                     "unexpected `SelfCtor` in pattern, expected identifier"
                 );
+                None
             }
             _ => span_bug!(
                 ident.span,
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 09f5a8e96d3de..4a1570499648f 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1206,7 +1206,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         let PathSource::TupleStruct(_, _) = source else { return };
         let Some(Res::Def(DefKind::Fn, _)) = res else { return };
         err.primary_message("expected a pattern, found a function call");
-        err.note("function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>");
+        err.note("function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>");
     }
 
     fn suggest_changing_type_to_const_param(
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index cbfe5d22f1dbc..edee7b4468cd0 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -358,7 +358,7 @@ fn build_options<O: Default>(
 
 #[allow(non_upper_case_globals)]
 mod desc {
-    pub(crate) const parse_no_flag: &str = "no value";
+    pub(crate) const parse_no_value: &str = "no value";
     pub(crate) const parse_bool: &str =
         "one of: `y`, `yes`, `on`, `true`, `n`, `no`, `off` or `false`";
     pub(crate) const parse_opt_bool: &str = parse_bool;
@@ -462,14 +462,18 @@ pub mod parse {
     pub(crate) use super::*;
     pub(crate) const MAX_THREADS_CAP: usize = 256;
 
-    /// This is for boolean options that don't take a value and start with
-    /// `no-`. This style of option is deprecated.
-    pub(crate) fn parse_no_flag(slot: &mut bool, v: Option<&str>) -> bool {
+    /// This is for boolean options that don't take a value, and are true simply
+    /// by existing on the command-line.
+    ///
+    /// This style of option is deprecated, and is mainly used by old options
+    /// beginning with `no-`.
+    pub(crate) fn parse_no_value(slot: &mut bool, v: Option<&str>) -> bool {
         match v {
             None => {
                 *slot = true;
                 true
             }
+            // Trying to specify a value is always forbidden.
             Some(_) => false,
         }
     }
@@ -1609,16 +1613,16 @@ options! {
         "perform LLVM link-time optimizations"),
     metadata: Vec<String> = (Vec::new(), parse_list, [TRACKED],
         "metadata to mangle symbol names with"),
-    no_prepopulate_passes: bool = (false, parse_no_flag, [TRACKED],
+    no_prepopulate_passes: bool = (false, parse_no_value, [TRACKED],
         "give an empty list of passes to the pass manager"),
     no_redzone: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "disable the use of the redzone"),
     #[rustc_lint_opt_deny_field_access("documented to do nothing")]
-    no_stack_check: bool = (false, parse_no_flag, [UNTRACKED],
+    no_stack_check: bool = (false, parse_no_value, [UNTRACKED],
         "this option is deprecated and does nothing"),
-    no_vectorize_loops: bool = (false, parse_no_flag, [TRACKED],
+    no_vectorize_loops: bool = (false, parse_no_value, [TRACKED],
         "disable loop vectorization optimization passes"),
-    no_vectorize_slp: bool = (false, parse_no_flag, [TRACKED],
+    no_vectorize_slp: bool = (false, parse_no_value, [TRACKED],
         "disable LLVM's SLP vectorization pass"),
     opt_level: String = ("0".to_string(), parse_string, [TRACKED],
         "optimization level (0-3, s, or z; default: 0)"),
@@ -1915,25 +1919,25 @@ options! {
         "dump facts from NLL analysis into side files (default: no)"),
     nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED],
         "the directory the NLL facts are dumped into (default: `nll-facts`)"),
-    no_analysis: bool = (false, parse_no_flag, [UNTRACKED],
+    no_analysis: bool = (false, parse_no_value, [UNTRACKED],
         "parse and expand the source, but run no analysis"),
-    no_codegen: bool = (false, parse_no_flag, [TRACKED_NO_CRATE_HASH],
+    no_codegen: bool = (false, parse_no_value, [TRACKED_NO_CRATE_HASH],
         "run all passes except codegen; no output"),
-    no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED],
+    no_generate_arange_section: bool = (false, parse_no_value, [TRACKED],
         "omit DWARF address ranges that give faster lookups"),
     no_implied_bounds_compat: bool = (false, parse_bool, [TRACKED],
         "disable the compatibility version of the `implied_bounds_ty` query"),
-    no_jump_tables: bool = (false, parse_no_flag, [TRACKED],
+    no_jump_tables: bool = (false, parse_no_value, [TRACKED],
         "disable the jump tables and lookup tables that can be generated from a switch case lowering"),
-    no_leak_check: bool = (false, parse_no_flag, [UNTRACKED],
+    no_leak_check: bool = (false, parse_no_value, [UNTRACKED],
         "disable the 'leak check' for subtyping; unsound, but useful for tests"),
-    no_link: bool = (false, parse_no_flag, [TRACKED],
+    no_link: bool = (false, parse_no_value, [TRACKED],
         "compile without linking"),
-    no_parallel_backend: bool = (false, parse_no_flag, [UNTRACKED],
+    no_parallel_backend: bool = (false, parse_no_value, [UNTRACKED],
         "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"),
-    no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED],
+    no_profiler_runtime: bool = (false, parse_no_value, [TRACKED],
         "prevent automatic injection of the profiler_builtins crate"),
-    no_trait_vptr: bool = (false, parse_no_flag, [TRACKED],
+    no_trait_vptr: bool = (false, parse_no_value, [TRACKED],
         "disable generation of trait vptr in vtable for upcasting"),
     no_unique_section_names: bool = (false, parse_bool, [TRACKED],
         "do not use unique names for text and data sections when -Z function-sections is used"),
@@ -1991,7 +1995,7 @@ options! {
     proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread,
         parse_proc_macro_execution_strategy, [UNTRACKED],
         "how to run proc-macro code (default: same-thread)"),
-    profile_closures: bool = (false, parse_no_flag, [UNTRACKED],
+    profile_closures: bool = (false, parse_no_value, [UNTRACKED],
         "profile size of closures"),
     profile_sample_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
         "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"),
@@ -2165,8 +2169,14 @@ written to standard error output)"),
         "enable unsound and buggy MIR optimizations (default: no)"),
     /// This name is kind of confusing: Most unstable options enable something themselves, while
     /// this just allows "normal" options to be feature-gated.
+    ///
+    /// The main check for `-Zunstable-options` takes place separately from the
+    /// usual parsing of `-Z` options (see [`crate::config::nightly_options`]),
+    /// so this boolean value is mostly used for enabling unstable _values_ of
+    /// stable options. That separate check doesn't handle boolean values, so
+    /// to avoid an inconsistent state we also forbid them here.
     #[rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field")]
-    unstable_options: bool = (false, parse_bool, [UNTRACKED],
+    unstable_options: bool = (false, parse_no_value, [UNTRACKED],
         "adds unstable command line options to rustc interface (default: no)"),
     use_ctors_section: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "use legacy .ctors section for initializers rather than .init_array"),
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 345e1cc31f32b..41d430f06df4a 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -91,14 +91,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             } else if tcx.is_lang_item(def_id, LangItem::Sized) {
                 // Sized is never implementable by end-users, it is
                 // always automatically computed.
-
-                // FIXME: Consider moving this check to the top level as it
-                // may also be useful for predicates other than `Sized`
-                // Error type cannot possibly implement `Sized` (fixes #123154)
-                if let Err(e) = obligation.predicate.skip_binder().self_ty().error_reported() {
-                    return Err(SelectionError::Overflow(e.into()));
-                }
-
                 let sized_conditions = self.sized_conditions(obligation);
                 self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
             } else if tcx.is_lang_item(def_id, LangItem::Unsize) {
@@ -230,13 +222,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) -> Result<(), SelectionError<'tcx>> {
         debug!(?stack.obligation);
 
-        // An error type will unify with anything. So, avoid
-        // matching an error type with `ParamCandidate`.
-        // This helps us avoid spurious errors like issue #121941.
-        if stack.obligation.predicate.references_error() {
-            return Ok(());
-        }
-
         let bounds = stack
             .obligation
             .param_env
@@ -563,19 +548,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &PolyTraitObligation<'tcx>,
         candidates: &mut SelectionCandidateSet<'tcx>,
     ) {
-        // Essentially any user-written impl will match with an error type,
-        // so creating `ImplCandidates` isn't useful. However, we might
-        // end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized`)
-        // This helps us avoid overflow: see issue #72839
-        // Since compilation is already guaranteed to fail, this is just
-        // to try to show the 'nicest' possible errors to the user.
-        // We don't check for errors in the `ParamEnv` - in practice,
-        // it seems to cause us to be overly aggressive in deciding
-        // to give up searching for candidates, leading to spurious errors.
-        if obligation.predicate.references_error() {
-            return;
-        }
-
         let drcx = DeepRejectCtxt::relate_rigid_infer(self.tcx());
         let obligation_args = obligation.predicate.skip_binder().trait_ref.args;
         self.tcx().for_each_relevant_impl(
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 5b4e895189b0e..e0c862a81f341 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2487,10 +2487,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id);
 
         let trait_ref = impl_trait_header.trait_ref.instantiate(self.tcx(), impl_args);
-        if trait_ref.references_error() {
-            return Err(());
-        }
-
         debug!(?impl_trait_header);
 
         let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } =
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 2127ba8a42321..292e777f28802 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -6,8 +6,7 @@ use rustc_index::bit_set::BitSet;
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{
-    self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
-    TypeVisitor, Upcast,
+    self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast,
 };
 use rustc_span::DUMMY_SP;
 use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
@@ -95,9 +94,6 @@ fn adt_sized_constraint<'tcx>(
     let tail_ty = tcx.type_of(tail_def.did).instantiate_identity();
 
     let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?;
-    if let Err(guar) = constraint_ty.error_reported() {
-        return Some(ty::EarlyBinder::bind(Ty::new_error(tcx, guar)));
-    }
 
     // perf hack: if there is a `constraint_ty: Sized` bound, then we know
     // that the type is sized and do not need to check it on the impl.
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index 8a8e624e72a2d..5e3a3df003843 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -684,19 +684,6 @@ impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
         self.skip_binder().projection_term.trait_def_id(cx)
     }
 
-    /// Get the trait ref required for this projection to be well formed.
-    /// Note that for generic associated types the predicates of the associated
-    /// type also need to be checked.
-    #[inline]
-    pub fn required_poly_trait_ref(&self, cx: I) -> ty::Binder<I, TraitRef<I>> {
-        // Note: unlike with `TraitRef::to_poly_trait_ref()`,
-        // `self.0.trait_ref` is permitted to have escaping regions.
-        // This is because here `self` has a `Binder` and so does our
-        // return value, so we are preserving the number of binding
-        // levels.
-        self.map_bound(|predicate| predicate.projection_term.trait_ref(cx))
-    }
-
     pub fn term(&self) -> ty::Binder<I, I::Term> {
         self.map_bound(|predicate| predicate.term)
     }
diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs
index db16d82be7dcc..5975134382e7d 100644
--- a/library/alloc/src/collections/btree/map/tests.rs
+++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -2270,6 +2270,54 @@ fn test_into_iter_drop_leak_height_0() {
     assert_eq!(e.dropped(), 1);
 }
 
+#[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+fn test_into_iter_drop_leak_kv_panic_in_key() {
+    let a_k = CrashTestDummy::new(0);
+    let a_v = CrashTestDummy::new(1);
+    let b_k = CrashTestDummy::new(2);
+    let b_v = CrashTestDummy::new(3);
+    let c_k = CrashTestDummy::new(4);
+    let c_v = CrashTestDummy::new(5);
+    let mut map = BTreeMap::new();
+    map.insert(a_k.spawn(Panic::Never), a_v.spawn(Panic::Never));
+    map.insert(b_k.spawn(Panic::InDrop), b_v.spawn(Panic::Never));
+    map.insert(c_k.spawn(Panic::Never), c_v.spawn(Panic::Never));
+
+    catch_unwind(move || drop(map.into_iter())).unwrap_err();
+
+    assert_eq!(a_k.dropped(), 1);
+    assert_eq!(a_v.dropped(), 1);
+    assert_eq!(b_k.dropped(), 1);
+    assert_eq!(b_v.dropped(), 1);
+    assert_eq!(c_k.dropped(), 1);
+    assert_eq!(c_v.dropped(), 1);
+}
+
+#[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+fn test_into_iter_drop_leak_kv_panic_in_val() {
+    let a_k = CrashTestDummy::new(0);
+    let a_v = CrashTestDummy::new(1);
+    let b_k = CrashTestDummy::new(2);
+    let b_v = CrashTestDummy::new(3);
+    let c_k = CrashTestDummy::new(4);
+    let c_v = CrashTestDummy::new(5);
+    let mut map = BTreeMap::new();
+    map.insert(a_k.spawn(Panic::Never), a_v.spawn(Panic::Never));
+    map.insert(b_k.spawn(Panic::Never), b_v.spawn(Panic::InDrop));
+    map.insert(c_k.spawn(Panic::Never), c_v.spawn(Panic::Never));
+
+    catch_unwind(move || drop(map.into_iter())).unwrap_err();
+
+    assert_eq!(a_k.dropped(), 1);
+    assert_eq!(a_v.dropped(), 1);
+    assert_eq!(b_k.dropped(), 1);
+    assert_eq!(b_v.dropped(), 1);
+    assert_eq!(c_k.dropped(), 1);
+    assert_eq!(c_v.dropped(), 1);
+}
+
 #[test]
 #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
 fn test_into_iter_drop_leak_height_1() {
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index 2a853ef421629..64a13bb6a0b3a 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -1173,11 +1173,25 @@ impl<K, V, NodeType> Handle<NodeRef<marker::Dying, K, V, NodeType>, marker::KV>
     /// The node that the handle refers to must not yet have been deallocated.
     #[inline]
     pub unsafe fn drop_key_val(mut self) {
+        // Run the destructor of the value even if the destructor of the key panics.
+        struct Dropper<'a, T>(&'a mut MaybeUninit<T>);
+        impl<T> Drop for Dropper<'_, T> {
+            #[inline]
+            fn drop(&mut self) {
+                unsafe {
+                    self.0.assume_init_drop();
+                }
+            }
+        }
+
         debug_assert!(self.idx < self.node.len());
         let leaf = self.node.as_leaf_dying();
         unsafe {
-            leaf.keys.get_unchecked_mut(self.idx).assume_init_drop();
-            leaf.vals.get_unchecked_mut(self.idx).assume_init_drop();
+            let key = leaf.keys.get_unchecked_mut(self.idx);
+            let val = leaf.vals.get_unchecked_mut(self.idx);
+            let _guard = Dropper(val);
+            key.assume_init_drop();
+            // dropping the guard will drop the value
         }
     }
 }
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index f2d7e0f481e76..4c2dfc6aa0c49 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -199,32 +199,12 @@ static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\
       8081828384858687888990919293949596979899";
 
 macro_rules! impl_Display {
-    ($($t:ident $(as $positive:ident)? named $name:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => {
+    ($($signed:ident, $unsigned:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => {
 
         $(
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl fmt::Display for $t {
+        impl fmt::Display for $unsigned {
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                // If it's a signed integer.
-                $(
-                    let is_nonnegative = *self >= 0;
-
-                    #[cfg(not(feature = "optimize_for_size"))]
-                    {
-                        if !is_nonnegative {
-                            // convert the negative num to positive by summing 1 to its 2s complement
-                            return (!self as $positive).wrapping_add(1)._fmt(false, f);
-                        }
-                    }
-                    #[cfg(feature = "optimize_for_size")]
-                    {
-                        if !is_nonnegative {
-                            // convert the negative num to positive by summing 1 to its 2s complement
-                            return $gen_name((!self.$conv_fn()).wrapping_add(1), false, f);
-                        }
-                    }
-                )?
-                // If it's a positive integer.
                 #[cfg(not(feature = "optimize_for_size"))]
                 {
                     self._fmt(true, f)
@@ -236,10 +216,24 @@ macro_rules! impl_Display {
             }
         }
 
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl fmt::Display for $signed {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                #[cfg(not(feature = "optimize_for_size"))]
+                {
+                    return self.unsigned_abs()._fmt(*self >= 0, f);
+                }
+                #[cfg(feature = "optimize_for_size")]
+                {
+                    return $gen_name((!self.unsigned_abs().$conv_fn()), *self >= 0, f);
+                }
+            }
+        }
+
         #[cfg(not(feature = "optimize_for_size"))]
-        impl $t {
-            fn _fmt(mut self: $t, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-                const SIZE: usize = $t::MAX.ilog(10) as usize + 1;
+        impl $unsigned {
+            fn _fmt(mut self, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                const SIZE: usize = $unsigned::MAX.ilog(10) as usize + 1;
                 let mut buf = [MaybeUninit::<u8>::uninit(); SIZE];
                 let mut curr = SIZE;
                 let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
@@ -258,7 +252,7 @@ macro_rules! impl_Display {
                     #[allow(unused_comparisons)]
                     // This block will be removed for smaller types at compile time and in the worst
                     // case, it will prevent to have the `10000` literal to overflow for `i8` and `u8`.
-                    if core::mem::size_of::<$t>() >= 2 {
+                    if core::mem::size_of::<$unsigned>() >= 2 {
                         // eagerly decode 4 characters at a time
                         while self >= 10000 {
                             let rem = (self % 10000) as usize;
@@ -312,8 +306,8 @@ macro_rules! impl_Display {
 
         #[cfg(feature = "optimize_for_size")]
         fn $gen_name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            // 2^128 is about 3*10^38, so 39 gives an extra byte of space
-            let mut buf = [MaybeUninit::<u8>::uninit(); 39];
+            const SIZE: usize = $u::MAX.ilog(10) as usize + 1;
+            let mut buf = [MaybeUninit::<u8>::uninit(); SIZE];
             let mut curr = buf.len();
             let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
 
@@ -523,16 +517,11 @@ impl_Debug! {
 mod imp {
     use super::*;
     impl_Display!(
-        i8 as u8 named fmt_i8,
-        u8 named fmt_u8,
-        i16 as u16  named fmt_i16,
-        u16 named fmt_u16,
-        i32 as u32 named fmt_i32,
-        u32 named fmt_u32,
-        i64 as u64 named fmt_i64,
-        u64 named fmt_u64,
-        isize as usize named fmt_isize,
-        usize named fmt_usize,
+        i8, u8,
+        i16, u16,
+        i32, u32,
+        i64, u64,
+        isize, usize,
         ; as u64 via to_u64 named fmt_u64
     );
     impl_Exp!(
@@ -545,18 +534,13 @@ mod imp {
 mod imp {
     use super::*;
     impl_Display!(
-        i8 as u8 named fmt_i8,
-        u8 named fmt_u8,
-        i16 as u16  named fmt_i16,
-        u16 named fmt_u16,
-        i32 as u32 named fmt_i32,
-        u32 named fmt_u32,
-        isize as usize named fmt_isize,
-        usize named fmt_usize,
+        i8, u8,
+        i16, u16,
+        i32, u32,
+        isize, usize,
         ; as u32 via to_u32 named fmt_u32);
     impl_Display!(
-        i64 as u64 named fmt_i64,
-        u64 named fmt_u64,
+        i64, u64,
         ; as u64 via to_u64 named fmt_u64);
 
     impl_Exp!(i8, u8, i16, u16, i32, u32, isize, usize as u32 via to_u32 named exp_u32);
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index d732a15117e9e..27f4daba44bf6 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -653,19 +653,28 @@ pub fn home_dir() -> Option<PathBuf> {
 /// may result in "insecure temporary file" security vulnerabilities. Consider
 /// using a crate that securely creates temporary files or directories.
 ///
+/// Note that the returned value may be a symbolic link, not a directory.
+///
 /// # Platform-specific behavior
 ///
 /// On Unix, returns the value of the `TMPDIR` environment variable if it is
-/// set, otherwise for non-Android it returns `/tmp`. On Android, since there
-/// is no global temporary folder (it is usually allocated per-app), it returns
-/// `/data/local/tmp`.
+/// set, otherwise the value is OS-specific:
+/// - On Android, there is no global temporary folder (it is usually allocated
+///   per-app), it returns `/data/local/tmp`.
+/// - On Darwin-based OSes (macOS, iOS, etc) it returns the directory provided
+///   by `confstr(_CS_DARWIN_USER_TEMP_DIR, ...)`, as recommended by [Apple's
+///   security guidelines][appledoc].
+/// - On all other unix-based OSes, it returns `/tmp`.
+///
 /// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] /
 /// [`GetTempPath`][GetTempPath], which this function uses internally.
+///
 /// Note that, this [may change in the future][changes].
 ///
 /// [changes]: io#platform-specific-behavior
 /// [GetTempPath2]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a
 /// [GetTempPath]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
+/// [appledoc]: https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10
 ///
 /// ```no_run
 /// use std::env;
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index f983d174ed61c..f207131ddf332 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -698,12 +698,82 @@ pub fn page_size() -> usize {
     unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
 }
 
+// Returns the value for [`confstr(key, ...)`][posix_confstr]. Currently only
+// used on Darwin, but should work on any unix (in case we need to get
+// `_CS_PATH` or `_CS_V[67]_ENV` in the future).
+//
+// [posix_confstr]:
+//     https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html
+//
+// FIXME: Support `confstr` in Miri.
+#[cfg(all(target_vendor = "apple", not(miri)))]
+fn confstr(key: c_int, size_hint: Option<usize>) -> io::Result<OsString> {
+    let mut buf: Vec<u8> = Vec::with_capacity(0);
+    let mut bytes_needed_including_nul = size_hint
+        .unwrap_or_else(|| {
+            // Treat "None" as "do an extra call to get the length". In theory
+            // we could move this into the loop below, but it's hard to do given
+            // that it isn't 100% clear if it's legal to pass 0 for `len` when
+            // the buffer isn't null.
+            unsafe { libc::confstr(key, core::ptr::null_mut(), 0) }
+        })
+        .max(1);
+    // If the value returned by `confstr` is greater than the len passed into
+    // it, then the value was truncated, meaning we need to retry. Note that
+    // while `confstr` results don't seem to change for a process, it's unclear
+    // if this is guaranteed anywhere, so looping does seem required.
+    while bytes_needed_including_nul > buf.capacity() {
+        // We write into the spare capacity of `buf`. This lets us avoid
+        // changing buf's `len`, which both simplifies `reserve` computation,
+        // allows working with `Vec<u8>` instead of `Vec<MaybeUninit<u8>>`, and
+        // may avoid a copy, since the Vec knows that none of the bytes are needed
+        // when reallocating (well, in theory anyway).
+        buf.reserve(bytes_needed_including_nul);
+        // `confstr` returns
+        // - 0 in the case of errors: we break and return an error.
+        // - The number of bytes written, iff the provided buffer is enough to
+        //   hold the entire value: we break and return the data in `buf`.
+        // - Otherwise, the number of bytes needed (including nul): we go
+        //   through the loop again.
+        bytes_needed_including_nul =
+            unsafe { libc::confstr(key, buf.as_mut_ptr().cast::<c_char>(), buf.capacity()) };
+    }
+    // `confstr` returns 0 in the case of an error.
+    if bytes_needed_including_nul == 0 {
+        return Err(io::Error::last_os_error());
+    }
+    // Safety: `confstr(..., buf.as_mut_ptr(), buf.capacity())` returned a
+    // non-zero value, meaning `bytes_needed_including_nul` bytes were
+    // initialized.
+    unsafe {
+        buf.set_len(bytes_needed_including_nul);
+        // Remove the NUL-terminator.
+        let last_byte = buf.pop();
+        // ... and smoke-check that it *was* a NUL-terminator.
+        assert_eq!(last_byte, Some(0), "`confstr` provided a string which wasn't nul-terminated");
+    };
+    Ok(OsString::from_vec(buf))
+}
+
+#[cfg(all(target_vendor = "apple", not(miri)))]
+fn darwin_temp_dir() -> PathBuf {
+    confstr(libc::_CS_DARWIN_USER_TEMP_DIR, Some(64)).map(PathBuf::from).unwrap_or_else(|_| {
+        // It failed for whatever reason (there are several possible reasons),
+        // so return the global one.
+        PathBuf::from("/tmp")
+    })
+}
+
 pub fn temp_dir() -> PathBuf {
     crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| {
-        if cfg!(target_os = "android") {
-            PathBuf::from("/data/local/tmp")
-        } else {
-            PathBuf::from("/tmp")
+        cfg_if::cfg_if! {
+            if #[cfg(all(target_vendor = "apple", not(miri)))] {
+                darwin_temp_dir()
+            } else if #[cfg(target_os = "android")] {
+                PathBuf::from("/data/local/tmp")
+            } else {
+                PathBuf::from("/tmp")
+            }
         }
     })
 }
diff --git a/library/std/src/sys/pal/unix/os/tests.rs b/library/std/src/sys/pal/unix/os/tests.rs
index efc29955b05fe..63a1cc1e94a1d 100644
--- a/library/std/src/sys/pal/unix/os/tests.rs
+++ b/library/std/src/sys/pal/unix/os/tests.rs
@@ -21,3 +21,28 @@ fn test_parse_glibc_version() {
         assert_eq!(parsed, super::parse_glibc_version(version_str));
     }
 }
+
+// Smoke check `confstr`, do it for several hint values, to ensure our resizing
+// logic is correct.
+#[test]
+#[cfg(all(target_vendor = "apple", not(miri)))]
+fn test_confstr() {
+    for key in [libc::_CS_DARWIN_USER_TEMP_DIR, libc::_CS_PATH] {
+        let value_nohint = super::confstr(key, None).unwrap_or_else(|e| {
+            panic!("confstr({key}, None) failed: {e:?}");
+        });
+        let end = (value_nohint.len() + 1) * 2;
+        for hint in 0..end {
+            assert_eq!(
+                super::confstr(key, Some(hint)).as_deref().ok(),
+                Some(&*value_nohint),
+                "confstr({key}, Some({hint})) failed",
+            );
+        }
+    }
+    // Smoke check that we don't loop forever or something if the input was not valid.
+    for hint in [None, Some(0), Some(1)] {
+        let hopefully_invalid = 123456789_i32;
+        assert!(super::confstr(hopefully_invalid, hint).is_err());
+    }
+}
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index dcea9f5f7d1d6..1cabd1c39f198 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -3,12 +3,14 @@
 //! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules.
 //! However, this contains ~all test parts we expect people to be able to build and run locally.
 
+use std::collections::HashSet;
 use std::ffi::{OsStr, OsString};
 use std::path::{Path, PathBuf};
 use std::{env, fs, iter};
 
 use clap_complete::shells;
 
+use crate::core::build_steps::compile::run_cargo;
 use crate::core::build_steps::doc::DocumentationFormat;
 use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget;
 use crate::core::build_steps::tool::{self, SourceType, Tool};
@@ -2185,6 +2187,7 @@ struct BookTest {
     path: PathBuf,
     name: &'static str,
     is_ext_doc: bool,
+    dependencies: Vec<&'static str>,
 }
 
 impl Step for BookTest {
@@ -2237,6 +2240,57 @@ impl BookTest {
         // Books often have feature-gated example text.
         rustbook_cmd.env("RUSTC_BOOTSTRAP", "1");
         rustbook_cmd.env("PATH", new_path).arg("test").arg(path);
+
+        // Books may also need to build dependencies. For example, `TheBook` has
+        // code samples which use the `trpl` crate. For the `rustdoc` invocation
+        // to find them them successfully, they need to be built first and their
+        // paths used to generate the
+        let libs = if !self.dependencies.is_empty() {
+            let mut lib_paths = vec![];
+            for dep in self.dependencies {
+                let mode = Mode::ToolRustc;
+                let target = builder.config.build;
+                let cargo = tool::prepare_tool_cargo(
+                    builder,
+                    compiler,
+                    mode,
+                    target,
+                    Kind::Build,
+                    dep,
+                    SourceType::Submodule,
+                    &[],
+                );
+
+                let stamp = builder
+                    .cargo_out(compiler, mode, target)
+                    .join(PathBuf::from(dep).file_name().unwrap())
+                    .with_extension("stamp");
+
+                let output_paths = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false);
+                let directories = output_paths
+                    .into_iter()
+                    .filter_map(|p| p.parent().map(ToOwned::to_owned))
+                    .fold(HashSet::new(), |mut set, dir| {
+                        set.insert(dir);
+                        set
+                    });
+
+                lib_paths.extend(directories);
+            }
+            lib_paths
+        } else {
+            vec![]
+        };
+
+        if !libs.is_empty() {
+            let paths = libs
+                .into_iter()
+                .map(|path| path.into_os_string())
+                .collect::<Vec<OsString>>()
+                .join(OsStr::new(","));
+            rustbook_cmd.args([OsString::from("--library-path"), paths]);
+        }
+
         builder.add_rust_test_threads(&mut rustbook_cmd);
         let _guard = builder.msg(
             Kind::Test,
@@ -2295,6 +2349,7 @@ macro_rules! test_book {
         $name:ident, $path:expr, $book_name:expr,
         default=$default:expr
         $(,submodules = $submodules:expr)?
+        $(,dependencies=$dependencies:expr)?
         ;
     )+) => {
         $(
@@ -2324,11 +2379,21 @@ macro_rules! test_book {
                             builder.require_submodule(submodule, None);
                         }
                     )*
+
+                    let dependencies = vec![];
+                    $(
+                        let mut dependencies = dependencies;
+                        for dep in $dependencies {
+                            dependencies.push(dep);
+                        }
+                    )?
+
                     builder.ensure(BookTest {
                         compiler: self.compiler,
                         path: PathBuf::from($path),
                         name: $book_name,
                         is_ext_doc: !$default,
+                        dependencies,
                     });
                 }
             }
@@ -2343,7 +2408,7 @@ test_book!(
     RustcBook, "src/doc/rustc", "rustc", default=true;
     RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false, submodules=["src/doc/rust-by-example"];
     EmbeddedBook, "src/doc/embedded-book", "embedded-book", default=false, submodules=["src/doc/embedded-book"];
-    TheBook, "src/doc/book", "book", default=false, submodules=["src/doc/book"];
+    TheBook, "src/doc/book", "book", default=false, submodules=["src/doc/book"], dependencies=["src/doc/book/packages/trpl"];
     UnstableBook, "src/doc/unstable-book", "unstable-book", default=true;
     EditionGuide, "src/doc/edition-guide", "edition-guide", default=false, submodules=["src/doc/edition-guide"];
 );
diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs
index 82a6b4d4f28cb..7bca47ffe3c61 100644
--- a/src/bootstrap/src/core/build_steps/vendor.rs
+++ b/src/bootstrap/src/core/build_steps/vendor.rs
@@ -17,6 +17,7 @@ pub fn default_paths_to_vendor(builder: &Builder<'_>) -> Vec<PathBuf> {
         "src/tools/rustbook/Cargo.toml",
         "src/tools/rustc-perf/Cargo.toml",
         "src/tools/opt-dist/Cargo.toml",
+        "src/doc/book/packages/trpl/Cargo.toml",
     ] {
         paths.push(builder.src.join(p));
     }
diff --git a/src/doc/book b/src/doc/book
index f38ce8baef98c..e16dd73690a6c 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit f38ce8baef98cb20229e56f1be2d50e345f11792
+Subproject commit e16dd73690a6cc3ecdc5f5d94bbc3ce158a42e16
diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml
index 2c29a2848b7e5..854c454733759 100644
--- a/src/tools/rustbook/Cargo.toml
+++ b/src/tools/rustbook/Cargo.toml
@@ -12,7 +12,7 @@ env_logger = "0.11"
 mdbook-trpl-listing = { path = "../../doc/book/packages/mdbook-trpl-listing" }
 mdbook-trpl-note = { path = "../../doc/book/packages/mdbook-trpl-note" }
 mdbook-i18n-helpers = "0.3.3"
-mdbook-spec = { path = "../../doc/reference/mdbook-spec"}
+mdbook-spec = { path = "../../doc/reference/mdbook-spec" }
 
 [dependencies.mdbook]
 version = "0.4.37"
diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs
index f905b9277ff51..a1ef18610b000 100644
--- a/src/tools/rustbook/src/main.rs
+++ b/src/tools/rustbook/src/main.rs
@@ -31,6 +31,20 @@ fn main() {
                               (Defaults to the current directory when omitted)")
     .value_parser(clap::value_parser!(PathBuf));
 
+    // Note: we don't parse this into a `PathBuf` because it is comma separated
+    // strings *and* we will ultimately pass it into `MDBook::test()`, which
+    // accepts `Vec<&str>`. Although it is a bit annoying that `-l/--lang` and
+    // `-L/--library-path` are so close, this is the same set of arguments we
+    // would pass when invoking mdbook on the CLI, so making them match when
+    // invoking rustbook makes for good consistency.
+    let library_path_arg = arg!(
+        -L --"library-path" <PATHS>
+        "A comma-separated list of directories to add to the crate search\n\
+        path when building tests"
+    )
+    .required(false)
+    .value_parser(parse_library_paths);
+
     let matches = Command::new("rustbook")
         .about("Build a book with mdBook")
         .author("Steve Klabnik <steve@steveklabnik.com>")
@@ -48,11 +62,12 @@ fn main() {
         .subcommand(
             Command::new("test")
                 .about("Tests that a book's Rust code samples compile")
-                .arg(dir_arg),
+                .arg(dir_arg)
+                .arg(library_path_arg),
         )
         .get_matches();
 
-    // Check which subcomamnd the user ran...
+    // Check which subcommand the user ran...
     match matches.subcommand() {
         Some(("build", sub_matches)) => {
             if let Err(e) = build(sub_matches) {
@@ -113,8 +128,12 @@ pub fn build(args: &ArgMatches) -> Result3<()> {
 
 fn test(args: &ArgMatches) -> Result3<()> {
     let book_dir = get_book_dir(args);
+    let library_paths = args
+        .try_get_one::<Vec<String>>("library-path")?
+        .map(|v| v.iter().map(|s| s.as_str()).collect::<Vec<&str>>())
+        .unwrap_or_default();
     let mut book = load_book(&book_dir)?;
-    book.test(vec![])
+    book.test(library_paths)
 }
 
 fn get_book_dir(args: &ArgMatches) -> PathBuf {
@@ -132,6 +151,10 @@ fn load_book(book_dir: &Path) -> Result3<MDBook> {
     Ok(book)
 }
 
+fn parse_library_paths(input: &str) -> Result<Vec<String>, String> {
+    Ok(input.split(",").map(String::from).collect())
+}
+
 fn handle_error(error: mdbook::errors::Error) -> ! {
     eprintln!("Error: {}", error);
 
@@ -139,5 +162,5 @@ fn handle_error(error: mdbook::errors::Error) -> ! {
         eprintln!("\tCaused By: {}", cause);
     }
 
-    ::std::process::exit(101);
+    std::process::exit(101);
 }
diff --git a/tests/crashes/124350.rs b/tests/crashes/124350.rs
deleted file mode 100644
index d6038f280cf81..0000000000000
--- a/tests/crashes/124350.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #124350
-
-struct Node<const D: usize> {}
-
-impl Node<D>
-where
-    SmallVec<{ D * 2 }>:,
-{
-    fn new() -> Self {
-        let mut node = Node::new();
-        (&a, 0)();
-
-        node
-    }
-}
-
-struct SmallVec<T1, T2> {}
diff --git a/tests/crashes/125758.rs b/tests/crashes/125758.rs
deleted file mode 100644
index 86c3b80abab9d..0000000000000
--- a/tests/crashes/125758.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-//@ known-bug: rust-lang/rust#125758
-#![feature(impl_trait_in_assoc_type)]
-
-trait Trait: Sized {
-    type Assoc2;
-}
-
-impl Trait for Bar {
-    type Assoc2 = impl std::fmt::Debug;
-}
-
-struct Foo {
-    field: <Bar as Trait>::Assoc2,
-}
-
-enum Bar {
-    C = 42,
-    D = 99,
-}
-
-static BAR: u8 = 42;
-
-static FOO2: (&Foo, &<Bar as Trait>::Assoc2) =
-    unsafe { (std::mem::transmute(&BAR), std::mem::transmute(&BAR)) };
-
-fn main() {}
diff --git a/tests/crashes/127351.rs b/tests/crashes/127351.rs
deleted file mode 100644
index e3f415948852d..0000000000000
--- a/tests/crashes/127351.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #127351
-#![feature(lazy_type_alias)]
-#![allow(incomplete_features)]
-
-struct Outer0<'a, T>(ExplicitTypeOutlives<'a, T>);
-type ExplicitTypeOutlives<'a, T: 'a> = (&'a (), T);
-
-pub struct Warns {
-    _significant_drop: ExplicitTypeOutlives,
-    field: String,
-}
-
-pub fn test(w: Warns) {
-    _ = || drop(w.field);
-}
-
-fn main() {}
diff --git a/tests/crashes/127353.rs b/tests/crashes/127353.rs
deleted file mode 100644
index 9bcb90b5c57f8..0000000000000
--- a/tests/crashes/127353.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//@ known-bug: #127353
-#![feature(type_alias_impl_trait)]
-trait Trait<T> {}
-type Alias<'a, U> = impl Trait<U>;
-
-fn f<'a>() -> Alias<'a, ()> {}
-
-pub enum UninhabitedVariants {
-    Tuple(Alias),
-}
-
-struct A;
-
-fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A {
-    match x {}
-}
-
-fn main() {}
diff --git a/tests/crashes/127742.rs b/tests/crashes/127742.rs
deleted file mode 100644
index 24add45413566..0000000000000
--- a/tests/crashes/127742.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ known-bug: #127742
-struct Vtable(dyn Cap);  // missing lifetime
-
-trait Cap<'a> {}
-
-union Transmute {
-    t: u64,  // ICEs with u64, u128, or usize. Correctly errors with u32.
-    u: &'static Vtable,
-}
-
-const G: &'static Vtable = unsafe { Transmute { t: 1 }.u };
diff --git a/tests/crashes/130521.rs b/tests/crashes/130521.rs
index 7c078ab579094..ccc2b444b822a 100644
--- a/tests/crashes/130521.rs
+++ b/tests/crashes/130521.rs
@@ -6,7 +6,7 @@ struct Vtable(dyn Cap);
 trait Cap<'a> {}
 
 union Transmute {
-    t: u64,
+    t: u128,
     u: &'static Vtable,
 }
 
diff --git a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr
index 396167f407055..e965c40fb5b86 100644
--- a/tests/ui/async-await/async-closures/fn-exception-target-features.stderr
+++ b/tests/ui/async-await/async-closures/fn-exception-target-features.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn<()>` is not satisfied
+error[E0277]: the trait bound `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn()` is not satisfied
   --> $DIR/fn-exception-target-features.rs:16:10
    |
 LL |     test(target_feature);
-   |     ---- ^^^^^^^^^^^^^^ the trait `AsyncFn<()>` is not implemented for fn item `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
+   |     ---- ^^^^^^^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
    |     |
    |     required by a bound introduced by this call
    |
diff --git a/tests/ui/async-await/async-closures/fn-exception.stderr b/tests/ui/async-await/async-closures/fn-exception.stderr
index bacd079af0f2d..20132e428332a 100644
--- a/tests/ui/async-await/async-closures/fn-exception.stderr
+++ b/tests/ui/async-await/async-closures/fn-exception.stderr
@@ -1,8 +1,8 @@
-error[E0277]: the trait bound `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}: AsyncFn<()>` is not satisfied
+error[E0277]: the trait bound `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}: AsyncFn()` is not satisfied
   --> $DIR/fn-exception.rs:19:10
    |
 LL |     test(unsafety);
-   |     ---- ^^^^^^^^ the trait `AsyncFn<()>` is not implemented for fn item `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}`
+   |     ---- ^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}`
    |     |
    |     required by a bound introduced by this call
    |
@@ -12,11 +12,11 @@ note: required by a bound in `test`
 LL | fn test(f: impl async Fn()) {}
    |                 ^^^^^^^^^^ required by this bound in `test`
 
-error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn<()>` is not satisfied
+error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn()` is not satisfied
   --> $DIR/fn-exception.rs:20:10
    |
 LL |     test(abi);
-   |     ---- ^^^ the trait `AsyncFn<()>` is not implemented for fn item `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}`
+   |     ---- ^^^ the trait `AsyncFn()` is not implemented for fn item `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}`
    |     |
    |     required by a bound introduced by this call
    |
diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs
new file mode 100644
index 0000000000000..2e7cf1b09fd00
--- /dev/null
+++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.rs
@@ -0,0 +1,14 @@
+//@ edition: 2021
+
+#![feature(async_closure)]
+
+use std::ops::AsyncFnMut;
+
+fn produce() -> impl AsyncFnMut() -> &'static str {
+    async || ""
+}
+
+fn main() {
+    let x: i32 = produce();
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr
new file mode 100644
index 0000000000000..863e61eb35ad4
--- /dev/null
+++ b/tests/ui/async-await/async-closures/pretty-async-fn-opaque.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/pretty-async-fn-opaque.rs:12:18
+   |
+LL | fn produce() -> impl AsyncFnMut() -> &'static str {
+   |                 --------------------------------- the found opaque type
+...
+LL |     let x: i32 = produce();
+   |            ---   ^^^^^^^^^ expected `i32`, found opaque type
+   |            |
+   |            expected due to this
+   |
+   = note:     expected type `i32`
+           found opaque type `impl AsyncFnMut() -> &'static str`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
index 5f980c46a1f54..b5ad8eb790f2b 100644
--- a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
+++ b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
@@ -5,7 +5,7 @@ LL |         let 0 = v1;
    |             ^ pattern `1_u32..=u32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u32`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -23,7 +23,7 @@ LL |         let (0 | 1) = v1;
    |              ^^^^^ pattern `2_u32..=u32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u32`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -37,7 +37,7 @@ LL |         let 1.. = v1;
    |             ^^^ pattern `0_u32` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u32`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -51,7 +51,7 @@ LL |         let [0, 0, 0, 0] = v2;
    |             ^^^^^^^^^^^^ pattern `[1_u32..=u32::MAX, _, _, _]` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `[u32; 4]`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
@@ -65,7 +65,7 @@ LL |         let [0] = v4;
    |             ^^^ patterns `&[]` and `&[_, _, ..]` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&[u32]`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -79,7 +79,7 @@ LL |         let Refutable::A = v3;
    |             ^^^^^^^^^^^^ pattern `Refutable::B` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Refutable` defined here
   --> $DIR/bad-pattern.rs:4:6
    |
@@ -104,7 +104,7 @@ LL |         let PAT = v1;
    |             ^^^ pattern `1_u32..=u32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u32`
 help: introduce a variable instead
    |
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.rs b/tests/ui/codemap_tests/huge_multispan_highlight.rs
index 7d7b757082350..6f6834b01bd61 100644
--- a/tests/ui/codemap_tests/huge_multispan_highlight.rs
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.rs
@@ -1,7 +1,7 @@
 //@ revisions: ascii unicode
 //@ compile-flags: --color=always
 //@[ascii] compile-flags: --error-format=human
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode
 //@ ignore-windows
 fn main() {
     let _ = match true {
diff --git a/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs b/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs
new file mode 100644
index 0000000000000..1af6d5742b1f6
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs
@@ -0,0 +1,18 @@
+// regression test for #124350
+
+struct Node<const D: usize> {}
+
+impl<const D: usize> Node<D>
+where
+    SmallVec<{ D * 2 }>:,
+    //~^ ERROR generic parameters may not be used in const operations
+    //~| ERROR constant provided when a type was expected
+{
+    fn new() -> Self {
+        Node::new()
+    }
+}
+
+struct SmallVec<T1>(T1);
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr
new file mode 100644
index 0000000000000..a8d6cebabe718
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr
@@ -0,0 +1,18 @@
+error: generic parameters may not be used in const operations
+  --> $DIR/bad-multiply.rs:7:16
+   |
+LL |     SmallVec<{ D * 2 }>:,
+   |                ^ cannot perform const operation using `D`
+   |
+   = help: const parameters may only be used as standalone arguments, i.e. `D`
+   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error[E0747]: constant provided when a type was expected
+  --> $DIR/bad-multiply.rs:7:14
+   |
+LL |     SmallVec<{ D * 2 }>:,
+   |              ^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/tests/ui/const-generics/kind_mismatch.rs b/tests/ui/const-generics/kind_mismatch.rs
index bab58d5952a5f..ecdc01a5ef901 100644
--- a/tests/ui/const-generics/kind_mismatch.rs
+++ b/tests/ui/const-generics/kind_mismatch.rs
@@ -20,5 +20,4 @@ pub fn remove_key<K, S: SubsetExcept<K>>() -> S {
 
 fn main() {
     let map: KeyHolder<0> = remove_key::<_, _>();
-    //~^ ERROR: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied
 }
diff --git a/tests/ui/const-generics/kind_mismatch.stderr b/tests/ui/const-generics/kind_mismatch.stderr
index e13bc6ee058d0..1487b18961986 100644
--- a/tests/ui/const-generics/kind_mismatch.stderr
+++ b/tests/ui/const-generics/kind_mismatch.stderr
@@ -14,26 +14,6 @@ LL | impl<K> ContainsKey<K> for KeyHolder<K> {}
    |      |
    |      help: consider changing this type parameter to a const parameter: `const K: u8`
 
-error[E0277]: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied
-  --> $DIR/kind_mismatch.rs:22:45
-   |
-LL |     let map: KeyHolder<0> = remove_key::<_, _>();
-   |                                             ^ the trait `ContainsKey<0>` is not implemented for `KeyHolder<0>`
-   |
-note: required for `KeyHolder<0>` to implement `SubsetExcept<_>`
-  --> $DIR/kind_mismatch.rs:15:28
-   |
-LL | impl<P, T: ContainsKey<0>> SubsetExcept<P> for T {}
-   |            --------------  ^^^^^^^^^^^^^^^     ^
-   |            |
-   |            unsatisfied trait bound introduced here
-note: required by a bound in `remove_key`
-  --> $DIR/kind_mismatch.rs:17:25
-   |
-LL | pub fn remove_key<K, S: SubsetExcept<K>>() -> S {
-   |                         ^^^^^^^^^^^^^^^ required by this bound in `remove_key`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0277, E0747.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0747`.
diff --git a/tests/ui/consts/const-match-check.eval1.stderr b/tests/ui/consts/const-match-check.eval1.stderr
index 84890214861b8..b1827009d2adc 100644
--- a/tests/ui/consts/const-match-check.eval1.stderr
+++ b/tests/ui/consts/const-match-check.eval1.stderr
@@ -5,7 +5,7 @@ LL |     A = { let 0 = 0; 0 },
    |               ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/consts/const-match-check.eval2.stderr b/tests/ui/consts/const-match-check.eval2.stderr
index 0aa12eb86dddc..04ac58bfe402f 100644
--- a/tests/ui/consts/const-match-check.eval2.stderr
+++ b/tests/ui/consts/const-match-check.eval2.stderr
@@ -5,7 +5,7 @@ LL |     let x: [i32; { let 0 = 0; 0 }] = [];
    |                        ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/consts/const-match-check.matchck.stderr b/tests/ui/consts/const-match-check.matchck.stderr
index bcca4c2a64783..05ddc4c821955 100644
--- a/tests/ui/consts/const-match-check.matchck.stderr
+++ b/tests/ui/consts/const-match-check.matchck.stderr
@@ -5,7 +5,7 @@ LL | const X: i32 = { let 0 = 0; 0 };
    |                      ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -23,7 +23,7 @@ LL | static Y: i32 = { let 0 = 0; 0 };
    |                       ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -41,7 +41,7 @@ LL |     const X: i32 = { let 0 = 0; 0 };
    |                          ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -59,7 +59,7 @@ LL |     const X: i32 = { let 0 = 0; 0 };
    |                          ^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/consts/const-pattern-irrefutable.stderr b/tests/ui/consts/const-pattern-irrefutable.stderr
index afb67a3a118a4..646426c942689 100644
--- a/tests/ui/consts/const-pattern-irrefutable.stderr
+++ b/tests/ui/consts/const-pattern-irrefutable.stderr
@@ -8,7 +8,7 @@ LL |     let a = 4;
    |         ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u8`
 help: introduce a variable instead
    |
@@ -25,7 +25,7 @@ LL |     let c = 4;
    |         ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `u8`
 help: introduce a variable instead
    |
@@ -42,7 +42,7 @@ LL |     let d = (4, 4);
    |         ^ patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `(u8, u8)`
 help: introduce a variable instead
    |
@@ -59,7 +59,7 @@ LL |     let e = S {
    |         ^ pattern `S { foo: 1_u8..=u8::MAX }` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `S` defined here
   --> $DIR/const-pattern-irrefutable.rs:15:8
    |
diff --git a/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr
index b9ceaa4af7ba0..88f7d2da47c28 100644
--- a/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr
+++ b/tests/ui/destructuring-assignment/non-exhaustive-destructure.stderr
@@ -5,7 +5,7 @@ LL |     None = Some(3);
    |     ^^^^ pattern `Some(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Option<i32>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs
index ce41ad2952bc9..dedae4365e889 100644
--- a/tests/ui/diagnostic-width/E0271.rs
+++ b/tests/ui/diagnostic-width/E0271.rs
@@ -1,6 +1,6 @@
 //@ revisions: ascii unicode
 //@[ascii] compile-flags: --diagnostic-width=40
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=40
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40
 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 trait Future {
     type Error;
diff --git a/tests/ui/diagnostic-width/flag-human.rs b/tests/ui/diagnostic-width/flag-human.rs
index 1af4165914164..8e656293b4102 100644
--- a/tests/ui/diagnostic-width/flag-human.rs
+++ b/tests/ui/diagnostic-width/flag-human.rs
@@ -1,6 +1,6 @@
 //@ revisions: ascii unicode
 //@[ascii] compile-flags: --diagnostic-width=20
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=20
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=20
 
 // This test checks that `-Z output-width` effects the human error output by restricting it to an
 // arbitrarily low value so that the effect is visible.
diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs
index 73f81f5872a64..695852f83ac0a 100644
--- a/tests/ui/diagnostic-width/long-E0308.rs
+++ b/tests/ui/diagnostic-width/long-E0308.rs
@@ -1,6 +1,6 @@
 //@ revisions: ascii unicode
 //@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
-//@[unicode] compile-flags: -Zunstable-options=yes --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
+//@[unicode] compile-flags: -Zunstable-options --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 
 mod a {
diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs
index 61c4b31e03a62..e630db8ba42a2 100644
--- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs
+++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs
@@ -1,5 +1,5 @@
 //@ revisions: ascii unicode
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode
 // ignore-tidy-linelength
 
 fn main() {
diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs
index 283506bd6c90d..de2f42a4a7292 100644
--- a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs
+++ b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs
@@ -1,5 +1,5 @@
 //@ revisions: ascii unicode
-//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode
+//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode
 // ignore-tidy-linelength
 
 fn main() {
diff --git a/tests/ui/empty/empty-never-array.stderr b/tests/ui/empty/empty-never-array.stderr
index 0104a43553843..f9f39a6371e26 100644
--- a/tests/ui/empty/empty-never-array.stderr
+++ b/tests/ui/empty/empty-never-array.stderr
@@ -5,7 +5,7 @@ LL |     let Helper::U(u) = Helper::T(t, []);
    |         ^^^^^^^^^^^^ pattern `Helper::T(_, _)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Helper<T, U>` defined here
   --> $DIR/empty-never-array.rs:3:6
    |
diff --git a/tests/ui/error-codes/E0005.stderr b/tests/ui/error-codes/E0005.stderr
index 4be37e2e45497..c643ee07a3739 100644
--- a/tests/ui/error-codes/E0005.stderr
+++ b/tests/ui/error-codes/E0005.stderr
@@ -5,7 +5,7 @@ LL |     let Some(y) = x;
    |         ^^^^^^^ pattern `None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Option<i32>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/error-emitter/unicode-output.rs b/tests/ui/error-emitter/unicode-output.rs
index ba6db37b66c22..5c083c4e57508 100644
--- a/tests/ui/error-emitter/unicode-output.rs
+++ b/tests/ui/error-emitter/unicode-output.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -Zunstable-options=yes --error-format=human-unicode --color=always
+//@ compile-flags: -Zunstable-options --error-format=human-unicode --color=always
 //@ edition:2018
 //@ only-linux
 
diff --git a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
index 4836ffe172318..b596da8463f21 100644
--- a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
+++ b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
@@ -5,7 +5,7 @@ LL |     let Ok(_x) = &foo();
    |         ^^^^^^ pattern `&Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&Result<u32, !>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs
index b33fda8e15443..7fffe312f4b7b 100644
--- a/tests/ui/generic-associated-types/issue-71176.rs
+++ b/tests/ui/generic-associated-types/issue-71176.rs
@@ -16,6 +16,8 @@ struct Holder<B> {
 
 fn main() {
     Holder {
-        inner: Box::new(()), //~ ERROR: the trait `Provider` cannot be made into an object
+        inner: Box::new(()),
+        //~^ ERROR: the trait `Provider` cannot be made into an object
+        //~| ERROR: the trait `Provider` cannot be made into an object
     };
 }
diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr
index 15d5a3df6f276..1cd2ed0d313dc 100644
--- a/tests/ui/generic-associated-types/issue-71176.stderr
+++ b/tests/ui/generic-associated-types/issue-71176.stderr
@@ -80,7 +80,24 @@ LL |     type A<'a>;
    = help: consider moving `A` to another trait
    = help: only type `()` implements the trait, consider using it directly instead
 
-error: aborting due to 5 previous errors
+error[E0038]: the trait `Provider` cannot be made into an object
+  --> $DIR/issue-71176.rs:19:16
+   |
+LL |         inner: Box::new(()),
+   |                ^^^^^^^^^^^^ `Provider` cannot be made into an object
+   |
+note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/issue-71176.rs:2:10
+   |
+LL | trait Provider {
+   |       -------- this trait cannot be made into an object...
+LL |     type A<'a>;
+   |          ^ ...because it contains the generic associated type `A`
+   = help: consider moving `A` to another trait
+   = help: only type `()` implements the trait, consider using it directly instead
+   = note: required for the cast from `Box<()>` to `Box<(dyn Provider<A<'_> = _> + 'static), {type error}>`
+
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0038, E0107.
 For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
index af11bc82d0c2e..65903dbe12e57 100644
--- a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
+++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
@@ -15,7 +15,7 @@ LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `[i32::MIN..=2_i32, ..]` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `[i32; 8]`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
index 0f60cd397b997..aa3d2cd2d904f 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
@@ -67,7 +67,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
index 204ee373bc538..63258f3538313 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
@@ -94,7 +94,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -108,7 +108,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
index e2916725fbd90..62be2ef7a4d83 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
@@ -4,7 +4,7 @@ error: expected a pattern range bound, found an expression
 LL |             0..5+1 => errors_only.push(x),
    |                ^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +         const VAL: /* Type */ = 5+1;
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
index f54e07c3a6370..dbe7f4482eed4 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
@@ -16,7 +16,7 @@ error: expected a pattern range bound, found an expression
 LL |             0..=(5+1) => errors_only.push(x),
    |                  ^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +         const VAL: /* Type */ = 5+1;
diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
index 4951591990462..17b65c1dae548 100644
--- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
+++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
@@ -15,7 +15,7 @@ LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `[i32::MIN..=2_i32, ..]` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `[i32; 8]`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
index caaac5434c56a..6f0f287fe122e 100644
--- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
+++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
@@ -74,7 +74,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/opaque-used-in-extraneous-argument.rs:20:5
    |
 LL |     open_parent(&old_path)
-   |     ^^^^^^^^^^^ --------- unexpected argument of type `&impl FnOnce<{type error}, Output = {type error}> + Fn<{type error}> + 'static`
+   |     ^^^^^^^^^^^ --------- unexpected argument of type `&impl Fn<{type error}> + FnOnce<{type error}, Output = {type error}> + 'static`
    |
 note: function defined here
   --> $DIR/opaque-used-in-extraneous-argument.rs:12:4
diff --git a/tests/ui/issues/issue-55587.stderr b/tests/ui/issues/issue-55587.stderr
index eec6426a29950..7a5d0e281007f 100644
--- a/tests/ui/issues/issue-55587.stderr
+++ b/tests/ui/issues/issue-55587.stderr
@@ -4,7 +4,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function
 LL |     let Path::new();
    |         ^^^^^^^^^^^ `fn` calls are not allowed in patterns
    |
-   = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+   = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.rs b/tests/ui/layout/ice-type-error-in-tail-124031.rs
index 0a2be11740358..ecd6f3d56f3f4 100644
--- a/tests/ui/layout/ice-type-error-in-tail-124031.rs
+++ b/tests/ui/layout/ice-type-error-in-tail-124031.rs
@@ -1,3 +1,5 @@
+//@ normalize-stderr-test: "\d+ bits" -> "$$BITS bits"
+
 // Regression test for issue #124031
 // Checks that we don't ICE when the tail
 // of an ADT has a type error
@@ -16,5 +18,6 @@ struct Other {
 fn main() {
     unsafe {
         std::mem::transmute::<Option<()>, Option<&Other>>(None);
+        //~^ ERROR cannot transmute between types of different sizes
     }
 }
diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.stderr b/tests/ui/layout/ice-type-error-in-tail-124031.stderr
index 57dc83f92dfda..a066e8574dc50 100644
--- a/tests/ui/layout/ice-type-error-in-tail-124031.stderr
+++ b/tests/ui/layout/ice-type-error-in-tail-124031.stderr
@@ -1,5 +1,5 @@
 error[E0046]: not all trait items implemented, missing: `RefTarget`
-  --> $DIR/ice-type-error-in-tail-124031.rs:9:1
+  --> $DIR/ice-type-error-in-tail-124031.rs:11:1
    |
 LL |     type RefTarget;
    |     -------------- `RefTarget` from trait
@@ -7,6 +7,16 @@ LL |     type RefTarget;
 LL | impl Trait for () {}
    | ^^^^^^^^^^^^^^^^^ missing `RefTarget` in implementation
 
-error: aborting due to 1 previous error
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+  --> $DIR/ice-type-error-in-tail-124031.rs:20:9
+   |
+LL |         std::mem::transmute::<Option<()>, Option<&Other>>(None);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: `Option<()>` ($BITS bits)
+   = note: target type: `Option<&Other>` ($BITS bits)
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0046`.
+Some errors have detailed explanations: E0046, E0512.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs
new file mode 100644
index 0000000000000..6ded9118700c0
--- /dev/null
+++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs
@@ -0,0 +1,18 @@
+// regression test for #127351
+
+#![feature(lazy_type_alias)]
+//~^ WARN the feature `lazy_type_alias` is incomplete
+
+type ExplicitTypeOutlives<T> = T;
+
+pub struct Warns {
+    _significant_drop: ExplicitTypeOutlives,
+    //~^ ERROR missing generics for type alias `ExplicitTypeOutlives`
+    field: String,
+}
+
+pub fn test(w: Warns) {
+    let _ = || drop(w.field);
+}
+
+fn main() {}
diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr
new file mode 100644
index 0000000000000..3a5ded60241b1
--- /dev/null
+++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr
@@ -0,0 +1,28 @@
+warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/bad-lazy-type-alias.rs:3:12
+   |
+LL | #![feature(lazy_type_alias)]
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0107]: missing generics for type alias `ExplicitTypeOutlives`
+  --> $DIR/bad-lazy-type-alias.rs:9:24
+   |
+LL |     _significant_drop: ExplicitTypeOutlives,
+   |                        ^^^^^^^^^^^^^^^^^^^^ expected 1 generic argument
+   |
+note: type alias defined here, with 1 generic parameter: `T`
+  --> $DIR/bad-lazy-type-alias.rs:6:6
+   |
+LL | type ExplicitTypeOutlives<T> = T;
+   |      ^^^^^^^^^^^^^^^^^^^^ -
+help: add missing generic argument
+   |
+LL |     _significant_drop: ExplicitTypeOutlives<T>,
+   |                                            +++
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr b/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr
index 13312306c07b7..58f9e267db372 100644
--- a/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr
+++ b/tests/ui/let-else/uninitialized-refutable-let-issue-123844.stderr
@@ -5,7 +5,7 @@ LL |     let Some(x);
    |         ^^^^^^^ pattern `None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Option<i32>`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/loops/loop-else-break-with-value.stderr b/tests/ui/loops/loop-else-break-with-value.stderr
index ca18f0fdd7f32..da3276c8cd358 100644
--- a/tests/ui/loops/loop-else-break-with-value.stderr
+++ b/tests/ui/loops/loop-else-break-with-value.stderr
@@ -21,7 +21,7 @@ LL |     let Some(1) = loop {
    |         ^^^^^^^ pattern `None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Option<i32>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/tests/ui/match/match-fn-call.stderr b/tests/ui/match/match-fn-call.stderr
index 297aa4cd95def..a3d61947080c0 100644
--- a/tests/ui/match/match-fn-call.stderr
+++ b/tests/ui/match/match-fn-call.stderr
@@ -4,7 +4,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function
 LL |         Path::new("foo") => println!("foo"),
    |         ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
    |
-   = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+   = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html
 
 error[E0164]: expected tuple struct or tuple variant, found associated function `Path::new`
   --> $DIR/match-fn-call.rs:8:9
@@ -12,7 +12,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function
 LL |         Path::new("bar") => println!("bar"),
    |         ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
    |
-   = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+   = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/mir/issue-112269.stderr b/tests/ui/mir/issue-112269.stderr
index adb662c98a7e8..80f329e2ce026 100644
--- a/tests/ui/mir/issue-112269.stderr
+++ b/tests/ui/mir/issue-112269.stderr
@@ -7,7 +7,7 @@ LL |     let x: i32 = 3;
    |         ^ patterns `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: introduce a variable instead
    |
@@ -23,7 +23,7 @@ LL |     let y = 4;
    |         ^ patterns `i32::MIN..=2_i32` and `4_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: introduce a variable instead
    |
diff --git a/tests/ui/never_type/exhaustive_patterns.stderr b/tests/ui/never_type/exhaustive_patterns.stderr
index 1314cbc52f881..1f22b9e619867 100644
--- a/tests/ui/never_type/exhaustive_patterns.stderr
+++ b/tests/ui/never_type/exhaustive_patterns.stderr
@@ -5,7 +5,7 @@ LL |     let Either::A(()) = foo();
    |         ^^^^^^^^^^^^^ pattern `Either::B(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Either<(), !>` defined here
   --> $DIR/exhaustive_patterns.rs:9:6
    |
diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.rs b/tests/ui/nll/user-annotations/region-error-ice-109072.rs
index bcdc6651cf5bb..3f2ad3ccbf582 100644
--- a/tests/ui/nll/user-annotations/region-error-ice-109072.rs
+++ b/tests/ui/nll/user-annotations/region-error-ice-109072.rs
@@ -11,5 +11,4 @@ impl Lt<'missing> for () { //~ ERROR undeclared lifetime
 
 fn main() {
     let _: <() as Lt<'_>>::T = &();
-    //~^ ERROR the trait bound `(): Lt<'_>` is not satisfied
 }
diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr
index c187c17d98c68..d90971bed25ba 100644
--- a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr
+++ b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr
@@ -21,13 +21,6 @@ help: consider introducing lifetime `'missing` here
 LL | impl<'missing> Lt<'missing> for () {
    |     ++++++++++
 
-error[E0277]: the trait bound `(): Lt<'_>` is not satisfied
-  --> $DIR/region-error-ice-109072.rs:13:13
-   |
-LL |     let _: <() as Lt<'_>>::T = &();
-   |             ^^ the trait `Lt<'_>` is not implemented for `()`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0261, E0277.
-For more information about an error, try `rustc --explain E0261`.
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr b/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
index fdb1a9bb4b78e..7044b8e035ad8 100644
--- a/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
+++ b/tests/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
@@ -5,7 +5,7 @@ LL |     let (0 | (1 | 2)) = 0;
    |          ^^^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/parser/bad-name.stderr b/tests/ui/parser/bad-name.stderr
index 5ca248380ee5b..a336923f4fd89 100644
--- a/tests/ui/parser/bad-name.stderr
+++ b/tests/ui/parser/bad-name.stderr
@@ -10,7 +10,7 @@ error: expected a pattern, found an expression
 LL |   let x.y::<isize>.z foo;
    |       ^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator, found `foo`
   --> $DIR/bad-name.rs:2:22
diff --git a/tests/ui/parser/issues/issue-24197.stderr b/tests/ui/parser/issues/issue-24197.stderr
index c92e165b23b65..4eadc897d88c8 100644
--- a/tests/ui/parser/issues/issue-24197.stderr
+++ b/tests/ui/parser/issues/issue-24197.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let buf[0] = 0;
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-24375.stderr b/tests/ui/parser/issues/issue-24375.stderr
index fef3fcde7b799..03cd33f18751c 100644
--- a/tests/ui/parser/issues/issue-24375.stderr
+++ b/tests/ui/parser/issues/issue-24375.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |         tmp[0] => {}
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == tmp[0] => {}
diff --git a/tests/ui/parser/pat-lt-bracket-5.stderr b/tests/ui/parser/pat-lt-bracket-5.stderr
index a2a972652d188..c68aefa0546d3 100644
--- a/tests/ui/parser/pat-lt-bracket-5.stderr
+++ b/tests/ui/parser/pat-lt-bracket-5.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let v[0] = v[1];
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error[E0425]: cannot find value `v` in this scope
   --> $DIR/pat-lt-bracket-5.rs:2:16
diff --git a/tests/ui/parser/pat-lt-bracket-6.stderr b/tests/ui/parser/pat-lt-bracket-6.stderr
index 14ae602fedfa1..0274809f800c5 100644
--- a/tests/ui/parser/pat-lt-bracket-6.stderr
+++ b/tests/ui/parser/pat-lt-bracket-6.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let Test(&desc[..]) = x;
    |              ^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error[E0308]: mismatched types
   --> $DIR/pat-lt-bracket-6.rs:10:30
diff --git a/tests/ui/parser/pat-ranges-3.stderr b/tests/ui/parser/pat-ranges-3.stderr
index ef080368e19ca..fcda924d98c51 100644
--- a/tests/ui/parser/pat-ranges-3.stderr
+++ b/tests/ui/parser/pat-ranges-3.stderr
@@ -4,7 +4,7 @@ error: expected a pattern range bound, found an expression
 LL |     let 10 ..= 10 + 3 = 12;
    |                ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern range bound, found an expression
   --> $DIR/pat-ranges-3.rs:7:9
@@ -12,7 +12,7 @@ error: expected a pattern range bound, found an expression
 LL |     let 10 - 3 ..= 10 = 8;
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/parser/recover/recover-pat-exprs.stderr b/tests/ui/parser/recover/recover-pat-exprs.stderr
index 6cb3753de8d17..041dfd647ad07 100644
--- a/tests/ui/parser/recover/recover-pat-exprs.stderr
+++ b/tests/ui/parser/recover/recover-pat-exprs.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |         x.y => (),
    |         ^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.y => (),
@@ -27,7 +27,7 @@ error: expected a pattern, found an expression
 LL |         x.0 => (),
    |         ^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.0 => (),
@@ -51,7 +51,7 @@ error: expected a pattern, found an expression
 LL |         x._0 => (),
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x._0 => (),
@@ -76,7 +76,7 @@ error: expected a pattern, found an expression
 LL |         x.0.1 => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.0.1 => (),
@@ -101,7 +101,7 @@ error: expected a pattern, found an expression
 LL |         x.4.y.17.__z => (),
    |         ^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.4.y.17.__z => (),
@@ -156,7 +156,7 @@ error: expected a pattern, found an expression
 LL |         x[0] => (),
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x[0] => (),
@@ -178,7 +178,7 @@ error: expected a pattern, found an expression
 LL |         x[..] => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x[..] => (),
@@ -228,7 +228,7 @@ error: expected a pattern, found an expression
 LL |         x.f() => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.f() => (),
@@ -250,7 +250,7 @@ error: expected a pattern, found an expression
 LL |         x._f() => (),
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x._f() => (),
@@ -273,7 +273,7 @@ error: expected a pattern, found an expression
 LL |         x? => (),
    |         ^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x? => (),
@@ -297,7 +297,7 @@ error: expected a pattern, found an expression
 LL |         ().f() => (),
    |         ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == ().f() => (),
@@ -322,7 +322,7 @@ error: expected a pattern, found an expression
 LL |         (0, x)?.f() => (),
    |         ^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == (0, x)?.f() => (),
@@ -347,7 +347,7 @@ error: expected a pattern, found an expression
 LL |         x.f().g() => (),
    |         ^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.f().g() => (),
@@ -372,7 +372,7 @@ error: expected a pattern, found an expression
 LL |         0.f()?.g()?? => (),
    |         ^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == 0.f()?.g()?? => (),
@@ -397,7 +397,7 @@ error: expected a pattern, found an expression
 LL |         x as usize => (),
    |         ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x as usize => (),
@@ -419,7 +419,7 @@ error: expected a pattern, found an expression
 LL |         0 as usize => (),
    |         ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == 0 as usize => (),
@@ -442,7 +442,7 @@ error: expected a pattern, found an expression
 LL |         x.f().0.4 as f32 => (),
    |         ^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == x.f().0.4 as f32 => (),
@@ -466,7 +466,7 @@ error: expected a pattern, found an expression
 LL |         1 + 1 => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == 1 + 1 => (),
@@ -488,7 +488,7 @@ error: expected a pattern, found an expression
 LL |         (1 + 2) * 3 => (),
    |         ^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == (1 + 2) * 3 => (),
@@ -511,7 +511,7 @@ error: expected a pattern, found an expression
 LL |         x.0 > 2 => (),
    |         ^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == (x.0 > 2) => (),
@@ -536,7 +536,7 @@ error: expected a pattern, found an expression
 LL |         x.0 == 2 => (),
    |         ^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == (x.0 == 2) => (),
@@ -561,7 +561,7 @@ error: expected a pattern, found an expression
 LL |         (x, y.0 > 2) if x != 0 => (),
    |             ^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to the match arm guard
    |
 LL |         (x, val) if x != 0 && val == (y.0 > 2) => (),
@@ -583,7 +583,7 @@ error: expected a pattern, found an expression
 LL |         (x, y.0 > 2) if x != 0 || x != 1 => (),
    |             ^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to the match arm guard
    |
 LL |         (x, val) if (x != 0 || x != 1) && val == (y.0 > 2) => (),
@@ -623,7 +623,7 @@ error: expected a pattern, found an expression
 LL |         u8::MAX.abs() => (),
    |         ^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == u8::MAX.abs() => (),
@@ -645,7 +645,7 @@ error: expected a pattern, found an expression
 LL |         z @ w @ v.u() => (),
    |                 ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         z @ w @ val if val == v.u() => (),
@@ -670,7 +670,7 @@ error: expected a pattern, found an expression
 LL |         y.ilog(3) => (),
    |         ^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == y.ilog(3) => (),
@@ -695,7 +695,7 @@ error: expected a pattern, found an expression
 LL |         n + 1 => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == n + 1 => (),
@@ -720,7 +720,7 @@ error: expected a pattern, found an expression
 LL |         ("".f() + 14 * 8) => (),
    |          ^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         (val) if val == "".f() + 14 * 8 => (),
@@ -745,7 +745,7 @@ error: expected a pattern, found an expression
 LL |         f?() => (),
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         val if val == f?() => (),
@@ -770,7 +770,7 @@ error: expected a pattern, found an expression
 LL |     let 1 + 1 = 2;
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected one of `)`, `,`, `@`, or `|`, found `*`
   --> $DIR/recover-pat-exprs.rs:104:28
@@ -787,7 +787,7 @@ error: expected a pattern, found an expression
 LL |         (1 + 2) * 3 => (),
    |          ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:75:5
@@ -795,7 +795,7 @@ error: expected a pattern, found an expression
 LL |     1 + 2 * PI.cos() => 2,
    |     ^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-exprs.rs:83:9
@@ -803,7 +803,7 @@ error: expected a pattern, found an expression
 LL |         x.sqrt() @ .. => (),
    |         ^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: aborting due to 45 previous errors
 
diff --git a/tests/ui/parser/recover/recover-pat-issues.stderr b/tests/ui/parser/recover/recover-pat-issues.stderr
index 17cb7b4aead80..bdd0b2b260e7f 100644
--- a/tests/ui/parser/recover/recover-pat-issues.stderr
+++ b/tests/ui/parser/recover/recover-pat-issues.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |         Foo("hi".to_owned()) => true,
    |             ^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         Foo(val) if val == "hi".to_owned() => true,
@@ -26,7 +26,7 @@ error: expected a pattern, found an expression
 LL |         Bar { baz: "hi".to_owned() } => true,
    |                    ^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         Bar { baz } if baz == "hi".to_owned() => true,
@@ -48,7 +48,7 @@ error: expected a pattern, found an expression
 LL |         &["foo".to_string()] => {}
    |           ^^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider moving the expression to a match arm guard
    |
 LL |         &[val] if val == "foo".to_string() => {}
@@ -70,7 +70,7 @@ error: expected a pattern, found an expression
 LL |     if let Some(MAGIC.0 as usize) = None::<usize> {}
    |                 ^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = MAGIC.0 as usize;
@@ -87,7 +87,7 @@ error: expected a pattern, found an expression
 LL |     if let (-1.some(4)) = (0, Some(4)) {}
    |             ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = -1.some(4);
@@ -104,7 +104,7 @@ error: expected a pattern, found an expression
 LL |     if let (-1.Some(4)) = (0, Some(4)) {}
    |             ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = -1.Some(4);
diff --git a/tests/ui/parser/recover/recover-pat-lets.stderr b/tests/ui/parser/recover/recover-pat-lets.stderr
index b481813b24621..55252729d7baa 100644
--- a/tests/ui/parser/recover/recover-pat-lets.stderr
+++ b/tests/ui/parser/recover/recover-pat-lets.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let x.expect("foo");
    |         ^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-lets.rs:7:9
@@ -12,7 +12,7 @@ error: expected a pattern, found an expression
 LL |     let x.unwrap(): u32;
    |         ^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-lets.rs:10:9
@@ -20,7 +20,7 @@ error: expected a pattern, found an expression
 LL |     let x[0] = 1;
    |         ^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: expected a pattern, found an expression
   --> $DIR/recover-pat-lets.rs:13:14
@@ -28,7 +28,7 @@ error: expected a pattern, found an expression
 LL |     let Some(1 + 1) = x else {
    |              ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 + 1;
@@ -45,7 +45,7 @@ error: expected a pattern, found an expression
 LL |     if let Some(1 + 1) = x {
    |                 ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 + 1;
diff --git a/tests/ui/parser/recover/recover-pat-ranges.stderr b/tests/ui/parser/recover/recover-pat-ranges.stderr
index 0a9b54474689a..e8f323596d0fa 100644
--- a/tests/ui/parser/recover/recover-pat-ranges.stderr
+++ b/tests/ui/parser/recover/recover-pat-ranges.stderr
@@ -88,7 +88,7 @@ error: expected a pattern range bound, found an expression
 LL |         ..=1 + 2 => (),
    |            ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 + 2;
@@ -109,7 +109,7 @@ error: expected a pattern range bound, found an expression
 LL |         (-4 + 0).. => (),
    |          ^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = -4 + 0;
@@ -130,7 +130,7 @@ error: expected a pattern range bound, found an expression
 LL |         (1 + 4)...1 * 2 => (),
    |          ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 + 4;
@@ -151,7 +151,7 @@ error: expected a pattern range bound, found an expression
 LL |         (1 + 4)...1 * 2 => (),
    |                   ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 1 * 2;
@@ -172,7 +172,7 @@ error: expected a pattern range bound, found an expression
 LL |         0.x()..="y".z() => (),
    |         ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 0.x();
@@ -193,7 +193,7 @@ error: expected a pattern range bound, found an expression
 LL |         0.x()..="y".z() => (),
    |                 ^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = "y".z();
diff --git a/tests/ui/parser/recover/recover-pat-wildcards.stderr b/tests/ui/parser/recover/recover-pat-wildcards.stderr
index 8d4212ed389dd..81a9920f6a243 100644
--- a/tests/ui/parser/recover/recover-pat-wildcards.stderr
+++ b/tests/ui/parser/recover/recover-pat-wildcards.stderr
@@ -77,7 +77,7 @@ error: expected a pattern range bound, found an expression
 LL |         4..=(2 + _) => ()
    |              ^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 help: consider extracting the expression into a `const`
    |
 LL +     const VAL: /* Type */ = 2 + _;
diff --git a/tests/ui/parser/recover/recover-range-pats.stderr b/tests/ui/parser/recover/recover-range-pats.stderr
index b8e91c2344aff..5c134bd4a82ab 100644
--- a/tests/ui/parser/recover/recover-range-pats.stderr
+++ b/tests/ui/parser/recover/recover-range-pats.stderr
@@ -613,7 +613,7 @@ LL |     mac2!(0, 1);
    |     ----------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -627,7 +627,7 @@ LL |     mac2!(0, 1);
    |     ----------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -641,7 +641,7 @@ LL |     mac2!(0, 1);
    |     ----------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -655,7 +655,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -669,7 +669,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -683,7 +683,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -697,7 +697,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -711,7 +711,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -725,7 +725,7 @@ LL |     mac!(0);
    |     ------- in this macro invocation
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/tests/ui/pattern/fn-in-pat.stderr b/tests/ui/pattern/fn-in-pat.stderr
index 41ea4df72a2ff..90b1dff32ce56 100644
--- a/tests/ui/pattern/fn-in-pat.stderr
+++ b/tests/ui/pattern/fn-in-pat.stderr
@@ -4,7 +4,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated function
 LL |         A::new() => (),
    |         ^^^^^^^^ `fn` calls are not allowed in patterns
    |
-   = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+   = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/pattern/issue-106552.stderr b/tests/ui/pattern/issue-106552.stderr
index 96f3d68458fa4..6d9a989f182ea 100644
--- a/tests/ui/pattern/issue-106552.stderr
+++ b/tests/ui/pattern/issue-106552.stderr
@@ -5,7 +5,7 @@ LL |     let 5 = 6;
    |         ^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
@@ -23,7 +23,7 @@ LL |     let x @ 5 = 6;
    |         ^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `let else` to handle the variants that aren't matched
    |
diff --git a/tests/ui/pattern/pattern-binding-disambiguation.stderr b/tests/ui/pattern/pattern-binding-disambiguation.stderr
index 61c32b6a17bdf..3ba63b4d253c4 100644
--- a/tests/ui/pattern/pattern-binding-disambiguation.stderr
+++ b/tests/ui/pattern/pattern-binding-disambiguation.stderr
@@ -87,7 +87,7 @@ LL |     let UnitVariant = UnitVariant;
    |         ^^^^^^^^^^^ patterns `E::TupleVariant` and `E::BracedVariant {  }` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `E` defined here
   --> $DIR/pattern-binding-disambiguation.rs:5:6
    |
diff --git a/tests/ui/pattern/self-ctor-133272.rs b/tests/ui/pattern/self-ctor-133272.rs
new file mode 100644
index 0000000000000..ad64d6b88cd91
--- /dev/null
+++ b/tests/ui/pattern/self-ctor-133272.rs
@@ -0,0 +1,21 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/133272>, where a `ref Self` ctor
+//! makes it possible to hit a `delayed_bug` that was converted into a `span_bug` in
+//! <https://github.com/rust-lang/rust/pull/121208>, and hitting this reveals that we did not have
+//! test coverage for this specific code pattern (heh) previously.
+//!
+//! # References
+//!
+//! - ICE bug report: <https://github.com/rust-lang/rust/issues/133272>.
+//! - Previous PR to change `delayed_bug` -> `span_bug`:
+//!   <https://github.com/rust-lang/rust/pull/121208>
+#![crate_type = "lib"]
+
+struct Foo;
+
+impl Foo {
+    fn fun() {
+        let S { ref Self } = todo!();
+        //~^ ERROR expected identifier, found keyword `Self`
+        //~| ERROR cannot find struct, variant or union type `S` in this scope
+    }
+}
diff --git a/tests/ui/pattern/self-ctor-133272.stderr b/tests/ui/pattern/self-ctor-133272.stderr
new file mode 100644
index 0000000000000..bca55a43d9c08
--- /dev/null
+++ b/tests/ui/pattern/self-ctor-133272.stderr
@@ -0,0 +1,15 @@
+error: expected identifier, found keyword `Self`
+  --> $DIR/self-ctor-133272.rs:17:21
+   |
+LL |         let S { ref Self } = todo!();
+   |                     ^^^^ expected identifier, found keyword
+
+error[E0422]: cannot find struct, variant or union type `S` in this scope
+  --> $DIR/self-ctor-133272.rs:17:13
+   |
+LL |         let S { ref Self } = todo!();
+   |             ^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0422`.
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
index ec08e22e2ca07..4a435bcc8bad9 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
@@ -54,7 +54,7 @@ LL |     let None = *x;
    |         ^^^^ pattern `Some(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: pattern `Some(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
    = note: the matched value is of type `Option<SecretlyUninhabitedForeignStruct>`
 help: you might want to use `if let` to ignore the variant that isn't matched
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
index ec08e22e2ca07..4a435bcc8bad9 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
@@ -54,7 +54,7 @@ LL |     let None = *x;
    |         ^^^^ pattern `Some(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: pattern `Some(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
    = note: the matched value is of type `Option<SecretlyUninhabitedForeignStruct>`
 help: you might want to use `if let` to ignore the variant that isn't matched
diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
index c6e41c1875fa7..23821decd6e43 100644
--- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr
@@ -150,7 +150,7 @@ LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<&u32, &!>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
index 2e5511527d59c..cf37bf67e860b 100644
--- a/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.min_exh_pats.stderr
@@ -126,7 +126,7 @@ LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<&u32, &!>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -140,7 +140,7 @@ LL |     let Ok(_x) = &res_u32_never;
    |         ^^^^^^ pattern `&Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&Result<u32, !>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
index 3f312d46c7ee8..84aefe7d96370 100644
--- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr
@@ -104,7 +104,7 @@ LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<&u32, &!>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -118,7 +118,7 @@ LL |     let Ok(_x) = &res_u32_never;
    |         ^^^^^^ pattern `&Err(!)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&Result<u32, !>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -239,7 +239,7 @@ LL |         let Ok(_) = *ptr_result_never_err;
    |             ^^^^^ pattern `Err(!)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<u8, !>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr
index bba50dab27b04..f3af74c16c30f 100644
--- a/tests/ui/pattern/usefulness/empty-types.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr
@@ -95,7 +95,7 @@ LL |     let Ok(_x) = res_u32_never.as_ref();
    |         ^^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<&u32, &!>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -109,7 +109,7 @@ LL |     let Ok(_x) = &res_u32_never;
    |         ^^^^^^ pattern `&Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `&Result<u32, !>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
@@ -230,7 +230,7 @@ LL |         let Ok(_) = *ptr_result_never_err;
    |             ^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<u8, !>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
diff --git a/tests/ui/pattern/usefulness/issue-31561.stderr b/tests/ui/pattern/usefulness/issue-31561.stderr
index cc72056582844..ba7ae3fa9a003 100644
--- a/tests/ui/pattern/usefulness/issue-31561.stderr
+++ b/tests/ui/pattern/usefulness/issue-31561.stderr
@@ -5,7 +5,7 @@ LL |     let Thing::Foo(y) = Thing::Foo(1);
    |         ^^^^^^^^^^^^^ patterns `Thing::Bar` and `Thing::Baz` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Thing` defined here
   --> $DIR/issue-31561.rs:1:6
    |
diff --git a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs
index 1d1ea8e496466..d0a8a10f2f371 100644
--- a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs
+++ b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.rs
@@ -44,7 +44,7 @@ fn by_val(e: E) {
     //~^ ERROR refutable pattern in local binding
     //~| patterns `E::B` and `E::C` not covered
     //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
-    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
     //~| NOTE the matched value is of type `E`
 }
 
@@ -60,7 +60,7 @@ fn by_ref_once(e: &E) {
     //~^ ERROR refutable pattern in local binding
     //~| patterns `&E::B` and `&E::C` not covered
     //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
-    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
     //~| NOTE the matched value is of type `&E`
 }
 
@@ -76,7 +76,7 @@ fn by_ref_thrice(e: & &mut &E) {
     //~^ ERROR refutable pattern in local binding
     //~| patterns `&&mut &E::B` and `&&mut &E::C` not covered
     //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
-    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
     //~| NOTE the matched value is of type `&&mut &E`
 }
 
@@ -103,7 +103,7 @@ fn ref_pat(e: Opt) {
     //~| NOTE the matched value is of type `Opt`
     //~| NOTE pattern `Opt::None` not covered
     //~| NOTE `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with
-    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+    //~| NOTE for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 }
 
 fn main() {}
diff --git a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
index a9e55fa53a68e..48d7a636055dc 100644
--- a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
+++ b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
@@ -29,7 +29,7 @@ LL |     let E::A = e;
    |         ^^^^ patterns `E::B` and `E::C` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `E` defined here
   --> $DIR/non-exhaustive-defined-here.rs:8:6
    |
@@ -78,7 +78,7 @@ LL |     let E::A = e;
    |         ^^^^ patterns `&E::B` and `&E::C` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `E` defined here
   --> $DIR/non-exhaustive-defined-here.rs:8:6
    |
@@ -127,7 +127,7 @@ LL |     let E::A = e;
    |         ^^^^ patterns `&&mut &E::B` and `&&mut &E::C` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `E` defined here
   --> $DIR/non-exhaustive-defined-here.rs:8:6
    |
@@ -173,7 +173,7 @@ LL |     let Opt::Some(ref _x) = e;
    |         ^^^^^^^^^^^^^^^^^ pattern `Opt::None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Opt` defined here
   --> $DIR/non-exhaustive-defined-here.rs:83:6
    |
diff --git a/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr b/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr
index e66cd11302387..23a5d895d6c1a 100644
--- a/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr
+++ b/tests/ui/pattern/usefulness/refutable-pattern-errors.stderr
@@ -13,7 +13,7 @@ LL |     let (1, (Some(1), 2..=3)) = (1, (None, 2));
    |         ^^^^^^^^^^^^^^^^^^^^^ patterns `(i32::MIN..=0_i32, _)` and `(2_i32..=i32::MAX, _)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `(i32, (Option<i32>, i32))`
 help: you might want to use `if let` to ignore the variants that aren't matched
    |
diff --git a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr
index 5abec88eeff00..35d436a1413ed 100644
--- a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr
+++ b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr
@@ -5,7 +5,7 @@ LL |     let Ok(x) = res;
    |         ^^^^^ pattern `Err(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `Result<u32, &R<'_>>`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/resolve/issue-10200.stderr b/tests/ui/resolve/issue-10200.stderr
index 172d016c6e6c4..4b6d9b6f1dfa6 100644
--- a/tests/ui/resolve/issue-10200.stderr
+++ b/tests/ui/resolve/issue-10200.stderr
@@ -7,7 +7,7 @@ LL | struct Foo(bool);
 LL |         foo(x)
    |         ^^^ help: a tuple struct with a similar name exists (notice the capitalization): `Foo`
    |
-   = note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr
index 1037033c4b74b..f89ae241f44bc 100644
--- a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr
+++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr
@@ -136,7 +136,7 @@ LL |     let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit
    |         ^^^^^^^^^^^^^^^ pattern `_` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `NonExhaustiveEnum`
 help: you might want to use `let else` to handle the variant that isn't matched
    |
diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr
index d40e98224355b..eec2f5b42fda9 100644
--- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr
+++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr
@@ -4,7 +4,7 @@ error: expected a pattern, found an expression
 LL |     let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes;
    |                               ^^^^^^^^^^^^^^^^^^ not a pattern
    |
-   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch18-00-patterns.html>
+   = note: arbitrary expressions are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
 
 error[E0412]: cannot find type `T` in this scope
   --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:55
diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs
index a7487b8aecb9c..d11ec79833217 100644
--- a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs
+++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs
@@ -17,7 +17,6 @@ impl<T, D> MyTrait<T> for D {
 }
 
 impl<T> MyTrait<T> for BadStruct {
-//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct`
     fn foo() {}
 }
 
diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr
index 13f6ae0805dad..0ecec03a023eb 100644
--- a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr
+++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr
@@ -4,16 +4,6 @@ error[E0412]: cannot find type `MissingType` in this scope
 LL |     err: MissingType
    |          ^^^^^^^^^^^ not found in this scope
 
-error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `BadStruct`
-  --> $DIR/issue-68830-spurious-diagnostics.rs:19:1
-   |
-LL | impl<T, D> MyTrait<T> for D {
-   | --------------------------- first implementation here
-...
-LL | impl<T> MyTrait<T> for BadStruct {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0119, E0412.
-For more information about an error, try `rustc --explain E0119`.
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
index a275d8e4e8397..4f92d3aceefe0 100644
--- a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
+++ b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
@@ -8,7 +8,7 @@ LL |     const A: i32 = 2;
    |     ------------ missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
    = note: the matched value is of type `i32`
 help: introduce a variable instead
    |
diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs
index a08407683d8fe..85c70a21f6839 100644
--- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs
+++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs
@@ -1,5 +1,6 @@
 fn function<T: PartialEq>() {
     foo == 2; //~ ERROR cannot find value `foo` in this scope [E0425]
+    //~^ ERROR mismatched types
 }
 
 fn main() {}
diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr
index 2da731dcc4b14..8010c0842ba97 100644
--- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr
+++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr
@@ -4,6 +4,18 @@ error[E0425]: cannot find value `foo` in this scope
 LL |     foo == 2;
    |     ^^^ not found in this scope
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs:2:12
+   |
+LL | fn function<T: PartialEq>() {
+   |             - expected this type parameter
+LL |     foo == 2;
+   |            ^ expected type parameter `T`, found integer
+   |
+   = note: expected type parameter `T`
+                        found type `{integer}`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0425`.
+Some errors have detailed explanations: E0308, E0425.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/issue-78372.rs b/tests/ui/traits/issue-78372.rs
index 82b13cc0b6238..f03baf2ceca36 100644
--- a/tests/ui/traits/issue-78372.rs
+++ b/tests/ui/traits/issue-78372.rs
@@ -10,5 +10,4 @@ trait X<T> {
 }
 trait Marker {}
 impl Marker for dyn Foo {}
-//~^ ERROR cannot be made into an object
 fn main() {}
diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr
index 4cc2c59fd8dc5..86234d15a5d4b 100644
--- a/tests/ui/traits/issue-78372.stderr
+++ b/tests/ui/traits/issue-78372.stderr
@@ -55,24 +55,6 @@ LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
    = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/issue-78372.rs:12:17
-   |
-LL |     fn foo(self: Smaht<Self, T>);
-   |                  -------------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
-...
-LL | impl Marker for dyn Foo {}
-   |                 ^^^^^^^ `Foo` cannot be made into an object
-   |
-note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
-  --> $DIR/issue-78372.rs:9:18
-   |
-LL | trait Foo: X<u32> {}
-   |       --- this trait cannot be made into an object...
-LL | trait X<T> {
-LL |     fn foo(self: Smaht<Self, T>);
-   |                  ^^^^^^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
-
 error[E0307]: invalid `self` parameter type: `Smaht<Self, T>`
   --> $DIR/issue-78372.rs:9:18
    |
@@ -88,7 +70,7 @@ error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion
 LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0038, E0307, E0378, E0412, E0658.
-For more information about an error, try `rustc --explain E0038`.
+Some errors have detailed explanations: E0307, E0378, E0412, E0658.
+For more information about an error, try `rustc --explain E0307`.
diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs
index 3af299e5b115a..4aadd45c49c1e 100644
--- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs
+++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs
@@ -10,6 +10,7 @@ fn w<'a, T: 'a, F: Fn(&'a T)>() {
     let b: &dyn FromResidual = &();
     //~^ ERROR: the trait `FromResidual` cannot be made into an object
     //~| ERROR: the trait `FromResidual` cannot be made into an object
+    //~| ERROR: the trait `FromResidual` cannot be made into an object
 }
 
 fn main() {}
diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
index 960802e2f8f82..c67a8c05379cd 100644
--- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
+++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr
@@ -6,6 +6,29 @@ LL |     let b: &dyn FromResidual = &();
    |
    = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause
 
+error[E0038]: the trait `FromResidual` cannot be made into an object
+  --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32
+   |
+LL |     let b: &dyn FromResidual = &();
+   |                                ^^^ `FromResidual` cannot be made into an object
+   |
+note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:2:8
+   |
+LL | trait FromResidual<R = <Self as Try>::Residual> {
+   |       ------------ this trait cannot be made into an object...
+LL |     fn from_residual(residual: R) -> Self;
+   |        ^^^^^^^^^^^^^ ...because associated function `from_residual` has no `self` parameter
+   = note: required for the cast from `&()` to `&dyn FromResidual<{type error}>`
+help: consider turning `from_residual` into a method by giving it a `&self` argument
+   |
+LL |     fn from_residual(&self, residual: R) -> Self;
+   |                      ++++++
+help: alternatively, consider constraining `from_residual` so it does not apply to trait objects
+   |
+LL |     fn from_residual(residual: R) -> Self where Self: Sized;
+   |                                           +++++++++++++++++
+
 error[E0038]: the trait `FromResidual` cannot be made into an object
   --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:12
    |
@@ -28,6 +51,6 @@ help: alternatively, consider constraining `from_residual` so it does not apply
 LL |     fn from_residual(residual: R) -> Self where Self: Sized;
    |                                           +++++++++++++++++
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/traits/span-bug-issue-121414.rs b/tests/ui/traits/span-bug-issue-121414.rs
index ec38d8c2de6a6..2f4ad34f0c858 100644
--- a/tests/ui/traits/span-bug-issue-121414.rs
+++ b/tests/ui/traits/span-bug-issue-121414.rs
@@ -6,8 +6,7 @@ impl<'a> Bar for Foo<'f> { //~ ERROR undeclared lifetime
     type Type = u32;
 }
 
-fn test() //~ ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied
-          //~| ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied
+fn test()
 where
     for<'a> <Foo<'a> as Bar>::Type: Sized,
 {
diff --git a/tests/ui/traits/span-bug-issue-121414.stderr b/tests/ui/traits/span-bug-issue-121414.stderr
index e2ef6672cd57a..744806a341506 100644
--- a/tests/ui/traits/span-bug-issue-121414.stderr
+++ b/tests/ui/traits/span-bug-issue-121414.stderr
@@ -6,22 +6,6 @@ LL | impl<'a> Bar for Foo<'f> {
    |      |
    |      help: consider introducing lifetime `'f` here: `'f,`
 
-error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied
-  --> $DIR/span-bug-issue-121414.rs:9:1
-   |
-LL | / fn test()
-LL | |
-LL | | where
-LL | |     for<'a> <Foo<'a> as Bar>::Type: Sized,
-   | |__________________________________________^ the trait `for<'a> Bar` is not implemented for `Foo<'a>`
-
-error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied
-  --> $DIR/span-bug-issue-121414.rs:9:4
-   |
-LL | fn test()
-   |    ^^^^ the trait `for<'a> Bar` is not implemented for `Foo<'a>`
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0261, E0277.
-For more information about an error, try `rustc --explain E0261`.
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
new file mode 100644
index 0000000000000..18cfb1c1f93be
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
@@ -0,0 +1,21 @@
+// regression test for #127353
+
+#![feature(type_alias_impl_trait)]
+trait Trait<T> {}
+type Alias<'a, U> = impl Trait<U>;
+//~^ ERROR unconstrained opaque type
+
+pub enum UninhabitedVariants {
+    Tuple(Alias),
+    //~^ ERROR missing lifetime specifier
+    //~| ERROR missing generics
+    //~| ERROR non-defining opaque type use in defining scope
+}
+
+fn uwu(x: UninhabitedVariants) {
+    //~^ ERROR item does not constrain
+    match x {}
+    //~^ ERROR non-exhaustive patterns
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr
new file mode 100644
index 0000000000000..cf366c55ea816
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr
@@ -0,0 +1,86 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/bad-tait-no-substs.rs:9:11
+   |
+LL |     Tuple(Alias),
+   |           ^^^^^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL ~ pub enum UninhabitedVariants<'a> {
+LL ~     Tuple(Alias<'a>),
+   |
+
+error[E0107]: missing generics for type alias `Alias`
+  --> $DIR/bad-tait-no-substs.rs:9:11
+   |
+LL |     Tuple(Alias),
+   |           ^^^^^ expected 1 generic argument
+   |
+note: type alias defined here, with 1 generic parameter: `U`
+  --> $DIR/bad-tait-no-substs.rs:5:6
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |      ^^^^^     -
+help: add missing generic argument
+   |
+LL |     Tuple(Alias<U>),
+   |                +++
+
+error[E0792]: non-defining opaque type use in defining scope
+  --> $DIR/bad-tait-no-substs.rs:9:11
+   |
+LL |     Tuple(Alias),
+   |           ^^^^^ argument `'_` is not a generic parameter
+   |
+note: for this opaque type
+  --> $DIR/bad-tait-no-substs.rs:5:21
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |                     ^^^^^^^^^^^^^
+
+error: item does not constrain `Alias::{opaque#0}`, but has it in its signature
+  --> $DIR/bad-tait-no-substs.rs:15:4
+   |
+LL | fn uwu(x: UninhabitedVariants) {
+   |    ^^^
+   |
+   = note: consider moving the opaque type's declaration and defining uses into a separate module
+note: this opaque type is in the signature
+  --> $DIR/bad-tait-no-substs.rs:5:21
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |                     ^^^^^^^^^^^^^
+
+error: unconstrained opaque type
+  --> $DIR/bad-tait-no-substs.rs:5:21
+   |
+LL | type Alias<'a, U> = impl Trait<U>;
+   |                     ^^^^^^^^^^^^^
+   |
+   = note: `Alias` must be used in combination with a concrete type within the same module
+
+error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` not covered
+  --> $DIR/bad-tait-no-substs.rs:17:11
+   |
+LL |     match x {}
+   |           ^ pattern `UninhabitedVariants::Tuple(_)` not covered
+   |
+note: `UninhabitedVariants` defined here
+  --> $DIR/bad-tait-no-substs.rs:8:10
+   |
+LL | pub enum UninhabitedVariants {
+   |          ^^^^^^^^^^^^^^^^^^^
+LL |     Tuple(Alias),
+   |     ----- not covered
+   = note: the matched value is of type `UninhabitedVariants`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+   |
+LL ~     match x {
+LL +         UninhabitedVariants::Tuple(_) => todo!(),
+LL +     }
+   |
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0004, E0106, E0107, E0792.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs
new file mode 100644
index 0000000000000..8314b28eeac4b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs
@@ -0,0 +1,22 @@
+// regression test for rust-lang/rust#125758
+
+#![feature(impl_trait_in_assoc_type)]
+
+trait Trait {
+    type Assoc2;
+}
+
+struct Bar;
+impl Trait for Bar {
+    type Assoc2 = impl std::fmt::Debug;
+    //~^ ERROR unconstrained opaque type
+}
+
+struct Foo {
+    field: <Bar as Trait>::Assoc2,
+}
+
+static BAR: u8 = 42;
+static FOO2: &Foo = unsafe { std::mem::transmute(&BAR) };
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr
new file mode 100644
index 0000000000000..6cbf6c83ff4ce
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+  --> $DIR/bad-transmute-itiat.rs:11:19
+   |
+LL |     type Assoc2 = impl std::fmt::Debug;
+   |                   ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Assoc2` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 1 previous error
+
diff --git a/tests/crashes/130956.rs b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs
similarity index 88%
rename from tests/crashes/130956.rs
rename to tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs
index ebb986d123f91..4332f1264a80b 100644
--- a/tests/crashes/130956.rs
+++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs
@@ -1,8 +1,11 @@
-//@ known-bug: #130956
+// Regression test for #130956
+
+#![feature(type_alias_impl_trait)]
 
 mod impl_trait_mod {
     use super::*;
     pub type OpaqueBlock = impl Trait;
+    //~^ ERROR unconstrained opaque type
     pub type OpaqueIf = impl Trait;
 
     pub struct BlockWrapper(OpaqueBlock);
diff --git a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr
new file mode 100644
index 0000000000000..8e5838d5ddf55
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+  --> $DIR/drop-analysis-on-unconstrained-tait.rs:7:28
+   |
+LL |     pub type OpaqueBlock = impl Trait;
+   |                            ^^^^^^^^^^
+   |
+   = note: `OpaqueBlock` must be used in combination with a concrete type within the same module
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr
index 50f33607c06f5..0e87f14aa14ae 100644
--- a/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr
+++ b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr
@@ -5,7 +5,7 @@ LL |     let Foo::D(_y, _z) = x;
    |         ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Foo` defined here
   --> $DIR/uninhabited-irrefutable.rs:19:6
    |
diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr
index bc1a9fa41915a..67527ce1ac452 100644
--- a/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr
+++ b/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr
@@ -5,7 +5,7 @@ LL |     let Foo::D(_y, _z) = x;
    |         ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Foo` defined here
   --> $DIR/uninhabited-irrefutable.rs:20:6
    |
diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr
index 50f33607c06f5..0e87f14aa14ae 100644
--- a/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr
+++ b/tests/ui/uninhabited/uninhabited-irrefutable.normal.stderr
@@ -5,7 +5,7 @@ LL |     let Foo::D(_y, _z) = x;
    |         ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
 note: `Foo` defined here
   --> $DIR/uninhabited-irrefutable.rs:19:6
    |
diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
index e6d4e2ee01a27..0be5127dcc4da 100644
--- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
+++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
@@ -14,5 +14,4 @@ impl Trait for Ref {} //~ ERROR:  implicit elided lifetime not allowed here
 
 extern "C" {
     pub fn repro(_: Wrapper<Ref>);
-    //~^ ERROR the trait bound `Ref<'_>: Trait` is not satisfied
 }
diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
index 59b55b2732d30..0af4ab022e1eb 100644
--- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
+++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
@@ -9,19 +9,6 @@ help: indicate the anonymous lifetime
 LL | impl Trait for Ref<'_> {}
    |                   ++++
 
-error[E0277]: the trait bound `Ref<'_>: Trait` is not satisfied
-  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21
-   |
-LL |     pub fn repro(_: Wrapper<Ref>);
-   |                     ^^^^^^^^^^^^ the trait `Trait` is not implemented for `Ref<'_>`
-   |
-note: required by a bound in `Wrapper`
-  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23
-   |
-LL | pub struct Wrapper<T: Trait>(T);
-   |                       ^^^^^ required by this bound in `Wrapper`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0726.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0726`.