about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-23 00:05:31 +0000
committerbors <bors@rust-lang.org>2024-04-23 00:05:31 +0000
commit9cf10bcf5b368de79abc24fc4d50a9d85b377ffa (patch)
tree975fed41d85532188712e2944555a73106f0f538
parent25087e02b34775520856b6cc15e50f5ed0c35f50 (diff)
parent000d0f9116c24c0e24a30e18bfd84f913b099520 (diff)
downloadrust-9cf10bcf5b368de79abc24fc4d50a9d85b377ffa.tar.gz
rust-9cf10bcf5b368de79abc24fc4d50a9d85b377ffa.zip
Auto merge of #124271 - GuillaumeGomez:rollup-7st9wd7, r=GuillaumeGomez
Rollup of 7 pull requests

Successful merges:

 - #115913 (checked_ilog: improve performance)
 - #124178 ([cleanup] [llvm backend] Prevent creating the same `Instance::mono` multiple times)
 - #124183 (Stop taking `ParamTy`/`ParamConst`/`EarlyParamRegion`/`AliasTy` by ref)
 - #124217 (coverage: Prepare for improved branch coverage)
 - #124230 (Stabilize generic `NonZero`.)
 - #124252 (Improve ICE message for forbidden dep-graph reads.)
 - #124268 (Update books)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_attr/src/lib.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs7
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_errors/src/lib.rs1
-rw-r--r--compiler/rustc_feature/src/lib.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs14
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs12
-rw-r--r--compiler/rustc_interface/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs4
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs8
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/util.rs8
-rw-r--r--compiler/rustc_mir_build/src/build/coverageinfo.rs103
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs38
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs47
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs76
-rw-r--r--compiler/rustc_passes/src/lib.rs1
-rw-r--r--compiler/rustc_query_impl/src/lib.rs1
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs45
-rw-r--r--compiler/rustc_query_system/src/lib.rs1
-rw-r--r--compiler/rustc_serialize/src/lib.rs1
-rw-r--r--compiler/rustc_session/src/lib.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs6
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs6
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/core/benches/num/int_log/mod.rs79
-rw-r--r--library/core/src/array/mod.rs5
-rw-r--r--library/core/src/iter/traits/double_ended.rs3
-rw-r--r--library/core/src/iter/traits/iterator.rs6
-rw-r--r--library/core/src/num/int_macros.rs18
-rw-r--r--library/core/src/num/mod.rs8
-rw-r--r--library/core/src/num/nonzero.rs10
-rw-r--r--library/core/src/num/uint_macros.rs19
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/proc_macro/src/lib.rs1
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/num.rs3
-rw-r--r--library/std/src/process.rs3
-rw-r--r--library/test/src/lib.rs1
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/reference0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/tools/miri/src/bin/miri.rs1
-rw-r--r--src/tools/miri/src/lib.rs1
-rw-r--r--tests/codegen/array-equality.rs1
-rw-r--r--tests/codegen/enum/enum-debug-niche-2.rs2
-rw-r--r--tests/codegen/function-arguments.rs1
-rw-r--r--tests/codegen/intrinsics/transmute-niched.rs1
-rw-r--r--tests/codegen/issues/issue-119422.rs1
-rw-r--r--tests/codegen/loads.rs1
-rw-r--r--tests/codegen/option-as-slice.rs1
-rw-r--r--tests/codegen/option-niche-eq.rs1
-rw-r--r--tests/codegen/slice-ref-equality.rs1
-rw-r--r--tests/codegen/transmute-optimized.rs1
-rw-r--r--tests/coverage/branch/if-let.cov-map41
-rw-r--r--tests/coverage/branch/if-let.coverage62
-rw-r--r--tests/coverage/branch/if-let.rs58
-rw-r--r--tests/coverage/branch/let-else.cov-map18
-rw-r--r--tests/coverage/branch/let-else.coverage37
-rw-r--r--tests/coverage/branch/let-else.rs35
-rw-r--r--tests/coverage/branch/match-arms.cov-map92
-rw-r--r--tests/coverage/branch/match-arms.coverage105
-rw-r--r--tests/coverage/branch/match-arms.rs90
-rw-r--r--tests/coverage/branch/match-trivial.cov-map17
-rw-r--r--tests/coverage/branch/match-trivial.coverage49
-rw-r--r--tests/coverage/branch/match-trivial.rs48
-rw-r--r--tests/debuginfo/msvc-pretty-enums.rs1
-rw-r--r--tests/debuginfo/numeric-types.rs1
-rw-r--r--tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff138
-rw-r--r--tests/mir-opt/coverage/branch_match_arms.rs27
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff (renamed from tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff)0
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff (renamed from tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff)0
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.rs (renamed from tests/mir-opt/instrument_coverage.rs)0
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff (renamed from tests/mir-opt/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff)0
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff (renamed from tests/mir-opt/instrument_coverage_cleanup.main.InstrumentCoverage.diff)0
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.rs (renamed from tests/mir-opt/instrument_coverage_cleanup.rs)0
-rw-r--r--tests/mir-opt/instsimplify/combine_transmutes.rs1
-rw-r--r--tests/ui/abi/compatibility.rs1
-rw-r--r--tests/ui/consts/const-eval/raw-bytes.rs2
-rw-r--r--tests/ui/consts/const-eval/ub-nonnull.rs2
-rw-r--r--tests/ui/consts/const-eval/valid-const.rs1
-rw-r--r--tests/ui/consts/tuple-struct-constructors.rs1
-rw-r--r--tests/ui/intrinsics/panic-uninitialized-zeroed.rs1
-rw-r--r--tests/ui/issues/issue-64593.rs1
-rw-r--r--tests/ui/layout/unsafe-cell-hides-niche.rs1
-rw-r--r--tests/ui/layout/zero-sized-array-enum-niche.rs1
-rw-r--r--tests/ui/layout/zero-sized-array-enum-niche.stderr8
-rw-r--r--tests/ui/lint/clashing-extern-fn.rs1
-rw-r--r--tests/ui/lint/clashing-extern-fn.stderr38
-rw-r--r--tests/ui/lint/invalid_value.rs2
-rw-r--r--tests/ui/lint/lint-ctypes-enum.rs1
-rw-r--r--tests/ui/lint/lint-ctypes-enum.stderr22
-rw-r--r--tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs1
-rw-r--r--tests/ui/print_type_sizes/niche-filling.rs1
-rw-r--r--tests/ui/structs-enums/enum-null-pointer-opt.rs1
-rw-r--r--tests/ui/structs-enums/enum-null-pointer-opt.stderr2
-rw-r--r--tests/ui/structs-enums/type-sizes.rs1
-rw-r--r--tests/ui/suggestions/core-std-import-order-issue-83564.rs1
-rw-r--r--tests/ui/suggestions/core-std-import-order-issue-83564.stderr2
-rw-r--r--tests/ui/traits/next-solver/specialization-transmute.rs1
-rw-r--r--tests/ui/traits/next-solver/specialization-transmute.stderr12
116 files changed, 1237 insertions, 274 deletions
diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs
index fada69c4e6d..dd87a5c4dc3 100644
--- a/compiler/rustc_attr/src/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
@@ -7,7 +7,6 @@
 #![allow(internal_features)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
-#![feature(generic_nonzero)]
 #![feature(let_chains)]
 
 #[macro_use]
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index ec0d4af599e..61cd085eef5 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1320,7 +1320,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             .into_iter()
             .map(|err| match err.obligation.predicate.kind().skip_binder() {
                 PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
-                    match predicate.self_ty().kind() {
+                    match *predicate.self_ty().kind() {
                         ty::Param(param_ty) => Ok((
                             generics.type_param(param_ty, tcx),
                             predicate.trait_ref.print_only_trait_path().to_string(),
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index dbea317e7bb..a505924fabd 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1070,7 +1070,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     // LL | blk();
                     //    | ----- this value implements `FnOnce`, which causes it to be moved when called
                     // ```
-                    if let ty::Param(param_ty) = self_ty.kind()
+                    if let ty::Param(param_ty) = *self_ty.kind()
                         && let generics = self.infcx.tcx.generics_of(self.mir_def_id())
                         && let param = generics.type_param(param_ty, self.infcx.tcx)
                         && let Some(hir_generics) = self
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index a62dfe13204..9e85c2d88f9 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -260,7 +260,8 @@ impl<'ll> CodegenCx<'ll, '_> {
 
     #[instrument(level = "debug", skip(self, llty))]
     pub(crate) fn get_static_inner(&self, def_id: DefId, llty: &'ll Type) -> &'ll Value {
-        if let Some(&g) = self.instances.borrow().get(&Instance::mono(self.tcx, def_id)) {
+        let instance = Instance::mono(self.tcx, def_id);
+        if let Some(&g) = self.instances.borrow().get(&instance) {
             trace!("used cached value");
             return g;
         }
@@ -273,7 +274,7 @@ impl<'ll> CodegenCx<'ll, '_> {
                  statics defined in the same CGU, but did not for `{def_id:?}`"
         );
 
-        let sym = self.tcx.symbol_name(Instance::mono(self.tcx, def_id)).name;
+        let sym = self.tcx.symbol_name(instance).name;
         let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
 
         debug!(?sym, ?fn_attrs);
@@ -363,7 +364,7 @@ impl<'ll> CodegenCx<'ll, '_> {
             }
         }
 
-        self.instances.borrow_mut().insert(Instance::mono(self.tcx, def_id), g);
+        self.instances.borrow_mut().insert(instance, g);
         g
     }
 
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 50420aaec04..d27d42737cd 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -11,7 +11,6 @@ Rust MIR: a lowered representation of Rust.
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(decl_macro)]
-#![feature(generic_nonzero)]
 #![feature(let_chains)]
 #![feature(slice_ptr_get)]
 #![feature(strict_provenance)]
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index b82a9a909e6..2b799d6f5d3 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -20,7 +20,6 @@
 #![feature(cfg_match)]
 #![feature(core_intrinsics)]
 #![feature(extend_one)]
-#![feature(generic_nonzero)]
 #![feature(hash_raw_entry)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(lazy_cell)]
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 8d6b22a9fa9..e3363e89594 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -15,7 +15,6 @@
 #![feature(box_patterns)]
 #![feature(error_reporter)]
 #![feature(extract_if)]
-#![feature(generic_nonzero)]
 #![feature(let_chains)]
 #![feature(negative_impls)]
 #![feature(never_type)]
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index cb28bb4e8e4..36ef8fe7816 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -12,7 +12,6 @@
 //! symbol to the `accepted` or `removed` modules respectively.
 
 #![allow(internal_features)]
-#![feature(generic_nonzero)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![feature(lazy_cell)]
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index c374f9762d6..66b86c9eb02 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -63,7 +63,6 @@ This API is completely unstable and subject to change.
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
 #![feature(control_flow_enum)]
-#![feature(generic_nonzero)]
 #![feature(if_let_guard)]
 #![feature(is_sorted)]
 #![feature(iter_intersperse)]
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 8923137fdd8..48b9142b014 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -2697,7 +2697,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn point_at_param_definition(&self, err: &mut Diag<'_>, param: ty::ParamTy) {
         let generics = self.tcx.generics_of(self.body_id);
-        let generic_param = generics.type_param(&param, self.tcx);
+        let generic_param = generics.type_param(param, self.tcx);
         if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param.kind {
             return;
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index d9e5289f632..b729fbe844a 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -2144,7 +2144,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let callee_ty = callee_ty.peel_refs();
             match *callee_ty.kind() {
                 ty::Param(param) => {
-                    let param = self.tcx.generics_of(self.body_id).type_param(&param, self.tcx);
+                    let param = self.tcx.generics_of(self.body_id).type_param(param, self.tcx);
                     if param.kind.is_synthetic() {
                         // if it's `impl Fn() -> ..` then just fall down to the def-id based logic
                         def_id = param.def_id;
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 46227e406a3..e74c4d06b5b 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -125,11 +125,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let Some(arg_ty) = args[0].as_type() else {
                     return false;
                 };
-                let ty::Param(param) = arg_ty.kind() else {
+                let ty::Param(param) = *arg_ty.kind() else {
                     return false;
                 };
                 // Is `generic_param` the same as the arg for this trait predicate?
-                generic_param.index == generics.type_param(&param, tcx).index
+                generic_param.index == generics.type_param(param, tcx).index
             } else {
                 false
             }
@@ -156,10 +156,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return false;
         }
 
-        match ty.peel_refs().kind() {
+        match *ty.peel_refs().kind() {
             ty::Param(param) => {
                 let generics = self.tcx.generics_of(self.body_id);
-                let generic_param = generics.type_param(&param, self.tcx);
+                let generic_param = generics.type_param(param, self.tcx);
                 for unsatisfied in unsatisfied_predicates.iter() {
                     // The parameter implements `IntoIterator`
                     // but it has called a method that requires it to implement `Iterator`
@@ -3232,9 +3232,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .sort_by_key(|&info| (!info.def_id.is_local(), self.tcx.def_path_str(info.def_id)));
             candidates.dedup();
 
-            let param_type = match rcvr_ty.kind() {
+            let param_type = match *rcvr_ty.kind() {
                 ty::Param(param) => Some(param),
-                ty::Ref(_, ty, _) => match ty.kind() {
+                ty::Ref(_, ty, _) => match *ty.kind() {
                     ty::Param(param) => Some(param),
                     _ => None,
                 },
@@ -3429,7 +3429,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 } else {
                                     param_type.map_or_else(
                                         || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented.
-                                        ToString::to_string,
+                                        |p| p.to_string(),
                                     )
                                 },
                             },
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index fdae9d84b5f..feef64bc6a5 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2371,7 +2371,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
             // type_param_sugg_span is (span, has_bounds)
             let (type_scope, type_param_sugg_span) = match bound_kind {
-                GenericKind::Param(ref param) => {
+                GenericKind::Param(param) => {
                     let generics = self.tcx.generics_of(generic_param_scope);
                     let def_id = generics.type_param(param, self.tcx).def_id.expect_local();
                     let scope = self.tcx.local_def_id_to_hir_id(def_id).owner.def_id;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 008b75b4c9a..6a42f9b42c3 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -28,7 +28,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
         match err {
             ArgumentSorts(values, _) | Sorts(values) => {
-                match (values.expected.kind(), values.found.kind()) {
+                match (*values.expected.kind(), *values.found.kind()) {
                     (ty::Closure(..), ty::Closure(..)) => {
                         diag.note("no two closures, even if identical, have the same type");
                         diag.help("consider boxing your closure and/or using it as a trait object");
@@ -452,7 +452,7 @@ impl<T> Trait<T> for X {
                     }
                     (ty::FnPtr(sig), ty::FnDef(def_id, _))
                     | (ty::FnDef(def_id, _), ty::FnPtr(sig)) => {
-                        if tcx.fn_sig(*def_id).skip_binder().unsafety() < sig.unsafety() {
+                        if tcx.fn_sig(def_id).skip_binder().unsafety() < sig.unsafety() {
                             diag.note(
                                 "unsafe functions cannot be coerced into safe function pointers",
                             );
@@ -527,7 +527,7 @@ impl<T> Trait<T> for X {
         diag: &mut Diag<'_>,
         msg: impl Fn() -> String,
         body_owner_def_id: DefId,
-        proj_ty: &ty::AliasTy<'tcx>,
+        proj_ty: ty::AliasTy<'tcx>,
         ty: Ty<'tcx>,
     ) -> bool {
         let tcx = self.tcx;
@@ -541,7 +541,7 @@ impl<T> Trait<T> for X {
         };
         // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
         // This will also work for `impl Trait`.
-        let ty::Param(param_ty) = proj_ty.self_ty().kind() else {
+        let ty::Param(param_ty) = *proj_ty.self_ty().kind() else {
             return false;
         };
         let generics = tcx.generics_of(body_owner_def_id);
@@ -598,7 +598,7 @@ impl<T> Trait<T> for X {
     fn expected_projection(
         &self,
         diag: &mut Diag<'_>,
-        proj_ty: &ty::AliasTy<'tcx>,
+        proj_ty: ty::AliasTy<'tcx>,
         values: ExpectedFound<Ty<'tcx>>,
         body_owner_def_id: DefId,
         cause_code: &ObligationCauseCode<'_>,
@@ -709,7 +709,7 @@ fn foo(&self) -> Self::T { String::new() }
         &self,
         diag: &mut Diag<'_>,
         msg: impl Fn() -> String,
-        proj_ty: &ty::AliasTy<'tcx>,
+        proj_ty: ty::AliasTy<'tcx>,
         ty: Ty<'tcx>,
     ) -> bool {
         let tcx = self.tcx;
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index d0ce23dacb5..75df006a56f 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -1,5 +1,4 @@
 #![feature(decl_macro)]
-#![feature(generic_nonzero)]
 #![feature(lazy_cell)]
 #![feature(let_chains)]
 #![feature(thread_spawn_unchecked)]
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 31c80c4d75b..086c3834410 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -32,7 +32,6 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(extract_if)]
-#![feature(generic_nonzero)]
 #![feature(if_let_guard)]
 #![feature(iter_order_by)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index f133a2f5f73..7dd03407bd7 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -6,7 +6,6 @@
 #![feature(error_iter)]
 #![feature(extract_if)]
 #![feature(coroutines)]
-#![feature(generic_nonzero)]
 #![feature(iter_from_coroutine)]
 #![feature(let_chains)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index e52a5863fd0..aadaca18326 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -35,7 +35,6 @@
 #![feature(const_type_name)]
 #![feature(discriminant_kind)]
 #![feature(coroutines)]
-#![feature(generic_nonzero)]
 #![feature(if_let_guard)]
 #![feature(inline_const)]
 #![feature(iter_from_coroutine)]
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index b1d0c815ae0..04011fd4194 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -314,7 +314,9 @@ impl Default for ConditionInfo {
 #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct MCDCBranchSpan {
     pub span: Span,
-    pub condition_info: ConditionInfo,
+    /// If `None`, this actually represents a normal branch span inserted for
+    /// code that was too complex for MC/DC.
+    pub condition_info: Option<ConditionInfo>,
     pub true_marker: BlockMarkerId,
     pub false_marker: BlockMarkerId,
 }
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 8291404ebf3..0c9ceae63c1 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -491,7 +491,7 @@ fn write_coverage_branch_info(
         writeln!(
             w,
             "{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
-            condition_info.condition_id
+            condition_info.map(|info| info.condition_id)
         )?;
     }
 
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index e984f543701..a99196cb363 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -263,7 +263,7 @@ impl<'tcx> Generics {
     /// Returns the `GenericParamDef` associated with this `EarlyParamRegion`.
     pub fn region_param(
         &'tcx self,
-        param: &ty::EarlyParamRegion,
+        param: ty::EarlyParamRegion,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx GenericParamDef {
         let param = self.param_at(param.index as usize, tcx);
@@ -274,7 +274,7 @@ impl<'tcx> Generics {
     }
 
     /// Returns the `GenericParamDef` associated with this `ParamTy`.
-    pub fn type_param(&'tcx self, param: &ParamTy, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
+    pub fn type_param(&'tcx self, param: ParamTy, tcx: TyCtxt<'tcx>) -> &'tcx GenericParamDef {
         let param = self.param_at(param.index as usize, tcx);
         match param.kind {
             GenericParamDefKind::Type { .. } => param,
@@ -286,7 +286,7 @@ impl<'tcx> Generics {
     /// `Generics`.
     pub fn opt_type_param(
         &'tcx self,
-        param: &ParamTy,
+        param: ParamTy,
         tcx: TyCtxt<'tcx>,
     ) -> Option<&'tcx GenericParamDef> {
         let param = self.opt_param_at(param.index as usize, tcx)?;
@@ -297,7 +297,7 @@ impl<'tcx> Generics {
     }
 
     /// Returns the `GenericParamDef` associated with this `ParamConst`.
-    pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
+    pub fn const_param(&'tcx self, param: ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
         let param = self.param_at(param.index as usize, tcx);
         match param.kind {
             GenericParamDefKind::Const { .. } => param,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 0bd009cd51d..e5450182bf2 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1276,7 +1276,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
 
     fn pretty_print_inherent_projection(
         &mut self,
-        alias_ty: &ty::AliasTy<'tcx>,
+        alias_ty: ty::AliasTy<'tcx>,
     ) -> Result<(), PrintError> {
         let def_key = self.tcx().def_key(alias_ty.def_id);
         self.path_generic_args(
@@ -3204,7 +3204,7 @@ define_print_and_forward_display! {
 
     ty::AliasTy<'tcx> {
         if let DefKind::Impl { of_trait: false } = cx.tcx().def_kind(cx.tcx().parent(self.def_id)) {
-            p!(pretty_print_inherent_projection(self))
+            p!(pretty_print_inherent_projection(*self))
         } else {
             // If we're printing verbosely, or don't want to invoke queries
             // (`is_impl_trait_in_trait`), then fall back to printing the def path.
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 6084e8d7cab..2a1af97ef24 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1379,7 +1379,7 @@ impl<'tcx> ParamTy {
         Ty::new_param(tcx, self.index, self.name)
     }
 
-    pub fn span_from_generics(&self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span {
+    pub fn span_from_generics(self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span {
         let generics = tcx.generics_of(item_with_generics);
         let type_param = generics.type_param(self, tcx);
         tcx.def_span(type_param.def_id)
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 9af665cfb6f..793ac126aa6 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -432,19 +432,19 @@ impl<'tcx> TyCtxt<'tcx> {
             .filter(|&(_, k)| {
                 match k.unpack() {
                     GenericArgKind::Lifetime(region) => match region.kind() {
-                        ty::ReEarlyParam(ref ebr) => {
+                        ty::ReEarlyParam(ebr) => {
                             !impl_generics.region_param(ebr, self).pure_wrt_drop
                         }
                         // Error: not a region param
                         _ => false,
                     },
-                    GenericArgKind::Type(ty) => match ty.kind() {
-                        ty::Param(ref pt) => !impl_generics.type_param(pt, self).pure_wrt_drop,
+                    GenericArgKind::Type(ty) => match *ty.kind() {
+                        ty::Param(pt) => !impl_generics.type_param(pt, self).pure_wrt_drop,
                         // Error: not a type param
                         _ => false,
                     },
                     GenericArgKind::Const(ct) => match ct.kind() {
-                        ty::ConstKind::Param(ref pc) => {
+                        ty::ConstKind::Param(pc) => {
                             !impl_generics.const_param(pc, self).pure_wrt_drop
                         }
                         // Error: not a const param
diff --git a/compiler/rustc_mir_build/src/build/coverageinfo.rs b/compiler/rustc_mir_build/src/build/coverageinfo.rs
index 57f809ef7cf..9e9ccd3dc2d 100644
--- a/compiler/rustc_mir_build/src/build/coverageinfo.rs
+++ b/compiler/rustc_mir_build/src/build/coverageinfo.rs
@@ -7,13 +7,13 @@ use rustc_middle::mir::coverage::{
     BlockMarkerId, BranchSpan, ConditionId, ConditionInfo, CoverageKind, MCDCBranchSpan,
     MCDCDecisionSpan,
 };
-use rustc_middle::mir::{self, BasicBlock, UnOp};
+use rustc_middle::mir::{self, BasicBlock, SourceInfo, UnOp};
 use rustc_middle::thir::{ExprId, ExprKind, LogicalOp, Thir};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
 
-use crate::build::Builder;
+use crate::build::{Builder, CFG};
 use crate::errors::MCDCExceedsConditionNumLimit;
 
 pub(crate) struct BranchInfoBuilder {
@@ -22,6 +22,7 @@ pub(crate) struct BranchInfoBuilder {
 
     num_block_markers: usize,
     branch_spans: Vec<BranchSpan>,
+
     mcdc_branch_spans: Vec<MCDCBranchSpan>,
     mcdc_decision_spans: Vec<MCDCDecisionSpan>,
     mcdc_state: Option<MCDCState>,
@@ -95,13 +96,7 @@ impl BranchInfoBuilder {
         }
     }
 
-    fn record_conditions_operation(&mut self, logical_op: LogicalOp, span: Span) {
-        if let Some(mcdc_state) = self.mcdc_state.as_mut() {
-            mcdc_state.record_conditions(logical_op, span);
-        }
-    }
-
-    fn fetch_condition_info(
+    fn fetch_mcdc_condition_info(
         &mut self,
         tcx: TyCtxt<'_>,
         true_marker: BlockMarkerId,
@@ -121,14 +116,9 @@ impl BranchInfoBuilder {
                 _ => {
                     // Do not generate mcdc mappings and statements for decisions with too many conditions.
                     let rebase_idx = self.mcdc_branch_spans.len() - decision.conditions_num + 1;
-                    let to_normal_branches = self.mcdc_branch_spans.split_off(rebase_idx);
-                    self.branch_spans.extend(to_normal_branches.into_iter().map(
-                        |MCDCBranchSpan { span, true_marker, false_marker, .. }| BranchSpan {
-                            span,
-                            true_marker,
-                            false_marker,
-                        },
-                    ));
+                    for branch in &mut self.mcdc_branch_spans[rebase_idx..] {
+                        branch.condition_info = None;
+                    }
 
                     // ConditionInfo of this branch shall also be reset.
                     condition_info = None;
@@ -144,12 +134,42 @@ impl BranchInfoBuilder {
         condition_info
     }
 
+    fn add_two_way_branch<'tcx>(
+        &mut self,
+        cfg: &mut CFG<'tcx>,
+        source_info: SourceInfo,
+        true_block: BasicBlock,
+        false_block: BasicBlock,
+    ) {
+        let true_marker = self.inject_block_marker(cfg, source_info, true_block);
+        let false_marker = self.inject_block_marker(cfg, source_info, false_block);
+
+        self.branch_spans.push(BranchSpan { span: source_info.span, true_marker, false_marker });
+    }
+
     fn next_block_marker_id(&mut self) -> BlockMarkerId {
         let id = BlockMarkerId::from_usize(self.num_block_markers);
         self.num_block_markers += 1;
         id
     }
 
+    fn inject_block_marker(
+        &mut self,
+        cfg: &mut CFG<'_>,
+        source_info: SourceInfo,
+        block: BasicBlock,
+    ) -> BlockMarkerId {
+        let id = self.next_block_marker_id();
+
+        let marker_statement = mir::Statement {
+            source_info,
+            kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
+        };
+        cfg.push(block, marker_statement);
+
+        id
+    }
+
     pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> {
         let Self {
             nots: _,
@@ -157,7 +177,7 @@ impl BranchInfoBuilder {
             branch_spans,
             mcdc_branch_spans,
             mcdc_decision_spans,
-            ..
+            mcdc_state: _,
         } = self;
 
         if num_block_markers == 0 {
@@ -325,7 +345,7 @@ impl Builder<'_, '_> {
         mut else_block: BasicBlock,
     ) {
         // Bail out if branch coverage is not enabled for this function.
-        let Some(branch_info) = self.coverage_branch_info.as_ref() else { return };
+        let Some(branch_info) = self.coverage_branch_info.as_mut() else { return };
 
         // If this condition expression is nested within one or more `!` expressions,
         // replace it with the enclosing `!` collected by `visit_unary_not`.
@@ -335,47 +355,34 @@ impl Builder<'_, '_> {
                 std::mem::swap(&mut then_block, &mut else_block);
             }
         }
-        let source_info = self.source_info(self.thir[expr_id].span);
-
-        // Now that we have `source_info`, we can upgrade to a &mut reference.
-        let branch_info = self.coverage_branch_info.as_mut().expect("upgrading & to &mut");
-
-        let mut inject_branch_marker = |block: BasicBlock| {
-            let id = branch_info.next_block_marker_id();
-
-            let marker_statement = mir::Statement {
-                source_info,
-                kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
-            };
-            self.cfg.push(block, marker_statement);
 
-            id
-        };
-
-        let true_marker = inject_branch_marker(then_block);
-        let false_marker = inject_branch_marker(else_block);
+        let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope };
 
-        if let Some(condition_info) =
-            branch_info.fetch_condition_info(self.tcx, true_marker, false_marker)
-        {
+        // Separate path for handling branches when MC/DC is enabled.
+        if branch_info.mcdc_state.is_some() {
+            let mut inject_block_marker =
+                |block| branch_info.inject_block_marker(&mut self.cfg, source_info, block);
+            let true_marker = inject_block_marker(then_block);
+            let false_marker = inject_block_marker(else_block);
+            let condition_info =
+                branch_info.fetch_mcdc_condition_info(self.tcx, true_marker, false_marker);
             branch_info.mcdc_branch_spans.push(MCDCBranchSpan {
                 span: source_info.span,
                 condition_info,
                 true_marker,
                 false_marker,
             });
-        } else {
-            branch_info.branch_spans.push(BranchSpan {
-                span: source_info.span,
-                true_marker,
-                false_marker,
-            });
+            return;
         }
+
+        branch_info.add_two_way_branch(&mut self.cfg, source_info, then_block, else_block);
     }
 
     pub(crate) fn visit_coverage_branch_operation(&mut self, logical_op: LogicalOp, span: Span) {
-        if let Some(branch_info) = self.coverage_branch_info.as_mut() {
-            branch_info.record_conditions_operation(logical_op, span);
+        if let Some(branch_info) = self.coverage_branch_info.as_mut()
+            && let Some(mcdc_state) = branch_info.mcdc_state.as_mut()
+        {
+            mcdc_state.record_conditions(logical_op, span);
         }
     }
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 9e8648b0f93..0b15c52c281 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -9,7 +9,7 @@ mod tests;
 
 use self::counters::{CounterIncrementSite, CoverageCounters};
 use self::graph::{BasicCoverageBlock, CoverageGraph};
-use self::spans::{BcbMapping, BcbMappingKind, CoverageSpans};
+use self::spans::{BcbBranchPair, BcbMapping, BcbMappingKind, CoverageSpans};
 
 use crate::MirPass;
 
@@ -141,21 +141,25 @@ fn create_mappings<'tcx>(
 
     let mut mappings = Vec::new();
 
-    mappings.extend(coverage_spans.all_bcb_mappings().filter_map(
+    mappings.extend(coverage_spans.mappings.iter().filter_map(
         |BcbMapping { kind: bcb_mapping_kind, span }| {
             let kind = match *bcb_mapping_kind {
                 BcbMappingKind::Code(bcb) => MappingKind::Code(term_for_bcb(bcb)),
-                BcbMappingKind::Branch { true_bcb, false_bcb } => MappingKind::Branch {
-                    true_term: term_for_bcb(true_bcb),
-                    false_term: term_for_bcb(false_bcb),
-                },
-                BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info } => {
-                    MappingKind::MCDCBranch {
+                BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info: None } => {
+                    MappingKind::Branch {
                         true_term: term_for_bcb(true_bcb),
                         false_term: term_for_bcb(false_bcb),
-                        mcdc_params: condition_info,
                     }
                 }
+                BcbMappingKind::MCDCBranch {
+                    true_bcb,
+                    false_bcb,
+                    condition_info: Some(mcdc_params),
+                } => MappingKind::MCDCBranch {
+                    true_term: term_for_bcb(true_bcb),
+                    false_term: term_for_bcb(false_bcb),
+                    mcdc_params,
+                },
                 BcbMappingKind::MCDCDecision { bitmap_idx, conditions_num, .. } => {
                     MappingKind::MCDCDecision(DecisionInfo { bitmap_idx, conditions_num })
                 }
@@ -165,6 +169,16 @@ fn create_mappings<'tcx>(
         },
     ));
 
+    mappings.extend(coverage_spans.branch_pairs.iter().filter_map(
+        |&BcbBranchPair { span, true_bcb, false_bcb }| {
+            let true_term = term_for_bcb(true_bcb);
+            let false_term = term_for_bcb(false_bcb);
+            let kind = MappingKind::Branch { true_term, false_term };
+            let code_region = make_code_region(source_map, file_name, span, body_span)?;
+            Some(Mapping { kind, code_region })
+        },
+    ));
+
     mappings
 }
 
@@ -233,7 +247,7 @@ fn inject_mcdc_statements<'tcx>(
 
     // Inject test vector update first because `inject_statement` always insert new statement at head.
     for (end_bcbs, bitmap_idx) in
-        coverage_spans.all_bcb_mappings().filter_map(|mapping| match &mapping.kind {
+        coverage_spans.mappings.iter().filter_map(|mapping| match &mapping.kind {
             BcbMappingKind::MCDCDecision { end_bcbs, bitmap_idx, .. } => {
                 Some((end_bcbs, *bitmap_idx))
             }
@@ -247,9 +261,9 @@ fn inject_mcdc_statements<'tcx>(
     }
 
     for (true_bcb, false_bcb, condition_id) in
-        coverage_spans.all_bcb_mappings().filter_map(|mapping| match mapping.kind {
+        coverage_spans.mappings.iter().filter_map(|mapping| match mapping.kind {
             BcbMappingKind::MCDCBranch { true_bcb, false_bcb, condition_info } => {
-                Some((true_bcb, false_bcb, condition_info.condition_id))
+                Some((true_bcb, false_bcb, condition_info?.condition_id))
             }
             _ => None,
         })
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index a4cd8a38c66..88f18b72085 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -15,13 +15,17 @@ mod from_mir;
 pub(super) enum BcbMappingKind {
     /// Associates an ordinary executable code span with its corresponding BCB.
     Code(BasicCoverageBlock),
-    /// Associates a branch span with BCBs for its true and false arms.
-    Branch { true_bcb: BasicCoverageBlock, false_bcb: BasicCoverageBlock },
+
+    // Ordinary branch mappings are stored separately, so they don't have a
+    // variant in this enum.
+    //
     /// Associates a mcdc branch span with condition info besides fields for normal branch.
     MCDCBranch {
         true_bcb: BasicCoverageBlock,
         false_bcb: BasicCoverageBlock,
-        condition_info: ConditionInfo,
+        /// If `None`, this actually represents a normal branch mapping inserted
+        /// for code that was too complex for MC/DC.
+        condition_info: Option<ConditionInfo>,
     },
     /// Associates a mcdc decision with its join BCB.
     MCDCDecision { end_bcbs: BTreeSet<BasicCoverageBlock>, bitmap_idx: u32, conditions_num: u16 },
@@ -33,9 +37,20 @@ pub(super) struct BcbMapping {
     pub(super) span: Span,
 }
 
+/// This is separate from [`BcbMappingKind`] to help prepare for larger changes
+/// that will be needed for improved branch coverage in the future.
+/// (See <https://github.com/rust-lang/rust/pull/124217>.)
+#[derive(Debug)]
+pub(super) struct BcbBranchPair {
+    pub(super) span: Span,
+    pub(super) true_bcb: BasicCoverageBlock,
+    pub(super) false_bcb: BasicCoverageBlock,
+}
+
 pub(super) struct CoverageSpans {
     bcb_has_mappings: BitSet<BasicCoverageBlock>,
-    mappings: Vec<BcbMapping>,
+    pub(super) mappings: Vec<BcbMapping>,
+    pub(super) branch_pairs: Vec<BcbBranchPair>,
     test_vector_bitmap_bytes: u32,
 }
 
@@ -44,10 +59,6 @@ impl CoverageSpans {
         self.bcb_has_mappings.contains(bcb)
     }
 
-    pub(super) fn all_bcb_mappings(&self) -> impl Iterator<Item = &BcbMapping> {
-        self.mappings.iter()
-    }
-
     pub(super) fn test_vector_bitmap_bytes(&self) -> u32 {
         self.test_vector_bitmap_bytes
     }
@@ -63,6 +74,7 @@ pub(super) fn generate_coverage_spans(
     basic_coverage_blocks: &CoverageGraph,
 ) -> Option<CoverageSpans> {
     let mut mappings = vec![];
+    let mut branch_pairs = vec![];
 
     if hir_info.is_async_fn {
         // An async function desugars into a function that returns a future,
@@ -84,14 +96,20 @@ pub(super) fn generate_coverage_spans(
             BcbMapping { kind: BcbMappingKind::Code(bcb), span }
         }));
 
-        mappings.extend(from_mir::extract_branch_mappings(
+        branch_pairs.extend(from_mir::extract_branch_pairs(
+            mir_body,
+            hir_info,
+            basic_coverage_blocks,
+        ));
+
+        mappings.extend(from_mir::extract_mcdc_mappings(
             mir_body,
             hir_info.body_span,
             basic_coverage_blocks,
         ));
     }
 
-    if mappings.is_empty() {
+    if mappings.is_empty() && branch_pairs.is_empty() {
         return None;
     }
 
@@ -104,8 +122,7 @@ pub(super) fn generate_coverage_spans(
     for BcbMapping { kind, span: _ } in &mappings {
         match *kind {
             BcbMappingKind::Code(bcb) => insert(bcb),
-            BcbMappingKind::Branch { true_bcb, false_bcb }
-            | BcbMappingKind::MCDCBranch { true_bcb, false_bcb, .. } => {
+            BcbMappingKind::MCDCBranch { true_bcb, false_bcb, .. } => {
                 insert(true_bcb);
                 insert(false_bcb);
             }
@@ -118,8 +135,12 @@ pub(super) fn generate_coverage_spans(
             }
         }
     }
+    for &BcbBranchPair { true_bcb, false_bcb, .. } in &branch_pairs {
+        insert(true_bcb);
+        insert(false_bcb);
+    }
 
-    Some(CoverageSpans { bcb_has_mappings, mappings, test_vector_bitmap_bytes })
+    Some(CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes })
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index b9919a2ae88..64f21d74b1c 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -13,7 +13,7 @@ use rustc_span::{ExpnKind, MacroKind, Span, Symbol};
 use crate::coverage::graph::{
     BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB,
 };
-use crate::coverage::spans::{BcbMapping, BcbMappingKind};
+use crate::coverage::spans::{BcbBranchPair, BcbMapping, BcbMappingKind};
 use crate::coverage::ExtractedHirInfo;
 
 /// Traverses the MIR body to produce an initial collection of coverage-relevant
@@ -366,15 +366,10 @@ impl SpanFromMir {
     }
 }
 
-pub(super) fn extract_branch_mappings(
+fn resolve_block_markers(
+    branch_info: &mir::coverage::BranchInfo,
     mir_body: &mir::Body<'_>,
-    body_span: Span,
-    basic_coverage_blocks: &CoverageGraph,
-) -> Vec<BcbMapping> {
-    let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else {
-        return vec![];
-    };
-
+) -> IndexVec<BlockMarkerId, Option<BasicBlock>> {
     let mut block_markers = IndexVec::<BlockMarkerId, Option<BasicBlock>>::from_elem_n(
         None,
         branch_info.num_block_markers,
@@ -389,6 +384,58 @@ pub(super) fn extract_branch_mappings(
         }
     }
 
+    block_markers
+}
+
+// FIXME: There is currently a lot of redundancy between
+// `extract_branch_pairs` and `extract_mcdc_mappings`. This is needed so
+// that they can each be modified without interfering with the other, but in
+// the long term we should try to bring them together again when branch coverage
+// and MC/DC coverage support are more mature.
+
+pub(super) fn extract_branch_pairs(
+    mir_body: &mir::Body<'_>,
+    hir_info: &ExtractedHirInfo,
+    basic_coverage_blocks: &CoverageGraph,
+) -> Vec<BcbBranchPair> {
+    let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else { return vec![] };
+
+    let block_markers = resolve_block_markers(branch_info, mir_body);
+
+    branch_info
+        .branch_spans
+        .iter()
+        .filter_map(|&BranchSpan { span: raw_span, true_marker, false_marker }| {
+            // For now, ignore any branch span that was introduced by
+            // expansion. This makes things like assert macros less noisy.
+            if !raw_span.ctxt().outer_expn_data().is_root() {
+                return None;
+            }
+            let (span, _) =
+                unexpand_into_body_span_with_visible_macro(raw_span, hir_info.body_span)?;
+
+            let bcb_from_marker =
+                |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
+
+            let true_bcb = bcb_from_marker(true_marker)?;
+            let false_bcb = bcb_from_marker(false_marker)?;
+
+            Some(BcbBranchPair { span, true_bcb, false_bcb })
+        })
+        .collect::<Vec<_>>()
+}
+
+pub(super) fn extract_mcdc_mappings(
+    mir_body: &mir::Body<'_>,
+    body_span: Span,
+    basic_coverage_blocks: &CoverageGraph,
+) -> Vec<BcbMapping> {
+    let Some(branch_info) = mir_body.coverage_branch_info.as_deref() else {
+        return vec![];
+    };
+
+    let block_markers = resolve_block_markers(branch_info, mir_body);
+
     let bcb_from_marker =
         |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
 
@@ -406,12 +453,6 @@ pub(super) fn extract_branch_mappings(
             Some((span, true_bcb, false_bcb))
         };
 
-    let branch_filter_map = |&BranchSpan { span: raw_span, true_marker, false_marker }| {
-        check_branch_bcb(raw_span, true_marker, false_marker).map(|(span, true_bcb, false_bcb)| {
-            BcbMapping { kind: BcbMappingKind::Branch { true_bcb, false_bcb }, span }
-        })
-    };
-
     let mcdc_branch_filter_map =
         |&MCDCBranchSpan { span: raw_span, true_marker, false_marker, condition_info }| {
             check_branch_bcb(raw_span, true_marker, false_marker).map(
@@ -446,10 +487,7 @@ pub(super) fn extract_branch_mappings(
         })
     };
 
-    branch_info
-        .branch_spans
-        .iter()
-        .filter_map(branch_filter_map)
+    std::iter::empty()
         .chain(branch_info.mcdc_branch_spans.iter().filter_map(mcdc_branch_filter_map))
         .chain(branch_info.mcdc_decision_spans.iter().filter_map(decision_filter_map))
         .collect::<Vec<_>>()
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index e03052bcfed..bce29e2af09 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -8,7 +8,6 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
-#![feature(generic_nonzero)]
 #![feature(let_chains)]
 #![feature(map_try_insert)]
 #![feature(try_blocks)]
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 3373835d813..914481d712e 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -3,7 +3,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![feature(generic_nonzero)]
 #![feature(min_specialization)]
 #![feature(rustc_attrs)]
 #![allow(rustc::potential_query_instability, unused_parens)]
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 534937003eb..2b3fa7f6cfa 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -459,7 +459,8 @@ impl<D: Deps> DepGraph<D> {
                     }
                     TaskDepsRef::Ignore => return,
                     TaskDepsRef::Forbid => {
-                        panic!("Illegal read of: {dep_node_index:?}")
+                        // Reading is forbidden in this context. ICE with a useful error message.
+                        panic_on_forbidden_read(data, dep_node_index)
                     }
                 };
                 let task_deps = &mut *task_deps;
@@ -1366,3 +1367,45 @@ pub(crate) fn print_markframe_trace<D: Deps>(graph: &DepGraph<D>, frame: Option<
 
     eprintln!("end of try_mark_green dep node stack");
 }
+
+#[cold]
+#[inline(never)]
+fn panic_on_forbidden_read<D: Deps>(data: &DepGraphData<D>, dep_node_index: DepNodeIndex) -> ! {
+    // We have to do an expensive reverse-lookup of the DepNode that
+    // corresponds to `dep_node_index`, but that's OK since we are about
+    // to ICE anyway.
+    let mut dep_node = None;
+
+    // First try to find the dep node among those that already existed in the
+    // previous session
+    for (prev_index, index) in data.current.prev_index_to_index.lock().iter_enumerated() {
+        if index == &Some(dep_node_index) {
+            dep_node = Some(data.previous.index_to_node(prev_index));
+            break;
+        }
+    }
+
+    if dep_node.is_none() {
+        // Try to find it among the new nodes
+        for shard in data.current.new_node_to_index.lock_shards() {
+            if let Some((node, _)) = shard.iter().find(|(_, index)| **index == dep_node_index) {
+                dep_node = Some(*node);
+                break;
+            }
+        }
+    }
+
+    let dep_node = dep_node.map_or_else(
+        || format!("with index {:?}", dep_node_index),
+        |dep_node| format!("`{:?}`", dep_node),
+    );
+
+    panic!(
+        "Error: trying to record dependency on DepNode {dep_node} in a \
+         context that does not allow it (e.g. during query deserialization). \
+         The most common case of recording a dependency on a DepNode `foo` is \
+         when the correspondng query `foo` is invoked. Invoking queries is not \
+         allowed as part of loading something from the incremental on-disk cache. \
+         See <https://github.com/rust-lang/rust/pull/91919>."
+    )
+}
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index 6a959a99e5d..416f556f57d 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -1,6 +1,5 @@
 #![feature(assert_matches)]
 #![feature(core_intrinsics)]
-#![feature(generic_nonzero)]
 #![feature(hash_raw_entry)]
 #![feature(min_specialization)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index 5a9403e0a85..3e1d8f3828b 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -11,7 +11,6 @@
 #![cfg_attr(bootstrap, feature(associated_type_bounds))]
 #![feature(const_option)]
 #![feature(core_intrinsics)]
-#![feature(generic_nonzero)]
 #![feature(inline_const)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index c63af90a7f3..58e1394c090 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,4 +1,3 @@
-#![feature(generic_nonzero)]
 #![feature(let_chains)]
 #![feature(lazy_cell)]
 #![feature(option_get_or_insert_default)]
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index db3794c1c40..9d3caaa01ab 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -124,7 +124,7 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
     msg: &str,
     err: &mut Diag<'_, G>,
     fn_sig: Option<&hir::FnSig<'_>>,
-    projection: Option<&ty::AliasTy<'_>>,
+    projection: Option<ty::AliasTy<'_>>,
     trait_pred: ty::PolyTraitPredicate<'tcx>,
     // When we are dealing with a trait, `super_traits` will be `Some`:
     // Given `trait T: A + B + C {}`
@@ -142,7 +142,7 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
     let generics = tcx.generics_of(item_id);
     // Given `fn foo(t: impl Trait)` where `Trait` requires assoc type `A`...
     if let Some((param, bound_str, fn_sig)) =
-        fn_sig.zip(projection).and_then(|(sig, p)| match p.self_ty().kind() {
+        fn_sig.zip(projection).and_then(|(sig, p)| match *p.self_ty().kind() {
             // Shenanigans to get the `Trait` from the `impl Trait`.
             ty::Param(param) => {
                 let param_def = generics.type_param(param, tcx);
@@ -252,7 +252,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         let trait_pred = self.resolve_numeric_literals_with_default(trait_pred);
 
         let self_ty = trait_pred.skip_binder().self_ty();
-        let (param_ty, projection) = match self_ty.kind() {
+        let (param_ty, projection) = match *self_ty.kind() {
             ty::Param(_) => (true, None),
             ty::Alias(ty::Projection, projection) => (false, Some(projection)),
             _ => (false, None),
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 8f5a30c436d..88ebf8754d3 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -482,7 +482,7 @@ fn is_impossible_associated_item(
         type Result = ControlFlow<()>;
         fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
             // If this is a parameter from the trait item's own generics, then bail
-            if let ty::Param(param) = t.kind()
+            if let ty::Param(param) = *t.kind()
                 && let param_def_id = self.generics.type_param(param, self.tcx).def_id
                 && self.tcx.parent(param_def_id) == self.trait_item_def_id
             {
@@ -492,7 +492,7 @@ fn is_impossible_associated_item(
         }
         fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result {
             if let ty::ReEarlyParam(param) = r.kind()
-                && let param_def_id = self.generics.region_param(&param, self.tcx).def_id
+                && let param_def_id = self.generics.region_param(param, self.tcx).def_id
                 && self.tcx.parent(param_def_id) == self.trait_item_def_id
             {
                 return ControlFlow::Break(());
@@ -501,7 +501,7 @@ fn is_impossible_associated_item(
         }
         fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
             if let ty::ConstKind::Param(param) = ct.kind()
-                && let param_def_id = self.generics.const_param(&param, self.tcx).def_id
+                && let param_def_id = self.generics.const_param(param, self.tcx).def_id
                 && self.tcx.parent(param_def_id) == self.trait_item_def_id
             {
                 return ControlFlow::Break(());
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index a652bb78116..d7d31a88c9b 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -130,7 +130,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
         TaitInBodyFinder { collector: self }.visit_expr(body);
     }
 
-    fn visit_opaque_ty(&mut self, alias_ty: &ty::AliasTy<'tcx>) {
+    fn visit_opaque_ty(&mut self, alias_ty: ty::AliasTy<'tcx>) {
         if !self.seen.insert(alias_ty.def_id.expect_local()) {
             return;
         }
@@ -205,7 +205,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
     #[instrument(skip(self), ret, level = "trace")]
     fn visit_ty(&mut self, t: Ty<'tcx>) {
         t.super_visit_with(self);
-        match t.kind() {
+        match *t.kind() {
             ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
                 self.visit_opaque_ty(alias_ty);
             }
@@ -279,7 +279,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
                     // assumption to the `param_env` of the default method. We also separately
                     // rely on that assumption here.
                     let ty = self.tcx.type_of(alias_ty.def_id).instantiate(self.tcx, alias_ty.args);
-                    let ty::Alias(ty::Opaque, alias_ty) = ty.kind() else { bug!("{ty:?}") };
+                    let ty::Alias(ty::Opaque, alias_ty) = *ty.kind() else { bug!("{ty:?}") };
                     self.visit_opaque_ty(alias_ty);
                 }
             }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index dec04d7e421..88faf5a9c7d 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -126,7 +126,6 @@
 #![feature(extend_one)]
 #![feature(fmt_internals)]
 #![feature(fn_traits)]
-#![feature(generic_nonzero)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hint_assert_unchecked)]
 #![feature(inline_const)]
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index a34bce66496..b5175a8487f 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -14,7 +14,6 @@
 #![feature(core_intrinsics)]
 #![feature(extract_if)]
 #![feature(exact_size_is_empty)]
-#![feature(generic_nonzero)]
 #![feature(linked_list_cursors)]
 #![feature(map_try_insert)]
 #![feature(new_uninit)]
diff --git a/library/core/benches/num/int_log/mod.rs b/library/core/benches/num/int_log/mod.rs
index bb61224b5ba..3807cd5d76c 100644
--- a/library/core/benches/num/int_log/mod.rs
+++ b/library/core/benches/num/int_log/mod.rs
@@ -1,7 +1,7 @@
 use rand::Rng;
 use test::{black_box, Bencher};
 
-macro_rules! int_log_bench {
+macro_rules! int_log10_bench {
     ($t:ty, $predictable:ident, $random:ident, $random_small:ident) => {
         #[bench]
         fn $predictable(bench: &mut Bencher) {
@@ -51,8 +51,75 @@ macro_rules! int_log_bench {
     };
 }
 
-int_log_bench! {u8, u8_log10_predictable, u8_log10_random, u8_log10_random_small}
-int_log_bench! {u16, u16_log10_predictable, u16_log10_random, u16_log10_random_small}
-int_log_bench! {u32, u32_log10_predictable, u32_log10_random, u32_log10_random_small}
-int_log_bench! {u64, u64_log10_predictable, u64_log10_random, u64_log10_random_small}
-int_log_bench! {u128, u128_log10_predictable, u128_log10_random, u128_log10_random_small}
+int_log10_bench! {u8, u8_log10_predictable, u8_log10_random, u8_log10_random_small}
+int_log10_bench! {u16, u16_log10_predictable, u16_log10_random, u16_log10_random_small}
+int_log10_bench! {u32, u32_log10_predictable, u32_log10_random, u32_log10_random_small}
+int_log10_bench! {u64, u64_log10_predictable, u64_log10_random, u64_log10_random_small}
+int_log10_bench! {u128, u128_log10_predictable, u128_log10_random, u128_log10_random_small}
+
+macro_rules! int_log_bench {
+    ($t:ty, $random:ident, $random_small:ident, $geometric:ident) => {
+        #[bench]
+        fn $random(bench: &mut Bencher) {
+            let mut rng = crate::bench_rng();
+            /* Exponentially distributed random numbers from the whole range of the type.  */
+            let numbers: Vec<$t> = (0..256)
+                .map(|_| {
+                    let x = rng.gen::<$t>() >> rng.gen_range(0..<$t>::BITS);
+                    if x >= 2 { x } else { 2 }
+                })
+                .collect();
+            bench.iter(|| {
+                for &b in &numbers {
+                    for &x in &numbers {
+                        black_box(black_box(x).ilog(b));
+                    }
+                }
+            });
+        }
+
+        #[bench]
+        fn $random_small(bench: &mut Bencher) {
+            let mut rng = crate::bench_rng();
+            /* Exponentially distributed random numbers from the range 0..256.  */
+            let numbers: Vec<$t> = (0..256)
+                .map(|_| {
+                    let x = (rng.gen::<u8>() >> rng.gen_range(0..u8::BITS)) as $t;
+                    if x >= 2 { x } else { 2 }
+                })
+                .collect();
+            bench.iter(|| {
+                for &b in &numbers {
+                    for &x in &numbers {
+                        black_box(black_box(x).ilog(b));
+                    }
+                }
+            });
+        }
+
+        #[bench]
+        fn $geometric(bench: &mut Bencher) {
+            let bases: [$t; 16] = [2, 3, 4, 5, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65];
+            let base_and_numbers: Vec<($t, Vec<$t>)> = bases
+                .iter()
+                .map(|&b| {
+                    let numbers = (0..=<$t>::MAX.ilog(b)).map(|exp| b.pow(exp)).collect();
+                    (b, numbers)
+                })
+                .collect();
+            bench.iter(|| {
+                for (b, numbers) in &base_and_numbers {
+                    for &x in numbers {
+                        black_box(black_box(x).ilog(black_box(*b)));
+                    }
+                }
+            });
+        }
+    };
+}
+
+int_log_bench! {u8, u8_log_random, u8_log_random_small, u8_log_geometric}
+int_log_bench! {u16, u16_log_random, u16_log_random_small, u16_log_geometric}
+int_log_bench! {u32, u32_log_random, u32_log_random_small, u32_log_geometric}
+int_log_bench! {u64, u64_log_random, u64_log_random_small, u64_log_geometric}
+int_log_bench! {u128, u128_log_random, u128_log_random_small, u128_log_geometric}
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 2a447aafe72..05874ab6c4c 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -512,7 +512,8 @@ impl<T, const N: usize> [T; N] {
     /// # Examples
     ///
     /// ```
-    /// #![feature(array_try_map, generic_nonzero)]
+    /// #![feature(array_try_map)]
+    ///
     /// let a = ["1", "2", "3"];
     /// let b = a.try_map(|v| v.parse::<u32>()).unwrap().map(|v| v + 1);
     /// assert_eq!(b, [2, 3, 4]);
@@ -522,8 +523,10 @@ impl<T, const N: usize> [T; N] {
     /// assert!(b.is_err());
     ///
     /// use std::num::NonZero;
+    ///
     /// let z = [1, 2, 0, 3, 4];
     /// assert_eq!(z.try_map(NonZero::new), None);
+    ///
     /// let a = [1, 2, 3];
     /// let b = a.try_map(NonZero::new);
     /// let c = b.map(|x| x.map(NonZero::get));
diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs
index 35092ec51cd..3b126785728 100644
--- a/library/core/src/iter/traits/double_ended.rs
+++ b/library/core/src/iter/traits/double_ended.rs
@@ -118,7 +118,8 @@ pub trait DoubleEndedIterator: Iterator {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(generic_nonzero, iter_advance_by)]
+    /// #![feature(iter_advance_by)]
+    ///
     /// use std::num::NonZero;
     ///
     /// let a = [3, 4, 5, 6];
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 95c03043e3e..7c1c6122efe 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -288,7 +288,8 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// #![feature(generic_nonzero, iter_advance_by)]
+    /// #![feature(iter_advance_by)]
+    ///
     /// use std::num::NonZero;
     ///
     /// let a = [1, 2, 3, 4];
@@ -2939,7 +2940,8 @@ pub trait Iterator {
     /// This also supports other types which implement [`Try`], not just [`Result`].
     ///
     /// ```
-    /// #![feature(generic_nonzero, try_find)]
+    /// #![feature(try_find)]
+    ///
     /// use std::num::NonZero;
     ///
     /// let a = [3, 5, 7, 4, 9, 0, 11u32];
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index de25b999bde..a92da88dd3f 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -3123,21 +3123,9 @@ macro_rules! int_impl {
             if self <= 0 || base <= 1 {
                 None
             } else {
-                let mut n = 0;
-                let mut r = self;
-
-                // Optimization for 128 bit wide integers.
-                if Self::BITS == 128 {
-                    let b = Self::ilog2(self) / (Self::ilog2(base) + 1);
-                    n += b;
-                    r /= base.pow(b as u32);
-                }
-
-                while r >= base {
-                    r /= base;
-                    n += 1;
-                }
-                Some(n)
+                // Delegate to the unsigned implementation.
+                // The condition makes sure that both casts are exact.
+                (self as $UnsignedT).checked_ilog(base as $UnsignedT)
             }
         }
 
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 9ebbb4ffe80..443401c5dba 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -67,15 +67,15 @@ pub use error::ParseIntError;
 )]
 pub use nonzero::ZeroablePrimitive;
 
-#[unstable(feature = "generic_nonzero", issue = "120257")]
+#[stable(feature = "generic_nonzero", since = "CURRENT_RUSTC_VERSION")]
 pub use nonzero::NonZero;
 
-#[stable(feature = "nonzero", since = "1.28.0")]
-pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
-
 #[stable(feature = "signed_nonzero", since = "1.34.0")]
 pub use nonzero::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
 
+#[stable(feature = "nonzero", since = "1.28.0")]
+pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
+
 #[stable(feature = "try_from", since = "1.34.0")]
 pub use error::TryFromIntError;
 
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 62ea7abf652..b9d771ba359 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -105,12 +105,11 @@ impl_zeroable_primitive!(
 /// For example, `Option<NonZero<u32>>` is the same size as `u32`:
 ///
 /// ```
-/// #![feature(generic_nonzero)]
-/// use core::mem::size_of;
+/// use core::{mem::size_of, num::NonZero};
 ///
-/// assert_eq!(size_of::<Option<core::num::NonZero<u32>>>(), size_of::<u32>());
+/// assert_eq!(size_of::<Option<NonZero<u32>>>(), size_of::<u32>());
 /// ```
-#[unstable(feature = "generic_nonzero", issue = "120257")]
+#[stable(feature = "generic_nonzero", since = "CURRENT_RUSTC_VERSION")]
 #[repr(transparent)]
 #[rustc_nonnull_optimization_guaranteed]
 #[rustc_diagnostic_item = "NonZero"]
@@ -562,7 +561,8 @@ macro_rules! nonzero_integer {
             /// Basic usage:
             ///
             /// ```
-            /// #![feature(generic_nonzero, non_zero_count_ones)]
+            /// #![feature(non_zero_count_ones)]
+            ///
             /// # fn main() { test().unwrap(); }
             /// # fn test() -> Option<()> {
             /// # use std::num::*;
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 58f713baa57..c13763243f0 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1095,18 +1095,25 @@ macro_rules! uint_impl {
                 None
             } else {
                 let mut n = 0;
-                let mut r = self;
+                let mut r = 1;
 
                 // Optimization for 128 bit wide integers.
                 if Self::BITS == 128 {
-                    let b = Self::ilog2(self) / (Self::ilog2(base) + 1);
-                    n += b;
-                    r /= base.pow(b as u32);
+                    // The following is a correct lower bound for ⌊log(base,self)⌋ because
+                    //
+                    // log(base,self) = log(2,self) / log(2,base)
+                    //                ≥ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1)
+                    //
+                    // hence
+                    //
+                    // ⌊log(base,self)⌋ ≥ ⌊ ⌊log(2,self)⌋ / (⌊log(2,base)⌋ + 1) ⌋ .
+                    n = self.ilog2() / (base.ilog2() + 1);
+                    r = base.pow(n);
                 }
 
-                while r >= base {
-                    r /= base;
+                while r <= self / base {
                     n += 1;
+                    r *= base;
                 }
                 Some(n)
             }
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index e741149e7ce..7bd962fa260 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -42,7 +42,6 @@
 #![feature(float_minimum_maximum)]
 #![feature(future_join)]
 #![feature(generic_assert_internals)]
-#![feature(generic_nonzero)]
 #![feature(array_try_from_fn)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index c8db028b651..1ceff2e506c 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -26,7 +26,6 @@
 #![feature(staged_api)]
 #![feature(allow_internal_unstable)]
 #![feature(decl_macro)]
-#![feature(generic_nonzero)]
 #![feature(maybe_uninit_write_slice)]
 #![feature(negative_impls)]
 #![feature(new_uninit)]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 241a443fab9..aa908f0499f 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -335,7 +335,6 @@
 #![feature(float_minimum_maximum)]
 #![feature(float_next_up_down)]
 #![feature(fmt_internals)]
-#![feature(generic_nonzero)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
 #![feature(hint_assert_unchecked)]
diff --git a/library/std/src/num.rs b/library/std/src/num.rs
index 1343fdfd1df..fbe68f7e303 100644
--- a/library/std/src/num.rs
+++ b/library/std/src/num.rs
@@ -23,11 +23,12 @@ pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError}
 )]
 pub use core::num::ZeroablePrimitive;
 
-#[unstable(feature = "generic_nonzero", issue = "120257")]
+#[stable(feature = "generic_nonzero", since = "CURRENT_RUSTC_VERSION")]
 pub use core::num::NonZero;
 
 #[stable(feature = "signed_nonzero", since = "1.34.0")]
 pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
+
 #[stable(feature = "nonzero", since = "1.28.0")]
 pub use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
 
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 69cc61b30ef..4a73a9be88b 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1865,7 +1865,8 @@ impl ExitStatusError {
     /// # Examples
     ///
     /// ```
-    /// #![feature(exit_status_error, generic_nonzero)]
+    /// #![feature(exit_status_error)]
+    ///
     /// # if cfg!(unix) {
     /// use std::num::NonZero;
     /// use std::process::Command;
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index f3c22061d25..f3a26e25938 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -17,7 +17,6 @@
 #![unstable(feature = "test", issue = "50297")]
 #![doc(test(attr(deny(warnings))))]
 #![doc(rust_logo)]
-#![feature(generic_nonzero)]
 #![feature(rustdoc_internals)]
 #![feature(internal_output_capture)]
 #![feature(staged_api)]
diff --git a/src/doc/book b/src/doc/book
-Subproject 3131aa4642c627a24f523c82566b94a7d920f68
+Subproject d207d894cc5e1d496ab99beeacd1a420e5d4d23
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject eb3eb80e106d03250c1fb7c5666b1c8c5967286
+Subproject 0c68e90acaae5a611f8f5098a3c2980de9845ab
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 55694913b1301cc809f9bf4a1ad1b3d6920efbd
+Subproject 5854fcc286557ad3ab34d325073d11d8118096b
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject b77a34bd46399687b4ce6a17198e9f316c98879
+Subproject 07425fed36b00e60341c5e29e28d37d40cbd445
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index db2cd01ce0b..0070d1f3ebc 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -1,4 +1,3 @@
-#![feature(generic_nonzero)]
 #![feature(rustc_private, stmt_expr_attributes)]
 #![allow(
     clippy::manual_range_contains,
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 2e19c9ff713..e1c0da9118d 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -2,7 +2,6 @@
 #![feature(cell_update)]
 #![feature(const_option)]
 #![feature(float_gamma)]
-#![feature(generic_nonzero)]
 #![feature(map_try_insert)]
 #![feature(never_type)]
 #![feature(try_blocks)]
diff --git a/tests/codegen/array-equality.rs b/tests/codegen/array-equality.rs
index 5b85da1d4a0..bc5425c7a4f 100644
--- a/tests/codegen/array-equality.rs
+++ b/tests/codegen/array-equality.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: -O -Z merge-functions=disabled
 //@ only-x86_64
 #![crate_type = "lib"]
-#![feature(generic_nonzero)]
 
 // CHECK-LABEL: @array_eq_value
 #[no_mangle]
diff --git a/tests/codegen/enum/enum-debug-niche-2.rs b/tests/codegen/enum/enum-debug-niche-2.rs
index 25871885e7e..58f43fe3ec6 100644
--- a/tests/codegen/enum/enum-debug-niche-2.rs
+++ b/tests/codegen/enum/enum-debug-niche-2.rs
@@ -7,7 +7,7 @@
 // CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_variant_part,{{.*}}size: 32,{{.*}}
 // CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i128 4294967295{{[,)].*}}
 // CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i128 0{{[,)].*}}
-#![feature(generic_nonzero, never_type)]
+#![feature(never_type)]
 
 #[derive(Copy, Clone)]
 pub struct Entity {
diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs
index 468ec0a7753..2b27dab078d 100644
--- a/tests/codegen/function-arguments.rs
+++ b/tests/codegen/function-arguments.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: -O -C no-prepopulate-passes
 #![crate_type = "lib"]
 #![feature(dyn_star)]
-#![feature(generic_nonzero)]
 #![feature(allocator_api)]
 
 use std::mem::MaybeUninit;
diff --git a/tests/codegen/intrinsics/transmute-niched.rs b/tests/codegen/intrinsics/transmute-niched.rs
index b5e0da1b2f5..f5b7bd2efea 100644
--- a/tests/codegen/intrinsics/transmute-niched.rs
+++ b/tests/codegen/intrinsics/transmute-niched.rs
@@ -3,7 +3,6 @@
 //@ [DBG] compile-flags: -C opt-level=0 -C no-prepopulate-passes
 //@ only-64bit (so I don't need to worry about usize)
 #![crate_type = "lib"]
-#![feature(generic_nonzero)]
 
 use std::mem::transmute;
 use std::num::NonZero;
diff --git a/tests/codegen/issues/issue-119422.rs b/tests/codegen/issues/issue-119422.rs
index 19480b4dc9e..aa56bfe79ac 100644
--- a/tests/codegen/issues/issue-119422.rs
+++ b/tests/codegen/issues/issue-119422.rs
@@ -4,7 +4,6 @@
 //@ compile-flags: -O --edition=2021 -Zmerge-functions=disabled
 //@ only-64bit (because the LLVM type of i64 for usize shows up)
 #![crate_type = "lib"]
-#![feature(generic_nonzero)]
 
 use core::ptr::NonNull;
 use core::num::NonZero;
diff --git a/tests/codegen/loads.rs b/tests/codegen/loads.rs
index ba4de77ce6f..e3e2f757770 100644
--- a/tests/codegen/loads.rs
+++ b/tests/codegen/loads.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: -C no-prepopulate-passes -Zmir-opt-level=0 -O
 
 #![crate_type = "lib"]
-#![feature(generic_nonzero)]
 
 use std::mem::MaybeUninit;
 use std::num::NonZero;
diff --git a/tests/codegen/option-as-slice.rs b/tests/codegen/option-as-slice.rs
index c5b1eafaccb..65637a2495d 100644
--- a/tests/codegen/option-as-slice.rs
+++ b/tests/codegen/option-as-slice.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: -O -Z randomize-layout=no
 //@ only-x86_64
 #![crate_type = "lib"]
-#![feature(generic_nonzero)]
 
 extern crate core;
 
diff --git a/tests/codegen/option-niche-eq.rs b/tests/codegen/option-niche-eq.rs
index 8b8044e9b75..7b955332fd3 100644
--- a/tests/codegen/option-niche-eq.rs
+++ b/tests/codegen/option-niche-eq.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: -O -Zmerge-functions=disabled
 //@ min-llvm-version: 18
 #![crate_type = "lib"]
-#![feature(generic_nonzero)]
 
 extern crate core;
 use core::cmp::Ordering;
diff --git a/tests/codegen/slice-ref-equality.rs b/tests/codegen/slice-ref-equality.rs
index 7ab70108fe0..1153d7817b2 100644
--- a/tests/codegen/slice-ref-equality.rs
+++ b/tests/codegen/slice-ref-equality.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -O -Zmerge-functions=disabled
 #![crate_type = "lib"]
-#![feature(generic_nonzero)]
 
 use std::num::NonZero;
 
diff --git a/tests/codegen/transmute-optimized.rs b/tests/codegen/transmute-optimized.rs
index 1a5f53e625a..8e5bcb2340e 100644
--- a/tests/codegen/transmute-optimized.rs
+++ b/tests/codegen/transmute-optimized.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -O -Z merge-functions=disabled
 #![crate_type = "lib"]
-#![feature(generic_nonzero)]
 
 // This tests that LLVM can optimize based on the niches in the source or
 // destination types for transmutes.
diff --git a/tests/coverage/branch/if-let.cov-map b/tests/coverage/branch/if-let.cov-map
new file mode 100644
index 00000000000..c12df8d9801
--- /dev/null
+++ b/tests/coverage/branch/if-let.cov-map
@@ -0,0 +1,41 @@
+Function name: if_let::if_let
+Raw bytes (38): 0x[01, 01, 02, 05, 09, 09, 02, 06, 01, 0c, 01, 01, 10, 02, 03, 11, 00, 12, 05, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 09, 02, 0c, 02, 06, 07, 03, 05, 01, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 2
+- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
+- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 18)
+    = (c1 - c2)
+- Code(Counter(1)) at (prev + 0, 22) to (start + 0, 27)
+- Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 2, 6)
+    = (c1 - c2)
+- Code(Counter(2)) at (prev + 2, 12) to (start + 2, 6)
+- Code(Expression(1, Add)) at (prev + 3, 5) to (start + 1, 2)
+    = (c2 + (c1 - c2))
+
+Function name: if_let::if_let_chain
+Raw bytes (52): 0x[01, 01, 04, 01, 05, 05, 09, 0f, 0d, 05, 09, 08, 01, 17, 01, 00, 33, 02, 01, 11, 00, 12, 01, 00, 16, 00, 17, 0d, 01, 15, 00, 16, 02, 00, 1a, 00, 1b, 0d, 01, 05, 03, 06, 0f, 03, 0c, 02, 06, 0b, 03, 05, 01, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 4
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
+Number of file 0 mappings: 8
+- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 51)
+- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 18)
+    = (c0 - c1)
+- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 23)
+- Code(Counter(3)) at (prev + 1, 21) to (start + 0, 22)
+- Code(Expression(0, Sub)) at (prev + 0, 26) to (start + 0, 27)
+    = (c0 - c1)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 3, 6)
+- Code(Expression(3, Add)) at (prev + 3, 12) to (start + 2, 6)
+    = (c1 + c2)
+- Code(Expression(2, Add)) at (prev + 3, 5) to (start + 1, 2)
+    = ((c1 + c2) + c3)
+
diff --git a/tests/coverage/branch/if-let.coverage b/tests/coverage/branch/if-let.coverage
new file mode 100644
index 00000000000..f30c5d34eca
--- /dev/null
+++ b/tests/coverage/branch/if-let.coverage
@@ -0,0 +1,62 @@
+   LL|       |#![feature(coverage_attribute, let_chains)]
+   LL|       |//@ edition: 2021
+   LL|       |//@ compile-flags: -Zcoverage-options=branch
+   LL|       |//@ llvm-cov-flags: --show-branches=count
+   LL|       |
+   LL|       |macro_rules! no_merge {
+   LL|       |    () => {
+   LL|       |        for _ in 0..1 {}
+   LL|       |    };
+   LL|       |}
+   LL|       |
+   LL|      3|fn if_let(input: Option<&str>) {
+   LL|      3|    no_merge!();
+   LL|       |
+   LL|      3|    if let Some(x) = input {
+                              ^2
+   LL|      2|        say(x);
+   LL|      2|    } else {
+   LL|      1|        say("none");
+   LL|      1|    }
+   LL|      3|    say("done");
+   LL|      3|}
+   LL|       |
+   LL|     15|fn if_let_chain(a: Option<&str>, b: Option<&str>) {
+   LL|     15|    if let Some(x) = a
+                              ^12
+   LL|     12|        && let Some(y) = b
+                                  ^8
+   LL|      8|    {
+   LL|      8|        say(x);
+   LL|      8|        say(y);
+   LL|      8|    } else {
+   LL|      7|        say("not both");
+   LL|      7|    }
+   LL|     15|    say("done");
+   LL|     15|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn say(message: &str) {
+   LL|       |    core::hint::black_box(message);
+   LL|       |}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    if_let(Some("x"));
+   LL|       |    if_let(Some("x"));
+   LL|       |    if_let(None);
+   LL|       |
+   LL|       |    for _ in 0..8 {
+   LL|       |        if_let_chain(Some("a"), Some("b"));
+   LL|       |    }
+   LL|       |    for _ in 0..4 {
+   LL|       |        if_let_chain(Some("a"), None);
+   LL|       |    }
+   LL|       |    for _ in 0..2 {
+   LL|       |        if_let_chain(None, Some("b"));
+   LL|       |    }
+   LL|       |    if_let_chain(None, None);
+   LL|       |}
+   LL|       |
+   LL|       |// FIXME(#124118) Actually instrument if-let and let-chains for branch coverage.
+
diff --git a/tests/coverage/branch/if-let.rs b/tests/coverage/branch/if-let.rs
new file mode 100644
index 00000000000..13db00a82b1
--- /dev/null
+++ b/tests/coverage/branch/if-let.rs
@@ -0,0 +1,58 @@
+#![feature(coverage_attribute, let_chains)]
+//@ edition: 2021
+//@ compile-flags: -Zcoverage-options=branch
+//@ llvm-cov-flags: --show-branches=count
+
+macro_rules! no_merge {
+    () => {
+        for _ in 0..1 {}
+    };
+}
+
+fn if_let(input: Option<&str>) {
+    no_merge!();
+
+    if let Some(x) = input {
+        say(x);
+    } else {
+        say("none");
+    }
+    say("done");
+}
+
+fn if_let_chain(a: Option<&str>, b: Option<&str>) {
+    if let Some(x) = a
+        && let Some(y) = b
+    {
+        say(x);
+        say(y);
+    } else {
+        say("not both");
+    }
+    say("done");
+}
+
+#[coverage(off)]
+fn say(message: &str) {
+    core::hint::black_box(message);
+}
+
+#[coverage(off)]
+fn main() {
+    if_let(Some("x"));
+    if_let(Some("x"));
+    if_let(None);
+
+    for _ in 0..8 {
+        if_let_chain(Some("a"), Some("b"));
+    }
+    for _ in 0..4 {
+        if_let_chain(Some("a"), None);
+    }
+    for _ in 0..2 {
+        if_let_chain(None, Some("b"));
+    }
+    if_let_chain(None, None);
+}
+
+// FIXME(#124118) Actually instrument if-let and let-chains for branch coverage.
diff --git a/tests/coverage/branch/let-else.cov-map b/tests/coverage/branch/let-else.cov-map
new file mode 100644
index 00000000000..ad987bd6bb1
--- /dev/null
+++ b/tests/coverage/branch/let-else.cov-map
@@ -0,0 +1,18 @@
+Function name: let_else::let_else
+Raw bytes (38): 0x[01, 01, 02, 05, 09, 09, 02, 06, 01, 0c, 01, 01, 10, 02, 03, 0e, 00, 0f, 05, 00, 13, 00, 18, 09, 01, 09, 01, 0f, 02, 04, 05, 00, 0b, 07, 01, 01, 00, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 2
+- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(2), rhs = Expression(0, Sub)
+Number of file 0 mappings: 6
+- Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
+- Code(Expression(0, Sub)) at (prev + 3, 14) to (start + 0, 15)
+    = (c1 - c2)
+- Code(Counter(1)) at (prev + 0, 19) to (start + 0, 24)
+- Code(Counter(2)) at (prev + 1, 9) to (start + 1, 15)
+- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 11)
+    = (c1 - c2)
+- Code(Expression(1, Add)) at (prev + 1, 1) to (start + 0, 2)
+    = (c2 + (c1 - c2))
+
diff --git a/tests/coverage/branch/let-else.coverage b/tests/coverage/branch/let-else.coverage
new file mode 100644
index 00000000000..83730e1dfba
--- /dev/null
+++ b/tests/coverage/branch/let-else.coverage
@@ -0,0 +1,37 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |//@ edition: 2021
+   LL|       |//@ compile-flags: -Zcoverage-options=branch
+   LL|       |//@ llvm-cov-flags: --show-branches=count
+   LL|       |
+   LL|       |macro_rules! no_merge {
+   LL|       |    () => {
+   LL|       |        for _ in 0..1 {}
+   LL|       |    };
+   LL|       |}
+   LL|       |
+   LL|      3|fn let_else(value: Option<&str>) {
+   LL|      3|    no_merge!();
+   LL|       |
+   LL|      3|    let Some(x) = value else {
+                           ^2
+   LL|      1|        say("none");
+   LL|      1|        return;
+   LL|       |    };
+   LL|       |
+   LL|      2|    say(x);
+   LL|      3|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn say(message: &str) {
+   LL|       |    core::hint::black_box(message);
+   LL|       |}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    let_else(Some("x"));
+   LL|       |    let_else(Some("x"));
+   LL|       |    let_else(None);
+   LL|       |}
+   LL|       |
+   LL|       |// FIXME(#124118) Actually instrument let-else for branch coverage.
+
diff --git a/tests/coverage/branch/let-else.rs b/tests/coverage/branch/let-else.rs
new file mode 100644
index 00000000000..af0665d8241
--- /dev/null
+++ b/tests/coverage/branch/let-else.rs
@@ -0,0 +1,35 @@
+#![feature(coverage_attribute)]
+//@ edition: 2021
+//@ compile-flags: -Zcoverage-options=branch
+//@ llvm-cov-flags: --show-branches=count
+
+macro_rules! no_merge {
+    () => {
+        for _ in 0..1 {}
+    };
+}
+
+fn let_else(value: Option<&str>) {
+    no_merge!();
+
+    let Some(x) = value else {
+        say("none");
+        return;
+    };
+
+    say(x);
+}
+
+#[coverage(off)]
+fn say(message: &str) {
+    core::hint::black_box(message);
+}
+
+#[coverage(off)]
+fn main() {
+    let_else(Some("x"));
+    let_else(Some("x"));
+    let_else(None);
+}
+
+// FIXME(#124118) Actually instrument let-else for branch coverage.
diff --git a/tests/coverage/branch/match-arms.cov-map b/tests/coverage/branch/match-arms.cov-map
new file mode 100644
index 00000000000..1f17f11baaa
--- /dev/null
+++ b/tests/coverage/branch/match-arms.cov-map
@@ -0,0 +1,92 @@
+Function name: match_arms::guards
+Raw bytes (88): 0x[01, 01, 08, 07, 15, 0b, 11, 0f, 0d, 00, 09, 17, 25, 1b, 21, 1f, 1d, 03, 19, 0c, 01, 30, 01, 01, 10, 29, 03, 0b, 00, 10, 19, 01, 11, 00, 29, 20, 19, 09, 00, 17, 00, 1b, 1d, 01, 11, 00, 29, 20, 1d, 0d, 00, 17, 00, 1b, 21, 01, 11, 00, 29, 20, 21, 11, 00, 17, 00, 1b, 25, 01, 11, 00, 29, 20, 25, 15, 00, 17, 00, 1b, 03, 01, 0e, 00, 18, 13, 03, 05, 01, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 8
+- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(5)
+- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4)
+- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(3)
+- expression 3 operands: lhs = Zero, rhs = Counter(2)
+- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(9)
+- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(8)
+- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(7)
+- expression 7 operands: lhs = Expression(0, Add), rhs = Counter(6)
+Number of file 0 mappings: 12
+- Code(Counter(0)) at (prev + 48, 1) to (start + 1, 16)
+- Code(Counter(10)) at (prev + 3, 11) to (start + 0, 16)
+- Code(Counter(6)) at (prev + 1, 17) to (start + 0, 41)
+- Branch { true: Counter(6), false: Counter(2) } at (prev + 0, 23) to (start + 0, 27)
+    true  = c6
+    false = c2
+- Code(Counter(7)) at (prev + 1, 17) to (start + 0, 41)
+- Branch { true: Counter(7), false: Counter(3) } at (prev + 0, 23) to (start + 0, 27)
+    true  = c7
+    false = c3
+- Code(Counter(8)) at (prev + 1, 17) to (start + 0, 41)
+- Branch { true: Counter(8), false: Counter(4) } at (prev + 0, 23) to (start + 0, 27)
+    true  = c8
+    false = c4
+- Code(Counter(9)) at (prev + 1, 17) to (start + 0, 41)
+- Branch { true: Counter(9), false: Counter(5) } at (prev + 0, 23) to (start + 0, 27)
+    true  = c9
+    false = c5
+- Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 24)
+    = ((((Zero + c2) + c3) + c4) + c5)
+- Code(Expression(4, Add)) at (prev + 3, 5) to (start + 1, 2)
+    = ((((((((Zero + c2) + c3) + c4) + c5) + c6) + c7) + c8) + c9)
+
+Function name: match_arms::match_arms
+Raw bytes (51): 0x[01, 01, 06, 05, 07, 0b, 11, 09, 0d, 13, 02, 17, 09, 11, 0d, 07, 01, 18, 01, 01, 10, 05, 03, 0b, 00, 10, 11, 01, 11, 00, 21, 0d, 01, 11, 00, 21, 09, 01, 11, 00, 21, 02, 01, 11, 00, 21, 0f, 03, 05, 01, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 6
+- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add)
+- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4)
+- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 3 operands: lhs = Expression(4, Add), rhs = Expression(0, Sub)
+- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(2)
+- expression 5 operands: lhs = Counter(4), rhs = Counter(3)
+Number of file 0 mappings: 7
+- Code(Counter(0)) at (prev + 24, 1) to (start + 1, 16)
+- Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16)
+- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33)
+- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 33)
+    = (c1 - ((c2 + c3) + c4))
+- Code(Expression(3, Add)) at (prev + 3, 5) to (start + 1, 2)
+    = (((c4 + c3) + c2) + (c1 - ((c2 + c3) + c4)))
+
+Function name: match_arms::or_patterns
+Raw bytes (75): 0x[01, 01, 0d, 11, 0d, 05, 2f, 33, 11, 09, 0d, 09, 2a, 05, 2f, 33, 11, 09, 0d, 03, 27, 09, 2a, 05, 2f, 33, 11, 09, 0d, 09, 01, 25, 01, 01, 10, 05, 03, 0b, 00, 10, 11, 01, 11, 00, 12, 0d, 00, 1e, 00, 1f, 03, 00, 24, 00, 2e, 09, 01, 11, 00, 12, 2a, 00, 1e, 00, 1f, 27, 00, 24, 00, 2e, 23, 03, 05, 01, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 13
+- expression 0 operands: lhs = Counter(4), rhs = Counter(3)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(11, Add)
+- expression 2 operands: lhs = Expression(12, Add), rhs = Counter(4)
+- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 4 operands: lhs = Counter(2), rhs = Expression(10, Sub)
+- expression 5 operands: lhs = Counter(1), rhs = Expression(11, Add)
+- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(4)
+- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 8 operands: lhs = Expression(0, Add), rhs = Expression(9, Add)
+- expression 9 operands: lhs = Counter(2), rhs = Expression(10, Sub)
+- expression 10 operands: lhs = Counter(1), rhs = Expression(11, Add)
+- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(4)
+- expression 12 operands: lhs = Counter(2), rhs = Counter(3)
+Number of file 0 mappings: 9
+- Code(Counter(0)) at (prev + 37, 1) to (start + 1, 16)
+- Code(Counter(1)) at (prev + 3, 11) to (start + 0, 16)
+- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31)
+- Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 46)
+    = (c4 + c3)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Expression(10, Sub)) at (prev + 0, 30) to (start + 0, 31)
+    = (c1 - ((c2 + c3) + c4))
+- Code(Expression(9, Add)) at (prev + 0, 36) to (start + 0, 46)
+    = (c2 + (c1 - ((c2 + c3) + c4)))
+- Code(Expression(8, Add)) at (prev + 3, 5) to (start + 1, 2)
+    = ((c4 + c3) + (c2 + (c1 - ((c2 + c3) + c4))))
+
diff --git a/tests/coverage/branch/match-arms.coverage b/tests/coverage/branch/match-arms.coverage
new file mode 100644
index 00000000000..ea8a6f97ab1
--- /dev/null
+++ b/tests/coverage/branch/match-arms.coverage
@@ -0,0 +1,105 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |//@ edition: 2021
+   LL|       |//@ compile-flags: -Zcoverage-options=branch
+   LL|       |//@ llvm-cov-flags: --show-branches=count
+   LL|       |
+   LL|       |// Tests for branch coverage of various kinds of match arms.
+   LL|       |
+   LL|       |// Helper macro to prevent start-of-function spans from being merged into
+   LL|       |// spans on the lines we care about.
+   LL|       |macro_rules! no_merge {
+   LL|       |    () => {
+   LL|       |        for _ in 0..1 {}
+   LL|       |    };
+   LL|       |}
+   LL|       |
+   LL|       |#[derive(Clone, Copy, Debug)]
+   LL|       |enum Enum {
+   LL|       |    A(u32),
+   LL|       |    B(u32),
+   LL|       |    C(u32),
+   LL|       |    D(u32),
+   LL|       |}
+   LL|       |
+   LL|     15|fn match_arms(value: Enum) {
+   LL|     15|    no_merge!();
+   LL|       |
+   LL|     15|    match value {
+   LL|      8|        Enum::D(d) => consume(d),
+   LL|      4|        Enum::C(c) => consume(c),
+   LL|      2|        Enum::B(b) => consume(b),
+   LL|      1|        Enum::A(a) => consume(a),
+   LL|       |    }
+   LL|       |
+   LL|     15|    consume(0);
+   LL|     15|}
+   LL|       |
+   LL|     15|fn or_patterns(value: Enum) {
+   LL|     15|    no_merge!();
+   LL|       |
+   LL|     15|    match value {
+   LL|     12|        Enum::D(x) | Enum::C(x) => consume(x),
+                              ^8           ^4
+   LL|      3|        Enum::B(y) | Enum::A(y) => consume(y),
+                              ^2           ^1
+   LL|       |    }
+   LL|       |
+   LL|     15|    consume(0);
+   LL|     15|}
+   LL|       |
+   LL|     45|fn guards(value: Enum, cond: bool) {
+   LL|     45|    no_merge!();
+   LL|       |
+   LL|      3|    match value {
+   LL|      8|        Enum::D(d) if cond => consume(d),
+  ------------------
+  |  Branch (LL:23): [True: 8, False: 16]
+  ------------------
+   LL|      4|        Enum::C(c) if cond => consume(c),
+  ------------------
+  |  Branch (LL:23): [True: 4, False: 8]
+  ------------------
+   LL|      2|        Enum::B(b) if cond => consume(b),
+  ------------------
+  |  Branch (LL:23): [True: 2, False: 4]
+  ------------------
+   LL|      1|        Enum::A(a) if cond => consume(a),
+  ------------------
+  |  Branch (LL:23): [True: 1, False: 2]
+  ------------------
+   LL|     30|        _ => consume(0),
+   LL|       |    }
+   LL|       |
+   LL|     45|    consume(0);
+   LL|     45|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn consume<T>(x: T) {
+   LL|       |    core::hint::black_box(x);
+   LL|       |}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    #[coverage(off)]
+   LL|       |    fn call_everything(e: Enum) {
+   LL|       |        match_arms(e);
+   LL|       |        or_patterns(e);
+   LL|       |        for cond in [false, false, true] {
+   LL|       |            guards(e, cond);
+   LL|       |        }
+   LL|       |    }
+   LL|       |
+   LL|       |    call_everything(Enum::A(0));
+   LL|       |    for b in 0..2 {
+   LL|       |        call_everything(Enum::B(b));
+   LL|       |    }
+   LL|       |    for c in 0..4 {
+   LL|       |        call_everything(Enum::C(c));
+   LL|       |    }
+   LL|       |    for d in 0..8 {
+   LL|       |        call_everything(Enum::D(d));
+   LL|       |    }
+   LL|       |}
+   LL|       |
+   LL|       |// FIXME(#124118) Actually instrument match arms for branch coverage.
+
diff --git a/tests/coverage/branch/match-arms.rs b/tests/coverage/branch/match-arms.rs
new file mode 100644
index 00000000000..63151f59ffe
--- /dev/null
+++ b/tests/coverage/branch/match-arms.rs
@@ -0,0 +1,90 @@
+#![feature(coverage_attribute)]
+//@ edition: 2021
+//@ compile-flags: -Zcoverage-options=branch
+//@ llvm-cov-flags: --show-branches=count
+
+// Tests for branch coverage of various kinds of match arms.
+
+// Helper macro to prevent start-of-function spans from being merged into
+// spans on the lines we care about.
+macro_rules! no_merge {
+    () => {
+        for _ in 0..1 {}
+    };
+}
+
+#[derive(Clone, Copy, Debug)]
+enum Enum {
+    A(u32),
+    B(u32),
+    C(u32),
+    D(u32),
+}
+
+fn match_arms(value: Enum) {
+    no_merge!();
+
+    match value {
+        Enum::D(d) => consume(d),
+        Enum::C(c) => consume(c),
+        Enum::B(b) => consume(b),
+        Enum::A(a) => consume(a),
+    }
+
+    consume(0);
+}
+
+fn or_patterns(value: Enum) {
+    no_merge!();
+
+    match value {
+        Enum::D(x) | Enum::C(x) => consume(x),
+        Enum::B(y) | Enum::A(y) => consume(y),
+    }
+
+    consume(0);
+}
+
+fn guards(value: Enum, cond: bool) {
+    no_merge!();
+
+    match value {
+        Enum::D(d) if cond => consume(d),
+        Enum::C(c) if cond => consume(c),
+        Enum::B(b) if cond => consume(b),
+        Enum::A(a) if cond => consume(a),
+        _ => consume(0),
+    }
+
+    consume(0);
+}
+
+#[coverage(off)]
+fn consume<T>(x: T) {
+    core::hint::black_box(x);
+}
+
+#[coverage(off)]
+fn main() {
+    #[coverage(off)]
+    fn call_everything(e: Enum) {
+        match_arms(e);
+        or_patterns(e);
+        for cond in [false, false, true] {
+            guards(e, cond);
+        }
+    }
+
+    call_everything(Enum::A(0));
+    for b in 0..2 {
+        call_everything(Enum::B(b));
+    }
+    for c in 0..4 {
+        call_everything(Enum::C(c));
+    }
+    for d in 0..8 {
+        call_everything(Enum::D(d));
+    }
+}
+
+// FIXME(#124118) Actually instrument match arms for branch coverage.
diff --git a/tests/coverage/branch/match-trivial.cov-map b/tests/coverage/branch/match-trivial.cov-map
new file mode 100644
index 00000000000..1136a529b25
--- /dev/null
+++ b/tests/coverage/branch/match-trivial.cov-map
@@ -0,0 +1,17 @@
+Function name: match_trivial::_uninhabited (unused)
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 01, 10]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Zero) at (prev + 22, 1) to (start + 1, 16)
+
+Function name: match_trivial::trivial
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 10, 05, 03, 0b, 05, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16)
+- Code(Counter(1)) at (prev + 3, 11) to (start + 5, 2)
+
diff --git a/tests/coverage/branch/match-trivial.coverage b/tests/coverage/branch/match-trivial.coverage
new file mode 100644
index 00000000000..4ffb172e1b6
--- /dev/null
+++ b/tests/coverage/branch/match-trivial.coverage
@@ -0,0 +1,49 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |//@ edition: 2021
+   LL|       |//@ compile-flags: -Zcoverage-options=branch
+   LL|       |//@ llvm-cov-flags: --show-branches=count
+   LL|       |
+   LL|       |// When instrumenting match expressions for branch coverage, make sure we don't
+   LL|       |// cause an ICE or produce weird coverage output for matches with <2 arms.
+   LL|       |
+   LL|       |// Helper macro to prevent start-of-function spans from being merged into
+   LL|       |// spans on the lines we care about.
+   LL|       |macro_rules! no_merge {
+   LL|       |    () => {
+   LL|       |        for _ in 0..1 {}
+   LL|       |    };
+   LL|       |}
+   LL|       |
+   LL|       |enum Uninhabited {}
+   LL|       |enum Trivial {
+   LL|       |    Value,
+   LL|       |}
+   LL|       |
+   LL|      0|fn _uninhabited(x: Uninhabited) {
+   LL|      0|    no_merge!();
+   LL|       |
+   LL|       |    match x {}
+   LL|       |
+   LL|       |    consume("done");
+   LL|       |}
+   LL|       |
+   LL|      1|fn trivial(x: Trivial) {
+   LL|      1|    no_merge!();
+   LL|       |
+   LL|      1|    match x {
+   LL|      1|        Trivial::Value => consume("trivial"),
+   LL|      1|    }
+   LL|      1|
+   LL|      1|    consume("done");
+   LL|      1|}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn consume<T>(x: T) {
+   LL|       |    core::hint::black_box(x);
+   LL|       |}
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |fn main() {
+   LL|       |    trivial(Trivial::Value);
+   LL|       |}
+
diff --git a/tests/coverage/branch/match-trivial.rs b/tests/coverage/branch/match-trivial.rs
new file mode 100644
index 00000000000..db8887a26b7
--- /dev/null
+++ b/tests/coverage/branch/match-trivial.rs
@@ -0,0 +1,48 @@
+#![feature(coverage_attribute)]
+//@ edition: 2021
+//@ compile-flags: -Zcoverage-options=branch
+//@ llvm-cov-flags: --show-branches=count
+
+// When instrumenting match expressions for branch coverage, make sure we don't
+// cause an ICE or produce weird coverage output for matches with <2 arms.
+
+// Helper macro to prevent start-of-function spans from being merged into
+// spans on the lines we care about.
+macro_rules! no_merge {
+    () => {
+        for _ in 0..1 {}
+    };
+}
+
+enum Uninhabited {}
+enum Trivial {
+    Value,
+}
+
+fn _uninhabited(x: Uninhabited) {
+    no_merge!();
+
+    match x {}
+
+    consume("done");
+}
+
+fn trivial(x: Trivial) {
+    no_merge!();
+
+    match x {
+        Trivial::Value => consume("trivial"),
+    }
+
+    consume("done");
+}
+
+#[coverage(off)]
+fn consume<T>(x: T) {
+    core::hint::black_box(x);
+}
+
+#[coverage(off)]
+fn main() {
+    trivial(Trivial::Value);
+}
diff --git a/tests/debuginfo/msvc-pretty-enums.rs b/tests/debuginfo/msvc-pretty-enums.rs
index cfac14a22c4..0293ec0ec39 100644
--- a/tests/debuginfo/msvc-pretty-enums.rs
+++ b/tests/debuginfo/msvc-pretty-enums.rs
@@ -132,7 +132,6 @@
 // cdb-command: dx -r2 arbitrary_discr2,d
 // cdb-check: arbitrary_discr2,d : Def [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
 // cdb-check:     [+0x[...]] __0              : 5678 [Type: unsigned int]
-#![feature(generic_nonzero)]
 #![feature(rustc_attrs)]
 #![feature(repr128)]
 #![feature(arbitrary_enum_discriminant)]
diff --git a/tests/debuginfo/numeric-types.rs b/tests/debuginfo/numeric-types.rs
index 1ff72d34fbd..98bc31e8855 100644
--- a/tests/debuginfo/numeric-types.rs
+++ b/tests/debuginfo/numeric-types.rs
@@ -237,7 +237,6 @@
 
 // lldb-command:v nz_usize
 // lldb-check:[...] 122 { __0 = { 0 = 122 } }
-#![feature(generic_nonzero)]
 
 use std::num::*;
 use std::sync::atomic::*;
diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
new file mode 100644
index 00000000000..e60f71f47b1
--- /dev/null
+++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
@@ -0,0 +1,138 @@
+- // MIR for `main` before InstrumentCoverage
++ // MIR for `main` after InstrumentCoverage
+  
+  fn main() -> () {
+      let mut _0: ();
+      let mut _1: Enum;
+      let mut _2: isize;
+      let _3: u32;
+      let mut _4: u32;
+      let _5: u32;
+      let mut _6: u32;
+      let _7: u32;
+      let mut _8: u32;
+      let _9: u32;
+      let mut _10: u32;
+      scope 1 {
+          debug d => _3;
+      }
+      scope 2 {
+          debug c => _5;
+      }
+      scope 3 {
+          debug b => _7;
+      }
+      scope 4 {
+          debug a => _9;
+      }
+  
++     coverage ExpressionId(0) => Expression { lhs: Counter(1), op: Add, rhs: Counter(2) };
++     coverage ExpressionId(1) => Expression { lhs: Expression(0), op: Add, rhs: Counter(3) };
++     coverage ExpressionId(2) => Expression { lhs: Counter(0), op: Subtract, rhs: Expression(1) };
++     coverage ExpressionId(3) => Expression { lhs: Counter(3), op: Add, rhs: Counter(2) };
++     coverage ExpressionId(4) => Expression { lhs: Expression(3), op: Add, rhs: Counter(1) };
++     coverage ExpressionId(5) => Expression { lhs: Expression(4), op: Add, rhs: Expression(2) };
++     coverage Code(Counter(0)) => $DIR/branch_match_arms.rs:14:1 - 15:21;
++     coverage Code(Counter(3)) => $DIR/branch_match_arms.rs:16:17 - 16:33;
++     coverage Code(Counter(2)) => $DIR/branch_match_arms.rs:17:17 - 17:33;
++     coverage Code(Counter(1)) => $DIR/branch_match_arms.rs:18:17 - 18:33;
++     coverage Code(Expression(2)) => $DIR/branch_match_arms.rs:19:17 - 19:33;
++     coverage Code(Expression(5)) => $DIR/branch_match_arms.rs:21:1 - 21:2;
++ 
+      bb0: {
++         Coverage::CounterIncrement(0);
+          StorageLive(_1);
+          _1 = Enum::A(const 0_u32);
+          PlaceMention(_1);
+          _2 = discriminant(_1);
+          switchInt(move _2) -> [0: bb5, 1: bb4, 2: bb3, 3: bb2, otherwise: bb1];
+      }
+  
+      bb1: {
+          FakeRead(ForMatchedPlace(None), _1);
+          unreachable;
+      }
+  
+      bb2: {
++         Coverage::CounterIncrement(3);
+          falseEdge -> [real: bb6, imaginary: bb3];
+      }
+  
+      bb3: {
++         Coverage::CounterIncrement(2);
+          falseEdge -> [real: bb8, imaginary: bb4];
+      }
+  
+      bb4: {
++         Coverage::CounterIncrement(1);
+          falseEdge -> [real: bb10, imaginary: bb5];
+      }
+  
+      bb5: {
++         Coverage::ExpressionUsed(2);
+          StorageLive(_9);
+          _9 = ((_1 as A).0: u32);
+          StorageLive(_10);
+          _10 = _9;
+          _0 = consume(move _10) -> [return: bb12, unwind: bb14];
+      }
+  
+      bb6: {
+          StorageLive(_3);
+          _3 = ((_1 as D).0: u32);
+          StorageLive(_4);
+          _4 = _3;
+          _0 = consume(move _4) -> [return: bb7, unwind: bb14];
+      }
+  
+      bb7: {
+          StorageDead(_4);
+          StorageDead(_3);
+          goto -> bb13;
+      }
+  
+      bb8: {
+          StorageLive(_5);
+          _5 = ((_1 as C).0: u32);
+          StorageLive(_6);
+          _6 = _5;
+          _0 = consume(move _6) -> [return: bb9, unwind: bb14];
+      }
+  
+      bb9: {
+          StorageDead(_6);
+          StorageDead(_5);
+          goto -> bb13;
+      }
+  
+      bb10: {
+          StorageLive(_7);
+          _7 = ((_1 as B).0: u32);
+          StorageLive(_8);
+          _8 = _7;
+          _0 = consume(move _8) -> [return: bb11, unwind: bb14];
+      }
+  
+      bb11: {
+          StorageDead(_8);
+          StorageDead(_7);
+          goto -> bb13;
+      }
+  
+      bb12: {
+          StorageDead(_10);
+          StorageDead(_9);
+          goto -> bb13;
+      }
+  
+      bb13: {
++         Coverage::ExpressionUsed(5);
+          StorageDead(_1);
+          return;
+      }
+  
+      bb14 (cleanup): {
+          resume;
+      }
+  }
+  
diff --git a/tests/mir-opt/coverage/branch_match_arms.rs b/tests/mir-opt/coverage/branch_match_arms.rs
new file mode 100644
index 00000000000..18764b38d6e
--- /dev/null
+++ b/tests/mir-opt/coverage/branch_match_arms.rs
@@ -0,0 +1,27 @@
+#![feature(coverage_attribute)]
+//@ test-mir-pass: InstrumentCoverage
+//@ compile-flags: -Cinstrument-coverage -Zno-profiler-runtime -Zcoverage-options=branch
+// skip-filecheck
+
+enum Enum {
+    A(u32),
+    B(u32),
+    C(u32),
+    D(u32),
+}
+
+// EMIT_MIR branch_match_arms.main.InstrumentCoverage.diff
+fn main() {
+    match Enum::A(0) {
+        Enum::D(d) => consume(d),
+        Enum::C(c) => consume(c),
+        Enum::B(b) => consume(b),
+        Enum::A(a) => consume(a),
+    }
+}
+
+#[inline(never)]
+#[coverage(off)]
+fn consume(x: u32) {
+    core::hint::black_box(x);
+}
diff --git a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
index 01b01ea5c17..01b01ea5c17 100644
--- a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
diff --git a/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
index 3606a9e3932..3606a9e3932 100644
--- a/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
diff --git a/tests/mir-opt/instrument_coverage.rs b/tests/mir-opt/coverage/instrument_coverage.rs
index beb88b607f9..beb88b607f9 100644
--- a/tests/mir-opt/instrument_coverage.rs
+++ b/tests/mir-opt/coverage/instrument_coverage.rs
diff --git a/tests/mir-opt/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
index 34d011540b9..34d011540b9 100644
--- a/tests/mir-opt/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
diff --git a/tests/mir-opt/instrument_coverage_cleanup.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
index 6756d5c1e1b..6756d5c1e1b 100644
--- a/tests/mir-opt/instrument_coverage_cleanup.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
diff --git a/tests/mir-opt/instrument_coverage_cleanup.rs b/tests/mir-opt/coverage/instrument_coverage_cleanup.rs
index acc544a28af..acc544a28af 100644
--- a/tests/mir-opt/instrument_coverage_cleanup.rs
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.rs
diff --git a/tests/mir-opt/instsimplify/combine_transmutes.rs b/tests/mir-opt/instsimplify/combine_transmutes.rs
index a1274dd1b40..0be7466001f 100644
--- a/tests/mir-opt/instsimplify/combine_transmutes.rs
+++ b/tests/mir-opt/instsimplify/combine_transmutes.rs
@@ -3,7 +3,6 @@
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
 #![feature(custom_mir)]
-#![feature(generic_nonzero)]
 
 use std::intrinsics::mir::*;
 use std::mem::{MaybeUninit, ManuallyDrop, transmute};
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index 3ee4542810c..373d1cce1d7 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -64,7 +64,6 @@
   [csky] needs-llvm-components: csky
 */
 #![feature(rustc_attrs, unsized_fn_params, transparent_unions)]
-#![cfg_attr(host, feature(generic_nonzero))]
 #![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)]
 #![allow(unused, improper_ctypes_definitions, internal_features)]
 
diff --git a/tests/ui/consts/const-eval/raw-bytes.rs b/tests/ui/consts/const-eval/raw-bytes.rs
index e5dfd5ca293..2fbf135c997 100644
--- a/tests/ui/consts/const-eval/raw-bytes.rs
+++ b/tests/ui/consts/const-eval/raw-bytes.rs
@@ -3,7 +3,7 @@
 // ignore-tidy-linelength
 //@ normalize-stderr-test "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼" -> "╾ALLOC_ID$1╼"
 #![allow(invalid_value)]
-#![feature(generic_nonzero, never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)]
+#![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)]
 
 use std::mem;
 use std::alloc::Layout;
diff --git a/tests/ui/consts/const-eval/ub-nonnull.rs b/tests/ui/consts/const-eval/ub-nonnull.rs
index 76bd5248ffd..10d304436f8 100644
--- a/tests/ui/consts/const-eval/ub-nonnull.rs
+++ b/tests/ui/consts/const-eval/ub-nonnull.rs
@@ -2,7 +2,7 @@
 //@ normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
 //@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
 #![allow(invalid_value)] // make sure we cannot allow away the errors tested here
-#![feature(generic_nonzero, rustc_attrs, ptr_metadata)]
+#![feature(rustc_attrs, ptr_metadata)]
 
 use std::mem;
 use std::ptr::NonNull;
diff --git a/tests/ui/consts/const-eval/valid-const.rs b/tests/ui/consts/const-eval/valid-const.rs
index 15d3e883456..777484c6b09 100644
--- a/tests/ui/consts/const-eval/valid-const.rs
+++ b/tests/ui/consts/const-eval/valid-const.rs
@@ -1,7 +1,6 @@
 //@ check-pass
 //
 // Some constants that *are* valid
-#![feature(generic_nonzero)]
 
 use std::mem;
 use std::ptr::NonNull;
diff --git a/tests/ui/consts/tuple-struct-constructors.rs b/tests/ui/consts/tuple-struct-constructors.rs
index d2f25aeec9b..e645b574075 100644
--- a/tests/ui/consts/tuple-struct-constructors.rs
+++ b/tests/ui/consts/tuple-struct-constructors.rs
@@ -1,7 +1,6 @@
 //@ run-pass
 //
 // https://github.com/rust-lang/rust/issues/41898
-#![feature(generic_nonzero)]
 
 use std::num::NonZero;
 
diff --git a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs
index b1ac7528d58..67b9832d601 100644
--- a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs
+++ b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -7,7 +7,6 @@
 //
 // This test checks panic emitted from `mem::{uninitialized,zeroed}`.
 #![allow(deprecated, invalid_value)]
-#![feature(generic_nonzero)]
 #![feature(never_type)]
 
 use std::{
diff --git a/tests/ui/issues/issue-64593.rs b/tests/ui/issues/issue-64593.rs
index 091c3a2f316..e28b9577347 100644
--- a/tests/ui/issues/issue-64593.rs
+++ b/tests/ui/issues/issue-64593.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 #![deny(improper_ctypes)]
-#![feature(generic_nonzero)]
 
 pub struct Error(std::num::NonZero<u32>);
 
diff --git a/tests/ui/layout/unsafe-cell-hides-niche.rs b/tests/ui/layout/unsafe-cell-hides-niche.rs
index 568eb819be2..fe51c9925e8 100644
--- a/tests/ui/layout/unsafe-cell-hides-niche.rs
+++ b/tests/ui/layout/unsafe-cell-hides-niche.rs
@@ -6,7 +6,6 @@
 //@ check-pass
 //@ compile-flags: --crate-type=lib
 //@ only-x86
-#![feature(generic_nonzero)]
 #![feature(repr_simd)]
 
 use std::cell::{UnsafeCell, RefCell, Cell};
diff --git a/tests/ui/layout/zero-sized-array-enum-niche.rs b/tests/ui/layout/zero-sized-array-enum-niche.rs
index 058f5923487..0c37c0f010e 100644
--- a/tests/ui/layout/zero-sized-array-enum-niche.rs
+++ b/tests/ui/layout/zero-sized-array-enum-niche.rs
@@ -1,6 +1,5 @@
 //@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN"
 #![crate_type = "lib"]
-#![feature(generic_nonzero)]
 #![feature(rustc_attrs)]
 
 // Various tests around the behavior of zero-sized arrays and
diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr
index af049125de4..ee34cfdfb0d 100644
--- a/tests/ui/layout/zero-sized-array-enum-niche.stderr
+++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr
@@ -98,7 +98,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),
        }
-  --> $DIR/zero-sized-array-enum-niche.rs:14:1
+  --> $DIR/zero-sized-array-enum-niche.rs:13:1
    |
 LL | type AlignedResult = Result<[u32; 0], bool>;
    | ^^^^^^^^^^^^^^^^^^
@@ -227,7 +227,7 @@ error: layout_of(MultipleAlignments) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),
        }
-  --> $DIR/zero-sized-array-enum-niche.rs:22:1
+  --> $DIR/zero-sized-array-enum-niche.rs:21:1
    |
 LL | enum MultipleAlignments {
    | ^^^^^^^^^^^^^^^^^^^^^^^
@@ -332,7 +332,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),
        }
-  --> $DIR/zero-sized-array-enum-niche.rs:38:1
+  --> $DIR/zero-sized-array-enum-niche.rs:37:1
    |
 LL | type NicheLosesToTagged = Result<[u32; 0], Packed<std::num::NonZero<u16>>>;
    | ^^^^^^^^^^^^^^^^^^^^^^^
@@ -441,7 +441,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
            max_repr_align: None,
            unadjusted_abi_align: Align(4 bytes),
        }
-  --> $DIR/zero-sized-array-enum-niche.rs:45:1
+  --> $DIR/zero-sized-array-enum-niche.rs:44:1
    |
 LL | type NicheWinsOverTagged = Result<[u32; 0], Packed<U16IsZero>>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/clashing-extern-fn.rs b/tests/ui/lint/clashing-extern-fn.rs
index cb63af0ea42..728dfabb393 100644
--- a/tests/ui/lint/clashing-extern-fn.rs
+++ b/tests/ui/lint/clashing-extern-fn.rs
@@ -2,7 +2,6 @@
 //@ aux-build:external_extern_fn.rs
 #![crate_type = "lib"]
 #![warn(clashing_extern_declarations)]
-#![feature(generic_nonzero)]
 
 mod redeclared_different_signature {
     mod a {
diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr
index 86ee789aeb2..43c8cdead9f 100644
--- a/tests/ui/lint/clashing-extern-fn.stderr
+++ b/tests/ui/lint/clashing-extern-fn.stderr
@@ -1,5 +1,5 @@
 warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
-  --> $DIR/clashing-extern-fn.rs:430:55
+  --> $DIR/clashing-extern-fn.rs:429:55
    |
 LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
    |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -9,7 +9,7 @@ LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
    = note: `#[warn(improper_ctypes)]` on by default
 
 warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
-  --> $DIR/clashing-extern-fn.rs:434:46
+  --> $DIR/clashing-extern-fn.rs:433:46
    |
 LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usize>>>;
    |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -18,7 +18,7 @@ LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
    = note: enum has no representation hint
 
 warning: `clash` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:15:13
+  --> $DIR/clashing-extern-fn.rs:14:13
    |
 LL |             fn clash(x: u8);
    |             --------------- `clash` previously declared here
@@ -35,7 +35,7 @@ LL | #![warn(clashing_extern_declarations)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `extern_link_name` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:53:9
+  --> $DIR/clashing-extern-fn.rs:52:9
    |
 LL |     #[link_name = "extern_link_name"]
    |     --------------------------------- `extern_link_name` previously declared here
@@ -47,7 +47,7 @@ LL |         fn extern_link_name(x: u32);
               found `unsafe extern "C" fn(u32)`
 
 warning: `some_other_extern_link_name` redeclares `some_other_new_name` with a different signature
-  --> $DIR/clashing-extern-fn.rs:56:9
+  --> $DIR/clashing-extern-fn.rs:55:9
    |
 LL |     fn some_other_new_name(x: i16);
    |     ------------------------------ `some_other_new_name` previously declared here
@@ -59,7 +59,7 @@ LL |         #[link_name = "some_other_new_name"]
               found `unsafe extern "C" fn(u32)`
 
 warning: `other_both_names_different` redeclares `link_name_same` with a different signature
-  --> $DIR/clashing-extern-fn.rs:60:9
+  --> $DIR/clashing-extern-fn.rs:59:9
    |
 LL |     #[link_name = "link_name_same"]
    |     ------------------------------- `link_name_same` previously declared here
@@ -71,7 +71,7 @@ LL |         #[link_name = "link_name_same"]
               found `unsafe extern "C" fn(u32)`
 
 warning: `different_mod` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:73:9
+  --> $DIR/clashing-extern-fn.rs:72:9
    |
 LL |         fn different_mod(x: u8);
    |         ----------------------- `different_mod` previously declared here
@@ -83,7 +83,7 @@ LL |         fn different_mod(x: u64);
               found `unsafe extern "C" fn(u64)`
 
 warning: `variadic_decl` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:83:9
+  --> $DIR/clashing-extern-fn.rs:82:9
    |
 LL |     fn variadic_decl(x: u8, ...);
    |     ---------------------------- `variadic_decl` previously declared here
@@ -95,7 +95,7 @@ LL |         fn variadic_decl(x: u8);
               found `unsafe extern "C" fn(u8)`
 
 warning: `weigh_banana` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:143:13
+  --> $DIR/clashing-extern-fn.rs:142:13
    |
 LL |             fn weigh_banana(count: *const Banana) -> u64;
    |             -------------------------------------------- `weigh_banana` previously declared here
@@ -107,7 +107,7 @@ LL |             fn weigh_banana(count: *const Banana) -> u64;
               found `unsafe extern "C" fn(*const three::Banana) -> u64`
 
 warning: `draw_point` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:172:13
+  --> $DIR/clashing-extern-fn.rs:171:13
    |
 LL |             fn draw_point(p: Point);
    |             ----------------------- `draw_point` previously declared here
@@ -119,7 +119,7 @@ LL |             fn draw_point(p: Point);
               found `unsafe extern "C" fn(sameish_members::b::Point)`
 
 warning: `origin` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:198:13
+  --> $DIR/clashing-extern-fn.rs:197:13
    |
 LL |             fn origin() -> Point3;
    |             --------------------- `origin` previously declared here
@@ -131,7 +131,7 @@ LL |             fn origin() -> Point3;
               found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3`
 
 warning: `transparent_incorrect` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:221:13
+  --> $DIR/clashing-extern-fn.rs:220:13
    |
 LL |             fn transparent_incorrect() -> T;
    |             ------------------------------- `transparent_incorrect` previously declared here
@@ -143,7 +143,7 @@ LL |             fn transparent_incorrect() -> isize;
               found `unsafe extern "C" fn() -> isize`
 
 warning: `missing_return_type` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:260:13
+  --> $DIR/clashing-extern-fn.rs:259:13
    |
 LL |             fn missing_return_type() -> usize;
    |             --------------------------------- `missing_return_type` previously declared here
@@ -155,7 +155,7 @@ LL |             fn missing_return_type();
               found `unsafe extern "C" fn()`
 
 warning: `non_zero_usize` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:278:13
+  --> $DIR/clashing-extern-fn.rs:277:13
    |
 LL |             fn non_zero_usize() -> core::num::NonZero<usize>;
    |             ------------------------------------------------ `non_zero_usize` previously declared here
@@ -167,7 +167,7 @@ LL |             fn non_zero_usize() -> usize;
               found `unsafe extern "C" fn() -> usize`
 
 warning: `non_null_ptr` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:280:13
+  --> $DIR/clashing-extern-fn.rs:279:13
    |
 LL |             fn non_null_ptr() -> core::ptr::NonNull<usize>;
    |             ---------------------------------------------- `non_null_ptr` previously declared here
@@ -179,7 +179,7 @@ LL |             fn non_null_ptr() -> *const usize;
               found `unsafe extern "C" fn() -> *const usize`
 
 warning: `option_non_zero_usize_incorrect` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:374:13
+  --> $DIR/clashing-extern-fn.rs:373:13
    |
 LL |             fn option_non_zero_usize_incorrect() -> usize;
    |             --------------------------------------------- `option_non_zero_usize_incorrect` previously declared here
@@ -191,7 +191,7 @@ LL |             fn option_non_zero_usize_incorrect() -> isize;
               found `unsafe extern "C" fn() -> isize`
 
 warning: `option_non_null_ptr_incorrect` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:376:13
+  --> $DIR/clashing-extern-fn.rs:375:13
    |
 LL |             fn option_non_null_ptr_incorrect() -> *const usize;
    |             -------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here
@@ -203,7 +203,7 @@ LL |             fn option_non_null_ptr_incorrect() -> *const isize;
               found `unsafe extern "C" fn() -> *const isize`
 
 warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:430:13
+  --> $DIR/clashing-extern-fn.rs:429:13
    |
 LL |             fn hidden_niche_transparent_no_niche() -> usize;
    |             ----------------------------------------------- `hidden_niche_transparent_no_niche` previously declared here
@@ -215,7 +215,7 @@ LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
               found `unsafe extern "C" fn() -> Option<TransparentNoNiche>`
 
 warning: `hidden_niche_unsafe_cell` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:434:13
+  --> $DIR/clashing-extern-fn.rs:433:13
    |
 LL |             fn hidden_niche_unsafe_cell() -> usize;
    |             -------------------------------------- `hidden_niche_unsafe_cell` previously declared here
diff --git a/tests/ui/lint/invalid_value.rs b/tests/ui/lint/invalid_value.rs
index 1d2f23aaaf6..29e8e6cfef6 100644
--- a/tests/ui/lint/invalid_value.rs
+++ b/tests/ui/lint/invalid_value.rs
@@ -2,7 +2,7 @@
 // in a lint.
 #![allow(deprecated)]
 #![deny(invalid_value)]
-#![feature(generic_nonzero, never_type, rustc_attrs)]
+#![feature(never_type, rustc_attrs)]
 
 use std::mem::{self, MaybeUninit};
 use std::ptr::NonNull;
diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs
index 3157b6e240a..c60290f8553 100644
--- a/tests/ui/lint/lint-ctypes-enum.rs
+++ b/tests/ui/lint/lint-ctypes-enum.rs
@@ -1,6 +1,5 @@
 #![allow(dead_code)]
 #![deny(improper_ctypes)]
-#![feature(generic_nonzero)]
 #![feature(ptr_internals)]
 #![feature(transparent_unions)]
 
diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr
index 48be3eb5a56..103fda8d402 100644
--- a/tests/ui/lint/lint-ctypes-enum.stderr
+++ b/tests/ui/lint/lint-ctypes-enum.stderr
@@ -1,5 +1,5 @@
 error: `extern` block uses type `U`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:61:13
+  --> $DIR/lint-ctypes-enum.rs:60:13
    |
 LL |    fn uf(x: U);
    |             ^ not FFI-safe
@@ -7,7 +7,7 @@ LL |    fn uf(x: U);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 note: the type is defined here
-  --> $DIR/lint-ctypes-enum.rs:10:1
+  --> $DIR/lint-ctypes-enum.rs:9:1
    |
 LL | enum U {
    | ^^^^^^
@@ -18,7 +18,7 @@ LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `B`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:62:13
+  --> $DIR/lint-ctypes-enum.rs:61:13
    |
 LL |    fn bf(x: B);
    |             ^ not FFI-safe
@@ -26,13 +26,13 @@ LL |    fn bf(x: B);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 note: the type is defined here
-  --> $DIR/lint-ctypes-enum.rs:13:1
+  --> $DIR/lint-ctypes-enum.rs:12:1
    |
 LL | enum B {
    | ^^^^^^
 
 error: `extern` block uses type `T`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:63:13
+  --> $DIR/lint-ctypes-enum.rs:62:13
    |
 LL |    fn tf(x: T);
    |             ^ not FFI-safe
@@ -40,13 +40,13 @@ LL |    fn tf(x: T);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 note: the type is defined here
-  --> $DIR/lint-ctypes-enum.rs:17:1
+  --> $DIR/lint-ctypes-enum.rs:16:1
    |
 LL | enum T {
    | ^^^^^^
 
 error: `extern` block uses type `u128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:75:23
+  --> $DIR/lint-ctypes-enum.rs:74:23
    |
 LL |    fn nonzero_u128(x: Option<num::NonZero<u128>>);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -54,7 +54,7 @@ LL |    fn nonzero_u128(x: Option<num::NonZero<u128>>);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `i128`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:82:23
+  --> $DIR/lint-ctypes-enum.rs:81:23
    |
 LL |    fn nonzero_i128(x: Option<num::NonZero<i128>>);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -62,7 +62,7 @@ LL |    fn nonzero_i128(x: Option<num::NonZero<i128>>);
    = note: 128-bit integers don't currently have a known stable ABI
 
 error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:87:28
+  --> $DIR/lint-ctypes-enum.rs:86:28
    |
 LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZero<u8>>>);
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -71,7 +71,7 @@ LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZero<u8>>>);
    = note: enum has no representation hint
 
 error: `extern` block uses type `Option<Rust<NonZero<u8>>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:89:20
+  --> $DIR/lint-ctypes-enum.rs:88:20
    |
 LL |    fn repr_rust(x: Option<Rust<num::NonZero<u8>>>);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -80,7 +80,7 @@ LL |    fn repr_rust(x: Option<Rust<num::NonZero<u8>>>);
    = note: enum has no representation hint
 
 error: `extern` block uses type `Result<(), NonZero<i32>>`, which is not FFI-safe
-  --> $DIR/lint-ctypes-enum.rs:90:20
+  --> $DIR/lint-ctypes-enum.rs:89:20
    |
 LL |    fn no_result(x: Result<(), num::NonZero<i32>>);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
diff --git a/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs b/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs
index bda5cef979e..8aa0d04e500 100644
--- a/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs
+++ b/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs
@@ -3,7 +3,6 @@
 //@ ignore-emscripten no processes
 //@ compile-flags: -C debug-assertions
 #![allow(arithmetic_overflow)]
-#![feature(generic_nonzero)]
 
 use std::num::NonZero;
 
diff --git a/tests/ui/print_type_sizes/niche-filling.rs b/tests/ui/print_type_sizes/niche-filling.rs
index 07da1cff27a..5dda0da8458 100644
--- a/tests/ui/print_type_sizes/niche-filling.rs
+++ b/tests/ui/print_type_sizes/niche-filling.rs
@@ -15,7 +15,6 @@
 //  ^-- needed because `--pass check` does not emit the output needed.
 //      FIXME: consider using an attribute instead of side-effects.
 #![allow(dead_code)]
-#![feature(generic_nonzero)]
 #![feature(rustc_attrs)]
 
 use std::num::NonZero;
diff --git a/tests/ui/structs-enums/enum-null-pointer-opt.rs b/tests/ui/structs-enums/enum-null-pointer-opt.rs
index a8418943ba4..7a9e1b3c1e4 100644
--- a/tests/ui/structs-enums/enum-null-pointer-opt.rs
+++ b/tests/ui/structs-enums/enum-null-pointer-opt.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-#![feature(generic_nonzero)]
 #![feature(transparent_unions)]
 
 use std::mem::size_of;
diff --git a/tests/ui/structs-enums/enum-null-pointer-opt.stderr b/tests/ui/structs-enums/enum-null-pointer-opt.stderr
index fca62bd1c80..64e93ffaffd 100644
--- a/tests/ui/structs-enums/enum-null-pointer-opt.stderr
+++ b/tests/ui/structs-enums/enum-null-pointer-opt.stderr
@@ -1,5 +1,5 @@
 warning: method `dummy` is never used
-  --> $DIR/enum-null-pointer-opt.rs:11:18
+  --> $DIR/enum-null-pointer-opt.rs:10:18
    |
 LL | trait Trait { fn dummy(&self) { } }
    |       -----      ^^^^^
diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs
index 50491d5ef3e..9c933a9ef1c 100644
--- a/tests/ui/structs-enums/type-sizes.rs
+++ b/tests/ui/structs-enums/type-sizes.rs
@@ -2,7 +2,6 @@
 
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
-#![feature(generic_nonzero)]
 #![feature(never_type)]
 #![feature(pointer_is_aligned_to)]
 #![feature(strict_provenance)]
diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.rs b/tests/ui/suggestions/core-std-import-order-issue-83564.rs
index 62b9b246cc8..6f2bdd7a38a 100644
--- a/tests/ui/suggestions/core-std-import-order-issue-83564.rs
+++ b/tests/ui/suggestions/core-std-import-order-issue-83564.rs
@@ -2,7 +2,6 @@
 //
 // This is a regression test for #83564.
 // For some reason, Rust 2018 or higher is required to reproduce the bug.
-#![feature(generic_nonzero)]
 
 fn main() {
     //~^ HELP consider importing one of these items
diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.stderr b/tests/ui/suggestions/core-std-import-order-issue-83564.stderr
index 56e10b9340c..8665cc6d87c 100644
--- a/tests/ui/suggestions/core-std-import-order-issue-83564.stderr
+++ b/tests/ui/suggestions/core-std-import-order-issue-83564.stderr
@@ -1,5 +1,5 @@
 error[E0433]: failed to resolve: use of undeclared type `NonZero`
-  --> $DIR/core-std-import-order-issue-83564.rs:9:14
+  --> $DIR/core-std-import-order-issue-83564.rs:8:14
    |
 LL |     let _x = NonZero::new(5u32).unwrap();
    |              ^^^^^^^ use of undeclared type `NonZero`
diff --git a/tests/ui/traits/next-solver/specialization-transmute.rs b/tests/ui/traits/next-solver/specialization-transmute.rs
index 17c55fb4d49..caa3bfc552e 100644
--- a/tests/ui/traits/next-solver/specialization-transmute.rs
+++ b/tests/ui/traits/next-solver/specialization-transmute.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -Znext-solver
 //~^ ERROR cannot normalize `<T as Default>::Id: '_`
-#![feature(generic_nonzero)]
 #![feature(specialization)]
 //~^ WARN the feature `specialization` is incomplete
 
diff --git a/tests/ui/traits/next-solver/specialization-transmute.stderr b/tests/ui/traits/next-solver/specialization-transmute.stderr
index 65e33700325..76ae08fdb7a 100644
--- a/tests/ui/traits/next-solver/specialization-transmute.stderr
+++ b/tests/ui/traits/next-solver/specialization-transmute.stderr
@@ -1,5 +1,5 @@
 warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/specialization-transmute.rs:4:12
+  --> $DIR/specialization-transmute.rs:3:12
    |
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
@@ -11,31 +11,31 @@ LL | #![feature(specialization)]
 error: cannot normalize `<T as Default>::Id: '_`
 
 error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id == _`
-  --> $DIR/specialization-transmute.rs:16:23
+  --> $DIR/specialization-transmute.rs:15:23
    |
 LL |     fn intu(&self) -> &Self::Id {
    |                       ^^^^^^^^^ cannot satisfy `<T as Default>::Id == _`
 
 error[E0284]: type annotations needed: cannot satisfy `T <: <T as Default>::Id`
-  --> $DIR/specialization-transmute.rs:18:9
+  --> $DIR/specialization-transmute.rs:17:9
    |
 LL |         self
    |         ^^^^ cannot satisfy `T <: <T as Default>::Id`
 
 error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
-  --> $DIR/specialization-transmute.rs:29:13
+  --> $DIR/specialization-transmute.rs:28:13
    |
 LL |     let s = transmute::<u8, Option<NonZero<u8>>>(0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
    |
 note: required by a bound in `transmute`
-  --> $DIR/specialization-transmute.rs:22:25
+  --> $DIR/specialization-transmute.rs:21:25
    |
 LL | fn transmute<T: Default<Id = U>, U: Copy>(t: T) -> U {
    |                         ^^^^^^ required by this bound in `transmute`
 
 error[E0282]: type annotations needed
-  --> $DIR/specialization-transmute.rs:14:23
+  --> $DIR/specialization-transmute.rs:13:23
    |
 LL |     default type Id = T;
    |                       ^ cannot infer type for associated type `<T as Default>::Id`