about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2024-03-31 05:40:36 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2024-03-31 05:40:36 +0000
commiteb8e8c06b6c6ab90b6ecbed1ac3820304c53ef01 (patch)
tree70ea36b7fd5f777449cc0622edc1f960490a2747
parent2dd824789c34d059ad787fc65ad15ffc668c895e (diff)
parent5baf1e13f568b61e121953bf6a3d09faee7dd446 (diff)
downloadrust-eb8e8c06b6c6ab90b6ecbed1ac3820304c53ef01.tar.gz
rust-eb8e8c06b6c6ab90b6ecbed1ac3820304c53ef01.zip
Merge from rustc
-rw-r--r--compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch4
-rw-r--r--compiler/rustc_data_structures/src/tagged_ptr/copy.rs1
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs160
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs47
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs13
-rw-r--r--compiler/rustc_lint/src/lints.rs18
-rw-r--r--compiler/rustc_lint/src/types.rs38
-rw-r--r--compiler/rustc_middle/src/ty/region.rs4
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs7
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs14
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs89
-rw-r--r--compiler/rustc_session/messages.ftl2
-rw-r--r--compiler/rustc_session/src/errors.rs4
-rw-r--r--compiler/rustc_session/src/session.rs5
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs153
-rw-r--r--compiler/rustc_type_ir/src/fold.rs51
-rw-r--r--compiler/rustc_type_ir/src/interner.rs13
-rw-r--r--compiler/rustc_type_ir/src/new.rs2
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/tests/lib.rs2
-rw-r--r--library/core/src/any.rs8
-rw-r--r--library/core/src/clone.rs2
-rw-r--r--library/core/src/cmp.rs4
-rw-r--r--library/core/src/default.rs4
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/marker.rs2
-rw-r--r--library/core/src/num/error.rs3
-rw-r--r--library/core/src/num/int_macros.rs26
-rw-r--r--library/core/src/num/mod.rs293
-rw-r--r--library/core/src/num/nonzero.rs3
-rw-r--r--library/core/src/num/uint_macros.rs27
-rw-r--r--library/core/src/ptr/const_ptr.rs17
-rw-r--r--library/core/src/ptr/metadata.rs2
-rw-r--r--library/core/src/ptr/mut_ptr.rs17
-rw-r--r--library/core/src/ptr/non_null.rs16
-rw-r--r--library/core/src/sync/atomic.rs12
-rw-r--r--library/core/tests/lib.rs3
-rw-r--r--library/core/tests/num/mod.rs10
-rw-r--r--library/core/tests/ptr.rs10
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--src/tools/compiletest/src/lib.rs4
-rw-r--r--src/tools/miri/tests/pass-dep/shims/posix_memalign.rs2
-rw-r--r--tests/assembly/is_aligned.rs2
-rw-r--r--tests/mir-opt/building/match/deref-patterns/string.foo.PreCodegen.after.mir (renamed from tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir)0
-rw-r--r--tests/mir-opt/building/match/deref-patterns/string.rs (renamed from tests/mir-opt/deref-patterns/string.rs)0
-rw-r--r--tests/mir-opt/building/match/exponential_or.match_tuple.SimplifyCfg-initial.after.mir (renamed from tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir)0
-rw-r--r--tests/mir-opt/building/match/exponential_or.rs (renamed from tests/mir-opt/exponential_or.rs)0
-rw-r--r--tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir (renamed from tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir)0
-rw-r--r--tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir (renamed from tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir)0
-rw-r--r--tests/mir-opt/building/match/match_false_edges.main.built.after.mir (renamed from tests/mir-opt/building/match_false_edges.main.built.after.mir)0
-rw-r--r--tests/mir-opt/building/match/match_false_edges.rs (renamed from tests/mir-opt/building/match_false_edges.rs)0
-rw-r--r--tests/mir-opt/building/match/simple_match.match_bool.built.after.mir (renamed from tests/mir-opt/building/simple_match.match_bool.built.after.mir)0
-rw-r--r--tests/mir-opt/building/match/simple_match.rs (renamed from tests/mir-opt/building/simple_match.rs)0
-rw-r--r--tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir118
-rw-r--r--tests/mir-opt/building/match/sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir88
-rw-r--r--tests/mir-opt/building/match/sort_candidates.rs41
-rw-r--r--tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir106
-rw-r--r--tests/mir-opt/match_test.rs19
-rw-r--r--tests/ui/attributes/unix_sigpipe/auxiliary/assert-sigpipe-disposition.rs34
-rw-r--r--tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs56
-rw-r--r--tests/ui/binop/binary-op-suggest-deref.stderr6
-rw-r--r--tests/ui/coherence/negative-coherence/regions-in-canonical.rs23
-rw-r--r--tests/ui/coherence/negative-coherence/regions-in-canonical.stderr11
-rw-r--r--tests/ui/compiletest-self-test/test-aux-bin.rs2
-rw-r--r--tests/ui/consts/const-eval/parse_ints.rs10
-rw-r--r--tests/ui/consts/const-eval/parse_ints.stderr31
-rw-r--r--tests/ui/lint/wide_pointer_comparisons.rs12
-rw-r--r--tests/ui/lint/wide_pointer_comparisons.stderr135
-rw-r--r--tests/ui/mir/alignment/packed.rs2
-rw-r--r--tests/ui/mismatched_types/binops.stderr12
-rw-r--r--tests/ui/sanitizer/cfg.rs1
-rw-r--r--tests/ui/sanitizer/cfi-async-closures.rs33
-rw-r--r--tests/ui/sanitizer/cfi-closure-fn-ptr-cast.rs22
-rw-r--r--tests/ui/sanitizer/cfi-closures.rs83
-rw-r--r--tests/ui/sanitizer/cfi-complex-receiver.rs1
-rw-r--r--tests/ui/sanitizer/cfi-coroutine.rs30
-rw-r--r--tests/ui/sanitizer/cfi-self-ref.rs1
-rw-r--r--tests/ui/sanitizer/cfi-supertraits.rs73
-rw-r--r--tests/ui/sanitizer/cfi-virtual-auto.rs1
-rw-r--r--tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs7
-rw-r--r--tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr36
-rw-r--r--tests/ui/structs-enums/type-sizes.rs2
83 files changed, 1385 insertions, 713 deletions
diff --git a/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
index 914ae986b50..36d0789d2a2 100644
--- a/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
+++ b/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch
@@ -14,7 +14,7 @@ index d0a119c..76fdece 100644
 @@ -89,7 +89,6 @@
  #![feature(never_type)]
  #![feature(unwrap_infallible)]
- #![feature(pointer_is_aligned)]
+ #![feature(pointer_is_aligned_to)]
 -#![feature(portable_simd)]
  #![feature(ptr_metadata)]
  #![feature(lazy_cell)]
@@ -27,6 +27,6 @@ index d0a119c..76fdece 100644
  mod slice;
  mod str;
  mod str_lossy;
--- 
+--
 2.42.1
 
diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
index ff4208def31..8b9e834b60b 100644
--- a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
+++ b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs
@@ -243,6 +243,7 @@ where
     T: Tag,
 {
     #[inline]
+    #[allow(ambiguous_wide_pointer_comparisons)]
     fn eq(&self, other: &Self) -> bool {
         self.packed == other.packed
     }
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 9bf4d63267a..d8a90d62dac 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -295,6 +295,8 @@ hir_analysis_not_supported_delegation =
     {$descr} is not supported yet
     .label = callee defined here
 
+hir_analysis_only_current_traits_adt = `{$name}` is not defined in the current crate
+
 hir_analysis_only_current_traits_arbitrary = only traits defined in the current crate can be implemented for arbitrary types
 
 hir_analysis_only_current_traits_foreign = this is not defined in the current crate because this is a foreign trait
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index ca8a635ab5e..1770f7b4e91 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -4,7 +4,7 @@
 use crate::errors;
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir as hir;
-use rustc_middle::ty::{self, AliasKind, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, AliasKind, TyCtxt, TypeVisitableExt};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
 use rustc_trait_selection::traits::{self, IsFirstInputType};
@@ -283,9 +283,14 @@ fn emit_orphan_check_error<'tcx>(
     let self_ty = trait_ref.self_ty();
     Err(match err {
         traits::OrphanCheckErr::NonLocalInputType(tys) => {
-            let (mut opaque, mut foreign, mut name, mut pointer, mut ty_diag) =
-                (Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new());
-            let mut sugg = None;
+            let mut diag = tcx.dcx().create_err(match self_ty.kind() {
+                ty::Adt(..) => errors::OnlyCurrentTraits::Outside { span: sp, note: () },
+                _ if self_ty.is_primitive() => {
+                    errors::OnlyCurrentTraits::Primitive { span: sp, note: () }
+                }
+                _ => errors::OnlyCurrentTraits::Arbitrary { span: sp, note: () },
+            });
+
             for &(mut ty, is_target_ty) in &tys {
                 let span = if matches!(is_target_ty, IsFirstInputType::Yes) {
                     // Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
@@ -296,113 +301,86 @@ fn emit_orphan_check_error<'tcx>(
                 };
 
                 ty = tcx.erase_regions(ty);
-                ty = match ty.kind() {
-                    // Remove the type arguments from the output, as they are not relevant.
-                    // You can think of this as the reverse of `resolve_vars_if_possible`.
-                    // That way if we had `Vec<MyType>`, we will properly attribute the
-                    // problem to `Vec<T>` and avoid confusing the user if they were to see
-                    // `MyType` in the error.
-                    ty::Adt(def, _) => Ty::new_adt(tcx, *def, ty::List::empty()),
-                    _ => ty,
-                };
-
-                fn push_to_foreign_or_name<'tcx>(
-                    is_foreign: bool,
-                    foreign: &mut Vec<errors::OnlyCurrentTraitsForeign>,
-                    name: &mut Vec<errors::OnlyCurrentTraitsName<'tcx>>,
-                    span: Span,
-                    sname: &'tcx str,
-                ) {
-                    if is_foreign {
-                        foreign.push(errors::OnlyCurrentTraitsForeign { span })
-                    } else {
-                        name.push(errors::OnlyCurrentTraitsName { span, name: sname });
-                    }
-                }
 
                 let is_foreign =
                     !trait_ref.def_id.is_local() && matches!(is_target_ty, IsFirstInputType::No);
 
                 match *ty.kind() {
                     ty::Slice(_) => {
-                        push_to_foreign_or_name(
-                            is_foreign,
-                            &mut foreign,
-                            &mut name,
-                            span,
-                            "slices",
-                        );
+                        if is_foreign {
+                            diag.subdiagnostic(
+                                tcx.dcx(),
+                                errors::OnlyCurrentTraitsForeign { span },
+                            );
+                        } else {
+                            diag.subdiagnostic(
+                                tcx.dcx(),
+                                errors::OnlyCurrentTraitsName { span, name: "slices" },
+                            );
+                        }
                     }
                     ty::Array(..) => {
-                        push_to_foreign_or_name(
-                            is_foreign,
-                            &mut foreign,
-                            &mut name,
-                            span,
-                            "arrays",
-                        );
+                        if is_foreign {
+                            diag.subdiagnostic(
+                                tcx.dcx(),
+                                errors::OnlyCurrentTraitsForeign { span },
+                            );
+                        } else {
+                            diag.subdiagnostic(
+                                tcx.dcx(),
+                                errors::OnlyCurrentTraitsName { span, name: "arrays" },
+                            );
+                        }
                     }
                     ty::Tuple(..) => {
-                        push_to_foreign_or_name(
-                            is_foreign,
-                            &mut foreign,
-                            &mut name,
-                            span,
-                            "tuples",
-                        );
+                        if is_foreign {
+                            diag.subdiagnostic(
+                                tcx.dcx(),
+                                errors::OnlyCurrentTraitsForeign { span },
+                            );
+                        } else {
+                            diag.subdiagnostic(
+                                tcx.dcx(),
+                                errors::OnlyCurrentTraitsName { span, name: "tuples" },
+                            );
+                        }
                     }
                     ty::Alias(ty::Opaque, ..) => {
-                        opaque.push(errors::OnlyCurrentTraitsOpaque { span })
+                        diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsOpaque { span });
                     }
                     ty::RawPtr(ptr_ty, mutbl) => {
                         if !self_ty.has_param() {
-                            let mut_key = mutbl.prefix_str();
-                            sugg = Some(errors::OnlyCurrentTraitsPointerSugg {
-                                wrapper_span: self_ty_span,
-                                struct_span: full_impl_span.shrink_to_lo(),
-                                mut_key,
-                                ptr_ty,
-                            });
+                            diag.subdiagnostic(
+                                tcx.dcx(),
+                                errors::OnlyCurrentTraitsPointerSugg {
+                                    wrapper_span: self_ty_span,
+                                    struct_span: full_impl_span.shrink_to_lo(),
+                                    mut_key: mutbl.prefix_str(),
+                                    ptr_ty,
+                                },
+                            );
                         }
-                        pointer.push(errors::OnlyCurrentTraitsPointer { span, pointer: ty });
+                        diag.subdiagnostic(
+                            tcx.dcx(),
+                            errors::OnlyCurrentTraitsPointer { span, pointer: ty },
+                        );
+                    }
+                    ty::Adt(adt_def, _) => {
+                        diag.subdiagnostic(
+                            tcx.dcx(),
+                            errors::OnlyCurrentTraitsAdt {
+                                span,
+                                name: tcx.def_path_str(adt_def.did()),
+                            },
+                        );
+                    }
+                    _ => {
+                        diag.subdiagnostic(tcx.dcx(), errors::OnlyCurrentTraitsTy { span, ty });
                     }
-                    _ => ty_diag.push(errors::OnlyCurrentTraitsTy { span, ty }),
                 }
             }
 
-            let err_struct = match self_ty.kind() {
-                ty::Adt(..) => errors::OnlyCurrentTraits::Outside {
-                    span: sp,
-                    note: (),
-                    opaque,
-                    foreign,
-                    name,
-                    pointer,
-                    ty: ty_diag,
-                    sugg,
-                },
-                _ if self_ty.is_primitive() => errors::OnlyCurrentTraits::Primitive {
-                    span: sp,
-                    note: (),
-                    opaque,
-                    foreign,
-                    name,
-                    pointer,
-                    ty: ty_diag,
-                    sugg,
-                },
-                _ => errors::OnlyCurrentTraits::Arbitrary {
-                    span: sp,
-                    note: (),
-                    opaque,
-                    foreign,
-                    name,
-                    pointer,
-                    ty: ty_diag,
-                    sugg,
-                },
-            };
-            tcx.dcx().emit_err(err_struct)
+            diag.emit()
         }
         traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => {
             let mut sp = sp;
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index fb919714afd..2d4742fa1dc 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1376,7 +1376,7 @@ pub struct TyParamSome<'a> {
 }
 
 #[derive(Diagnostic)]
-pub enum OnlyCurrentTraits<'a> {
+pub enum OnlyCurrentTraits {
     #[diag(hir_analysis_only_current_traits_outside, code = E0117)]
     Outside {
         #[primary_span]
@@ -1384,18 +1384,6 @@ pub enum OnlyCurrentTraits<'a> {
         span: Span,
         #[note(hir_analysis_only_current_traits_note)]
         note: (),
-        #[subdiagnostic]
-        opaque: Vec<OnlyCurrentTraitsOpaque>,
-        #[subdiagnostic]
-        foreign: Vec<OnlyCurrentTraitsForeign>,
-        #[subdiagnostic]
-        name: Vec<OnlyCurrentTraitsName<'a>>,
-        #[subdiagnostic]
-        pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
-        #[subdiagnostic]
-        ty: Vec<OnlyCurrentTraitsTy<'a>>,
-        #[subdiagnostic]
-        sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
     },
     #[diag(hir_analysis_only_current_traits_primitive, code = E0117)]
     Primitive {
@@ -1404,18 +1392,6 @@ pub enum OnlyCurrentTraits<'a> {
         span: Span,
         #[note(hir_analysis_only_current_traits_note)]
         note: (),
-        #[subdiagnostic]
-        opaque: Vec<OnlyCurrentTraitsOpaque>,
-        #[subdiagnostic]
-        foreign: Vec<OnlyCurrentTraitsForeign>,
-        #[subdiagnostic]
-        name: Vec<OnlyCurrentTraitsName<'a>>,
-        #[subdiagnostic]
-        pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
-        #[subdiagnostic]
-        ty: Vec<OnlyCurrentTraitsTy<'a>>,
-        #[subdiagnostic]
-        sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
     },
     #[diag(hir_analysis_only_current_traits_arbitrary, code = E0117)]
     Arbitrary {
@@ -1424,18 +1400,6 @@ pub enum OnlyCurrentTraits<'a> {
         span: Span,
         #[note(hir_analysis_only_current_traits_note)]
         note: (),
-        #[subdiagnostic]
-        opaque: Vec<OnlyCurrentTraitsOpaque>,
-        #[subdiagnostic]
-        foreign: Vec<OnlyCurrentTraitsForeign>,
-        #[subdiagnostic]
-        name: Vec<OnlyCurrentTraitsName<'a>>,
-        #[subdiagnostic]
-        pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
-        #[subdiagnostic]
-        ty: Vec<OnlyCurrentTraitsTy<'a>>,
-        #[subdiagnostic]
-        sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
     },
 }
 
@@ -1445,7 +1409,6 @@ pub struct OnlyCurrentTraitsOpaque {
     #[primary_span]
     pub span: Span,
 }
-
 #[derive(Subdiagnostic)]
 #[label(hir_analysis_only_current_traits_foreign)]
 pub struct OnlyCurrentTraitsForeign {
@@ -1478,6 +1441,14 @@ pub struct OnlyCurrentTraitsTy<'a> {
 }
 
 #[derive(Subdiagnostic)]
+#[label(hir_analysis_only_current_traits_adt)]
+pub struct OnlyCurrentTraitsAdt {
+    #[primary_span]
+    pub span: Span,
+    pub name: String,
+}
+
+#[derive(Subdiagnostic)]
 #[multipart_suggestion(
     hir_analysis_only_current_traits_pointer_sugg,
     applicability = "maybe-incorrect"
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index ebc5e11a561..8ea1a88be5d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1916,18 +1916,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat: &'tcx hir::Pat<'tcx>,
         ty: Ty<'tcx>,
     ) {
-        struct V<'tcx> {
-            tcx: TyCtxt<'tcx>,
+        struct V {
             pat_hir_ids: Vec<hir::HirId>,
         }
 
-        impl<'tcx> Visitor<'tcx> for V<'tcx> {
-            type NestedFilter = rustc_middle::hir::nested_filter::All;
-
-            fn nested_visit_map(&mut self) -> Self::Map {
-                self.tcx.hir()
-            }
-
+        impl<'tcx> Visitor<'tcx> for V {
             fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) {
                 self.pat_hir_ids.push(p.hir_id);
                 hir::intravisit::walk_pat(self, p);
@@ -1938,7 +1931,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let err = Ty::new_error(self.tcx, guar);
             self.write_ty(hir_id, err);
             self.write_ty(pat.hir_id, err);
-            let mut visitor = V { tcx: self.tcx, pat_hir_ids: vec![] };
+            let mut visitor = V { pat_hir_ids: vec![] };
             hir::intravisit::walk_pat(&mut visitor, pat);
             // Mark all the subpatterns as `{type error}` as well. This allows errors for specific
             // subpatterns to be silenced.
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index cf3890dc61c..a034bebc85e 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1632,11 +1632,13 @@ pub struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> {
     pub ne: &'a str,
     pub deref_left: &'a str,
     pub deref_right: &'a str,
+    pub l_modifiers: &'a str,
+    pub r_modifiers: &'a str,
     #[suggestion_part(code = "{ne}std::ptr::eq({deref_left}")]
     pub left: Span,
-    #[suggestion_part(code = ", {deref_right}")]
+    #[suggestion_part(code = "{l_modifiers}, {deref_right}")]
     pub middle: Span,
-    #[suggestion_part(code = ")")]
+    #[suggestion_part(code = "{r_modifiers})")]
     pub right: Span,
 }
 
@@ -1652,11 +1654,13 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
         ne: &'a str,
         deref_left: &'a str,
         deref_right: &'a str,
+        l_modifiers: &'a str,
+        r_modifiers: &'a str,
         #[suggestion_part(code = "{ne}std::ptr::addr_eq({deref_left}")]
         left: Span,
-        #[suggestion_part(code = ", {deref_right}")]
+        #[suggestion_part(code = "{l_modifiers}, {deref_right}")]
         middle: Span,
-        #[suggestion_part(code = ")")]
+        #[suggestion_part(code = "{r_modifiers})")]
         right: Span,
     },
     #[multipart_suggestion(
@@ -1670,13 +1674,15 @@ pub enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
         deref_right: &'a str,
         paren_left: &'a str,
         paren_right: &'a str,
+        l_modifiers: &'a str,
+        r_modifiers: &'a str,
         #[suggestion_part(code = "({deref_left}")]
         left_before: Option<Span>,
-        #[suggestion_part(code = "{paren_left}.cast::<()>()")]
+        #[suggestion_part(code = "{l_modifiers}{paren_left}.cast::<()>()")]
         left_after: Span,
         #[suggestion_part(code = "({deref_right}")]
         right_before: Option<Span>,
-        #[suggestion_part(code = "{paren_right}.cast::<()>()")]
+        #[suggestion_part(code = "{r_modifiers}{paren_right}.cast::<()>()")]
         right_after: Span,
     },
 }
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 68cc024d9c7..534eb60eeb0 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -670,7 +670,11 @@ fn lint_wide_pointer<'tcx>(
     l: &'tcx hir::Expr<'tcx>,
     r: &'tcx hir::Expr<'tcx>,
 ) {
-    let ptr_unsized = |mut ty: Ty<'tcx>| -> Option<(usize, bool)> {
+    let ptr_unsized = |mut ty: Ty<'tcx>| -> Option<(
+        /* number of refs */ usize,
+        /* modifiers */ String,
+        /* is dyn */ bool,
+    )> {
         let mut refs = 0;
         // here we remove any "implicit" references and count the number
         // of them to correctly suggest the right number of deref
@@ -678,11 +682,20 @@ fn lint_wide_pointer<'tcx>(
             ty = *inner_ty;
             refs += 1;
         }
-        match ty.kind() {
-            ty::RawPtr(ty, _) => (!ty.is_sized(cx.tcx, cx.param_env))
-                .then(|| (refs, matches!(ty.kind(), ty::Dynamic(_, _, ty::Dyn)))),
-            _ => None,
-        }
+
+        // get the inner type of a pointer (or akin)
+        let mut modifiers = String::new();
+        ty = match ty.kind() {
+            ty::RawPtr(ty, _) => *ty,
+            ty::Adt(def, args) if cx.tcx.is_diagnostic_item(sym::NonNull, def.did()) => {
+                modifiers.push_str(".as_ptr()");
+                args.type_at(0)
+            }
+            _ => return None,
+        };
+
+        (!ty.is_sized(cx.tcx, cx.param_env))
+            .then(|| (refs, modifiers, matches!(ty.kind(), ty::Dynamic(_, _, ty::Dyn))))
     };
 
     // the left and right operands can have references, remove any explicit references
@@ -696,10 +709,10 @@ fn lint_wide_pointer<'tcx>(
         return;
     };
 
-    let Some((l_ty_refs, l_inner_ty_is_dyn)) = ptr_unsized(l_ty) else {
+    let Some((l_ty_refs, l_modifiers, l_inner_ty_is_dyn)) = ptr_unsized(l_ty) else {
         return;
     };
-    let Some((r_ty_refs, r_inner_ty_is_dyn)) = ptr_unsized(r_ty) else {
+    let Some((r_ty_refs, r_modifiers, r_inner_ty_is_dyn)) = ptr_unsized(r_ty) else {
         return;
     };
 
@@ -724,6 +737,9 @@ fn lint_wide_pointer<'tcx>(
     let deref_left = &*"*".repeat(l_ty_refs);
     let deref_right = &*"*".repeat(r_ty_refs);
 
+    let l_modifiers = &*l_modifiers;
+    let r_modifiers = &*r_modifiers;
+
     cx.emit_span_lint(
         AMBIGUOUS_WIDE_POINTER_COMPARISONS,
         e.span,
@@ -733,6 +749,8 @@ fn lint_wide_pointer<'tcx>(
                     ne,
                     deref_left,
                     deref_right,
+                    l_modifiers,
+                    r_modifiers,
                     left,
                     middle,
                     right,
@@ -743,6 +761,8 @@ fn lint_wide_pointer<'tcx>(
                     ne,
                     deref_left,
                     deref_right,
+                    l_modifiers,
+                    r_modifiers,
                     left,
                     middle,
                     right,
@@ -751,6 +771,8 @@ fn lint_wide_pointer<'tcx>(
                 AmbiguousWidePointerComparisonsAddrSuggestion::Cast {
                     deref_left,
                     deref_right,
+                    l_modifiers,
+                    r_modifiers,
                     paren_left: if l_ty_refs != 0 { ")" } else { "" },
                     paren_right: if r_ty_refs != 0 { ")" } else { "" },
                     left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()),
diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs
index 867faf63261..b92800a1728 100644
--- a/compiler/rustc_middle/src/ty/region.rs
+++ b/compiler/rustc_middle/src/ty/region.rs
@@ -140,6 +140,10 @@ impl<'tcx> rustc_type_ir::new::Region<TyCtxt<'tcx>> for Region<'tcx> {
     fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
         Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
     }
+
+    fn new_static(tcx: TyCtxt<'tcx>) -> Self {
+        tcx.lifetimes.re_static
+    }
 }
 
 /// Region utilities
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 57a675e4453..b5e619f1e2a 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1624,6 +1624,13 @@ impl<'tcx> Ty<'tcx> {
 
     #[inline]
     pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
+        debug_assert_eq!(
+            tcx.generics_of(def.did()).count(),
+            args.len(),
+            "wrong number of args for ADT: {:#?} vs {:#?}",
+            tcx.generics_of(def.did()).params,
+            args
+        );
         Ty::new(tcx, Adt(def, args))
     }
 
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index b66dd83b7ec..690879b9488 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -650,12 +650,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 }
             }
 
-            // FIXME(#29623): return `Some(1)` when the values are different.
-            (TestKind::Eq { value: test_val, .. }, TestCase::Constant { value: case_val })
-                if test_val == case_val =>
-            {
-                fully_matched = true;
-                Some(TestBranch::Success)
+            (TestKind::Eq { value: test_val, .. }, TestCase::Constant { value: case_val }) => {
+                if test_val == case_val {
+                    fully_matched = true;
+                    Some(TestBranch::Success)
+                } else {
+                    fully_matched = false;
+                    Some(TestBranch::Failure)
+                }
             }
 
             (
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index 16d8453ea24..1899517c0e2 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -296,10 +296,7 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
         Region::new_anon_bound(self.interner(), self.binder_index, var)
     }
 
-    fn fold_ty(&mut self, t: I::Ty) -> I::Ty
-    where
-        I::Ty: TypeSuperFoldable<I>,
-    {
+    fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
         let kind = match t.kind() {
             ty::Infer(i) => match i {
                 ty::TyVar(vid) => {
@@ -378,47 +375,48 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
         Ty::new_anon_bound(self.interner(), self.binder_index, var)
     }
 
-    fn fold_const(&mut self, c: I::Const) -> I::Const
-    where
-        I::Const: TypeSuperFoldable<I>,
-    {
+    fn fold_const(&mut self, c: I::Const) -> I::Const {
+        // We could canonicalize all consts with static types, but the only ones we
+        // *really* need to worry about are the ones that we end up putting into `CanonicalVarKind`
+        // since canonical vars can't reference other canonical vars.
+        let ty = c
+            .ty()
+            .fold_with(&mut RegionsToStatic { interner: self.interner(), binder: ty::INNERMOST });
         let kind = match c.kind() {
-            ty::ConstKind::Infer(i) => {
-                // FIXME: we should fold the ty too eventually
-                match i {
-                    ty::InferConst::Var(vid) => {
-                        assert_eq!(
-                            self.infcx.root_ct_var(vid),
-                            vid,
-                            "region vid should have been resolved fully before canonicalization"
-                        );
-                        assert_eq!(
-                            self.infcx.probe_ct_var(vid),
-                            None,
-                            "region vid should have been resolved fully before canonicalization"
-                        );
-                        CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), c.ty())
-                    }
-                    ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
-                    ty::InferConst::Fresh(_) => todo!(),
+            ty::ConstKind::Infer(i) => match i {
+                ty::InferConst::Var(vid) => {
+                    assert_eq!(
+                        self.infcx.root_ct_var(vid),
+                        vid,
+                        "region vid should have been resolved fully before canonicalization"
+                    );
+                    assert_eq!(
+                        self.infcx.probe_ct_var(vid),
+                        None,
+                        "region vid should have been resolved fully before canonicalization"
+                    );
+                    CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), ty)
                 }
-            }
+                ty::InferConst::EffectVar(_) => CanonicalVarKind::Effect,
+                ty::InferConst::Fresh(_) => todo!(),
+            },
             ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode {
                 CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
                     PlaceholderLike::new(placeholder.universe(), self.variables.len().into()),
-                    c.ty(),
+                    ty,
                 ),
                 CanonicalizeMode::Response { .. } => {
-                    CanonicalVarKind::PlaceholderConst(placeholder, c.ty())
+                    CanonicalVarKind::PlaceholderConst(placeholder, ty)
                 }
             },
             ty::ConstKind::Param(_) => match self.canonicalize_mode {
                 CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst(
                     PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()),
-                    c.ty(),
+                    ty,
                 ),
                 CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"),
             },
+            // FIXME: See comment above -- we could fold the region separately or something.
             ty::ConstKind::Bound(_, _)
             | ty::ConstKind::Unevaluated(_)
             | ty::ConstKind::Value(_)
@@ -435,6 +433,35 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
             }),
         );
 
-        Const::new_anon_bound(self.interner(), self.binder_index, var, c.ty())
+        Const::new_anon_bound(self.interner(), self.binder_index, var, ty)
+    }
+}
+
+struct RegionsToStatic<I> {
+    interner: I,
+    binder: ty::DebruijnIndex,
+}
+
+impl<I: Interner> TypeFolder<I> for RegionsToStatic<I> {
+    fn interner(&self) -> I {
+        self.interner
+    }
+
+    fn fold_binder<T>(&mut self, t: I::Binder<T>) -> I::Binder<T>
+    where
+        T: TypeFoldable<I>,
+        I::Binder<T>: TypeSuperFoldable<I>,
+    {
+        self.binder.shift_in(1);
+        let t = t.fold_with(self);
+        self.binder.shift_out(1);
+        t
+    }
+
+    fn fold_region(&mut self, r: I::Region) -> I::Region {
+        match r.kind() {
+            ty::ReBound(db, _) if self.binder > db => r,
+            _ => Region::new_static(self.interner()),
+        }
     }
 }
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index 179fd79bef7..b8dacc6968d 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -96,6 +96,8 @@ session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Cli
 
 session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
 
+session_sanitizer_kcfi_requires_panic_abort = `-Z sanitizer=kcfi` requires `-C panic=abort`
+
 session_sanitizer_not_supported = {$us} sanitizer is not supported for this target
 
 session_sanitizers_not_supported = {$us} sanitizers are not supported for this target
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index 0a855f87586..2e4c7d14ecd 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -146,6 +146,10 @@ pub(crate) struct SanitizerCfiGeneralizePointersRequiresCfi;
 pub(crate) struct SanitizerCfiNormalizeIntegersRequiresCfi;
 
 #[derive(Diagnostic)]
+#[diag(session_sanitizer_kcfi_requires_panic_abort)]
+pub(crate) struct SanitizerKcfiRequiresPanicAbort;
+
+#[derive(Diagnostic)]
 #[diag(session_split_lto_unit_requires_lto)]
 pub(crate) struct SplitLtoUnitRequiresLto;
 
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 85428303382..55fff4421ae 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1211,6 +1211,11 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
         sess.dcx().emit_err(errors::SanitizerCfiRequiresLto);
     }
 
+    // KCFI requires panic=abort
+    if sess.is_sanitizer_kcfi_enabled() && sess.panic_strategy() != PanicStrategy::Abort {
+        sess.dcx().emit_err(errors::SanitizerKcfiRequiresPanicAbort);
+    }
+
     // LLVM CFI using rustc LTO requires a single codegen unit.
     if sess.is_sanitizer_cfi_enabled()
         && sess.lto() == config::Lto::Fat
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index 7fd5cfeb48b..5963bd7c5f1 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -10,6 +10,7 @@
 use rustc_data_structures::base_n;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
+use rustc_hir::lang_items::LangItem;
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{
@@ -641,9 +642,7 @@ fn encode_ty<'tcx>(
         }
 
         // Function types
-        ty::FnDef(def_id, args)
-        | ty::Closure(def_id, args)
-        | ty::CoroutineClosure(def_id, args) => {
+        ty::FnDef(def_id, args) | ty::Closure(def_id, args) => {
             // u<length><name>[I<element-type1..element-typeN>E], where <element-type> is <subst>,
             // as vendor extended type.
             let mut s = String::new();
@@ -654,6 +653,18 @@ fn encode_ty<'tcx>(
             typeid.push_str(&s);
         }
 
+        ty::CoroutineClosure(def_id, args) => {
+            // u<length><name>[I<element-type1..element-typeN>E], where <element-type> is <subst>,
+            // as vendor extended type.
+            let mut s = String::new();
+            let name = encode_ty_name(tcx, *def_id);
+            let _ = write!(s, "u{}{}", name.len(), &name);
+            let parent_args = tcx.mk_args(args.as_coroutine_closure().parent_args());
+            s.push_str(&encode_args(tcx, parent_args, dict, options));
+            compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
+            typeid.push_str(&s);
+        }
+
         ty::Coroutine(def_id, args, ..) => {
             // u<length><name>[I<element-type1..element-typeN>E], where <element-type> is <subst>,
             // as vendor extended type.
@@ -1140,45 +1151,102 @@ pub fn typeid_for_instance<'tcx>(
         let predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(predicate)]);
         let self_ty = Ty::new_dynamic(tcx, predicates, tcx.lifetimes.re_erased, ty::Dyn);
         instance.args = tcx.mk_args_trait(self_ty, List::empty());
-    } else if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
-        instance.args = strip_receiver_auto(tcx, instance.args);
+    } else if let ty::InstanceDef::Virtual(def_id, _) = instance.def {
+        let upcast_ty = match tcx.trait_of_item(def_id) {
+            Some(trait_id) => trait_object_ty(
+                tcx,
+                ty::Binder::dummy(ty::TraitRef::from_method(tcx, trait_id, instance.args)),
+            ),
+            // drop_in_place won't have a defining trait, skip the upcast
+            None => instance.args.type_at(0),
+        };
+        let stripped_ty = strip_receiver_auto(tcx, upcast_ty);
+        instance.args = tcx.mk_args_trait(stripped_ty, instance.args.into_iter().skip(1));
+    } else if let ty::InstanceDef::VTableShim(def_id) = instance.def
+        && let Some(trait_id) = tcx.trait_of_item(def_id)
+    {
+        // VTableShims may have a trait method, but a concrete Self. This is not suitable for a vtable,
+        // as the caller will not know the concrete Self.
+        let trait_ref = ty::TraitRef::new(tcx, trait_id, instance.args);
+        let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
+        instance.args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
     }
 
-    if !options.contains(EncodeTyOptions::NO_SELF_TYPE_ERASURE)
-        && let Some(impl_id) = tcx.impl_of_method(instance.def_id())
-        && let Some(trait_ref) = tcx.impl_trait_ref(impl_id)
-    {
-        let impl_method = tcx.associated_item(instance.def_id());
-        let method_id = impl_method
-            .trait_item_def_id
-            .expect("Part of a trait implementation, but not linked to the def_id?");
-        let trait_method = tcx.associated_item(method_id);
-        let trait_id = trait_ref.skip_binder().def_id;
-        if traits::is_vtable_safe_method(tcx, trait_id, trait_method)
-            && tcx.object_safety_violations(trait_id).is_empty()
+    if !options.contains(EncodeTyOptions::NO_SELF_TYPE_ERASURE) {
+        if let Some(impl_id) = tcx.impl_of_method(instance.def_id())
+            && let Some(trait_ref) = tcx.impl_trait_ref(impl_id)
         {
-            // Trait methods will have a Self polymorphic parameter, where the concreteized
-            // implementatation will not. We need to walk back to the more general trait method
-            let trait_ref = tcx.instantiate_and_normalize_erasing_regions(
-                instance.args,
-                ty::ParamEnv::reveal_all(),
-                trait_ref,
-            );
+            let impl_method = tcx.associated_item(instance.def_id());
+            let method_id = impl_method
+                .trait_item_def_id
+                .expect("Part of a trait implementation, but not linked to the def_id?");
+            let trait_method = tcx.associated_item(method_id);
+            let trait_id = trait_ref.skip_binder().def_id;
+            if traits::is_vtable_safe_method(tcx, trait_id, trait_method)
+                && tcx.object_safety_violations(trait_id).is_empty()
+            {
+                // Trait methods will have a Self polymorphic parameter, where the concreteized
+                // implementatation will not. We need to walk back to the more general trait method
+                let trait_ref = tcx.instantiate_and_normalize_erasing_regions(
+                    instance.args,
+                    ty::ParamEnv::reveal_all(),
+                    trait_ref,
+                );
+                let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
+
+                // At the call site, any call to this concrete function through a vtable will be
+                // `Virtual(method_id, idx)` with appropriate arguments for the method. Since we have the
+                // original method id, and we've recovered the trait arguments, we can make the callee
+                // instance we're computing the alias set for match the caller instance.
+                //
+                // Right now, our code ignores the vtable index everywhere, so we use 0 as a placeholder.
+                // If we ever *do* start encoding the vtable index, we will need to generate an alias set
+                // based on which vtables we are putting this method into, as there will be more than one
+                // index value when supertraits are involved.
+                instance.def = ty::InstanceDef::Virtual(method_id, 0);
+                let abstract_trait_args =
+                    tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
+                instance.args = instance.args.rebase_onto(tcx, impl_id, abstract_trait_args);
+            }
+        } else if tcx.is_closure_like(instance.def_id()) {
+            // We're either a closure or a coroutine. Our goal is to find the trait we're defined on,
+            // instantiate it, and take the type of its only method as our own.
+            let closure_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
+            let (trait_id, inputs) = match closure_ty.kind() {
+                ty::Closure(..) => {
+                    let closure_args = instance.args.as_closure();
+                    let trait_id = tcx.fn_trait_kind_to_def_id(closure_args.kind()).unwrap();
+                    let tuple_args =
+                        tcx.instantiate_bound_regions_with_erased(closure_args.sig()).inputs()[0];
+                    (trait_id, tuple_args)
+                }
+                ty::Coroutine(..) => (
+                    tcx.require_lang_item(LangItem::Coroutine, None),
+                    instance.args.as_coroutine().resume_ty(),
+                ),
+                ty::CoroutineClosure(..) => (
+                    tcx.require_lang_item(LangItem::FnOnce, None),
+                    tcx.instantiate_bound_regions_with_erased(
+                        instance.args.as_coroutine_closure().coroutine_closure_sig(),
+                    )
+                    .tupled_inputs_ty,
+                ),
+                x => bug!("Unexpected type kind for closure-like: {x:?}"),
+            };
+            let trait_ref = ty::TraitRef::new(tcx, trait_id, [closure_ty, inputs]);
             let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
+            let abstract_args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
+            // There should be exactly one method on this trait, and it should be the one we're
+            // defining.
+            let call = tcx
+                .associated_items(trait_id)
+                .in_definition_order()
+                .find(|it| it.kind == ty::AssocKind::Fn)
+                .expect("No call-family function on closure-like Fn trait?")
+                .def_id;
 
-            // At the call site, any call to this concrete function through a vtable will be
-            // `Virtual(method_id, idx)` with appropriate arguments for the method. Since we have the
-            // original method id, and we've recovered the trait arguments, we can make the callee
-            // instance we're computing the alias set for match the caller instance.
-            //
-            // Right now, our code ignores the vtable index everywhere, so we use 0 as a placeholder.
-            // If we ever *do* start encoding the vtable index, we will need to generate an alias set
-            // based on which vtables we are putting this method into, as there will be more than one
-            // index value when supertraits are involved.
-            instance.def = ty::InstanceDef::Virtual(method_id, 0);
-            let abstract_trait_args =
-                tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
-            instance.args = instance.args.rebase_onto(tcx, impl_id, abstract_trait_args);
+            instance.def = ty::InstanceDef::Virtual(call, 0);
+            instance.args = abstract_args;
         }
     }
 
@@ -1191,15 +1259,11 @@ pub fn typeid_for_instance<'tcx>(
     typeid_for_fnabi(tcx, fn_abi, options)
 }
 
-fn strip_receiver_auto<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    args: ty::GenericArgsRef<'tcx>,
-) -> ty::GenericArgsRef<'tcx> {
-    let ty = args.type_at(0);
+fn strip_receiver_auto<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     let ty::Dynamic(preds, lifetime, kind) = ty.kind() else {
         bug!("Tried to strip auto traits from non-dynamic type {ty}");
     };
-    let new_rcvr = if preds.principal().is_some() {
+    if preds.principal().is_some() {
         let filtered_preds =
             tcx.mk_poly_existential_predicates_from_iter(preds.into_iter().filter(|pred| {
                 !matches!(pred.skip_binder(), ty::ExistentialPredicate::AutoTrait(..))
@@ -1210,8 +1274,7 @@ fn strip_receiver_auto<'tcx>(
         // about it. This technically discards the knowledge that it was a type that was made
         // into a trait object at some point, but that's not a lot.
         tcx.types.unit
-    };
-    tcx.mk_args_trait(new_rcvr, args.into_iter().skip(1))
+    }
 }
 
 #[instrument(skip(tcx), ret)]
diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs
index 8d402588398..01bb3d73dbd 100644
--- a/compiler/rustc_type_ir/src/fold.rs
+++ b/compiler/rustc_type_ir/src/fold.rs
@@ -136,31 +136,21 @@ pub trait TypeFolder<I: Interner>: FallibleTypeFolder<I, Error = Never> {
         t.super_fold_with(self)
     }
 
-    fn fold_ty(&mut self, t: I::Ty) -> I::Ty
-    where
-        I::Ty: TypeSuperFoldable<I>,
-    {
+    fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
         t.super_fold_with(self)
     }
 
     // The default region folder is a no-op because `Region` is non-recursive
-    // and has no `super_fold_with` method to call. That also explains the
-    // lack of `I::Region: TypeSuperFoldable<I>` bound on this method.
+    // and has no `super_fold_with` method to call.
     fn fold_region(&mut self, r: I::Region) -> I::Region {
         r
     }
 
-    fn fold_const(&mut self, c: I::Const) -> I::Const
-    where
-        I::Const: TypeSuperFoldable<I>,
-    {
+    fn fold_const(&mut self, c: I::Const) -> I::Const {
         c.super_fold_with(self)
     }
 
-    fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate
-    where
-        I::Predicate: TypeSuperFoldable<I>,
-    {
+    fn fold_predicate(&mut self, p: I::Predicate) -> I::Predicate {
         p.super_fold_with(self)
     }
 }
@@ -185,31 +175,21 @@ pub trait FallibleTypeFolder<I: Interner>: Sized {
         t.try_super_fold_with(self)
     }
 
-    fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, Self::Error>
-    where
-        I::Ty: TypeSuperFoldable<I>,
-    {
+    fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, Self::Error> {
         t.try_super_fold_with(self)
     }
 
     // The default region folder is a no-op because `Region` is non-recursive
-    // and has no `super_fold_with` method to call. That also explains the
-    // lack of `I::Region: TypeSuperFoldable<I>` bound on this method.
+    // and has no `super_fold_with` method to call.
     fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, Self::Error> {
         Ok(r)
     }
 
-    fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Self::Error>
-    where
-        I::Const: TypeSuperFoldable<I>,
-    {
+    fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Self::Error> {
         c.try_super_fold_with(self)
     }
 
-    fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, Self::Error>
-    where
-        I::Predicate: TypeSuperFoldable<I>,
-    {
+    fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, Self::Error> {
         p.try_super_fold_with(self)
     }
 }
@@ -234,10 +214,7 @@ where
         Ok(self.fold_binder(t))
     }
 
-    fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, Never>
-    where
-        I::Ty: TypeSuperFoldable<I>,
-    {
+    fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, Never> {
         Ok(self.fold_ty(t))
     }
 
@@ -245,17 +222,11 @@ where
         Ok(self.fold_region(r))
     }
 
-    fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Never>
-    where
-        I::Const: TypeSuperFoldable<I>,
-    {
+    fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Never> {
         Ok(self.fold_const(c))
     }
 
-    fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, Never>
-    where
-        I::Predicate: TypeSuperFoldable<I>,
-    {
+    fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, Never> {
         Ok(self.fold_predicate(p))
     }
 }
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index ae1e1902f14..7a2885dd3bb 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -2,13 +2,14 @@ use smallvec::SmallVec;
 use std::fmt::Debug;
 use std::hash::Hash;
 
+use crate::fold::TypeSuperFoldable;
 use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
 use crate::{
     new, BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebugWithInfcx, RegionKind, TyKind,
     UniverseIndex,
 };
 
-pub trait Interner: Sized {
+pub trait Interner: Sized + Copy {
     type DefId: Copy + Debug + Hash + Eq;
     type AdtDef: Copy + Debug + Hash + Eq;
 
@@ -34,6 +35,7 @@ pub trait Interner: Sized {
         + Into<Self::GenericArg>
         + IntoKind<Kind = TyKind<Self>>
         + TypeSuperVisitable<Self>
+        + TypeSuperFoldable<Self>
         + Flags
         + new::Ty<Self>;
     type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
@@ -57,6 +59,7 @@ pub trait Interner: Sized {
         + IntoKind<Kind = ConstKind<Self>>
         + ConstTy<Self>
         + TypeSuperVisitable<Self>
+        + TypeSuperFoldable<Self>
         + Flags
         + new::Const<Self>;
     type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
@@ -82,7 +85,13 @@ pub trait Interner: Sized {
     type PlaceholderRegion: Copy + Debug + Hash + Eq + PlaceholderLike;
 
     // Predicates
-    type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
+    type Predicate: Copy
+        + Debug
+        + Hash
+        + Eq
+        + TypeSuperVisitable<Self>
+        + TypeSuperFoldable<Self>
+        + Flags;
     type TraitPredicate: Copy + Debug + Hash + Eq;
     type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
     type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
diff --git a/compiler/rustc_type_ir/src/new.rs b/compiler/rustc_type_ir/src/new.rs
index e7e695e5908..1572a641d06 100644
--- a/compiler/rustc_type_ir/src/new.rs
+++ b/compiler/rustc_type_ir/src/new.rs
@@ -6,6 +6,8 @@ pub trait Ty<I: Interner<Ty = Self>> {
 
 pub trait Region<I: Interner<Region = Self>> {
     fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
+
+    fn new_static(interner: I) -> Self;
 }
 
 pub trait Const<I: Interner<Const = Self>> {
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index b6a9d6005d4..cafd59cb0d9 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -198,7 +198,6 @@
 #![feature(multiple_supertrait_upcastable)]
 #![feature(negative_impls)]
 #![feature(never_type)]
-#![feature(pointer_is_aligned)]
 #![feature(rustc_allow_const_fn_unstable)]
 #![feature(rustc_attrs)]
 #![feature(slice_internals)]
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 04709af5c0a..a34bce66496 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -37,7 +37,7 @@
 #![feature(const_trait_impl)]
 #![feature(const_str_from_utf8)]
 #![feature(panic_update_hook)]
-#![feature(pointer_is_aligned)]
+#![feature(pointer_is_aligned_to)]
 #![feature(slice_flatten)]
 #![feature(thin_box)]
 #![feature(strict_provenance)]
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index a4252d0c9e0..37cb8e7d303 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -40,10 +40,10 @@
 //!
 //! ## Examples
 //!
-//! Consider a situation where we want to log out a value passed to a function.
-//! We know the value we're working on implements Debug, but we don't know its
+//! Consider a situation where we want to log a value passed to a function.
+//! We know the value we're working on implements `Debug`, but we don't know its
 //! concrete type. We want to give special treatment to certain types: in this
-//! case printing out the length of String values prior to their value.
+//! case printing out the length of `String` values prior to their value.
 //! We don't know the concrete type of our value at compile time, so we need to
 //! use runtime reflection instead.
 //!
@@ -51,7 +51,7 @@
 //! use std::fmt::Debug;
 //! use std::any::Any;
 //!
-//! // Logger function for any type that implements Debug.
+//! // Logger function for any type that implements `Debug`.
 //! fn log<T: Any + Debug>(value: &T) {
 //!     let value_any = value as &dyn Any;
 //!
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index ba86334f950..d448c5338fc 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -227,7 +227,7 @@ mod impls {
     impl_clone! {
         usize u8 u16 u32 u64 u128
         isize i8 i16 i32 i64 i128
-        f32 f64
+        f16 f32 f64 f128
         bool char
     }
 
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index cc9ef673da7..b0c5021022f 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -1493,7 +1493,7 @@ mod impls {
     }
 
     partial_eq_impl! {
-        bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
+        bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
     }
 
     macro_rules! eq_impl {
@@ -1546,7 +1546,7 @@ mod impls {
         }
     }
 
-    partial_ord_impl! { f32 f64 }
+    partial_ord_impl! { f16 f32 f64 f128 }
 
     macro_rules! ord_impl {
         ($($t:ty)*) => ($(
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index a5075554682..e717a8d022f 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -178,5 +178,9 @@ default_impl! { i32, 0, "Returns the default value of `0`" }
 default_impl! { i64, 0, "Returns the default value of `0`" }
 default_impl! { i128, 0, "Returns the default value of `0`" }
 
+#[cfg(not(bootstrap))]
+default_impl! { f16, 0.0f16, "Returns the default value of `0.0`" }
 default_impl! { f32, 0.0f32, "Returns the default value of `0.0`" }
 default_impl! { f64, 0.0f64, "Returns the default value of `0.0`" }
+#[cfg(not(bootstrap))]
+default_impl! { f128, 0.0f128, "Returns the default value of `0.0`" }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 18dd3440b6e..0cc3ad1ead7 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -137,6 +137,7 @@
 #![feature(const_heap)]
 #![feature(const_hint_assert_unchecked)]
 #![feature(const_index_range_slice_index)]
+#![feature(const_int_from_str)]
 #![feature(const_intrinsic_copy)]
 #![feature(const_intrinsic_forget)]
 #![feature(const_ipv4)]
@@ -228,6 +229,8 @@
 #![feature(doc_notable_trait)]
 #![feature(effects)]
 #![feature(extern_types)]
+#![feature(f128)]
+#![feature(f16)]
 #![feature(freeze_impls)]
 #![feature(fundamental)]
 #![feature(generic_arg_infer)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index a56a2578c22..385c288db12 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -422,7 +422,7 @@ marker_impls! {
     Copy for
         usize, u8, u16, u32, u64, u128,
         isize, i8, i16, i32, i64, i128,
-        f32, f64,
+        f16, f32, f64, f128,
         bool, char,
         {T: ?Sized} *const T,
         {T: ?Sized} *mut T,
diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs
index 14e99578a7c..a2d7e6f7b07 100644
--- a/library/core/src/num/error.rs
+++ b/library/core/src/num/error.rs
@@ -113,8 +113,9 @@ pub enum IntErrorKind {
 impl ParseIntError {
     /// Outputs the detailed cause of parsing an integer failing.
     #[must_use]
+    #[rustc_const_unstable(feature = "const_int_from_str", issue = "59133")]
     #[stable(feature = "int_error_matching", since = "1.55.0")]
-    pub fn kind(&self) -> &IntErrorKind {
+    pub const fn kind(&self) -> &IntErrorKind {
         &self.kind
     }
 }
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 2fec8ef2381..2f5184da885 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -60,32 +60,6 @@ macro_rules! int_impl {
         #[stable(feature = "int_bits_const", since = "1.53.0")]
         pub const BITS: u32 = <$UnsignedT>::BITS;
 
-        /// Converts a string slice in a given base to an integer.
-        ///
-        /// The string is expected to be an optional `+` or `-` sign followed by digits.
-        /// Leading and trailing whitespace represent an error. Digits are a subset of these characters,
-        /// depending on `radix`:
-        ///
-        ///  * `0-9`
-        ///  * `a-z`
-        ///  * `A-Z`
-        ///
-        /// # Panics
-        ///
-        /// This function panics if `radix` is not in the range from 2 to 36.
-        ///
-        /// # Examples
-        ///
-        /// Basic usage:
-        ///
-        /// ```
-        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));")]
-        /// ```
-        #[stable(feature = "rust1", since = "1.0.0")]
-        pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
-            from_str_radix(src, radix)
-        }
-
         /// Returns the number of ones in the binary representation of `self`.
         ///
         /// # Examples
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 03c977abbbb..9e519dad432 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -6,7 +6,6 @@ use crate::ascii;
 use crate::hint;
 use crate::intrinsics;
 use crate::mem;
-use crate::ops::{Add, Mul, Sub};
 use crate::str::FromStr;
 
 // Used because the `?` operator is not allowed in a const context.
@@ -1386,51 +1385,19 @@ pub enum FpCategory {
     Normal,
 }
 
-#[doc(hidden)]
-trait FromStrRadixHelper:
-    PartialOrd + Copy + Add<Output = Self> + Sub<Output = Self> + Mul<Output = Self>
-{
-    const MIN: Self;
-    fn from_u32(u: u32) -> Self;
-    fn checked_mul(&self, other: u32) -> Option<Self>;
-    fn checked_sub(&self, other: u32) -> Option<Self>;
-    fn checked_add(&self, other: u32) -> Option<Self>;
-}
-
 macro_rules! from_str_radix_int_impl {
     ($($t:ty)*) => {$(
         #[stable(feature = "rust1", since = "1.0.0")]
         impl FromStr for $t {
             type Err = ParseIntError;
             fn from_str(src: &str) -> Result<Self, ParseIntError> {
-                from_str_radix(src, 10)
+                <$t>::from_str_radix(src, 10)
             }
         }
     )*}
 }
 from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
 
-macro_rules! impl_helper_for {
-    ($($t:ty)*) => ($(impl FromStrRadixHelper for $t {
-        const MIN: Self = Self::MIN;
-        #[inline]
-        fn from_u32(u: u32) -> Self { u as Self }
-        #[inline]
-        fn checked_mul(&self, other: u32) -> Option<Self> {
-            Self::checked_mul(*self, other as Self)
-        }
-        #[inline]
-        fn checked_sub(&self, other: u32) -> Option<Self> {
-            Self::checked_sub(*self, other as Self)
-        }
-        #[inline]
-        fn checked_add(&self, other: u32) -> Option<Self> {
-            Self::checked_add(*self, other as Self)
-        }
-    })*)
-}
-impl_helper_for! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
-
 /// Determines if a string of text of that length of that radix could be guaranteed to be
 /// stored in the given type T.
 /// Note that if the radix is known to the compiler, it is just the check of digits.len that
@@ -1438,92 +1405,198 @@ impl_helper_for! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
 #[doc(hidden)]
 #[inline(always)]
 #[unstable(issue = "none", feature = "std_internals")]
-pub fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool {
+pub const fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool {
     radix <= 16 && digits.len() <= mem::size_of::<T>() * 2 - is_signed_ty as usize
 }
 
-fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, ParseIntError> {
-    use self::IntErrorKind::*;
-    use self::ParseIntError as PIE;
+#[track_caller]
+const fn from_str_radix_panic_ct(_radix: u32) -> ! {
+    panic!("from_str_radix_int: must lie in the range `[2, 36]`");
+}
 
-    assert!(
-        (2..=36).contains(&radix),
-        "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
-        radix
-    );
+#[track_caller]
+fn from_str_radix_panic_rt(radix: u32) -> ! {
+    panic!("from_str_radix_int: must lie in the range `[2, 36]` - found {}", radix);
+}
 
-    if src.is_empty() {
-        return Err(PIE { kind: Empty });
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cold]
+#[track_caller]
+const fn from_str_radix_assert(radix: u32) {
+    if 2 > radix || radix > 36 {
+        // The only difference between these two functions is their panic message.
+        intrinsics::const_eval_select((radix,), from_str_radix_panic_ct, from_str_radix_panic_rt);
     }
+}
 
-    let is_signed_ty = T::from_u32(0) > T::MIN;
-
-    // all valid digits are ascii, so we will just iterate over the utf8 bytes
-    // and cast them to chars. .to_digit() will safely return None for anything
-    // other than a valid ascii digit for the given radix, including the first-byte
-    // of multi-byte sequences
-    let src = src.as_bytes();
+macro_rules! from_str_radix {
+    ($($int_ty:ty)+) => {$(
+        impl $int_ty {
+            /// Converts a string slice in a given base to an integer.
+            ///
+            /// The string is expected to be an optional `+` sign
+            /// followed by digits.
+            /// Leading and trailing whitespace represent an error.
+            /// Digits are a subset of these characters, depending on `radix`:
+            ///
+            /// * `0-9`
+            /// * `a-z`
+            /// * `A-Z`
+            ///
+            /// # Panics
+            ///
+            /// This function panics if `radix` is not in the range from 2 to 36.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_str_radix(\"A\", 16), Ok(10));")]
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[rustc_const_unstable(feature = "const_int_from_str", issue = "59133")]
+            pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
+                use self::IntErrorKind::*;
+                use self::ParseIntError as PIE;
+
+                from_str_radix_assert(radix);
+
+                if src.is_empty() {
+                    return Err(PIE { kind: Empty });
+                }
 
-    let (is_positive, digits) = match src[0] {
-        b'+' | b'-' if src[1..].is_empty() => {
-            return Err(PIE { kind: InvalidDigit });
-        }
-        b'+' => (true, &src[1..]),
-        b'-' if is_signed_ty => (false, &src[1..]),
-        _ => (true, src),
-    };
+                #[allow(unused_comparisons)]
+                let is_signed_ty = 0 > <$int_ty>::MIN;
+
+                // all valid digits are ascii, so we will just iterate over the utf8 bytes
+                // and cast them to chars. .to_digit() will safely return None for anything
+                // other than a valid ascii digit for the given radix, including the first-byte
+                // of multi-byte sequences
+                let src = src.as_bytes();
+
+                let (is_positive, mut digits) = match src {
+                    [b'+' | b'-'] => {
+                        return Err(PIE { kind: InvalidDigit });
+                    }
+                    [b'+', rest @ ..] => (true, rest),
+                    [b'-', rest @ ..] if is_signed_ty => (false, rest),
+                    _ => (true, src),
+                };
+
+                let mut result = 0;
+
+                macro_rules! unwrap_or_PIE {
+                    ($option:expr, $kind:ident) => {
+                        match $option {
+                            Some(value) => value,
+                            None => return Err(PIE { kind: $kind }),
+                        }
+                    };
+                }
 
-    let mut result = T::from_u32(0);
-
-    if can_not_overflow::<T>(radix, is_signed_ty, digits) {
-        // If the len of the str is short compared to the range of the type
-        // we are parsing into, then we can be certain that an overflow will not occur.
-        // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
-        // above is a faster (conservative) approximation of this.
-        //
-        // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
-        // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
-        // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
-        macro_rules! run_unchecked_loop {
-            ($unchecked_additive_op:expr) => {
-                for &c in digits {
-                    result = result * T::from_u32(radix);
-                    let x = (c as char).to_digit(radix).ok_or(PIE { kind: InvalidDigit })?;
-                    result = $unchecked_additive_op(result, T::from_u32(x));
+                if can_not_overflow::<$int_ty>(radix, is_signed_ty, digits) {
+                    // If the len of the str is short compared to the range of the type
+                    // we are parsing into, then we can be certain that an overflow will not occur.
+                    // This bound is when `radix.pow(digits.len()) - 1 <= T::MAX` but the condition
+                    // above is a faster (conservative) approximation of this.
+                    //
+                    // Consider radix 16 as it has the highest information density per digit and will thus overflow the earliest:
+                    // `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
+                    // `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
+                    macro_rules! run_unchecked_loop {
+                        ($unchecked_additive_op:tt) => {{
+                            while let [c, rest @ ..] = digits {
+                                result = result * (radix as $int_ty);
+                                let x = unwrap_or_PIE!((*c as char).to_digit(radix), InvalidDigit);
+                                result = result $unchecked_additive_op (x as $int_ty);
+                                digits = rest;
+                            }
+                        }};
+                    }
+                    if is_positive {
+                        run_unchecked_loop!(+)
+                    } else {
+                        run_unchecked_loop!(-)
+                    };
+                } else {
+                    macro_rules! run_checked_loop {
+                        ($checked_additive_op:ident, $overflow_err:ident) => {{
+                            while let [c, rest @ ..] = digits {
+                                // When `radix` is passed in as a literal, rather than doing a slow `imul`
+                                // the compiler can use shifts if `radix` can be expressed as a
+                                // sum of powers of 2 (x*10 can be written as x*8 + x*2).
+                                // When the compiler can't use these optimisations,
+                                // the latency of the multiplication can be hidden by issuing it
+                                // before the result is needed to improve performance on
+                                // modern out-of-order CPU as multiplication here is slower
+                                // than the other instructions, we can get the end result faster
+                                // doing multiplication first and let the CPU spends other cycles
+                                // doing other computation and get multiplication result later.
+                                let mul = result.checked_mul(radix as $int_ty);
+                                let x = unwrap_or_PIE!((*c as char).to_digit(radix), InvalidDigit) as $int_ty;
+                                result = unwrap_or_PIE!(mul, $overflow_err);
+                                result = unwrap_or_PIE!(<$int_ty>::$checked_additive_op(result, x), $overflow_err);
+                                digits = rest;
+                            }
+                        }};
+                    }
+                    if is_positive {
+                        run_checked_loop!(checked_add, PosOverflow)
+                    } else {
+                        run_checked_loop!(checked_sub, NegOverflow)
+                    };
                 }
-            };
+                Ok(result)
+            }
         }
-        if is_positive {
-            run_unchecked_loop!(<T as core::ops::Add>::add)
-        } else {
-            run_unchecked_loop!(<T as core::ops::Sub>::sub)
-        };
-    } else {
-        macro_rules! run_checked_loop {
-            ($checked_additive_op:ident, $overflow_err:expr) => {
-                for &c in digits {
-                    // When `radix` is passed in as a literal, rather than doing a slow `imul`
-                    // the compiler can use shifts if `radix` can be expressed as a
-                    // sum of powers of 2 (x*10 can be written as x*8 + x*2).
-                    // When the compiler can't use these optimisations,
-                    // the latency of the multiplication can be hidden by issuing it
-                    // before the result is needed to improve performance on
-                    // modern out-of-order CPU as multiplication here is slower
-                    // than the other instructions, we can get the end result faster
-                    // doing multiplication first and let the CPU spends other cycles
-                    // doing other computation and get multiplication result later.
-                    let mul = result.checked_mul(radix);
-                    let x = (c as char).to_digit(radix).ok_or(PIE { kind: InvalidDigit })?;
-                    result = mul.ok_or_else($overflow_err)?;
-                    result = T::$checked_additive_op(&result, x).ok_or_else($overflow_err)?;
-                }
-            };
+    )+}
+}
+
+from_str_radix! { i8 u8 i16 u16 i32 u32 i64 u64 i128 u128 }
+
+// Re-use the relevant implementation of from_str_radix for isize and usize to avoid outputting two
+// identical functions.
+macro_rules! from_str_radix_size_impl {
+    ($($t:ident $size:ty),*) => {$(
+    impl $size {
+        /// Converts a string slice in a given base to an integer.
+        ///
+        /// The string is expected to be an optional `+` sign
+        /// followed by digits.
+        /// Leading and trailing whitespace represent an error.
+        /// Digits are a subset of these characters, depending on `radix`:
+        ///
+        /// * `0-9`
+        /// * `a-z`
+        /// * `A-Z`
+        ///
+        /// # Panics
+        ///
+        /// This function panics if `radix` is not in the range from 2 to 36.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        #[doc = concat!("assert_eq!(", stringify!($size), "::from_str_radix(\"A\", 16), Ok(10));")]
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[rustc_const_unstable(feature = "const_int_from_str", issue = "59133")]
+        pub const fn from_str_radix(src: &str, radix: u32) -> Result<$size, ParseIntError> {
+            match <$t>::from_str_radix(src, radix) {
+                Ok(x) => Ok(x as $size),
+                Err(e) => Err(e),
+            }
         }
-        if is_positive {
-            run_checked_loop!(checked_add, || PIE { kind: PosOverflow })
-        } else {
-            run_checked_loop!(checked_sub, || PIE { kind: NegOverflow })
-        };
-    }
-    Ok(result)
+    })*}
 }
+
+#[cfg(target_pointer_width = "16")]
+from_str_radix_size_impl! { i16 isize, u16 usize }
+#[cfg(target_pointer_width = "32")]
+from_str_radix_size_impl! { i32 isize, u32 usize }
+#[cfg(target_pointer_width = "64")]
+from_str_radix_size_impl! { i64 isize, u64 usize }
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 1171407c07a..62ea7abf652 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -11,7 +11,6 @@ use crate::ptr;
 use crate::str::FromStr;
 use crate::ub_checks;
 
-use super::from_str_radix;
 use super::{IntErrorKind, ParseIntError};
 
 /// A marker trait for primitive types which can be zero.
@@ -804,7 +803,7 @@ macro_rules! nonzero_integer {
         impl FromStr for $Ty {
             type Err = ParseIntError;
             fn from_str(src: &str) -> Result<Self, Self::Err> {
-                Self::new(from_str_radix(src, 10)?)
+                Self::new(<$Int>::from_str_radix(src, 10)?)
                     .ok_or(ParseIntError {
                         kind: IntErrorKind::Zero
                     })
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index f76f110fc4e..3f4b5955d62 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -58,33 +58,6 @@ macro_rules! uint_impl {
         #[stable(feature = "int_bits_const", since = "1.53.0")]
         pub const BITS: u32 = Self::MAX.count_ones();
 
-        /// Converts a string slice in a given base to an integer.
-        ///
-        /// The string is expected to be an optional `+` sign
-        /// followed by digits.
-        /// Leading and trailing whitespace represent an error.
-        /// Digits are a subset of these characters, depending on `radix`:
-        ///
-        /// * `0-9`
-        /// * `a-z`
-        /// * `A-Z`
-        ///
-        /// # Panics
-        ///
-        /// This function panics if `radix` is not in the range from 2 to 36.
-        ///
-        /// # Examples
-        ///
-        /// Basic usage:
-        ///
-        /// ```
-        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::from_str_radix(\"A\", 16), Ok(10));")]
-        /// ```
-        #[stable(feature = "rust1", since = "1.0.0")]
-        pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
-            from_str_radix(src, radix)
-        }
-
         /// Returns the number of ones in the binary representation of `self`.
         ///
         /// # Examples
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 68ce80ee321..99bd631b581 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1401,8 +1401,6 @@ impl<T: ?Sized> *const T {
     /// # Examples
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
-    ///
     /// // On some platforms, the alignment of i32 is less than 4.
     /// #[repr(align(4))]
     /// struct AlignedI32(i32);
@@ -1425,7 +1423,6 @@ impl<T: ?Sized> *const T {
     /// underlying allocation.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of primitives is less than their size.
@@ -1451,7 +1448,6 @@ impl<T: ?Sized> *const T {
     /// pointer is aligned, even if the compiletime pointer wasn't aligned.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of primitives is less than their size.
@@ -1477,7 +1473,6 @@ impl<T: ?Sized> *const T {
     /// runtime and compiletime.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of primitives is less than their size.
@@ -1501,7 +1496,7 @@ impl<T: ?Sized> *const T {
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
-    #[unstable(feature = "pointer_is_aligned", issue = "96284")]
+    #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
     pub const fn is_aligned(self) -> bool
     where
@@ -1522,7 +1517,7 @@ impl<T: ?Sized> *const T {
     /// # Examples
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
     /// #[repr(align(4))]
@@ -1551,7 +1546,7 @@ impl<T: ?Sized> *const T {
     /// cannot be stricter aligned than the reference's underlying allocation.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
@@ -1576,7 +1571,7 @@ impl<T: ?Sized> *const T {
     /// pointer is aligned, even if the compiletime pointer wasn't aligned.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
@@ -1600,7 +1595,7 @@ impl<T: ?Sized> *const T {
     /// runtime and compiletime.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// const _: () = {
@@ -1616,7 +1611,7 @@ impl<T: ?Sized> *const T {
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
-    #[unstable(feature = "pointer_is_aligned", issue = "96284")]
+    #[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
     #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
     pub const fn is_aligned_to(self, align: usize) -> bool {
         if !align.is_power_of_two() {
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index 7f9d8e677d2..9b5da935e07 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -57,7 +57,7 @@ pub trait Pointee {
     // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata`
     // in `library/core/src/ptr/metadata.rs`
     // in sync with those here:
-    type Metadata: Copy + Send + Sync + Ord + Hash + Unpin;
+    type Metadata: fmt::Debug + Copy + Send + Sync + Ord + Hash + Unpin;
 }
 
 /// Pointers to types implementing this trait alias are “thin”.
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 3dde83541d4..e9d39b2c276 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1660,8 +1660,6 @@ impl<T: ?Sized> *mut T {
     /// # Examples
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
-    ///
     /// // On some platforms, the alignment of i32 is less than 4.
     /// #[repr(align(4))]
     /// struct AlignedI32(i32);
@@ -1684,7 +1682,6 @@ impl<T: ?Sized> *mut T {
     /// underlying allocation.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// #![feature(const_pointer_is_aligned)]
     /// #![feature(const_mut_refs)]
     ///
@@ -1711,7 +1708,6 @@ impl<T: ?Sized> *mut T {
     /// pointer is aligned, even if the compiletime pointer wasn't aligned.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of primitives is less than their size.
@@ -1738,7 +1734,6 @@ impl<T: ?Sized> *mut T {
     /// runtime and compiletime.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of primitives is less than their size.
@@ -1762,7 +1757,7 @@ impl<T: ?Sized> *mut T {
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
-    #[unstable(feature = "pointer_is_aligned", issue = "96284")]
+    #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
     pub const fn is_aligned(self) -> bool
     where
@@ -1783,7 +1778,7 @@ impl<T: ?Sized> *mut T {
     /// # Examples
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
     /// #[repr(align(4))]
@@ -1812,7 +1807,7 @@ impl<T: ?Sized> *mut T {
     /// cannot be stricter aligned than the reference's underlying allocation.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
     /// #![feature(const_mut_refs)]
     ///
@@ -1838,7 +1833,7 @@ impl<T: ?Sized> *mut T {
     /// pointer is aligned, even if the compiletime pointer wasn't aligned.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
@@ -1863,7 +1858,7 @@ impl<T: ?Sized> *mut T {
     /// runtime and compiletime.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// const _: () = {
@@ -1879,7 +1874,7 @@ impl<T: ?Sized> *mut T {
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
     #[must_use]
     #[inline]
-    #[unstable(feature = "pointer_is_aligned", issue = "96284")]
+    #[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
     #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
     pub const fn is_aligned_to(self, align: usize) -> bool {
         if !align.is_power_of_two() {
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index c0a36bb405e..f0e4b958bc6 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -1288,7 +1288,6 @@ impl<T: ?Sized> NonNull<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// use std::ptr::NonNull;
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
@@ -1313,7 +1312,6 @@ impl<T: ?Sized> NonNull<T> {
     /// underlying allocation.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// #![feature(const_pointer_is_aligned)]
     /// #![feature(non_null_convenience)]
     /// #![feature(const_option)]
@@ -1343,7 +1341,6 @@ impl<T: ?Sized> NonNull<T> {
     /// pointer is aligned, even if the compiletime pointer wasn't aligned.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of primitives is less than their size.
@@ -1369,7 +1366,6 @@ impl<T: ?Sized> NonNull<T> {
     /// runtime and compiletime.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// #![feature(const_pointer_is_aligned)]
     /// #![feature(const_option)]
     /// #![feature(const_nonnull_new)]
@@ -1394,7 +1390,7 @@ impl<T: ?Sized> NonNull<T> {
     /// ```
     ///
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
-    #[unstable(feature = "pointer_is_aligned", issue = "96284")]
+    #[stable(feature = "pointer_is_aligned", since = "CURRENT_RUSTC_VERSION")]
     #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
     #[must_use]
     #[inline]
@@ -1417,7 +1413,7 @@ impl<T: ?Sized> NonNull<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
     /// #[repr(align(4))]
@@ -1446,7 +1442,7 @@ impl<T: ?Sized> NonNull<T> {
     /// cannot be stricter aligned than the reference's underlying allocation.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
@@ -1471,7 +1467,7 @@ impl<T: ?Sized> NonNull<T> {
     /// pointer is aligned, even if the compiletime pointer wasn't aligned.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// // On some platforms, the alignment of i32 is less than 4.
@@ -1495,7 +1491,7 @@ impl<T: ?Sized> NonNull<T> {
     /// runtime and compiletime.
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
+    /// #![feature(pointer_is_aligned_to)]
     /// #![feature(const_pointer_is_aligned)]
     ///
     /// const _: () = {
@@ -1509,7 +1505,7 @@ impl<T: ?Sized> NonNull<T> {
     /// ```
     ///
     /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
-    #[unstable(feature = "pointer_is_aligned", issue = "96284")]
+    #[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
     #[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "104203")]
     #[must_use]
     #[inline]
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 77002ef87aa..0a749fcb8f9 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -418,14 +418,12 @@ impl AtomicBool {
     /// # Examples
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// use std::sync::atomic::{self, AtomicBool};
-    /// use std::mem::align_of;
     ///
     /// // Get a pointer to an allocated value
     /// let ptr: *mut bool = Box::into_raw(Box::new(false));
     ///
-    /// assert!(ptr.is_aligned_to(align_of::<AtomicBool>()));
+    /// assert!(ptr.cast::<AtomicBool>().is_aligned());
     ///
     /// {
     ///     // Create an atomic view of the allocated value
@@ -1216,14 +1214,12 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(pointer_is_aligned)]
     /// use std::sync::atomic::{self, AtomicPtr};
-    /// use std::mem::align_of;
     ///
     /// // Get a pointer to an allocated value
     /// let ptr: *mut *mut u8 = Box::into_raw(Box::new(std::ptr::null_mut()));
     ///
-    /// assert!(ptr.is_aligned_to(align_of::<AtomicPtr<u8>>()));
+    /// assert!(ptr.cast::<AtomicPtr<u8>>().is_aligned());
     ///
     /// {
     ///     // Create an atomic view of the allocated value
@@ -2199,14 +2195,12 @@ macro_rules! atomic_int {
             /// # Examples
             ///
             /// ```
-            /// #![feature(pointer_is_aligned)]
             #[doc = concat!($extra_feature, "use std::sync::atomic::{self, ", stringify!($atomic_type), "};")]
-            /// use std::mem::align_of;
             ///
             /// // Get a pointer to an allocated value
             #[doc = concat!("let ptr: *mut ", stringify!($int_type), " = Box::into_raw(Box::new(0));")]
             ///
-            #[doc = concat!("assert!(ptr.is_aligned_to(align_of::<", stringify!($atomic_type), ">()));")]
+            #[doc = concat!("assert!(ptr.cast::<", stringify!($atomic_type), ">().is_aligned());")]
             ///
             /// {
             ///     // Create an atomic view of the allocated value
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 421062f5873..52d2b798c91 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -16,6 +16,7 @@
 #![feature(const_hash)]
 #![feature(const_heap)]
 #![feature(const_intrinsic_copy)]
+#![feature(const_int_from_str)]
 #![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_nonnull_new)]
 #![feature(const_pointer_is_aligned)]
@@ -95,7 +96,7 @@
 #![feature(const_waker)]
 #![feature(never_type)]
 #![feature(unwrap_infallible)]
-#![feature(pointer_is_aligned)]
+#![feature(pointer_is_aligned_to)]
 #![feature(portable_simd)]
 #![feature(ptr_metadata)]
 #![feature(lazy_cell)]
diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs
index 863da9b18a2..0fed854318d 100644
--- a/library/core/tests/num/mod.rs
+++ b/library/core/tests/num/mod.rs
@@ -214,6 +214,16 @@ fn test_infallible_try_from_int_error() {
     assert!(func(0).is_ok());
 }
 
+const _TEST_CONST_PARSE: () = {
+    let Ok(-0x8000) = i16::from_str_radix("-8000", 16) else { panic!() };
+    let Ok(12345) = u64::from_str_radix("12345", 10) else { panic!() };
+    if let Err(e) = i8::from_str_radix("+", 10) {
+        let IntErrorKind::InvalidDigit = e.kind() else { panic!() };
+    } else {
+        panic!()
+    }
+};
+
 macro_rules! test_impl_from {
     ($fn_name:ident, bool, $target: ty) => {
         #[test]
diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs
index 5c518e2d593..f0656f997fd 100644
--- a/library/core/tests/ptr.rs
+++ b/library/core/tests/ptr.rs
@@ -841,12 +841,20 @@ fn ptr_metadata_bounds() {
     fn static_assert_expected_bounds_for_metadata<Meta>()
     where
         // Keep this in sync with the associated type in `library/core/src/ptr/metadata.rs`
-        Meta: Copy + Send + Sync + Ord + std::hash::Hash + Unpin,
+        Meta: Debug + Copy + Send + Sync + Ord + std::hash::Hash + Unpin,
     {
     }
 }
 
 #[test]
+fn pointee_metadata_debug() {
+    assert_eq!("()", format!("{:?}", metadata::<u32>(&17)));
+    assert_eq!("2", format!("{:?}", metadata::<[u32]>(&[19, 23])));
+    let for_dyn = format!("{:?}", metadata::<dyn Debug>(&29));
+    assert!(for_dyn.starts_with("DynMetadata(0x"), "{:?}", for_dyn);
+}
+
+#[test]
 fn dyn_metadata() {
     #[derive(Debug)]
     #[repr(align(32))]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 3781ae15c3a..31a8711e0eb 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -341,7 +341,7 @@
 #![feature(panic_can_unwind)]
 #![feature(panic_info_message)]
 #![feature(panic_internals)]
-#![feature(pointer_is_aligned)]
+#![feature(pointer_is_aligned_to)]
 #![feature(portable_simd)]
 #![feature(prelude_2024)]
 #![feature(ptr_as_uninit)]
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index b791b38379f..1624e2a6084 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -571,7 +571,9 @@ pub fn make_tests(
         &modified_tests,
         &mut poisoned,
     )
-    .unwrap_or_else(|_| panic!("Could not read tests from {}", config.src_base.display()));
+    .unwrap_or_else(|reason| {
+        panic!("Could not read tests from {}: {reason}", config.src_base.display())
+    });
 
     if poisoned {
         eprintln!();
diff --git a/src/tools/miri/tests/pass-dep/shims/posix_memalign.rs b/src/tools/miri/tests/pass-dep/shims/posix_memalign.rs
index 5cf62995fbe..db66b213416 100644
--- a/src/tools/miri/tests/pass-dep/shims/posix_memalign.rs
+++ b/src/tools/miri/tests/pass-dep/shims/posix_memalign.rs
@@ -1,6 +1,6 @@
 //@ignore-target-windows: No libc on Windows
 
-#![feature(pointer_is_aligned)]
+#![feature(pointer_is_aligned_to)]
 #![feature(strict_provenance)]
 
 use core::ptr;
diff --git a/tests/assembly/is_aligned.rs b/tests/assembly/is_aligned.rs
index 9d637793f87..14423a52064 100644
--- a/tests/assembly/is_aligned.rs
+++ b/tests/assembly/is_aligned.rs
@@ -7,7 +7,7 @@
 #![crate_type="rlib"]
 
 #![feature(core_intrinsics)]
-#![feature(pointer_is_aligned)]
+#![feature(pointer_is_aligned_to)]
 
 // CHECK-LABEL: is_aligned_to_unchecked
 // CHECK: decq
diff --git a/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir b/tests/mir-opt/building/match/deref-patterns/string.foo.PreCodegen.after.mir
index 1e4f7485089..1e4f7485089 100644
--- a/tests/mir-opt/deref-patterns/string.foo.PreCodegen.after.mir
+++ b/tests/mir-opt/building/match/deref-patterns/string.foo.PreCodegen.after.mir
diff --git a/tests/mir-opt/deref-patterns/string.rs b/tests/mir-opt/building/match/deref-patterns/string.rs
index bb4b5379b27..bb4b5379b27 100644
--- a/tests/mir-opt/deref-patterns/string.rs
+++ b/tests/mir-opt/building/match/deref-patterns/string.rs
diff --git a/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
index 596dcef85fd..596dcef85fd 100644
--- a/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/building/match/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
diff --git a/tests/mir-opt/exponential_or.rs b/tests/mir-opt/building/match/exponential_or.rs
index 89963b9bdf4..89963b9bdf4 100644
--- a/tests/mir-opt/exponential_or.rs
+++ b/tests/mir-opt/building/match/exponential_or.rs
diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir
index 194afdf7dd8..194afdf7dd8 100644
--- a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.full_tested_match.built.after.mir
diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir
index ae83075434f..ae83075434f 100644
--- a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.full_tested_match2.built.after.mir
diff --git a/tests/mir-opt/building/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
index b71b2412cdf..b71b2412cdf 100644
--- a/tests/mir-opt/building/match_false_edges.main.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
diff --git a/tests/mir-opt/building/match_false_edges.rs b/tests/mir-opt/building/match/match_false_edges.rs
index 839eda40c85..839eda40c85 100644
--- a/tests/mir-opt/building/match_false_edges.rs
+++ b/tests/mir-opt/building/match/match_false_edges.rs
diff --git a/tests/mir-opt/building/simple_match.match_bool.built.after.mir b/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir
index faa2456fd10..faa2456fd10 100644
--- a/tests/mir-opt/building/simple_match.match_bool.built.after.mir
+++ b/tests/mir-opt/building/match/simple_match.match_bool.built.after.mir
diff --git a/tests/mir-opt/building/simple_match.rs b/tests/mir-opt/building/match/simple_match.rs
index 4f0a3046a06..4f0a3046a06 100644
--- a/tests/mir-opt/building/simple_match.rs
+++ b/tests/mir-opt/building/match/simple_match.rs
diff --git a/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir
new file mode 100644
index 00000000000..e95a97b5b87
--- /dev/null
+++ b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir
@@ -0,0 +1,118 @@
+// MIR for `constant_eq` after SimplifyCfg-initial
+
+fn constant_eq(_1: &str, _2: bool) -> u32 {
+    debug s => _1;
+    debug b => _2;
+    let mut _0: u32;
+    let mut _3: (&str, bool);
+    let mut _4: &str;
+    let mut _5: bool;
+    let mut _6: bool;
+    let mut _7: bool;
+    let mut _8: &&str;
+    let mut _9: &bool;
+    let mut _10: bool;
+
+    bb0: {
+        StorageLive(_3);
+        StorageLive(_4);
+        _4 = _1;
+        StorageLive(_5);
+        _5 = _2;
+        _3 = (move _4, move _5);
+        StorageDead(_5);
+        StorageDead(_4);
+        PlaceMention(_3);
+        _7 = <str as PartialEq>::eq((_3.0: &str), const "a") -> [return: bb11, unwind: bb19];
+    }
+
+    bb1: {
+        switchInt((_3.1: bool)) -> [0: bb2, otherwise: bb3];
+    }
+
+    bb2: {
+        _0 = const 5_u32;
+        goto -> bb18;
+    }
+
+    bb3: {
+        falseEdge -> [real: bb17, imaginary: bb2];
+    }
+
+    bb4: {
+        falseEdge -> [real: bb12, imaginary: bb9];
+    }
+
+    bb5: {
+        switchInt((_3.1: bool)) -> [0: bb1, otherwise: bb6];
+    }
+
+    bb6: {
+        falseEdge -> [real: bb16, imaginary: bb3];
+    }
+
+    bb7: {
+        _6 = <str as PartialEq>::eq((_3.0: &str), const "b") -> [return: bb10, unwind: bb19];
+    }
+
+    bb8: {
+        switchInt((_3.1: bool)) -> [0: bb1, otherwise: bb9];
+    }
+
+    bb9: {
+        falseEdge -> [real: bb15, imaginary: bb6];
+    }
+
+    bb10: {
+        switchInt(move _6) -> [0: bb1, otherwise: bb8];
+    }
+
+    bb11: {
+        switchInt(move _7) -> [0: bb7, otherwise: bb4];
+    }
+
+    bb12: {
+        _8 = &fake (_3.0: &str);
+        _9 = &fake (_3.1: bool);
+        StorageLive(_10);
+        _10 = const true;
+        switchInt(move _10) -> [0: bb14, otherwise: bb13];
+    }
+
+    bb13: {
+        StorageDead(_10);
+        FakeRead(ForMatchGuard, _8);
+        FakeRead(ForMatchGuard, _9);
+        _0 = const 1_u32;
+        goto -> bb18;
+    }
+
+    bb14: {
+        StorageDead(_10);
+        falseEdge -> [real: bb5, imaginary: bb9];
+    }
+
+    bb15: {
+        _0 = const 2_u32;
+        goto -> bb18;
+    }
+
+    bb16: {
+        _0 = const 3_u32;
+        goto -> bb18;
+    }
+
+    bb17: {
+        _0 = const 4_u32;
+        goto -> bb18;
+    }
+
+    bb18: {
+        StorageDead(_3);
+        return;
+    }
+
+    bb19 (cleanup): {
+        resume;
+    }
+}
diff --git a/tests/mir-opt/building/match/sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir
new file mode 100644
index 00000000000..80d3c2e5c23
--- /dev/null
+++ b/tests/mir-opt/building/match/sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir
@@ -0,0 +1,88 @@
+// MIR for `disjoint_ranges` after SimplifyCfg-initial
+
+fn disjoint_ranges(_1: i32, _2: bool) -> u32 {
+    debug x => _1;
+    debug b => _2;
+    let mut _0: u32;
+    let mut _3: bool;
+    let mut _4: bool;
+    let mut _5: bool;
+    let mut _6: bool;
+    let mut _7: &i32;
+    let mut _8: bool;
+
+    bb0: {
+        PlaceMention(_1);
+        _5 = Le(const 0_i32, _1);
+        switchInt(move _5) -> [0: bb3, otherwise: bb8];
+    }
+
+    bb1: {
+        _0 = const 3_u32;
+        goto -> bb14;
+    }
+
+    bb2: {
+        falseEdge -> [real: bb9, imaginary: bb4];
+    }
+
+    bb3: {
+        _3 = Le(const 10_i32, _1);
+        switchInt(move _3) -> [0: bb5, otherwise: bb7];
+    }
+
+    bb4: {
+        falseEdge -> [real: bb12, imaginary: bb6];
+    }
+
+    bb5: {
+        switchInt(_1) -> [4294967295: bb6, otherwise: bb1];
+    }
+
+    bb6: {
+        falseEdge -> [real: bb13, imaginary: bb1];
+    }
+
+    bb7: {
+        _4 = Le(_1, const 20_i32);
+        switchInt(move _4) -> [0: bb5, otherwise: bb4];
+    }
+
+    bb8: {
+        _6 = Lt(_1, const 10_i32);
+        switchInt(move _6) -> [0: bb3, otherwise: bb2];
+    }
+
+    bb9: {
+        _7 = &fake _1;
+        StorageLive(_8);
+        _8 = _2;
+        switchInt(move _8) -> [0: bb11, otherwise: bb10];
+    }
+
+    bb10: {
+        StorageDead(_8);
+        FakeRead(ForMatchGuard, _7);
+        _0 = const 0_u32;
+        goto -> bb14;
+    }
+
+    bb11: {
+        StorageDead(_8);
+        falseEdge -> [real: bb1, imaginary: bb4];
+    }
+
+    bb12: {
+        _0 = const 1_u32;
+        goto -> bb14;
+    }
+
+    bb13: {
+        _0 = const 2_u32;
+        goto -> bb14;
+    }
+
+    bb14: {
+        return;
+    }
+}
diff --git a/tests/mir-opt/building/match/sort_candidates.rs b/tests/mir-opt/building/match/sort_candidates.rs
new file mode 100644
index 00000000000..a2583ff8284
--- /dev/null
+++ b/tests/mir-opt/building/match/sort_candidates.rs
@@ -0,0 +1,41 @@
+// Check specific cases of sorting candidates in match lowering.
+#![feature(exclusive_range_pattern)]
+
+// EMIT_MIR sort_candidates.constant_eq.SimplifyCfg-initial.after.mir
+fn constant_eq(s: &str, b: bool) -> u32 {
+    // Check that we only test "a" once
+
+    // CHECK-LABEL: fn constant_eq(
+    // CHECK: bb0: {
+    // CHECK: [[a:_.*]] = const "a";
+    // CHECK-NOT: {{_.*}} = const "a";
+    match (s, b) {
+        ("a", _) if true => 1,
+        ("b", true) => 2,
+        ("a", true) => 3,
+        (_, true) => 4,
+        _ => 5,
+    }
+}
+
+// EMIT_MIR sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir
+fn disjoint_ranges(x: i32, b: bool) -> u32 {
+    // When `(0..=10).contains(x) && !b`, we should jump to the last arm without testing the two
+    // other candidates.
+
+    // CHECK-LABEL: fn disjoint_ranges(
+    // CHECK: debug b => _2;
+    // CHECK: bb0: {
+    // CHECK: switchInt(_2) -> [0: [[jump:bb.*]], otherwise: {{bb.*}}];
+    // CHECK: [[jump]]: {
+    // CHECK-NEXT: _0 = const 3_u32;
+    // CHECK-NEXT: return;
+    match x {
+        0..10 if b => 0,
+        10..=20 => 1,
+        -1 => 2,
+        _ => 3,
+    }
+}
+
+fn main() {}
diff --git a/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir
deleted file mode 100644
index 107f56f7f69..00000000000
--- a/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir
+++ /dev/null
@@ -1,106 +0,0 @@
-// MIR for `main` after SimplifyCfg-initial
-
-fn main() -> () {
-    let mut _0: ();
-    let _1: i32;
-    let _3: i32;
-    let mut _4: bool;
-    let mut _5: bool;
-    let mut _6: bool;
-    let mut _7: bool;
-    let mut _8: &i32;
-    let mut _9: bool;
-    scope 1 {
-        debug x => _1;
-        let _2: bool;
-        scope 2 {
-            debug b => _2;
-        }
-    }
-
-    bb0: {
-        StorageLive(_1);
-        _1 = const 3_i32;
-        FakeRead(ForLet(None), _1);
-        StorageLive(_2);
-        _2 = const true;
-        FakeRead(ForLet(None), _2);
-        StorageLive(_3);
-        PlaceMention(_1);
-        _6 = Le(const 0_i32, _1);
-        switchInt(move _6) -> [0: bb3, otherwise: bb8];
-    }
-
-    bb1: {
-        _3 = const 3_i32;
-        goto -> bb14;
-    }
-
-    bb2: {
-        falseEdge -> [real: bb9, imaginary: bb4];
-    }
-
-    bb3: {
-        _4 = Le(const 10_i32, _1);
-        switchInt(move _4) -> [0: bb5, otherwise: bb7];
-    }
-
-    bb4: {
-        falseEdge -> [real: bb12, imaginary: bb6];
-    }
-
-    bb5: {
-        switchInt(_1) -> [4294967295: bb6, otherwise: bb1];
-    }
-
-    bb6: {
-        falseEdge -> [real: bb13, imaginary: bb1];
-    }
-
-    bb7: {
-        _5 = Le(_1, const 20_i32);
-        switchInt(move _5) -> [0: bb5, otherwise: bb4];
-    }
-
-    bb8: {
-        _7 = Lt(_1, const 10_i32);
-        switchInt(move _7) -> [0: bb3, otherwise: bb2];
-    }
-
-    bb9: {
-        _8 = &fake _1;
-        StorageLive(_9);
-        _9 = _2;
-        switchInt(move _9) -> [0: bb11, otherwise: bb10];
-    }
-
-    bb10: {
-        StorageDead(_9);
-        FakeRead(ForMatchGuard, _8);
-        _3 = const 0_i32;
-        goto -> bb14;
-    }
-
-    bb11: {
-        StorageDead(_9);
-        falseEdge -> [real: bb1, imaginary: bb4];
-    }
-
-    bb12: {
-        _3 = const 1_i32;
-        goto -> bb14;
-    }
-
-    bb13: {
-        _3 = const 2_i32;
-        goto -> bb14;
-    }
-
-    bb14: {
-        StorageDead(_3);
-        _0 = const ();
-        StorageDead(_2);
-        StorageDead(_1);
-        return;
-    }
-}
diff --git a/tests/mir-opt/match_test.rs b/tests/mir-opt/match_test.rs
deleted file mode 100644
index e465289e427..00000000000
--- a/tests/mir-opt/match_test.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// skip-filecheck
-// Make sure redundant testing paths in `match` expressions are sorted out.
-
-#![feature(exclusive_range_pattern)]
-
-// EMIT_MIR match_test.main.SimplifyCfg-initial.after.mir
-fn main() {
-    let x = 3;
-    let b = true;
-
-    // When `(0..=10).contains(x) && !b`, we should jump to the last arm
-    // without testing two other candidates.
-    match x {
-        0..10 if b => 0,
-        10..=20 => 1,
-        -1 => 2,
-        _ => 3,
-    };
-}
diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-sigpipe-disposition.rs b/tests/ui/attributes/unix_sigpipe/auxiliary/assert-sigpipe-disposition.rs
new file mode 100644
index 00000000000..117f6134b4e
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/auxiliary/assert-sigpipe-disposition.rs
@@ -0,0 +1,34 @@
+// It is UB to unwind out of `fn start()` according to
+// https://doc.rust-lang.org/beta/unstable-book/language-features/start.html so
+// panic with abort to avoid UB:
+//@ compile-flags: -Cpanic=abort
+//@ no-prefer-dynamic so panic=abort works
+
+#![feature(start, rustc_private)]
+
+extern crate libc;
+
+// Use #[start] so we don't have a runtime that messes with SIGPIPE.
+#[start]
+fn start(argc: isize, argv: *const *const u8) -> isize {
+    assert_eq!(argc, 2, "Must pass SIG_IGN or SIG_DFL as first arg");
+    let arg1 = unsafe { std::ffi::CStr::from_ptr(*argv.offset(1) as *const libc::c_char) }
+        .to_str()
+        .unwrap();
+
+    let expected = match arg1 {
+        "SIG_IGN" => libc::SIG_IGN,
+        "SIG_DFL" => libc::SIG_DFL,
+        arg => panic!("Must pass SIG_IGN or SIG_DFL as first arg. Got: {}", arg),
+    };
+
+    let actual = unsafe {
+        let mut actual: libc::sigaction = std::mem::zeroed();
+        libc::sigaction(libc::SIGPIPE, std::ptr::null(), &mut actual);
+        actual.sa_sigaction
+    };
+
+    assert_eq!(actual, expected, "actual and expected SIGPIPE disposition in child differs");
+
+    0
+}
diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs
new file mode 100644
index 00000000000..f96bd634876
--- /dev/null
+++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-and-child-processes.rs
@@ -0,0 +1,56 @@
+//@ revisions: default sig_dfl sig_ign inherit
+//@ ignore-cross-compile because aux-bin does not yet support it
+//@ only-unix because SIGPIPE is a unix thing
+//@ run-pass
+//@ aux-bin:assert-sigpipe-disposition.rs
+//@ aux-crate:sigpipe_utils=sigpipe-utils.rs
+
+// Checks the signal disposition of `SIGPIPE` in child processes, and in our own
+// process for robustness. Without any `unix_sigpipe` attribute, `SIG_IGN` is
+// the default. But there is a difference in how `SIGPIPE` is treated in child
+// processes with and without the attribute. Search for
+// `unix_sigpipe_attr_specified()` in the code base to learn more.
+
+#![feature(rustc_private)]
+#![cfg_attr(any(sig_dfl, sig_ign, inherit), feature(unix_sigpipe))]
+
+extern crate libc;
+extern crate sigpipe_utils;
+
+use sigpipe_utils::*;
+
+#[cfg_attr(sig_dfl, unix_sigpipe = "sig_dfl")]
+#[cfg_attr(sig_ign, unix_sigpipe = "sig_ign")]
+#[cfg_attr(inherit, unix_sigpipe = "inherit")]
+fn main() {
+    // By default we get SIG_IGN but the child gets SIG_DFL through an explicit
+    // reset before exec:
+    // https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L363-L384
+    #[cfg(default)]
+    let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_DFL");
+
+    // With #[unix_sigpipe = "sig_dfl"] we get SIG_DFL and the child does too
+    // without any special code running before exec.
+    #[cfg(sig_dfl)]
+    let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL");
+
+    // With #[unix_sigpipe = "sig_ign"] we get SIG_IGN and the child does too
+    // without any special code running before exec.
+    #[cfg(sig_ign)]
+    let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_IGN");
+
+    // With #[unix_sigpipe = "inherit"] we get SIG_DFL and the child does too
+    // without any special code running before exec.
+    #[cfg(inherit)]
+    let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL");
+
+    assert_sigpipe_handler(we_expect);
+
+    assert!(
+        std::process::Command::new("./auxiliary/bin/assert-sigpipe-disposition")
+            .arg(child_expects)
+            .status()
+            .unwrap()
+            .success()
+    );
+}
diff --git a/tests/ui/binop/binary-op-suggest-deref.stderr b/tests/ui/binop/binary-op-suggest-deref.stderr
index 32bd2554abb..47af51e2106 100644
--- a/tests/ui/binop/binary-op-suggest-deref.stderr
+++ b/tests/ui/binop/binary-op-suggest-deref.stderr
@@ -247,15 +247,15 @@ LL |     _ = &&0 == Foo;
    |
    = help: the trait `PartialEq<Foo>` is not implemented for `&&{integer}`
    = help: the following other types implement trait `PartialEq<Rhs>`:
+             f128
+             f16
              f32
              f64
              i128
              i16
              i32
              i64
-             i8
-             isize
-           and 6 others
+           and 8 others
 
 error[E0369]: binary operation `==` cannot be applied to type `Foo`
   --> $DIR/binary-op-suggest-deref.rs:60:13
diff --git a/tests/ui/coherence/negative-coherence/regions-in-canonical.rs b/tests/ui/coherence/negative-coherence/regions-in-canonical.rs
new file mode 100644
index 00000000000..6c2a11e0135
--- /dev/null
+++ b/tests/ui/coherence/negative-coherence/regions-in-canonical.rs
@@ -0,0 +1,23 @@
+//@ check-pass
+
+#![feature(adt_const_params)]
+//~^ WARN the feature `adt_const_params` is incomplete
+#![feature(with_negative_coherence, negative_impls)]
+
+pub trait A<const K: &'static str> {}
+pub trait C {}
+
+
+struct W<T>(T);
+
+// Negative coherence:
+// Proving `W<!T>: !A<"">` requires proving `CONST alias-eq ""`, which requires proving
+// `CONST normalizes-to (?1c: &str)`. The type's region is uniquified, so it ends up being
+// put in to the canonical vars list with an infer region => ICE.
+impl<T> C for T where T: A<""> {}
+impl<T> C for W<T> {}
+
+impl<T> !A<CONST> for W<T> {}
+const CONST: &str = "";
+
+fn main() {}
diff --git a/tests/ui/coherence/negative-coherence/regions-in-canonical.stderr b/tests/ui/coherence/negative-coherence/regions-in-canonical.stderr
new file mode 100644
index 00000000000..dc8c926f182
--- /dev/null
+++ b/tests/ui/coherence/negative-coherence/regions-in-canonical.stderr
@@ -0,0 +1,11 @@
+warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/regions-in-canonical.rs:3:12
+   |
+LL | #![feature(adt_const_params)]
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/compiletest-self-test/test-aux-bin.rs b/tests/ui/compiletest-self-test/test-aux-bin.rs
index 9e01e3ffabf..c1c28e12b3b 100644
--- a/tests/ui/compiletest-self-test/test-aux-bin.rs
+++ b/tests/ui/compiletest-self-test/test-aux-bin.rs
@@ -1,4 +1,4 @@
-//@ ignore-cross-compile because we run the compiled code
+//@ ignore-cross-compile because aux-bin does not yet support it
 //@ aux-bin: print-it-works.rs
 //@ run-pass
 
diff --git a/tests/ui/consts/const-eval/parse_ints.rs b/tests/ui/consts/const-eval/parse_ints.rs
new file mode 100644
index 00000000000..ff9fc47e65c
--- /dev/null
+++ b/tests/ui/consts/const-eval/parse_ints.rs
@@ -0,0 +1,10 @@
+#![feature(const_int_from_str)]
+
+const _OK: () = match i32::from_str_radix("-1234", 10) {
+    Ok(x) => assert!(x == -1234),
+    Err(_) => panic!(),
+};
+const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); };
+const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); };
+
+fn main () {}
diff --git a/tests/ui/consts/const-eval/parse_ints.stderr b/tests/ui/consts/const-eval/parse_ints.stderr
new file mode 100644
index 00000000000..9e49fe433a1
--- /dev/null
+++ b/tests/ui/consts/const-eval/parse_ints.stderr
@@ -0,0 +1,31 @@
+error[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/num/mod.rs:LL:COL
+   |
+   = note: the evaluated program panicked at 'from_str_radix_int: must lie in the range `[2, 36]`', $SRC_DIR/core/src/num/mod.rs:LL:COL
+   |
+note: inside `core::num::<impl u64>::from_str_radix`
+  --> $SRC_DIR/core/src/num/mod.rs:LL:COL
+note: inside `_TOO_LOW`
+  --> $DIR/parse_ints.rs:7:24
+   |
+LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); };
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in the macro `from_str_radix` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+  --> $SRC_DIR/core/src/num/mod.rs:LL:COL
+   |
+   = note: the evaluated program panicked at 'from_str_radix_int: must lie in the range `[2, 36]`', $SRC_DIR/core/src/num/mod.rs:LL:COL
+   |
+note: inside `core::num::<impl u64>::from_str_radix`
+  --> $SRC_DIR/core/src/num/mod.rs:LL:COL
+note: inside `_TOO_HIGH`
+  --> $DIR/parse_ints.rs:8:25
+   |
+LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); };
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in the macro `from_str_radix` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/lint/wide_pointer_comparisons.rs b/tests/ui/lint/wide_pointer_comparisons.rs
index bc4b3cecabc..05097cbf1e3 100644
--- a/tests/ui/lint/wide_pointer_comparisons.rs
+++ b/tests/ui/lint/wide_pointer_comparisons.rs
@@ -3,6 +3,7 @@
 use std::rc::Rc;
 use std::sync::Arc;
 use std::cmp::PartialEq;
+use std::ptr::NonNull;
 
 struct A;
 struct B;
@@ -51,6 +52,17 @@ fn main() {
     //~^ WARN ambiguous wide pointer comparison
 
     {
+        let a = NonNull::<dyn T>::new(a as *mut _).unwrap();
+        let b = NonNull::<dyn T>::new(b as *mut _).unwrap();
+        let _ = a == b;
+        //~^ WARN ambiguous wide pointer comparison
+        let _ = a >= b;
+        //~^ WARN ambiguous wide pointer comparison
+        let _ = &a == &b;
+        //~^ WARN ambiguous wide pointer comparison
+    }
+
+    {
         // &*const ?Sized
         let a = &a;
         let b = &b;
diff --git a/tests/ui/lint/wide_pointer_comparisons.stderr b/tests/ui/lint/wide_pointer_comparisons.stderr
index 8140f9fa5aa..81a221c0ee6 100644
--- a/tests/ui/lint/wide_pointer_comparisons.stderr
+++ b/tests/ui/lint/wide_pointer_comparisons.stderr
@@ -1,5 +1,5 @@
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:19:13
+  --> $DIR/wide_pointer_comparisons.rs:20:13
    |
 LL |     let _ = a == b;
    |             ^^^^^^
@@ -11,7 +11,7 @@ LL |     let _ = std::ptr::addr_eq(a, b);
    |             ++++++++++++++++++ ~  +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:21:13
+  --> $DIR/wide_pointer_comparisons.rs:22:13
    |
 LL |     let _ = a != b;
    |             ^^^^^^
@@ -22,7 +22,7 @@ LL |     let _ = !std::ptr::addr_eq(a, b);
    |             +++++++++++++++++++ ~  +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:23:13
+  --> $DIR/wide_pointer_comparisons.rs:24:13
    |
 LL |     let _ = a < b;
    |             ^^^^^
@@ -33,7 +33,7 @@ LL |     let _ = a.cast::<()>() < b.cast::<()>();
    |              +++++++++++++    +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:25:13
+  --> $DIR/wide_pointer_comparisons.rs:26:13
    |
 LL |     let _ = a <= b;
    |             ^^^^^^
@@ -44,7 +44,7 @@ LL |     let _ = a.cast::<()>() <= b.cast::<()>();
    |              +++++++++++++     +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:27:13
+  --> $DIR/wide_pointer_comparisons.rs:28:13
    |
 LL |     let _ = a > b;
    |             ^^^^^
@@ -55,7 +55,7 @@ LL |     let _ = a.cast::<()>() > b.cast::<()>();
    |              +++++++++++++    +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:29:13
+  --> $DIR/wide_pointer_comparisons.rs:30:13
    |
 LL |     let _ = a >= b;
    |             ^^^^^^
@@ -66,7 +66,7 @@ LL |     let _ = a.cast::<()>() >= b.cast::<()>();
    |              +++++++++++++     +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:32:13
+  --> $DIR/wide_pointer_comparisons.rs:33:13
    |
 LL |     let _ = PartialEq::eq(&a, &b);
    |             ^^^^^^^^^^^^^^^^^^^^^
@@ -77,7 +77,7 @@ LL |     let _ = std::ptr::addr_eq(a, b);
    |             ~~~~~~~~~~~~~~~~~~ ~  ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:34:13
+  --> $DIR/wide_pointer_comparisons.rs:35:13
    |
 LL |     let _ = PartialEq::ne(&a, &b);
    |             ^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +88,7 @@ LL |     let _ = !std::ptr::addr_eq(a, b);
    |             ~~~~~~~~~~~~~~~~~~~ ~  ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:36:13
+  --> $DIR/wide_pointer_comparisons.rs:37:13
    |
 LL |     let _ = a.eq(&b);
    |             ^^^^^^^^
@@ -99,7 +99,7 @@ LL |     let _ = std::ptr::addr_eq(a, b);
    |             ++++++++++++++++++ ~  ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:38:13
+  --> $DIR/wide_pointer_comparisons.rs:39:13
    |
 LL |     let _ = a.ne(&b);
    |             ^^^^^^^^
@@ -110,7 +110,7 @@ LL |     let _ = !std::ptr::addr_eq(a, b);
    |             +++++++++++++++++++ ~  ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:40:13
+  --> $DIR/wide_pointer_comparisons.rs:41:13
    |
 LL |     let _ = a.cmp(&b);
    |             ^^^^^^^^^
@@ -121,7 +121,7 @@ LL |     let _ = a.cast::<()>().cmp(&b.cast::<()>());
    |              +++++++++++++       +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:42:13
+  --> $DIR/wide_pointer_comparisons.rs:43:13
    |
 LL |     let _ = a.partial_cmp(&b);
    |             ^^^^^^^^^^^^^^^^^
@@ -132,7 +132,7 @@ LL |     let _ = a.cast::<()>().partial_cmp(&b.cast::<()>());
    |              +++++++++++++               +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:44:13
+  --> $DIR/wide_pointer_comparisons.rs:45:13
    |
 LL |     let _ = a.le(&b);
    |             ^^^^^^^^
@@ -143,7 +143,7 @@ LL |     let _ = a.cast::<()>().le(&b.cast::<()>());
    |              +++++++++++++      +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:46:13
+  --> $DIR/wide_pointer_comparisons.rs:47:13
    |
 LL |     let _ = a.lt(&b);
    |             ^^^^^^^^
@@ -154,7 +154,7 @@ LL |     let _ = a.cast::<()>().lt(&b.cast::<()>());
    |              +++++++++++++      +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:48:13
+  --> $DIR/wide_pointer_comparisons.rs:49:13
    |
 LL |     let _ = a.ge(&b);
    |             ^^^^^^^^
@@ -165,7 +165,7 @@ LL |     let _ = a.cast::<()>().ge(&b.cast::<()>());
    |              +++++++++++++      +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:50:13
+  --> $DIR/wide_pointer_comparisons.rs:51:13
    |
 LL |     let _ = a.gt(&b);
    |             ^^^^^^^^
@@ -176,7 +176,40 @@ LL |     let _ = a.cast::<()>().gt(&b.cast::<()>());
    |              +++++++++++++      +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:58:17
+  --> $DIR/wide_pointer_comparisons.rs:57:17
+   |
+LL |         let _ = a == b;
+   |                 ^^^^^^
+   |
+help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
+   |
+LL |         let _ = std::ptr::addr_eq(a.as_ptr(), b.as_ptr());
+   |                 ++++++++++++++++++ ~~~~~~~~~~  ++++++++++
+
+warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
+  --> $DIR/wide_pointer_comparisons.rs:59:17
+   |
+LL |         let _ = a >= b;
+   |                 ^^^^^^
+   |
+help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
+   |
+LL |         let _ = a.as_ptr().cast::<()>() >= b.as_ptr().cast::<()>();
+   |                  ++++++++++++++++++++++     ++++++++++++++++++++++
+
+warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
+  --> $DIR/wide_pointer_comparisons.rs:61:17
+   |
+LL |         let _ = &a == &b;
+   |                 ^^^^^^^^
+   |
+help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
+   |
+LL |         let _ = std::ptr::addr_eq(a.as_ptr(), b.as_ptr());
+   |                 ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~  ++++++++++
+
+warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
+  --> $DIR/wide_pointer_comparisons.rs:70:17
    |
 LL |         let _ = a == b;
    |                 ^^^^^^
@@ -187,7 +220,7 @@ LL |         let _ = std::ptr::addr_eq(*a, *b);
    |                 +++++++++++++++++++ ~~~ +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:60:17
+  --> $DIR/wide_pointer_comparisons.rs:72:17
    |
 LL |         let _ = a != b;
    |                 ^^^^^^
@@ -198,7 +231,7 @@ LL |         let _ = !std::ptr::addr_eq(*a, *b);
    |                 ++++++++++++++++++++ ~~~ +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:62:17
+  --> $DIR/wide_pointer_comparisons.rs:74:17
    |
 LL |         let _ = a < b;
    |                 ^^^^^
@@ -209,7 +242,7 @@ LL |         let _ = (*a).cast::<()>() < (*b).cast::<()>();
    |                 ++ ++++++++++++++   ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:64:17
+  --> $DIR/wide_pointer_comparisons.rs:76:17
    |
 LL |         let _ = a <= b;
    |                 ^^^^^^
@@ -220,7 +253,7 @@ LL |         let _ = (*a).cast::<()>() <= (*b).cast::<()>();
    |                 ++ ++++++++++++++    ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:66:17
+  --> $DIR/wide_pointer_comparisons.rs:78:17
    |
 LL |         let _ = a > b;
    |                 ^^^^^
@@ -231,7 +264,7 @@ LL |         let _ = (*a).cast::<()>() > (*b).cast::<()>();
    |                 ++ ++++++++++++++   ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:68:17
+  --> $DIR/wide_pointer_comparisons.rs:80:17
    |
 LL |         let _ = a >= b;
    |                 ^^^^^^
@@ -242,7 +275,7 @@ LL |         let _ = (*a).cast::<()>() >= (*b).cast::<()>();
    |                 ++ ++++++++++++++    ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:71:17
+  --> $DIR/wide_pointer_comparisons.rs:83:17
    |
 LL |         let _ = PartialEq::eq(a, b);
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -253,7 +286,7 @@ LL |         let _ = std::ptr::addr_eq(*a, *b);
    |                 ~~~~~~~~~~~~~~~~~~~ ~~~ ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:73:17
+  --> $DIR/wide_pointer_comparisons.rs:85:17
    |
 LL |         let _ = PartialEq::ne(a, b);
    |                 ^^^^^^^^^^^^^^^^^^^
@@ -264,7 +297,7 @@ LL |         let _ = !std::ptr::addr_eq(*a, *b);
    |                 ~~~~~~~~~~~~~~~~~~~~ ~~~ ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:75:17
+  --> $DIR/wide_pointer_comparisons.rs:87:17
    |
 LL |         let _ = PartialEq::eq(&a, &b);
    |                 ^^^^^^^^^^^^^^^^^^^^^
@@ -275,7 +308,7 @@ LL |         let _ = std::ptr::addr_eq(*a, *b);
    |                 ~~~~~~~~~~~~~~~~~~~ ~~~ ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:77:17
+  --> $DIR/wide_pointer_comparisons.rs:89:17
    |
 LL |         let _ = PartialEq::ne(&a, &b);
    |                 ^^^^^^^^^^^^^^^^^^^^^
@@ -286,7 +319,7 @@ LL |         let _ = !std::ptr::addr_eq(*a, *b);
    |                 ~~~~~~~~~~~~~~~~~~~~ ~~~ ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:79:17
+  --> $DIR/wide_pointer_comparisons.rs:91:17
    |
 LL |         let _ = a.eq(b);
    |                 ^^^^^^^
@@ -297,7 +330,7 @@ LL |         let _ = std::ptr::addr_eq(*a, *b);
    |                 +++++++++++++++++++ ~~~ ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:81:17
+  --> $DIR/wide_pointer_comparisons.rs:93:17
    |
 LL |         let _ = a.ne(b);
    |                 ^^^^^^^
@@ -308,7 +341,7 @@ LL |         let _ = !std::ptr::addr_eq(*a, *b);
    |                 ++++++++++++++++++++ ~~~ ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:83:17
+  --> $DIR/wide_pointer_comparisons.rs:95:17
    |
 LL |         let _ = a.cmp(&b);
    |                 ^^^^^^^^^
@@ -319,7 +352,7 @@ LL |         let _ = (*a).cast::<()>().cmp(&(*b).cast::<()>());
    |                 ++ ++++++++++++++      ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:85:17
+  --> $DIR/wide_pointer_comparisons.rs:97:17
    |
 LL |         let _ = a.partial_cmp(&b);
    |                 ^^^^^^^^^^^^^^^^^
@@ -330,7 +363,7 @@ LL |         let _ = (*a).cast::<()>().partial_cmp(&(*b).cast::<()>());
    |                 ++ ++++++++++++++              ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:87:17
+  --> $DIR/wide_pointer_comparisons.rs:99:17
    |
 LL |         let _ = a.le(&b);
    |                 ^^^^^^^^
@@ -341,7 +374,7 @@ LL |         let _ = (*a).cast::<()>().le(&(*b).cast::<()>());
    |                 ++ ++++++++++++++     ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:89:17
+  --> $DIR/wide_pointer_comparisons.rs:101:17
    |
 LL |         let _ = a.lt(&b);
    |                 ^^^^^^^^
@@ -352,7 +385,7 @@ LL |         let _ = (*a).cast::<()>().lt(&(*b).cast::<()>());
    |                 ++ ++++++++++++++     ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:91:17
+  --> $DIR/wide_pointer_comparisons.rs:103:17
    |
 LL |         let _ = a.ge(&b);
    |                 ^^^^^^^^
@@ -363,7 +396,7 @@ LL |         let _ = (*a).cast::<()>().ge(&(*b).cast::<()>());
    |                 ++ ++++++++++++++     ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:93:17
+  --> $DIR/wide_pointer_comparisons.rs:105:17
    |
 LL |         let _ = a.gt(&b);
    |                 ^^^^^^^^
@@ -374,7 +407,7 @@ LL |         let _ = (*a).cast::<()>().gt(&(*b).cast::<()>());
    |                 ++ ++++++++++++++     ++ ++++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:98:13
+  --> $DIR/wide_pointer_comparisons.rs:110:13
    |
 LL |     let _ = s == s;
    |             ^^^^^^
@@ -389,7 +422,7 @@ LL |     let _ = std::ptr::eq(s, s);
    |             +++++++++++++ ~  +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:102:13
+  --> $DIR/wide_pointer_comparisons.rs:114:13
    |
 LL |     let _ = s == s;
    |             ^^^^^^
@@ -404,7 +437,7 @@ LL |     let _ = std::ptr::eq(s, s);
    |             +++++++++++++ ~  +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:106:17
+  --> $DIR/wide_pointer_comparisons.rs:118:17
    |
 LL |         let _ = a == b;
    |                 ^^^^^^
@@ -419,7 +452,7 @@ LL |         let _ = std::ptr::eq(a, b);
    |                 +++++++++++++ ~  +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:108:17
+  --> $DIR/wide_pointer_comparisons.rs:120:17
    |
 LL |         let _ = a != b;
    |                 ^^^^^^
@@ -434,7 +467,7 @@ LL |         let _ = !std::ptr::eq(a, b);
    |                 ++++++++++++++ ~  +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:110:17
+  --> $DIR/wide_pointer_comparisons.rs:122:17
    |
 LL |         let _ = a < b;
    |                 ^^^^^
@@ -445,7 +478,7 @@ LL |         let _ = a.cast::<()>() < b.cast::<()>();
    |                  +++++++++++++    +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:112:17
+  --> $DIR/wide_pointer_comparisons.rs:124:17
    |
 LL |         let _ = a <= b;
    |                 ^^^^^^
@@ -456,7 +489,7 @@ LL |         let _ = a.cast::<()>() <= b.cast::<()>();
    |                  +++++++++++++     +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:114:17
+  --> $DIR/wide_pointer_comparisons.rs:126:17
    |
 LL |         let _ = a > b;
    |                 ^^^^^
@@ -467,7 +500,7 @@ LL |         let _ = a.cast::<()>() > b.cast::<()>();
    |                  +++++++++++++    +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:116:17
+  --> $DIR/wide_pointer_comparisons.rs:128:17
    |
 LL |         let _ = a >= b;
    |                 ^^^^^^
@@ -478,7 +511,7 @@ LL |         let _ = a.cast::<()>() >= b.cast::<()>();
    |                  +++++++++++++     +++++++++++++
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:119:17
+  --> $DIR/wide_pointer_comparisons.rs:131:17
    |
 LL |         let _ = PartialEq::eq(&a, &b);
    |                 ^^^^^^^^^^^^^^^^^^^^^
@@ -493,7 +526,7 @@ LL |         let _ = std::ptr::eq(a, b);
    |                 ~~~~~~~~~~~~~ ~  ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:121:17
+  --> $DIR/wide_pointer_comparisons.rs:133:17
    |
 LL |         let _ = PartialEq::ne(&a, &b);
    |                 ^^^^^^^^^^^^^^^^^^^^^
@@ -508,7 +541,7 @@ LL |         let _ = !std::ptr::eq(a, b);
    |                 ~~~~~~~~~~~~~~ ~  ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:123:17
+  --> $DIR/wide_pointer_comparisons.rs:135:17
    |
 LL |         let _ = a.eq(&b);
    |                 ^^^^^^^^
@@ -523,7 +556,7 @@ LL |         let _ = std::ptr::eq(a, b);
    |                 +++++++++++++ ~  ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:125:17
+  --> $DIR/wide_pointer_comparisons.rs:137:17
    |
 LL |         let _ = a.ne(&b);
    |                 ^^^^^^^^
@@ -538,7 +571,7 @@ LL |         let _ = !std::ptr::eq(a, b);
    |                 ++++++++++++++ ~  ~
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:130:9
+  --> $DIR/wide_pointer_comparisons.rs:142:9
    |
 LL |         &*a == &*b
    |         ^^^^^^^^^^
@@ -553,7 +586,7 @@ LL |         std::ptr::eq(*a, *b)
    |         ~~~~~~~~~~~~~  ~   +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:141:14
+  --> $DIR/wide_pointer_comparisons.rs:153:14
    |
 LL |         cmp!(a, b);
    |              ^^^^
@@ -564,7 +597,7 @@ LL |         cmp!(std::ptr::addr_eq(a, b));
    |              ++++++++++++++++++ ~  +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:147:39
+  --> $DIR/wide_pointer_comparisons.rs:159:39
    |
 LL |             ($a:ident, $b:ident) => { $a == $b }
    |                                       ^^^^^^^^
@@ -579,7 +612,7 @@ LL |             ($a:ident, $b:ident) => { std::ptr::addr_eq($a, $b) }
    |                                       ++++++++++++++++++  ~   +
 
 warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
-  --> $DIR/wide_pointer_comparisons.rs:157:37
+  --> $DIR/wide_pointer_comparisons.rs:169:37
    |
 LL |             ($a:expr, $b:expr) => { $a == $b }
    |                                     ^^
@@ -591,5 +624,5 @@ LL |         cmp!(&a, &b);
    = help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
    = note: this warning originates in the macro `cmp` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-warning: 50 warnings emitted
+warning: 53 warnings emitted
 
diff --git a/tests/ui/mir/alignment/packed.rs b/tests/ui/mir/alignment/packed.rs
index fe8ecc668b8..1a12425f11a 100644
--- a/tests/ui/mir/alignment/packed.rs
+++ b/tests/ui/mir/alignment/packed.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 //@ compile-flags: -C debug-assertions
 
-#![feature(strict_provenance, pointer_is_aligned)]
+#![feature(strict_provenance)]
 
 #[repr(packed)]
 struct Misaligner {
diff --git a/tests/ui/mismatched_types/binops.stderr b/tests/ui/mismatched_types/binops.stderr
index 3585587ed4c..f8047c8e2d4 100644
--- a/tests/ui/mismatched_types/binops.stderr
+++ b/tests/ui/mismatched_types/binops.stderr
@@ -73,15 +73,15 @@ LL |     5 < String::new();
    |
    = help: the trait `PartialOrd<String>` is not implemented for `{integer}`
    = help: the following other types implement trait `PartialOrd<Rhs>`:
+             f128
+             f16
              f32
              f64
              i128
              i16
              i32
              i64
-             i8
-             isize
-           and 6 others
+           and 8 others
 
 error[E0277]: can't compare `{integer}` with `Result<{integer}, _>`
   --> $DIR/binops.rs:7:7
@@ -91,15 +91,15 @@ LL |     6 == Ok(1);
    |
    = help: the trait `PartialEq<Result<{integer}, _>>` is not implemented for `{integer}`
    = help: the following other types implement trait `PartialEq<Rhs>`:
+             f128
+             f16
              f32
              f64
              i128
              i16
              i32
              i64
-             i8
-             isize
-           and 6 others
+           and 8 others
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/sanitizer/cfg.rs b/tests/ui/sanitizer/cfg.rs
index 942141bd3fe..b1ba17d5713 100644
--- a/tests/ui/sanitizer/cfg.rs
+++ b/tests/ui/sanitizer/cfg.rs
@@ -11,6 +11,7 @@
 //@[cfi]compile-flags:     -Clto -Ccodegen-units=1
 //@[kcfi]needs-llvm-components: x86
 //@[kcfi]compile-flags:    -Zsanitizer=kcfi    --cfg kcfi --target x86_64-unknown-none
+//@[kcfi]compile-flags:    -C panic=abort
 //@[leak]needs-sanitizer-leak
 //@[leak]compile-flags:    -Zsanitizer=leak    --cfg leak
 //@[memory]needs-sanitizer-memory
diff --git a/tests/ui/sanitizer/cfi-async-closures.rs b/tests/ui/sanitizer/cfi-async-closures.rs
new file mode 100644
index 00000000000..d94f2992d84
--- /dev/null
+++ b/tests/ui/sanitizer/cfi-async-closures.rs
@@ -0,0 +1,33 @@
+// Check various forms of dynamic closure calls
+
+//@ edition: 2021
+//@ revisions: cfi kcfi
+// FIXME(#122848) Remove only-linux once OSX CFI binaries work
+//@ only-linux
+//@ [cfi] needs-sanitizer-cfi
+//@ [kcfi] needs-sanitizer-kcfi
+//@ compile-flags: -C target-feature=-crt-static
+//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
+//@ [cfi] compile-flags: -Z sanitizer=cfi
+//@ [kcfi] compile-flags: -Z sanitizer=kcfi
+//@ [kcfi] compile-flags: -C panic=abort -Z panic-abort-tests -C prefer-dynamic=off
+//@ run-pass
+
+#![feature(async_closure)]
+#![feature(async_fn_traits)]
+
+use std::ops::AsyncFn;
+
+#[inline(never)]
+fn identity<T>(x: T) -> T { x }
+
+// We can't actually create a `dyn AsyncFn()`, because it's not object-safe, but we should check
+// that we don't bug out when we encounter one.
+
+fn main() {
+   let f = identity(async || ());
+   let _ = f.async_call(());
+   let _ = f();
+   let g: Box<dyn FnOnce() -> _> = Box::new(f) as _;
+   let _ = g();
+}
diff --git a/tests/ui/sanitizer/cfi-closure-fn-ptr-cast.rs b/tests/ui/sanitizer/cfi-closure-fn-ptr-cast.rs
deleted file mode 100644
index 1ae494d87d4..00000000000
--- a/tests/ui/sanitizer/cfi-closure-fn-ptr-cast.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Tests that converting a closure to a function pointer works
-// The notable thing being tested here is that when the closure does not capture anything,
-// the call method from its Fn trait takes a ZST representing its environment. The compiler then
-// uses the assumption that the ZST is non-passed to reify this into a function pointer.
-//
-// This checks that the reified function pointer will have the expected alias set at its call-site.
-
-//@ revisions: cfi kcfi
-// FIXME(#122848) Remove only-linux once OSX CFI binaries work
-//@ only-linux
-//@ [cfi] needs-sanitizer-cfi
-//@ [kcfi] needs-sanitizer-kcfi
-//@ compile-flags: -C target-feature=-crt-static
-//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
-//@ [cfi] compile-flags: -Z sanitizer=cfi
-//@ [kcfi] compile-flags: -Z sanitizer=kcfi
-//@ run-pass
-
-pub fn main() {
-    let f: &fn() = &((|| ()) as _);
-    f();
-}
diff --git a/tests/ui/sanitizer/cfi-closures.rs b/tests/ui/sanitizer/cfi-closures.rs
new file mode 100644
index 00000000000..54f1cc035bc
--- /dev/null
+++ b/tests/ui/sanitizer/cfi-closures.rs
@@ -0,0 +1,83 @@
+// Check various forms of dynamic closure calls
+
+//@ revisions: cfi kcfi
+// FIXME(#122848) Remove only-linux once OSX CFI binaries work
+//@ only-linux
+//@ [cfi] needs-sanitizer-cfi
+//@ [kcfi] needs-sanitizer-kcfi
+//@ compile-flags: -C target-feature=-crt-static
+//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
+//@ [cfi] compile-flags: -Z sanitizer=cfi
+//@ [kcfi] compile-flags: -Z sanitizer=kcfi
+//@ [kcfi] compile-flags: -C panic=abort -Z panic-abort-tests -C prefer-dynamic=off
+//@ compile-flags: --test
+//@ run-pass
+
+#![feature(fn_traits)]
+#![feature(unboxed_closures)]
+#![feature(cfg_sanitize)]
+
+fn foo<'a, T>() -> Box<dyn Fn(&'a T) -> &'a T> {
+    Box::new(|x| x)
+}
+
+#[test]
+fn dyn_fn_with_params() {
+    let x = 3;
+    let f = foo();
+    f(&x);
+    // FIXME remove once drops are working.
+    std::mem::forget(f);
+}
+
+#[test]
+fn call_fn_trait() {
+   let f: &(dyn Fn()) = &(|| {}) as _;
+   f.call(());
+}
+
+#[test]
+fn fn_ptr_cast() {
+    let f: &fn() = &((|| ()) as _);
+    f();
+}
+
+fn use_fnmut<F: FnMut()>(mut f: F) {
+    f()
+}
+
+#[test]
+fn fn_to_fnmut() {
+    let f: &(dyn Fn()) = &(|| {}) as _;
+    use_fnmut(f);
+}
+
+fn hrtb_helper(f: &dyn for<'a> Fn(&'a usize)) {
+    f(&10)
+}
+
+#[test]
+fn hrtb_fn() {
+    hrtb_helper((&|x: &usize| println!("{}", *x)) as _)
+}
+
+#[test]
+fn fnonce() {
+    let f: Box<dyn FnOnce()> = Box::new(|| {}) as _;
+    f();
+}
+
+fn use_closure<C>(call: extern "rust-call" fn(&C, ()) -> i32, f: &C) -> i32 {
+    call(f, ())
+}
+
+#[test]
+// FIXME after KCFI reify support is added, remove this
+// It will appear to work if you test locally, set -C opt-level=0 to see it fail.
+#[cfg_attr(sanitize = "kcfi", ignore)]
+fn closure_addr_taken() {
+    let x = 3i32;
+    let f = || x;
+    let call = Fn::<()>::call;
+    use_closure(call, &f);
+}
diff --git a/tests/ui/sanitizer/cfi-complex-receiver.rs b/tests/ui/sanitizer/cfi-complex-receiver.rs
index 52095a384b2..c7b45a775ca 100644
--- a/tests/ui/sanitizer/cfi-complex-receiver.rs
+++ b/tests/ui/sanitizer/cfi-complex-receiver.rs
@@ -11,6 +11,7 @@
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
+//@ [kcfi] compile-flags: -C panic=abort -C prefer-dynamic=off
 //@ run-pass
 
 use std::sync::Arc;
diff --git a/tests/ui/sanitizer/cfi-coroutine.rs b/tests/ui/sanitizer/cfi-coroutine.rs
new file mode 100644
index 00000000000..24e59cf5b4d
--- /dev/null
+++ b/tests/ui/sanitizer/cfi-coroutine.rs
@@ -0,0 +1,30 @@
+// Verifies that we can call dynamic coroutines
+
+//@ revisions: cfi kcfi
+// FIXME(#122848) Remove only-linux once OSX CFI binaries work
+//@ only-linux
+//@ [cfi] needs-sanitizer-cfi
+//@ [kcfi] needs-sanitizer-kcfi
+//@ compile-flags: -C target-feature=-crt-static
+//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
+//@ [cfi] compile-flags: -Z sanitizer=cfi
+//@ [kcfi] compile-flags: -Z sanitizer=kcfi
+//@ [kcfi] compile-flags: -C panic=abort -Z panic-abort-tests -C prefer-dynamic=off
+//@ compile-flags: --test
+//@ run-pass
+
+#![feature(coroutines)]
+#![feature(coroutine_trait)]
+
+use std::ops::{Coroutine, CoroutineState};
+use std::pin::{pin, Pin};
+
+fn main() {
+    let mut coro = |x: i32| {
+        yield x;
+        "done"
+    };
+    let mut abstract_coro: Pin<&mut dyn Coroutine<i32,Yield=i32,Return=&'static str>> = pin!(coro);
+    assert_eq!(abstract_coro.as_mut().resume(2), CoroutineState::Yielded(2));
+    assert_eq!(abstract_coro.as_mut().resume(0), CoroutineState::Complete("done"));
+}
diff --git a/tests/ui/sanitizer/cfi-self-ref.rs b/tests/ui/sanitizer/cfi-self-ref.rs
index f8793aec6e2..3b524ac661c 100644
--- a/tests/ui/sanitizer/cfi-self-ref.rs
+++ b/tests/ui/sanitizer/cfi-self-ref.rs
@@ -9,6 +9,7 @@
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
+//@ [kcfi] compile-flags: -C panic=abort -C prefer-dynamic=off
 //@ run-pass
 
 use std::marker::PhantomData;
diff --git a/tests/ui/sanitizer/cfi-supertraits.rs b/tests/ui/sanitizer/cfi-supertraits.rs
new file mode 100644
index 00000000000..ed3d722ebb7
--- /dev/null
+++ b/tests/ui/sanitizer/cfi-supertraits.rs
@@ -0,0 +1,73 @@
+#![feature(trait_upcasting)]
+// Check that super-traits are callable.
+
+//@ revisions: cfi kcfi
+// FIXME(#122848) Remove only-linux once OSX CFI binaries work
+//@ only-linux
+//@ [cfi] needs-sanitizer-cfi
+//@ [kcfi] needs-sanitizer-kcfi
+//@ compile-flags: -C target-feature=-crt-static
+//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
+//@ [cfi] compile-flags: -Z sanitizer=cfi
+//@ [kcfi] compile-flags: -Z sanitizer=kcfi
+//@ [kcfi] compile-flags: -C panic=abort -C prefer-dynamic=off
+//@ run-pass
+
+trait Parent1 {
+    type P1;
+    fn p1(&self) -> Self::P1;
+}
+
+trait Parent2 {
+    type P2;
+    fn p2(&self) -> Self::P2;
+}
+
+trait Child : Parent1 + Parent2 {
+    type C;
+    fn c(&self) -> Self::C;
+}
+
+struct Foo;
+
+impl Parent1 for Foo {
+    type P1 = u16;
+    fn p1(&self) -> Self::P1 {
+        println!("p1");
+        1
+    }
+}
+
+impl Parent2 for Foo {
+    type P2 = u32;
+    fn p2(&self) -> Self::P2 {
+        println!("p2");
+        2
+    }
+}
+
+impl Child for Foo {
+    type C = u8;
+    fn c(&self) -> Self::C {
+        println!("c");
+        0
+    }
+}
+
+fn main() {
+    // Child can access its own methods and super methods.
+    let x = &Foo as &dyn Child<C=u8,P1=u16,P2=u32>;
+    x.c();
+    x.p1();
+    x.p2();
+    // Parents can be created and access their methods.
+    let y = &Foo as &dyn Parent1<P1=u16>;
+    y.p1();
+    let z = &Foo as &dyn Parent2<P2=u32>;
+    z.p2();
+    // Trait upcasting works
+    let x1 = x as &dyn Parent1<P1=u16>;
+    x1.p1();
+    let x2 = x as &dyn Parent2<P2=u32>;
+    x2.p2();
+}
diff --git a/tests/ui/sanitizer/cfi-virtual-auto.rs b/tests/ui/sanitizer/cfi-virtual-auto.rs
index 517c3d49f76..6971d516a20 100644
--- a/tests/ui/sanitizer/cfi-virtual-auto.rs
+++ b/tests/ui/sanitizer/cfi-virtual-auto.rs
@@ -9,6 +9,7 @@
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
+//@ [kcfi] compile-flags: -C panic=abort -C prefer-dynamic=off
 //@ run-pass
 
 trait Foo {
diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs
new file mode 100644
index 00000000000..d08ca644a1c
--- /dev/null
+++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs
@@ -0,0 +1,7 @@
+fn main() {
+    let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes;
+//~^ ERROR expected a pattern, found an expression
+//~| ERROR cannot find type `T` in this scope
+//~| ERROR type and const arguments are not allowed on builtin type `str`
+//~| ERROR expected unit struct, unit variant or constant, found associated function `str<, T>::as_bytes`
+}
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
new file mode 100644
index 00000000000..19d4ac713ce
--- /dev/null
+++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr
@@ -0,0 +1,36 @@
+error: expected a pattern, found an expression
+  --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:31
+   |
+LL |     let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes;
+   |                               ^^^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:55
+   |
+LL |     let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes;
+   |                                                       ^ not found in this scope
+
+error[E0109]: type and const arguments are not allowed on builtin type `str`
+  --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:15
+   |
+LL |     let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes;
+   |         ---   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  ^ type and const arguments not allowed
+   |         |
+   |         not allowed on builtin type `str`
+   |
+help: primitive type `str` doesn't have generic parameters
+   |
+LL -     let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes;
+LL +     let str::as_bytes;
+   |
+
+error[E0533]: expected unit struct, unit variant or constant, found associated function `str<, T>::as_bytes`
+  --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:9
+   |
+LL |     let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0109, E0412, E0533.
+For more information about an error, try `rustc --explain E0109`.
diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs
index 66f663ce077..50491d5ef3e 100644
--- a/tests/ui/structs-enums/type-sizes.rs
+++ b/tests/ui/structs-enums/type-sizes.rs
@@ -4,7 +4,7 @@
 #![allow(dead_code)]
 #![feature(generic_nonzero)]
 #![feature(never_type)]
-#![feature(pointer_is_aligned)]
+#![feature(pointer_is_aligned_to)]
 #![feature(strict_provenance)]
 
 use std::mem::size_of;