about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs15
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs20
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs5
-rw-r--r--compiler/rustc_data_structures/src/graph/iterate/mod.rs10
-rw-r--r--compiler/rustc_data_structures/src/graph/mod.rs1
-rw-r--r--compiler/rustc_data_structures/src/graph/reversed.rs42
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0253.md12
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs23
-rw-r--r--compiler/rustc_index/src/bit_set.rs30
-rw-r--r--compiler/rustc_index/src/bit_set/tests.rs26
-rw-r--r--compiler/rustc_middle/src/ty/context.rs33
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs11
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs446
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs133
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters/iter_nodes.rs16
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs306
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs64
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters/tests.rs41
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters/union_find.rs116
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters/union_find/tests.rs32
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs174
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs43
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs1
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs6
-rw-r--r--compiler/rustc_resolve/src/imports.rs14
-rw-r--r--compiler/rustc_resolve/src/lib.rs11
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--library/core/src/pin.rs4
-rw-r--r--library/core/src/ptr/alignment.rs12
-rw-r--r--library/core/src/ptr/mod.rs11
-rw-r--r--library/core/src/ptr/non_null.rs16
m---------src/llvm-project0
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt1
-rw-r--r--tests/coverage/abort.cov-map61
-rw-r--r--tests/coverage/assert-ne.cov-map10
-rw-r--r--tests/coverage/assert.cov-map45
-rw-r--r--tests/coverage/assert.coverage14
-rw-r--r--tests/coverage/assert_not.cov-map12
-rw-r--r--tests/coverage/async.cov-map47
-rw-r--r--tests/coverage/async_block.cov-map16
-rw-r--r--tests/coverage/async_closure.cov-map10
-rw-r--r--tests/coverage/await_ready.cov-map10
-rw-r--r--tests/coverage/branch/guard.cov-map30
-rw-r--r--tests/coverage/branch/if-let.cov-map22
-rw-r--r--tests/coverage/branch/if.cov-map186
-rw-r--r--tests/coverage/branch/lazy-boolean.cov-map212
-rw-r--r--tests/coverage/branch/let-else.cov-map22
-rw-r--r--tests/coverage/branch/match-arms.cov-map114
-rw-r--r--tests/coverage/branch/match-trivial.cov-map6
-rw-r--r--tests/coverage/branch/no-mir-spans.cov-map67
-rw-r--r--tests/coverage/branch/while.cov-map120
-rw-r--r--tests/coverage/continue.cov-map141
-rw-r--r--tests/coverage/coroutine.cov-map29
-rw-r--r--tests/coverage/inline.cov-map40
-rw-r--r--tests/coverage/issue-84561.cov-map184
-rw-r--r--tests/coverage/loop-break.cov-map10
-rw-r--r--tests/coverage/loops_branches.cov-map130
-rw-r--r--tests/coverage/match_or_pattern.cov-map99
-rw-r--r--tests/coverage/mcdc/nested_if.cov-map205
-rw-r--r--tests/coverage/nested_loops.cov-map75
-rw-r--r--tests/coverage/overflow.cov-map45
-rw-r--r--tests/coverage/overflow.coverage14
-rw-r--r--tests/coverage/panic_unwind.cov-map45
-rw-r--r--tests/coverage/panic_unwind.coverage14
-rw-r--r--tests/coverage/simple_loop.cov-map10
-rw-r--r--tests/coverage/simple_match.cov-map38
-rw-r--r--tests/coverage/try_error_result.cov-map266
-rw-r--r--tests/coverage/unicode.cov-map13
-rw-r--r--tests/coverage/unused.cov-map58
-rw-r--r--tests/coverage/while.cov-map10
-rw-r--r--tests/coverage/while_early_ret.cov-map36
-rw-r--r--tests/coverage/yield.cov-map50
-rw-r--r--tests/incremental/overlapping-impls-in-new-solver-issue-135514.rs40
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff10
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff63
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff71
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff63
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff71
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff72
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff80
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff72
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff80
-rw-r--r--tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff30
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir32
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir12
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir8
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir8
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir14
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir14
-rw-r--r--tests/run-make/extern-fn-reachable/Makefile26
-rw-r--r--tests/run-make/extern-fn-reachable/dylib.rs15
-rw-r--r--tests/run-make/extern-fn-reachable/rmake.rs46
-rw-r--r--tests/rustdoc-gui/links-color.goml6
-rw-r--r--tests/ui/consts/const-block-const-bound.rs4
-rw-r--r--tests/ui/consts/const-block-const-bound.stderr4
-rw-r--r--tests/ui/consts/issue-94675.rs6
-rw-r--r--tests/ui/consts/issue-94675.stderr2
-rw-r--r--tests/ui/error-codes/E0253.rs4
-rw-r--r--tests/ui/error-codes/E0253.stderr6
-rw-r--r--tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs63
-rw-r--r--tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr53
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.rs3
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.stderr6
-rw-r--r--tests/ui/imports/import-trait-method.rs4
-rw-r--r--tests/ui/imports/import-trait-method.stderr21
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs14
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr19
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/return-fn-ptr.rs22
-rw-r--r--tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr39
-rw-r--r--tests/ui/suggestions/fn-to-method.normal.stderr (renamed from tests/ui/suggestions/fn-to-method.stderr)6
-rw-r--r--tests/ui/suggestions/fn-to-method.rs8
-rw-r--r--tests/ui/use/import_trait_associated_functions-2015.rs61
-rw-r--r--tests/ui/use/import_trait_associated_functions.rs61
-rw-r--r--tests/ui/use/use-from-trait-xc.rs4
-rw-r--r--tests/ui/use/use-from-trait-xc.stderr18
-rw-r--r--tests/ui/use/use-from-trait.rs4
-rw-r--r--tests/ui/use/use-from-trait.stderr18
118 files changed, 2932 insertions, 2545 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index a1979c8b8ab..eca8a688ff4 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1654,7 +1654,20 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 match *cast_kind {
                     CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, coercion_source) => {
                         let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
-                        let src_sig = op.ty(body, tcx).fn_sig(tcx);
+                        let src_ty = op.ty(body, tcx);
+                        let mut src_sig = src_ty.fn_sig(tcx);
+                        if let ty::FnDef(def_id, _) = src_ty.kind()
+                            && let ty::FnPtr(_, target_hdr) = *ty.kind()
+                            && tcx.codegen_fn_attrs(def_id).safe_target_features
+                            && target_hdr.safety.is_safe()
+                            && let Some(safe_sig) = tcx.adjust_target_feature_sig(
+                                *def_id,
+                                src_sig,
+                                body.source.def_id(),
+                            )
+                        {
+                            src_sig = safe_sig;
+                        }
 
                         // HACK: This shouldn't be necessary... We can remove this when we actually
                         // get binders with where clauses, then elaborate implied bounds into that
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index 8af17d01b0a..35c3e3ed315 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -4,14 +4,18 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 
-fn parent_impl_constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
+fn parent_impl_or_trait_constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
     let parent_id = tcx.local_parent(def_id);
-    if matches!(tcx.def_kind(parent_id), DefKind::Impl { .. })
-        && let Some(header) = tcx.impl_trait_header(parent_id)
-    {
-        header.constness
-    } else {
-        hir::Constness::NotConst
+    match tcx.def_kind(parent_id) {
+        DefKind::Impl { of_trait: true } => tcx.impl_trait_header(parent_id).unwrap().constness,
+        DefKind::Trait => {
+            if tcx.is_const_trait(parent_id.into()) {
+                hir::Constness::Const
+            } else {
+                hir::Constness::NotConst
+            }
+        }
+        _ => hir::Constness::NotConst,
     }
 }
 
@@ -34,7 +38,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
 
                 // If the function itself is not annotated with `const`, it may still be a `const fn`
                 // if it resides in a const trait impl.
-                parent_impl_constness(tcx, def_id)
+                parent_impl_or_trait_constness(tcx, def_id)
             } else {
                 tcx.dcx().span_bug(
                     tcx.def_span(def_id),
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index ba7fbb254c6..cfdfbdb7880 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -360,10 +360,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
             // sensitive check here. But we can at least rule out functions that are not const at
             // all. That said, we have to allow calling functions inside a trait marked with
             // #[const_trait]. These *are* const-checked!
-            // FIXME(const_trait_impl): why does `is_const_fn` not classify them as const?
-            if (!ecx.tcx.is_const_fn(def) && !ecx.tcx.is_const_default_method(def))
-                || ecx.tcx.has_attr(def, sym::rustc_do_not_const_check)
-            {
+            if !ecx.tcx.is_const_fn(def) || ecx.tcx.has_attr(def, sym::rustc_do_not_const_check) {
                 // We certainly do *not* want to actually call the fn
                 // though, so be sure we return here.
                 throw_unsup_format!("calling non-const function `{}`", instance)
diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs
index ecda7d3fba8..7b4573d7a84 100644
--- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs
@@ -125,6 +125,16 @@ where
     pub fn visited(&self, node: G::Node) -> bool {
         self.visited.contains(node)
     }
+
+    /// Returns a reference to the set of nodes that have been visited, with
+    /// the same caveats as [`Self::visited`].
+    ///
+    /// When incorporating the visited nodes into another bitset, using bulk
+    /// operations like `union` or `intersect` can be more efficient than
+    /// processing each node individually.
+    pub fn visited_set(&self) -> &DenseBitSet<G::Node> {
+        &self.visited
+    }
 }
 
 impl<G> std::fmt::Debug for DepthFirstSearch<G>
diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs
index 103ddd917bf..92035e8bc48 100644
--- a/compiler/rustc_data_structures/src/graph/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/mod.rs
@@ -4,6 +4,7 @@ pub mod dominators;
 pub mod implementation;
 pub mod iterate;
 mod reference;
+pub mod reversed;
 pub mod scc;
 pub mod vec_graph;
 
diff --git a/compiler/rustc_data_structures/src/graph/reversed.rs b/compiler/rustc_data_structures/src/graph/reversed.rs
new file mode 100644
index 00000000000..9b726deaa15
--- /dev/null
+++ b/compiler/rustc_data_structures/src/graph/reversed.rs
@@ -0,0 +1,42 @@
+use crate::graph::{DirectedGraph, Predecessors, Successors};
+
+/// View that reverses the direction of edges in its underlying graph, so that
+/// successors become predecessors and vice-versa.
+///
+/// Because of `impl<G: Graph> Graph for &G`, the underlying graph can be
+/// wrapped by-reference instead of by-value if desired.
+#[derive(Clone, Copy, Debug)]
+pub struct ReversedGraph<G> {
+    pub inner: G,
+}
+
+impl<G> ReversedGraph<G> {
+    pub fn new(inner: G) -> Self {
+        Self { inner }
+    }
+}
+
+impl<G: DirectedGraph> DirectedGraph for ReversedGraph<G> {
+    type Node = G::Node;
+
+    fn num_nodes(&self) -> usize {
+        self.inner.num_nodes()
+    }
+}
+
+// Implementing `StartNode` is not possible in general, because the start node
+// of an underlying graph is instead an _end_ node in the reversed graph.
+// But would be possible to define another wrapper type that adds an explicit
+// start node to its underlying graph, if desired.
+
+impl<G: Predecessors> Successors for ReversedGraph<G> {
+    fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
+        self.inner.predecessors(node)
+    }
+}
+
+impl<G: Successors> Predecessors for ReversedGraph<G> {
+    fn predecessors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
+        self.inner.successors(node)
+    }
+}
diff --git a/compiler/rustc_error_codes/src/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md
index aea51d40238..705d1bfc53e 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0253.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0253.md
@@ -1,19 +1,19 @@
-Attempt was made to import an unimportable value. This can happen when trying
-to import a method from a trait.
+Attempt was made to import an unimportable type. This can happen when trying
+to import a type from a trait.
 
 Erroneous code example:
 
 ```compile_fail,E0253
 mod foo {
     pub trait MyTrait {
-        fn do_something();
+        type SomeType;
     }
 }
 
-use foo::MyTrait::do_something;
-// error: `do_something` is not directly importable
+use foo::MyTrait::SomeType;
+// error: `SomeType` is not directly importable
 
 fn main() {}
 ```
 
-It's invalid to directly import methods belonging to a trait or concrete type.
+It's invalid to directly import types belonging to a trait.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index fb83487c939..6b88651715e 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -521,6 +521,8 @@ declare_features! (
     (unstable, impl_trait_in_bindings, "1.64.0", Some(63065)),
     /// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
     (unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
+    /// Allows `use` associated functions from traits.
+    (unstable, import_trait_associated_functions, "CURRENT_RUSTC_VERSION", Some(134691)),
     /// Allows associated types in inherent impls.
     (incomplete, inherent_associated_types, "1.52.0", Some(8995)),
     /// Allow anonymous constants from an inline `const` block in pattern position
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index ec7c1efa38e..6945dbc3216 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -920,7 +920,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         match b.kind() {
             ty::FnPtr(_, b_hdr) => {
-                let a_sig = a.fn_sig(self.tcx);
+                let mut a_sig = a.fn_sig(self.tcx);
                 if let ty::FnDef(def_id, _) = *a.kind() {
                     // Intrinsics are not coercible to function pointers
                     if self.tcx.intrinsic(def_id).is_some() {
@@ -932,19 +932,20 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                         return Err(TypeError::ForceInlineCast);
                     }
 
-                    let fn_attrs = self.tcx.codegen_fn_attrs(def_id);
-                    if matches!(fn_attrs.inline, InlineAttr::Force { .. }) {
-                        return Err(TypeError::ForceInlineCast);
-                    }
-
-                    // FIXME(target_feature): Safe `#[target_feature]` functions could be cast to safe fn pointers (RFC 2396),
-                    // as you can already write that "cast" in user code by wrapping a target_feature fn call in a closure,
-                    // which is safe. This is sound because you already need to be executing code that is satisfying the target
-                    // feature constraints..
                     if b_hdr.safety.is_safe()
                         && self.tcx.codegen_fn_attrs(def_id).safe_target_features
                     {
-                        return Err(TypeError::TargetFeatureCast(def_id));
+                        // Allow the coercion if the current function has all the features that would be
+                        // needed to call the coercee safely.
+                        if let Some(safe_sig) = self.tcx.adjust_target_feature_sig(
+                            def_id,
+                            a_sig,
+                            self.fcx.body_id.into(),
+                        ) {
+                            a_sig = safe_sig;
+                        } else {
+                            return Err(TypeError::TargetFeatureCast(def_id));
+                        }
                     }
                 }
 
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs
index d93707b745d..f12df831cb5 100644
--- a/compiler/rustc_index/src/bit_set.rs
+++ b/compiler/rustc_index/src/bit_set.rs
@@ -281,6 +281,24 @@ impl<T: Idx> DenseBitSet<T> {
     }
 
     bit_relations_inherent_impls! {}
+
+    /// Sets `self = self | !other`.
+    ///
+    /// FIXME: Incorporate this into [`BitRelations`] and fill out
+    /// implementations for other bitset types, if needed.
+    pub fn union_not(&mut self, other: &DenseBitSet<T>) {
+        assert_eq!(self.domain_size, other.domain_size);
+
+        // FIXME(Zalathar): If we were to forcibly _set_ all excess bits before
+        // the bitwise update, and then clear them again afterwards, we could
+        // quickly and accurately detect whether the update changed anything.
+        // But that's only worth doing if there's an actual use-case.
+
+        bitwise(&mut self.words, &other.words, |a, b| a | !b);
+        // The bitwise update `a | !b` can result in the last word containing
+        // out-of-domain bits, so we need to clear them.
+        self.clear_excess_bits();
+    }
 }
 
 // dense REL dense
@@ -1087,6 +1105,18 @@ impl<T: Idx> fmt::Debug for ChunkedBitSet<T> {
     }
 }
 
+/// Sets `out_vec[i] = op(out_vec[i], in_vec[i])` for each index `i` in both
+/// slices. The slices must have the same length.
+///
+/// Returns true if at least one bit in `out_vec` was changed.
+///
+/// ## Warning
+/// Some bitwise operations (e.g. union-not, xor) can set output bits that were
+/// unset in in both inputs. If this happens in the last word/chunk of a bitset,
+/// it can cause the bitset to contain out-of-domain values, which need to
+/// be cleared with `clear_excess_bits_in_final_word`. This also makes the
+/// "changed" return value unreliable, because the change might have only
+/// affected excess bits.
 #[inline]
 fn bitwise<Op>(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool
 where
diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs
index 0350740aa81..eaa4aafe721 100644
--- a/compiler/rustc_index/src/bit_set/tests.rs
+++ b/compiler/rustc_index/src/bit_set/tests.rs
@@ -76,6 +76,32 @@ fn union_two_sets() {
 }
 
 #[test]
+fn union_not() {
+    let mut a = DenseBitSet::<usize>::new_empty(100);
+    let mut b = DenseBitSet::<usize>::new_empty(100);
+
+    a.insert(3);
+    a.insert(5);
+    a.insert(80);
+    a.insert(81);
+
+    b.insert(5); // Already in `a`.
+    b.insert(7);
+    b.insert(63);
+    b.insert(81); // Already in `a`.
+    b.insert(90);
+
+    a.union_not(&b);
+
+    // After union-not, `a` should contain all values in the domain, except for
+    // the ones that are in `b` and were _not_ already in `a`.
+    assert_eq!(
+        a.iter().collect::<Vec<_>>(),
+        (0usize..100).filter(|&x| !matches!(x, 7 | 63 | 90)).collect::<Vec<_>>(),
+    );
+}
+
+#[test]
 fn chunked_bitset() {
     let mut b0 = ChunkedBitSet::<usize>::new_empty(0);
     let b0b = b0.clone();
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index fab0047babf..7035e641f39 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -60,7 +60,7 @@ use crate::dep_graph::{DepGraph, DepKindStruct};
 use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
 use crate::lint::lint_level;
 use crate::metadata::ModChild;
-use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
+use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
 use crate::middle::{resolve_bound_vars, stability};
 use crate::mir::interpret::{self, Allocation, ConstAllocation};
 use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
@@ -1776,6 +1776,37 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
         self.sess.dcx()
     }
+
+    pub fn is_target_feature_call_safe(
+        self,
+        callee_features: &[TargetFeature],
+        body_features: &[TargetFeature],
+    ) -> bool {
+        // If the called function has target features the calling function hasn't,
+        // the call requires `unsafe`. Don't check this on wasm
+        // targets, though. For more information on wasm see the
+        // is_like_wasm check in hir_analysis/src/collect.rs
+        self.sess.target.options.is_like_wasm
+            || callee_features
+                .iter()
+                .all(|feature| body_features.iter().any(|f| f.name == feature.name))
+    }
+
+    /// Returns the safe version of the signature of the given function, if calling it
+    /// would be safe in the context of the given caller.
+    pub fn adjust_target_feature_sig(
+        self,
+        fun_def: DefId,
+        fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
+        caller: DefId,
+    ) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
+        let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
+        let callee_features = &self.codegen_fn_attrs(caller).target_features;
+        if self.is_target_feature_call_safe(&fun_features, &callee_features) {
+            return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
+        }
+        None
+    }
 }
 
 impl<'tcx> TyCtxtAt<'tcx> {
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 6279d0f94af..5eed9ef798d 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -495,14 +495,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                     };
                     self.requires_unsafe(expr.span, CallToUnsafeFunction(func_id));
                 } else if let &ty::FnDef(func_did, _) = fn_ty.kind() {
-                    // If the called function has target features the calling function hasn't,
-                    // the call requires `unsafe`. Don't check this on wasm
-                    // targets, though. For more information on wasm see the
-                    // is_like_wasm check in hir_analysis/src/collect.rs
-                    if !self.tcx.sess.target.options.is_like_wasm
-                        && !callee_features.iter().all(|feature| {
-                            self.body_target_features.iter().any(|f| f.name == feature.name)
-                        })
+                    if !self
+                        .tcx
+                        .is_target_feature_call_safe(callee_features, self.body_target_features)
                     {
                         let missing: Vec<_> = callee_features
                             .iter()
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index a9111a5ef9b..1a9323329f6 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -1,18 +1,24 @@
 use std::cmp::Ordering;
 use std::fmt::{self, Debug};
 
+use either::Either;
+use itertools::Itertools;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::DirectedGraph;
 use rustc_index::IndexVec;
 use rustc_index::bit_set::DenseBitSet;
 use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op};
-use tracing::{debug, debug_span, instrument};
 
-use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, ReadyFirstTraversal};
+use crate::coverage::counters::balanced_flow::BalancedFlowGraph;
+use crate::coverage::counters::iter_nodes::IterNodes;
+use crate::coverage::counters::node_flow::{CounterTerm, MergedNodeFlowGraph, NodeCounters};
+use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
 
-#[cfg(test)]
-mod tests;
+mod balanced_flow;
+mod iter_nodes;
+mod node_flow;
+mod union_find;
 
 /// The coverage counter or counter expression associated with a particular
 /// BCB node or BCB edge.
@@ -48,10 +54,12 @@ struct BcbExpression {
 }
 
 /// Enum representing either a node or an edge in the coverage graph.
+///
+/// FIXME(#135481): This enum is no longer needed now that we only instrument
+/// nodes and not edges. It can be removed in a subsequent PR.
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub(super) enum Site {
     Node { bcb: BasicCoverageBlock },
-    Edge { from_bcb: BasicCoverageBlock, to_bcb: BasicCoverageBlock },
 }
 
 /// Generates and stores coverage counter and coverage expression information
@@ -79,10 +87,38 @@ impl CoverageCounters {
         graph: &CoverageGraph,
         bcb_needs_counter: &DenseBitSet<BasicCoverageBlock>,
     ) -> Self {
-        let mut builder = CountersBuilder::new(graph, bcb_needs_counter);
-        builder.make_bcb_counters();
+        let balanced_graph = BalancedFlowGraph::for_graph(graph, |n| !graph[n].is_out_summable);
+        let merged_graph = MergedNodeFlowGraph::for_balanced_graph(&balanced_graph);
+
+        // A "reloop" node has exactly one out-edge, which jumps back to the top
+        // of an enclosing loop. Reloop nodes are typically visited more times
+        // than loop-exit nodes, so try to avoid giving them physical counters.
+        let is_reloop_node = IndexVec::from_fn_n(
+            |node| match graph.successors[node].as_slice() {
+                &[succ] => graph.dominates(succ, node),
+                _ => false,
+            },
+            graph.num_nodes(),
+        );
 
-        builder.into_coverage_counters()
+        let mut nodes = balanced_graph.iter_nodes().rev().collect::<Vec<_>>();
+        // The first node is the sink, which must not get a physical counter.
+        assert_eq!(nodes[0], balanced_graph.sink);
+        // Sort the real nodes, such that earlier (lesser) nodes take priority
+        // in being given a counter expression instead of a physical counter.
+        nodes[1..].sort_by(|&a, &b| {
+            // Start with a dummy `Equal` to make the actual tests line up nicely.
+            Ordering::Equal
+                // Prefer a physical counter for return/yield nodes.
+                .then_with(|| Ord::cmp(&graph[a].is_out_summable, &graph[b].is_out_summable))
+                // Prefer an expression for reloop nodes (see definition above).
+                .then_with(|| Ord::cmp(&is_reloop_node[a], &is_reloop_node[b]).reverse())
+                // Otherwise, prefer a physical counter for dominating nodes.
+                .then_with(|| graph.cmp_in_dominator_order(a, b).reverse())
+        });
+        let node_counters = merged_graph.make_node_counters(&nodes);
+
+        Transcriber::new(graph.num_nodes(), node_counters).transcribe_counters(bcb_needs_counter)
     }
 
     fn with_num_bcbs(num_bcbs: usize) -> Self {
@@ -182,321 +218,51 @@ impl CoverageCounters {
     }
 }
 
-/// Symbolic representation of the coverage counter to be used for a particular
-/// node or edge in the coverage graph. The same site counter can be used for
-/// multiple sites, if they have been determined to have the same count.
-#[derive(Clone, Copy, Debug)]
-enum SiteCounter {
-    /// A physical counter at some node/edge.
-    Phys { site: Site },
-    /// A counter expression for a node that takes the sum of all its in-edge
-    /// counters.
-    NodeSumExpr { bcb: BasicCoverageBlock },
-    /// A counter expression for an edge that takes the counter of its source
-    /// node, and subtracts the counters of all its sibling out-edges.
-    EdgeDiffExpr { from_bcb: BasicCoverageBlock, to_bcb: BasicCoverageBlock },
-}
-
-/// Yields the graph successors of `from_bcb` that aren't `to_bcb`. This is
-/// used when creating a counter expression for [`SiteCounter::EdgeDiffExpr`].
-///
-/// For example, in this diagram the sibling out-edge targets of edge `AC` are
-/// the nodes `B` and `D`.
-///
-/// ```text
-///    A
-///  / | \
-/// B  C  D
-/// ```
-fn sibling_out_edge_targets(
-    graph: &CoverageGraph,
-    from_bcb: BasicCoverageBlock,
-    to_bcb: BasicCoverageBlock,
-) -> impl Iterator<Item = BasicCoverageBlock> + Captures<'_> {
-    graph.successors[from_bcb].iter().copied().filter(move |&t| t != to_bcb)
-}
-
-/// Helper struct that allows counter creation to inspect the BCB graph, and
-/// the set of nodes that need counters.
-struct CountersBuilder<'a> {
-    graph: &'a CoverageGraph,
-    bcb_needs_counter: &'a DenseBitSet<BasicCoverageBlock>,
-
-    site_counters: FxHashMap<Site, SiteCounter>,
-}
-
-impl<'a> CountersBuilder<'a> {
-    fn new(
-        graph: &'a CoverageGraph,
-        bcb_needs_counter: &'a DenseBitSet<BasicCoverageBlock>,
-    ) -> Self {
-        assert_eq!(graph.num_nodes(), bcb_needs_counter.domain_size());
-        Self { graph, bcb_needs_counter, site_counters: FxHashMap::default() }
-    }
-
-    fn make_bcb_counters(&mut self) {
-        debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
-
-        // Traverse the coverage graph, ensuring that every node that needs a
-        // coverage counter has one.
-        for bcb in ReadyFirstTraversal::new(self.graph) {
-            let _span = debug_span!("traversal", ?bcb).entered();
-            if self.bcb_needs_counter.contains(bcb) {
-                self.make_node_counter_and_out_edge_counters(bcb);
-            }
-        }
-    }
-
-    /// Make sure the given node has a node counter, and then make sure each of
-    /// its out-edges has an edge counter (if appropriate).
-    #[instrument(level = "debug", skip(self))]
-    fn make_node_counter_and_out_edge_counters(&mut self, from_bcb: BasicCoverageBlock) {
-        // First, ensure that this node has a counter of some kind.
-        // We might also use that counter to compute one of the out-edge counters.
-        self.get_or_make_node_counter(from_bcb);
-
-        // If this node's out-edges won't sum to the node's counter,
-        // then there's no reason to create edge counters here.
-        if !self.graph[from_bcb].is_out_summable {
-            return;
-        }
-
-        // When choosing which out-edge should be given a counter expression, ignore edges that
-        // already have counters, or could use the existing counter of their target node.
-        let out_edge_has_counter = |to_bcb| {
-            if self.site_counters.contains_key(&Site::Edge { from_bcb, to_bcb }) {
-                return true;
-            }
-            self.graph.sole_predecessor(to_bcb) == Some(from_bcb)
-                && self.site_counters.contains_key(&Site::Node { bcb: to_bcb })
-        };
-
-        // Determine the set of out-edges that could benefit from being given an expression.
-        let candidate_successors = self.graph.successors[from_bcb]
-            .iter()
-            .copied()
-            .filter(|&to_bcb| !out_edge_has_counter(to_bcb))
-            .collect::<Vec<_>>();
-        debug!(?candidate_successors);
-
-        // If there are out-edges without counters, choose one to be given an expression
-        // (computed from this node and the other out-edges) instead of a physical counter.
-        let Some(to_bcb) = self.choose_out_edge_for_expression(from_bcb, &candidate_successors)
-        else {
-            return;
-        };
-
-        // For each out-edge other than the one that was chosen to get an expression,
-        // ensure that it has a counter (existing counter/expression or a new counter).
-        for target in sibling_out_edge_targets(self.graph, from_bcb, to_bcb) {
-            self.get_or_make_edge_counter(from_bcb, target);
-        }
-
-        // Now create an expression for the chosen edge, by taking the counter
-        // for its source node and subtracting the sum of its sibling out-edges.
-        let counter = SiteCounter::EdgeDiffExpr { from_bcb, to_bcb };
-        self.site_counters.insert(Site::Edge { from_bcb, to_bcb }, counter);
-    }
-
-    #[instrument(level = "debug", skip(self))]
-    fn get_or_make_node_counter(&mut self, bcb: BasicCoverageBlock) -> SiteCounter {
-        // If the BCB already has a counter, return it.
-        if let Some(&counter) = self.site_counters.get(&Site::Node { bcb }) {
-            debug!("{bcb:?} already has a counter: {counter:?}");
-            return counter;
-        }
-
-        let counter = self.make_node_counter_inner(bcb);
-        self.site_counters.insert(Site::Node { bcb }, counter);
-        counter
-    }
-
-    fn make_node_counter_inner(&mut self, bcb: BasicCoverageBlock) -> SiteCounter {
-        // If the node's sole in-edge already has a counter, use that.
-        if let Some(sole_pred) = self.graph.sole_predecessor(bcb)
-            && let Some(&edge_counter) =
-                self.site_counters.get(&Site::Edge { from_bcb: sole_pred, to_bcb: bcb })
-        {
-            return edge_counter;
-        }
-
-        let predecessors = self.graph.predecessors[bcb].as_slice();
-
-        // Handle cases where we can't compute a node's count from its in-edges:
-        // - START_BCB has no in-edges, so taking the sum would panic (or be wrong).
-        // - For nodes with one in-edge, or that directly loop to themselves,
-        //   trying to get the in-edge counts would require this node's counter,
-        //   leading to infinite recursion.
-        if predecessors.len() <= 1 || predecessors.contains(&bcb) {
-            debug!(?bcb, ?predecessors, "node has <=1 predecessors or is its own predecessor");
-            let counter = SiteCounter::Phys { site: Site::Node { bcb } };
-            debug!(?bcb, ?counter, "node gets a physical counter");
-            return counter;
-        }
-
-        // A BCB with multiple incoming edges can compute its count by ensuring that counters
-        // exist for each of those edges, and then adding them up to get a total count.
-        for &from_bcb in predecessors {
-            self.get_or_make_edge_counter(from_bcb, bcb);
-        }
-        let sum_of_in_edges = SiteCounter::NodeSumExpr { bcb };
-
-        debug!("{bcb:?} gets a new counter (sum of predecessor counters): {sum_of_in_edges:?}");
-        sum_of_in_edges
-    }
-
-    #[instrument(level = "debug", skip(self))]
-    fn get_or_make_edge_counter(
-        &mut self,
-        from_bcb: BasicCoverageBlock,
-        to_bcb: BasicCoverageBlock,
-    ) -> SiteCounter {
-        // If the edge already has a counter, return it.
-        if let Some(&counter) = self.site_counters.get(&Site::Edge { from_bcb, to_bcb }) {
-            debug!("Edge {from_bcb:?}->{to_bcb:?} already has a counter: {counter:?}");
-            return counter;
-        }
-
-        let counter = self.make_edge_counter_inner(from_bcb, to_bcb);
-        self.site_counters.insert(Site::Edge { from_bcb, to_bcb }, counter);
-        counter
-    }
-
-    fn make_edge_counter_inner(
-        &mut self,
-        from_bcb: BasicCoverageBlock,
-        to_bcb: BasicCoverageBlock,
-    ) -> SiteCounter {
-        // If the target node has exactly one in-edge (i.e. this one), then just
-        // use the node's counter, since it will have the same value.
-        if let Some(sole_pred) = self.graph.sole_predecessor(to_bcb) {
-            assert_eq!(sole_pred, from_bcb);
-            // This call must take care not to invoke `get_or_make_edge` for
-            // this edge, since that would result in infinite recursion!
-            return self.get_or_make_node_counter(to_bcb);
-        }
-
-        // If the source node has exactly one out-edge (i.e. this one) and would have
-        // the same execution count as that edge, then just use the node's counter.
-        if let Some(simple_succ) = self.graph.simple_successor(from_bcb) {
-            assert_eq!(simple_succ, to_bcb);
-            return self.get_or_make_node_counter(from_bcb);
-        }
-
-        // Make a new counter to count this edge.
-        let counter = SiteCounter::Phys { site: Site::Edge { from_bcb, to_bcb } };
-        debug!(?from_bcb, ?to_bcb, ?counter, "edge gets a physical counter");
-        counter
-    }
-
-    /// Given a set of candidate out-edges (represented by their successor node),
-    /// choose one to be given a counter expression instead of a physical counter.
-    fn choose_out_edge_for_expression(
-        &self,
-        from_bcb: BasicCoverageBlock,
-        candidate_successors: &[BasicCoverageBlock],
-    ) -> Option<BasicCoverageBlock> {
-        // Try to find a candidate that leads back to the top of a loop,
-        // because reloop edges tend to be executed more times than loop-exit edges.
-        if let Some(reloop_target) = self.find_good_reloop_edge(from_bcb, &candidate_successors) {
-            debug!("Selecting reloop target {reloop_target:?} to get an expression");
-            return Some(reloop_target);
-        }
-
-        // We couldn't identify a "good" edge, so just choose an arbitrary one.
-        let arbitrary_target = candidate_successors.first().copied()?;
-        debug!(?arbitrary_target, "selecting arbitrary out-edge to get an expression");
-        Some(arbitrary_target)
-    }
-
-    /// Given a set of candidate out-edges (represented by their successor node),
-    /// tries to find one that leads back to the top of a loop.
-    ///
-    /// Reloop edges are good candidates for counter expressions, because they
-    /// will tend to be executed more times than a loop-exit edge, so it's nice
-    /// for them to be able to avoid a physical counter increment.
-    fn find_good_reloop_edge(
-        &self,
-        from_bcb: BasicCoverageBlock,
-        candidate_successors: &[BasicCoverageBlock],
-    ) -> Option<BasicCoverageBlock> {
-        // If there are no candidates, avoid iterating over the loop stack.
-        if candidate_successors.is_empty() {
-            return None;
-        }
-
-        // Consider each loop on the current traversal context stack, top-down.
-        for loop_header_node in self.graph.loop_headers_containing(from_bcb) {
-            // Try to find a candidate edge that doesn't exit this loop.
-            for &target_bcb in candidate_successors {
-                // An edge is a reloop edge if its target dominates any BCB that has
-                // an edge back to the loop header. (Otherwise it's an exit edge.)
-                let is_reloop_edge = self
-                    .graph
-                    .reloop_predecessors(loop_header_node)
-                    .any(|reloop_bcb| self.graph.dominates(target_bcb, reloop_bcb));
-                if is_reloop_edge {
-                    // We found a good out-edge to be given an expression.
-                    return Some(target_bcb);
-                }
-            }
-
-            // All of the candidate edges exit this loop, so keep looking
-            // for a good reloop edge for one of the outer loops.
-        }
-
-        None
-    }
-
-    fn into_coverage_counters(self) -> CoverageCounters {
-        Transcriber::new(&self).transcribe_counters()
-    }
-}
-
-/// Helper struct for converting `CountersBuilder` into a final `CoverageCounters`.
-struct Transcriber<'a> {
-    old: &'a CountersBuilder<'a>,
+struct Transcriber {
+    old: NodeCounters<BasicCoverageBlock>,
     new: CoverageCounters,
     phys_counter_for_site: FxHashMap<Site, BcbCounter>,
 }
 
-impl<'a> Transcriber<'a> {
-    fn new(old: &'a CountersBuilder<'a>) -> Self {
+impl Transcriber {
+    fn new(num_nodes: usize, old: NodeCounters<BasicCoverageBlock>) -> Self {
         Self {
             old,
-            new: CoverageCounters::with_num_bcbs(old.graph.num_nodes()),
+            new: CoverageCounters::with_num_bcbs(num_nodes),
             phys_counter_for_site: FxHashMap::default(),
         }
     }
 
-    fn transcribe_counters(mut self) -> CoverageCounters {
-        for bcb in self.old.bcb_needs_counter.iter() {
+    fn transcribe_counters(
+        mut self,
+        bcb_needs_counter: &DenseBitSet<BasicCoverageBlock>,
+    ) -> CoverageCounters {
+        for bcb in bcb_needs_counter.iter() {
             let site = Site::Node { bcb };
-            let site_counter = self.site_counter(site);
-
-            // Resolve the site counter into flat lists of nodes/edges whose
-            // physical counts contribute to the counter for this node.
-            // Distinguish between counts that will be added vs subtracted.
-            let mut pos = vec![];
-            let mut neg = vec![];
-            self.push_resolved_sites(site_counter, &mut pos, &mut neg);
-
-            // Simplify by cancelling out sites that appear on both sides.
-            let (mut pos, mut neg) = sort_and_cancel(pos, neg);
+            let (mut pos, mut neg): (Vec<_>, Vec<_>) =
+                self.old.counter_expr(bcb).iter().partition_map(
+                    |&CounterTerm { node, op }| match op {
+                        Op::Add => Either::Left(node),
+                        Op::Subtract => Either::Right(node),
+                    },
+                );
 
             if pos.is_empty() {
-                // If we somehow end up with no positive terms after cancellation,
-                // fall back to creating a physical counter. There's no known way
-                // for this to happen, but it's hard to confidently rule it out.
+                // If we somehow end up with no positive terms, fall back to
+                // creating a physical counter. There's no known way for this
+                // to happen, but we can avoid an ICE if it does.
                 debug_assert!(false, "{site:?} has no positive counter terms");
-                pos = vec![Some(site)];
+                pos = vec![bcb];
                 neg = vec![];
             }
 
-            let mut new_counters_for_sites = |sites: Vec<Option<Site>>| {
+            pos.sort();
+            neg.sort();
+
+            let mut new_counters_for_sites = |sites: Vec<BasicCoverageBlock>| {
                 sites
                     .into_iter()
-                    .filter_map(|id| try { self.ensure_phys_counter(id?) })
+                    .map(|node| self.ensure_phys_counter(Site::Node { bcb: node }))
                     .collect::<Vec<_>>()
             };
             let mut pos = new_counters_for_sites(pos);
@@ -513,79 +279,7 @@ impl<'a> Transcriber<'a> {
         self.new
     }
 
-    fn site_counter(&self, site: Site) -> SiteCounter {
-        self.old.site_counters.get(&site).copied().unwrap_or_else(|| {
-            // We should have already created all necessary site counters.
-            // But if we somehow didn't, avoid crashing in release builds,
-            // and just use an extra physical counter instead.
-            debug_assert!(false, "{site:?} should have a counter");
-            SiteCounter::Phys { site }
-        })
-    }
-
     fn ensure_phys_counter(&mut self, site: Site) -> BcbCounter {
         *self.phys_counter_for_site.entry(site).or_insert_with(|| self.new.make_phys_counter(site))
     }
-
-    /// Resolves the given counter into flat lists of nodes/edges, whose counters
-    /// will then be added and subtracted to form a counter expression.
-    fn push_resolved_sites(&self, counter: SiteCounter, pos: &mut Vec<Site>, neg: &mut Vec<Site>) {
-        match counter {
-            SiteCounter::Phys { site } => pos.push(site),
-            SiteCounter::NodeSumExpr { bcb } => {
-                for &from_bcb in &self.old.graph.predecessors[bcb] {
-                    let edge_counter = self.site_counter(Site::Edge { from_bcb, to_bcb: bcb });
-                    self.push_resolved_sites(edge_counter, pos, neg);
-                }
-            }
-            SiteCounter::EdgeDiffExpr { from_bcb, to_bcb } => {
-                // First, add the count for `from_bcb`.
-                let node_counter = self.site_counter(Site::Node { bcb: from_bcb });
-                self.push_resolved_sites(node_counter, pos, neg);
-
-                // Then subtract the counts for the other out-edges.
-                for target in sibling_out_edge_targets(self.old.graph, from_bcb, to_bcb) {
-                    let edge_counter = self.site_counter(Site::Edge { from_bcb, to_bcb: target });
-                    // Swap `neg` and `pos` so that the counter is subtracted.
-                    self.push_resolved_sites(edge_counter, neg, pos);
-                }
-            }
-        }
-    }
-}
-
-/// Given two lists:
-/// - Sorts each list.
-/// - Converts each list to `Vec<Option<T>>`.
-/// - Scans for values that appear in both lists, and cancels them out by
-///   replacing matching pairs of values with `None`.
-fn sort_and_cancel<T: Ord>(mut pos: Vec<T>, mut neg: Vec<T>) -> (Vec<Option<T>>, Vec<Option<T>>) {
-    pos.sort();
-    neg.sort();
-
-    // Convert to `Vec<Option<T>>`. If `T` has a niche, this should be zero-cost.
-    let mut pos = pos.into_iter().map(Some).collect::<Vec<_>>();
-    let mut neg = neg.into_iter().map(Some).collect::<Vec<_>>();
-
-    // Scan through the lists using two cursors. When either cursor reaches the
-    // end of its list, there can be no more equal pairs, so stop.
-    let mut p = 0;
-    let mut n = 0;
-    while p < pos.len() && n < neg.len() {
-        // If the values are equal, remove them and advance both cursors.
-        // Otherwise, advance whichever cursor points to the lesser value.
-        // (Choosing which cursor to advance relies on both lists being sorted.)
-        match pos[p].cmp(&neg[n]) {
-            Ordering::Less => p += 1,
-            Ordering::Equal => {
-                pos[p] = None;
-                neg[n] = None;
-                p += 1;
-                n += 1;
-            }
-            Ordering::Greater => n += 1,
-        }
-    }
-
-    (pos, neg)
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs b/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs
new file mode 100644
index 00000000000..c108f96a564
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs
@@ -0,0 +1,133 @@
+//! A control-flow graph can be said to have “balanced flow” if the flow
+//! (execution count) of each node is equal to the sum of its in-edge flows,
+//! and also equal to the sum of its out-edge flows.
+//!
+//! Control-flow graphs typically have one or more nodes that don't satisfy the
+//! balanced-flow property, e.g.:
+//! - The start node has out-edges, but no in-edges.
+//! - Return nodes have in-edges, but no out-edges.
+//! - `Yield` nodes can have an out-flow that is less than their in-flow.
+//! - Inescapable loops cause the in-flow/out-flow relationship to break down.
+//!
+//! Balanced-flow graphs are nevertheless useful for analysis, so this module
+//! provides a wrapper type ([`BalancedFlowGraph`]) that imposes balanced flow
+//! on an underlying graph. This is done by non-destructively adding synthetic
+//! nodes and edges as necessary.
+
+use rustc_data_structures::graph;
+use rustc_data_structures::graph::iterate::DepthFirstSearch;
+use rustc_data_structures::graph::reversed::ReversedGraph;
+use rustc_index::Idx;
+use rustc_index::bit_set::DenseBitSet;
+
+use crate::coverage::counters::iter_nodes::IterNodes;
+
+/// A view of an underlying graph that has been augmented to have “balanced flow”.
+/// This means that the flow (execution count) of each node is equal to the
+/// sum of its in-edge flows, and also equal to the sum of its out-edge flows.
+///
+/// To achieve this, a synthetic "sink" node is non-destructively added to the
+/// graph, with synthetic in-edges from these nodes:
+/// - Any node that has no out-edges.
+/// - Any node that explicitly requires a sink edge, as indicated by a
+///   caller-supplied `force_sink_edge` function.
+/// - Any node that would otherwise be unable to reach the sink, because it is
+///   part of an inescapable loop.
+///
+/// To make the graph fully balanced, there is also a synthetic edge from the
+/// sink node back to the start node.
+///
+/// ---
+/// The benefit of having a balanced-flow graph is that it can be subsequently
+/// transformed in ways that are guaranteed to preserve balanced flow
+/// (e.g. merging nodes together), which is useful for discovering relationships
+/// between the node flows of different nodes in the graph.
+pub(crate) struct BalancedFlowGraph<G: graph::DirectedGraph> {
+    graph: G,
+    sink_edge_nodes: DenseBitSet<G::Node>,
+    pub(crate) sink: G::Node,
+}
+
+impl<G: graph::DirectedGraph> BalancedFlowGraph<G> {
+    /// Creates a balanced view of an underlying graph, by adding a synthetic
+    /// sink node that has in-edges from nodes that need or request such an edge,
+    /// and a single out-edge to the start node.
+    ///
+    /// Assumes that all nodes in the underlying graph are reachable from the
+    /// start node.
+    pub(crate) fn for_graph(graph: G, force_sink_edge: impl Fn(G::Node) -> bool) -> Self
+    where
+        G: graph::ControlFlowGraph,
+    {
+        let mut sink_edge_nodes = DenseBitSet::new_empty(graph.num_nodes());
+        let mut dfs = DepthFirstSearch::new(ReversedGraph::new(&graph));
+
+        // First, determine the set of nodes that explicitly request or require
+        // an out-edge to the sink.
+        for node in graph.iter_nodes() {
+            if force_sink_edge(node) || graph.successors(node).next().is_none() {
+                sink_edge_nodes.insert(node);
+                dfs.push_start_node(node);
+            }
+        }
+
+        // Next, find all nodes that are currently not reverse-reachable from
+        // `sink_edge_nodes`, and add them to the set as well.
+        dfs.complete_search();
+        sink_edge_nodes.union_not(dfs.visited_set());
+
+        // The sink node is 1 higher than the highest real node.
+        let sink = G::Node::new(graph.num_nodes());
+
+        BalancedFlowGraph { graph, sink_edge_nodes, sink }
+    }
+}
+
+impl<G> graph::DirectedGraph for BalancedFlowGraph<G>
+where
+    G: graph::DirectedGraph,
+{
+    type Node = G::Node;
+
+    /// Returns the number of nodes in this balanced-flow graph, which is 1
+    /// more than the number of nodes in the underlying graph, to account for
+    /// the synthetic sink node.
+    fn num_nodes(&self) -> usize {
+        // The sink node's index is already the size of the underlying graph,
+        // so just add 1 to that instead.
+        self.sink.index() + 1
+    }
+}
+
+impl<G> graph::StartNode for BalancedFlowGraph<G>
+where
+    G: graph::StartNode,
+{
+    fn start_node(&self) -> Self::Node {
+        self.graph.start_node()
+    }
+}
+
+impl<G> graph::Successors for BalancedFlowGraph<G>
+where
+    G: graph::StartNode + graph::Successors,
+{
+    fn successors(&self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
+        let real_edges;
+        let sink_edge;
+
+        if node == self.sink {
+            // The sink node has no real out-edges, and one synthetic out-edge
+            // to the start node.
+            real_edges = None;
+            sink_edge = Some(self.graph.start_node());
+        } else {
+            // Real nodes have their real out-edges, and possibly one synthetic
+            // out-edge to the sink node.
+            real_edges = Some(self.graph.successors(node));
+            sink_edge = self.sink_edge_nodes.contains(node).then_some(self.sink);
+        }
+
+        real_edges.into_iter().flatten().chain(sink_edge)
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/coverage/counters/iter_nodes.rs b/compiler/rustc_mir_transform/src/coverage/counters/iter_nodes.rs
new file mode 100644
index 00000000000..9d87f7af1b0
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/coverage/counters/iter_nodes.rs
@@ -0,0 +1,16 @@
+use rustc_data_structures::graph;
+use rustc_index::Idx;
+
+pub(crate) trait IterNodes: graph::DirectedGraph {
+    /// Iterates over all nodes of a graph in ascending numeric order.
+    /// Assumes that nodes are densely numbered, i.e. every index in
+    /// `0..num_nodes` is a valid node.
+    ///
+    /// FIXME: Can this just be part of [`graph::DirectedGraph`]?
+    fn iter_nodes(
+        &self,
+    ) -> impl Iterator<Item = Self::Node> + DoubleEndedIterator + ExactSizeIterator {
+        (0..self.num_nodes()).map(<Self::Node as Idx>::new)
+    }
+}
+impl<G: graph::DirectedGraph> IterNodes for G {}
diff --git a/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs b/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs
new file mode 100644
index 00000000000..610498c6c0e
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs
@@ -0,0 +1,306 @@
+//! For each node in a control-flow graph, determines whether that node should
+//! have a physical counter, or a counter expression that is derived from the
+//! physical counters of other nodes.
+//!
+//! Based on the algorithm given in
+//! "Optimal measurement points for program frequency counts"
+//! (Knuth & Stevenson, 1973).
+
+use rustc_data_structures::graph;
+use rustc_index::bit_set::DenseBitSet;
+use rustc_index::{Idx, IndexVec};
+use rustc_middle::mir::coverage::Op;
+use smallvec::SmallVec;
+
+use crate::coverage::counters::iter_nodes::IterNodes;
+use crate::coverage::counters::union_find::{FrozenUnionFind, UnionFind};
+
+#[cfg(test)]
+mod tests;
+
+/// View of some underlying graph, in which each node's successors have been
+/// merged into a single "supernode".
+///
+/// The resulting supernodes have no obvious meaning on their own.
+/// However, merging successor nodes means that a node's out-edges can all
+/// be combined into a single out-edge, whose flow is the same as the flow
+/// (execution count) of its corresponding node in the original graph.
+///
+/// With all node flows now in the original graph now represented as edge flows
+/// in the merged graph, it becomes possible to analyze the original node flows
+/// using techniques for analyzing edge flows.
+#[derive(Debug)]
+pub(crate) struct MergedNodeFlowGraph<Node: Idx> {
+    /// Maps each node to the supernode that contains it, indicated by some
+    /// arbitrary "root" node that is part of that supernode.
+    supernodes: FrozenUnionFind<Node>,
+    /// For each node, stores the single supernode that all of its successors
+    /// have been merged into.
+    ///
+    /// (Note that each node in a supernode can potentially have a _different_
+    /// successor supernode from its peers.)
+    succ_supernodes: IndexVec<Node, Node>,
+}
+
+impl<Node: Idx> MergedNodeFlowGraph<Node> {
+    /// Creates a "merged" view of an underlying graph.
+    ///
+    /// The given graph is assumed to have [“balanced flow”](balanced-flow),
+    /// though it does not necessarily have to be a `BalancedFlowGraph`.
+    ///
+    /// [balanced-flow]: `crate::coverage::counters::balanced_flow::BalancedFlowGraph`.
+    pub(crate) fn for_balanced_graph<G>(graph: G) -> Self
+    where
+        G: graph::DirectedGraph<Node = Node> + graph::Successors,
+    {
+        let mut supernodes = UnionFind::<G::Node>::new(graph.num_nodes());
+
+        // For each node, merge its successors into a single supernode, and
+        // arbitrarily choose one of those successors to represent all of them.
+        let successors = graph
+            .iter_nodes()
+            .map(|node| {
+                graph
+                    .successors(node)
+                    .reduce(|a, b| supernodes.unify(a, b))
+                    .expect("each node in a balanced graph must have at least one out-edge")
+            })
+            .collect::<IndexVec<G::Node, G::Node>>();
+
+        // Now that unification is complete, freeze the supernode forest,
+        // and resolve each arbitrarily-chosen successor to its canonical root.
+        // (This avoids having to explicitly resolve them later.)
+        let supernodes = supernodes.freeze();
+        let succ_supernodes = successors.into_iter().map(|succ| supernodes.find(succ)).collect();
+
+        Self { supernodes, succ_supernodes }
+    }
+
+    fn num_nodes(&self) -> usize {
+        self.succ_supernodes.len()
+    }
+
+    fn is_supernode(&self, node: Node) -> bool {
+        self.supernodes.find(node) == node
+    }
+
+    /// Using the information in this merged graph, together with a given
+    /// permutation of all nodes in the graph, to create physical counters and
+    /// counter expressions for each node in the underlying graph.
+    ///
+    /// The given list must contain exactly one copy of each node in the
+    /// underlying balanced-flow graph. The order of nodes is used as a hint to
+    /// influence counter allocation:
+    /// - Earlier nodes are more likely to receive counter expressions.
+    /// - Later nodes are more likely to receive physical counters.
+    pub(crate) fn make_node_counters(&self, all_nodes_permutation: &[Node]) -> NodeCounters<Node> {
+        let mut builder = SpantreeBuilder::new(self);
+
+        for &node in all_nodes_permutation {
+            builder.visit_node(node);
+        }
+
+        NodeCounters { counter_exprs: builder.finish() }
+    }
+}
+
+/// End result of allocating physical counters and counter expressions for the
+/// nodes of a graph.
+#[derive(Debug)]
+pub(crate) struct NodeCounters<Node: Idx> {
+    counter_exprs: IndexVec<Node, CounterExprVec<Node>>,
+}
+
+impl<Node: Idx> NodeCounters<Node> {
+    /// For the given node, returns the finished list of terms that represent
+    /// its physical counter or counter expression. Always non-empty.
+    ///
+    /// If a node was given a physical counter, its "expression" will contain
+    /// that counter as its sole element.
+    pub(crate) fn counter_expr(&self, this: Node) -> &[CounterTerm<Node>] {
+        self.counter_exprs[this].as_slice()
+    }
+}
+
+#[derive(Debug)]
+struct SpantreeEdge<Node> {
+    /// If true, this edge in the spantree has been reversed an odd number of
+    /// times, so all physical counters added to its node's counter expression
+    /// need to be negated.
+    is_reversed: bool,
+    /// Each spantree edge is "claimed" by the (regular) node that caused it to
+    /// be created. When a node with a physical counter traverses this edge,
+    /// that counter is added to the claiming node's counter expression.
+    claiming_node: Node,
+    /// Supernode at the other end of this spantree edge. Transitively points
+    /// to the "root" of this supernode's spantree component.
+    span_parent: Node,
+}
+
+/// Part of a node's counter expression, which is a sum of counter terms.
+#[derive(Debug)]
+pub(crate) struct CounterTerm<Node> {
+    /// Whether to add or subtract the value of the node's physical counter.
+    pub(crate) op: Op,
+    /// The node whose physical counter is represented by this term.
+    pub(crate) node: Node,
+}
+
+/// Stores the list of counter terms that make up a node's counter expression.
+type CounterExprVec<Node> = SmallVec<[CounterTerm<Node>; 2]>;
+
+#[derive(Debug)]
+struct SpantreeBuilder<'a, Node: Idx> {
+    graph: &'a MergedNodeFlowGraph<Node>,
+    is_unvisited: DenseBitSet<Node>,
+    /// Links supernodes to each other, gradually forming a spanning tree of
+    /// the merged-flow graph.
+    ///
+    /// A supernode without a span edge is the root of its component of the
+    /// spantree. Nodes that aren't supernodes cannot have a spantree edge.
+    span_edges: IndexVec<Node, Option<SpantreeEdge<Node>>>,
+    /// Shared path buffer recycled by all calls to `yank_to_spantree_root`.
+    yank_buffer: Vec<Node>,
+    /// An in-progress counter expression for each node. Each expression is
+    /// initially empty, and will be filled in as relevant nodes are visited.
+    counter_exprs: IndexVec<Node, CounterExprVec<Node>>,
+}
+
+impl<'a, Node: Idx> SpantreeBuilder<'a, Node> {
+    fn new(graph: &'a MergedNodeFlowGraph<Node>) -> Self {
+        let num_nodes = graph.num_nodes();
+        Self {
+            graph,
+            is_unvisited: DenseBitSet::new_filled(num_nodes),
+            span_edges: IndexVec::from_fn_n(|_| None, num_nodes),
+            yank_buffer: vec![],
+            counter_exprs: IndexVec::from_fn_n(|_| SmallVec::new(), num_nodes),
+        }
+    }
+
+    /// Given a supernode, finds the supernode that is the "root" of its
+    /// spantree component. Two nodes that have the same spantree root are
+    /// connected in the spantree.
+    fn spantree_root(&self, this: Node) -> Node {
+        debug_assert!(self.graph.is_supernode(this));
+
+        match self.span_edges[this] {
+            None => this,
+            Some(SpantreeEdge { span_parent, .. }) => self.spantree_root(span_parent),
+        }
+    }
+
+    /// Rotates edges in the spantree so that `this` is the root of its
+    /// spantree component.
+    fn yank_to_spantree_root(&mut self, this: Node) {
+        debug_assert!(self.graph.is_supernode(this));
+
+        // The rotation is done iteratively, by first traversing from `this` to
+        // its root and storing the path in a buffer, and then traversing the
+        // path buffer backwards to reverse all the edges.
+
+        // Recycle the same path buffer for all calls to this method.
+        let path_buf = &mut self.yank_buffer;
+        path_buf.clear();
+        path_buf.push(this);
+
+        // Traverse the spantree until we reach a supernode that has no
+        // span-parent, which must be the root.
+        let mut curr = this;
+        while let &Some(SpantreeEdge { span_parent, .. }) = &self.span_edges[curr] {
+            path_buf.push(span_parent);
+            curr = span_parent;
+        }
+
+        // For each spantree edge `a -> b` in the path that was just traversed,
+        // reverse it to become `a <- b`, while preserving `claiming_node`.
+        for &[a, b] in path_buf.array_windows::<2>().rev() {
+            let SpantreeEdge { is_reversed, claiming_node, span_parent } = self.span_edges[a]
+                .take()
+                .expect("all nodes in the path (except the last) have a `span_parent`");
+            debug_assert_eq!(span_parent, b);
+            debug_assert!(self.span_edges[b].is_none());
+            self.span_edges[b] =
+                Some(SpantreeEdge { is_reversed: !is_reversed, claiming_node, span_parent: a });
+        }
+
+        // The result of the rotation is that `this` is now a spantree root.
+        debug_assert!(self.span_edges[this].is_none());
+    }
+
+    /// Must be called exactly once for each node in the balanced-flow graph.
+    fn visit_node(&mut self, this: Node) {
+        // Assert that this node was unvisited, and mark it visited.
+        assert!(self.is_unvisited.remove(this), "node has already been visited: {this:?}");
+
+        // Get the supernode containing `this`, and make it the root of its
+        // component of the spantree.
+        let this_supernode = self.graph.supernodes.find(this);
+        self.yank_to_spantree_root(this_supernode);
+
+        // Get the supernode containing all of this's successors.
+        let succ_supernode = self.graph.succ_supernodes[this];
+        debug_assert!(self.graph.is_supernode(succ_supernode));
+
+        // If two supernodes are already connected in the spantree, they will
+        // have the same spantree root. (Each supernode is connected to itself.)
+        if this_supernode != self.spantree_root(succ_supernode) {
+            // Adding this node's flow edge to the spantree would cause two
+            // previously-disconnected supernodes to become connected, so add
+            // it. That spantree-edge is now "claimed" by this node.
+            //
+            // Claiming a spantree-edge means that this node will get a counter
+            // expression instead of a physical counter. That expression is
+            // currently empty, but will be built incrementally as the other
+            // nodes are visited.
+            self.span_edges[this_supernode] = Some(SpantreeEdge {
+                is_reversed: false,
+                claiming_node: this,
+                span_parent: succ_supernode,
+            });
+        } else {
+            // This node's flow edge would join two supernodes that are already
+            // connected in the spantree (or are the same supernode). That would
+            // create a cycle in the spantree, so don't add an edge.
+            //
+            // Instead, create a physical counter for this node, and add that
+            // counter to all expressions on the path from `succ_supernode` to
+            // `this_supernode`.
+
+            // Instead of setting `this.measure = true` as in the original paper,
+            // we just add the node's ID to its own "expression".
+            self.counter_exprs[this].push(CounterTerm { node: this, op: Op::Add });
+
+            // Walk the spantree from `this.successor` back to `this`. For each
+            // spantree edge along the way, add this node's physical counter to
+            // the counter expression of the node that claimed the spantree edge.
+            let mut curr = succ_supernode;
+            while curr != this_supernode {
+                let &SpantreeEdge { is_reversed, claiming_node, span_parent } =
+                    self.span_edges[curr].as_ref().unwrap();
+                let op = if is_reversed { Op::Subtract } else { Op::Add };
+                self.counter_exprs[claiming_node].push(CounterTerm { node: this, op });
+
+                curr = span_parent;
+            }
+        }
+    }
+
+    /// Asserts that all nodes have been visited, and returns the computed
+    /// counter expressions (made up of physical counters) for each node.
+    fn finish(self) -> IndexVec<Node, CounterExprVec<Node>> {
+        let Self { graph, is_unvisited, span_edges, yank_buffer: _, counter_exprs } = self;
+        assert!(is_unvisited.is_empty(), "some nodes were never visited: {is_unvisited:?}");
+        debug_assert!(
+            span_edges
+                .iter_enumerated()
+                .all(|(node, span_edge)| { span_edge.is_some() <= graph.is_supernode(node) }),
+            "only supernodes can have a span edge",
+        );
+        debug_assert!(
+            counter_exprs.iter().all(|expr| !expr.is_empty()),
+            "after visiting all nodes, every node should have a non-empty expression",
+        );
+        counter_exprs
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs b/compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs
new file mode 100644
index 00000000000..9e7f754523d
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/coverage/counters/node_flow/tests.rs
@@ -0,0 +1,64 @@
+use itertools::Itertools;
+use rustc_data_structures::graph;
+use rustc_data_structures::graph::vec_graph::VecGraph;
+use rustc_index::Idx;
+use rustc_middle::mir::coverage::Op;
+
+use super::{CounterTerm, MergedNodeFlowGraph, NodeCounters};
+
+fn merged_node_flow_graph<G: graph::Successors>(graph: G) -> MergedNodeFlowGraph<G::Node> {
+    MergedNodeFlowGraph::for_balanced_graph(graph)
+}
+
+fn make_graph<Node: Idx + Ord>(num_nodes: usize, edge_pairs: Vec<(Node, Node)>) -> VecGraph<Node> {
+    VecGraph::new(num_nodes, edge_pairs)
+}
+
+/// Example used in "Optimal Measurement Points for Program Frequency Counts"
+/// (Knuth & Stevenson, 1973), but with 0-based node IDs.
+#[test]
+fn example_driver() {
+    let graph = make_graph::<u32>(5, vec![
+        (0, 1),
+        (0, 3),
+        (1, 0),
+        (1, 2),
+        (2, 1),
+        (2, 4),
+        (3, 3),
+        (3, 4),
+        (4, 0),
+    ]);
+
+    let merged = merged_node_flow_graph(&graph);
+    let counters = merged.make_node_counters(&[3, 1, 2, 0, 4]);
+
+    assert_eq!(format_counter_expressions(&counters), &[
+        // (comment to force vertical formatting for clarity)
+        "[0]: +c0",
+        "[1]: +c0 +c2 -c4",
+        "[2]: +c2",
+        "[3]: +c3",
+        "[4]: +c4",
+    ]);
+}
+
+fn format_counter_expressions<Node: Idx>(counters: &NodeCounters<Node>) -> Vec<String> {
+    let format_item = |&CounterTerm { node, op }| {
+        let op = match op {
+            Op::Subtract => '-',
+            Op::Add => '+',
+        };
+        format!("{op}c{node:?}")
+    };
+
+    counters
+        .counter_exprs
+        .indices()
+        .map(|node| {
+            let mut expr = counters.counter_expr(node).iter().collect::<Vec<_>>();
+            expr.sort_by_key(|item| item.node.index());
+            format!("[{node:?}]: {}", expr.into_iter().map(format_item).join(" "))
+        })
+        .collect()
+}
diff --git a/compiler/rustc_mir_transform/src/coverage/counters/tests.rs b/compiler/rustc_mir_transform/src/coverage/counters/tests.rs
deleted file mode 100644
index 794d4358f82..00000000000
--- a/compiler/rustc_mir_transform/src/coverage/counters/tests.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use std::fmt::Debug;
-
-use super::sort_and_cancel;
-
-fn flatten<T>(input: Vec<Option<T>>) -> Vec<T> {
-    input.into_iter().flatten().collect()
-}
-
-fn sort_and_cancel_and_flatten<T: Clone + Ord>(pos: Vec<T>, neg: Vec<T>) -> (Vec<T>, Vec<T>) {
-    let (pos_actual, neg_actual) = sort_and_cancel(pos, neg);
-    (flatten(pos_actual), flatten(neg_actual))
-}
-
-#[track_caller]
-fn check_test_case<T: Clone + Debug + Ord>(
-    pos: Vec<T>,
-    neg: Vec<T>,
-    pos_expected: Vec<T>,
-    neg_expected: Vec<T>,
-) {
-    eprintln!("pos = {pos:?}; neg = {neg:?}");
-    let output = sort_and_cancel_and_flatten(pos, neg);
-    assert_eq!(output, (pos_expected, neg_expected));
-}
-
-#[test]
-fn cancellation() {
-    let cases: &[(Vec<u32>, Vec<u32>, Vec<u32>, Vec<u32>)] = &[
-        (vec![], vec![], vec![], vec![]),
-        (vec![4, 2, 1, 5, 3], vec![], vec![1, 2, 3, 4, 5], vec![]),
-        (vec![5, 5, 5, 5, 5], vec![5], vec![5, 5, 5, 5], vec![]),
-        (vec![1, 1, 2, 2, 3, 3], vec![1, 2, 3], vec![1, 2, 3], vec![]),
-        (vec![1, 1, 2, 2, 3, 3], vec![2, 4, 2], vec![1, 1, 3, 3], vec![4]),
-    ];
-
-    for (pos, neg, pos_expected, neg_expected) in cases {
-        check_test_case(pos.to_vec(), neg.to_vec(), pos_expected.to_vec(), neg_expected.to_vec());
-        // Same test case, but with its inputs flipped and its outputs flipped.
-        check_test_case(neg.to_vec(), pos.to_vec(), neg_expected.to_vec(), pos_expected.to_vec());
-    }
-}
diff --git a/compiler/rustc_mir_transform/src/coverage/counters/union_find.rs b/compiler/rustc_mir_transform/src/coverage/counters/union_find.rs
new file mode 100644
index 00000000000..2da4f5f5fce
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/coverage/counters/union_find.rs
@@ -0,0 +1,116 @@
+use std::cmp::Ordering;
+use std::mem;
+
+use rustc_index::{Idx, IndexVec};
+
+#[cfg(test)]
+mod tests;
+
+/// Simple implementation of a union-find data structure, i.e. a disjoint-set
+/// forest.
+#[derive(Debug)]
+pub(crate) struct UnionFind<Key: Idx> {
+    table: IndexVec<Key, UnionFindEntry<Key>>,
+}
+
+#[derive(Debug)]
+struct UnionFindEntry<Key> {
+    /// Transitively points towards the "root" of the set containing this key.
+    ///
+    /// Invariant: A root key is its own parent.
+    parent: Key,
+    /// When merging two "root" keys, their ranks determine which key becomes
+    /// the new root, to prevent the parent tree from becoming unnecessarily
+    /// tall. See [`UnionFind::unify`] for details.
+    rank: u32,
+}
+
+impl<Key: Idx> UnionFind<Key> {
+    /// Creates a new disjoint-set forest containing the keys `0..num_keys`.
+    /// Initially, every key is part of its own one-element set.
+    pub(crate) fn new(num_keys: usize) -> Self {
+        // Initially, every key is the root of its own set, so its parent is itself.
+        Self { table: IndexVec::from_fn_n(|key| UnionFindEntry { parent: key, rank: 0 }, num_keys) }
+    }
+
+    /// Returns the "root" key of the disjoint-set containing the given key.
+    /// If two keys have the same root, they belong to the same set.
+    ///
+    /// Also updates internal data structures to make subsequent `find`
+    /// operations faster.
+    pub(crate) fn find(&mut self, key: Key) -> Key {
+        // Loop until we find a key that is its own parent.
+        let mut curr = key;
+        while let parent = self.table[curr].parent
+            && curr != parent
+        {
+            // Perform "path compression" by peeking one layer ahead, and
+            // setting the current key's parent to that value.
+            // (This works even when `parent` is the root of its set, because
+            // of the invariant that a root is its own parent.)
+            let parent_parent = self.table[parent].parent;
+            self.table[curr].parent = parent_parent;
+
+            // Advance by one step and continue.
+            curr = parent;
+        }
+        curr
+    }
+
+    /// Merges the set containing `a` and the set containing `b` into one set.
+    ///
+    /// Returns the common root of both keys, after the merge.
+    pub(crate) fn unify(&mut self, a: Key, b: Key) -> Key {
+        let mut a = self.find(a);
+        let mut b = self.find(b);
+
+        // If both keys have the same root, they're already in the same set,
+        // so there's nothing more to do.
+        if a == b {
+            return a;
+        };
+
+        // Ensure that `a` has strictly greater rank, swapping if necessary.
+        // If both keys have the same rank, increment the rank of `a` so that
+        // future unifications will also prefer `a`, leading to flatter trees.
+        match Ord::cmp(&self.table[a].rank, &self.table[b].rank) {
+            Ordering::Less => mem::swap(&mut a, &mut b),
+            Ordering::Equal => self.table[a].rank += 1,
+            Ordering::Greater => {}
+        }
+
+        debug_assert!(self.table[a].rank > self.table[b].rank);
+        debug_assert_eq!(self.table[b].parent, b);
+
+        // Make `a` the parent of `b`.
+        self.table[b].parent = a;
+
+        a
+    }
+
+    /// Creates a snapshot of this disjoint-set forest that can no longer be
+    /// mutated, but can be queried without mutation.
+    pub(crate) fn freeze(&mut self) -> FrozenUnionFind<Key> {
+        // Just resolve each key to its actual root.
+        let roots = self.table.indices().map(|key| self.find(key)).collect();
+        FrozenUnionFind { roots }
+    }
+}
+
+/// Snapshot of a disjoint-set forest that can no longer be mutated, but can be
+/// queried in O(1) time without mutation.
+///
+/// This is really just a wrapper around a direct mapping from keys to roots,
+/// but with a [`Self::find`] method that resembles [`UnionFind::find`].
+#[derive(Debug)]
+pub(crate) struct FrozenUnionFind<Key: Idx> {
+    roots: IndexVec<Key, Key>,
+}
+
+impl<Key: Idx> FrozenUnionFind<Key> {
+    /// Returns the "root" key of the disjoint-set containing the given key.
+    /// If two keys have the same root, they belong to the same set.
+    pub(crate) fn find(&self, key: Key) -> Key {
+        self.roots[key]
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/coverage/counters/union_find/tests.rs b/compiler/rustc_mir_transform/src/coverage/counters/union_find/tests.rs
new file mode 100644
index 00000000000..34a4e4f8e6e
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/coverage/counters/union_find/tests.rs
@@ -0,0 +1,32 @@
+use super::UnionFind;
+
+#[test]
+fn empty() {
+    let mut sets = UnionFind::<u32>::new(10);
+
+    for i in 1..10 {
+        assert_eq!(sets.find(i), i);
+    }
+}
+
+#[test]
+fn transitive() {
+    let mut sets = UnionFind::<u32>::new(10);
+
+    sets.unify(3, 7);
+    sets.unify(4, 2);
+
+    assert_eq!(sets.find(7), sets.find(3));
+    assert_eq!(sets.find(2), sets.find(4));
+    assert_ne!(sets.find(3), sets.find(4));
+
+    sets.unify(7, 4);
+
+    assert_eq!(sets.find(7), sets.find(3));
+    assert_eq!(sets.find(2), sets.find(4));
+    assert_eq!(sets.find(3), sets.find(4));
+
+    for i in [0, 1, 5, 6, 8, 9] {
+        assert_eq!(sets.find(i), i);
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index 3fa8b063fa7..25dc7f31227 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -1,7 +1,6 @@
 use std::cmp::Ordering;
-use std::collections::VecDeque;
 use std::ops::{Index, IndexMut};
-use std::{iter, mem, slice};
+use std::{mem, slice};
 
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
@@ -211,54 +210,6 @@ impl CoverageGraph {
         self.dominator_order_rank[a].cmp(&self.dominator_order_rank[b])
     }
 
-    /// Returns the source of this node's sole in-edge, if it has exactly one.
-    /// That edge can be assumed to have the same execution count as the node
-    /// itself (in the absence of panics).
-    pub(crate) fn sole_predecessor(
-        &self,
-        to_bcb: BasicCoverageBlock,
-    ) -> Option<BasicCoverageBlock> {
-        // Unlike `simple_successor`, there is no need for extra checks here.
-        if let &[from_bcb] = self.predecessors[to_bcb].as_slice() { Some(from_bcb) } else { None }
-    }
-
-    /// Returns the target of this node's sole out-edge, if it has exactly
-    /// one, but only if that edge can be assumed to have the same execution
-    /// count as the node itself (in the absence of panics).
-    pub(crate) fn simple_successor(
-        &self,
-        from_bcb: BasicCoverageBlock,
-    ) -> Option<BasicCoverageBlock> {
-        // If a node's count is the sum of its out-edges, and it has exactly
-        // one out-edge, then that edge has the same count as the node.
-        if self.bcbs[from_bcb].is_out_summable
-            && let &[to_bcb] = self.successors[from_bcb].as_slice()
-        {
-            Some(to_bcb)
-        } else {
-            None
-        }
-    }
-
-    /// For each loop that contains the given node, yields the "loop header"
-    /// node representing that loop, from innermost to outermost. If the given
-    /// node is itself a loop header, it is yielded first.
-    pub(crate) fn loop_headers_containing(
-        &self,
-        bcb: BasicCoverageBlock,
-    ) -> impl Iterator<Item = BasicCoverageBlock> + Captures<'_> {
-        let self_if_loop_header = self.is_loop_header.contains(bcb).then_some(bcb).into_iter();
-
-        let mut curr = Some(bcb);
-        let strictly_enclosing = iter::from_fn(move || {
-            let enclosing = self.enclosing_loop_header[curr?];
-            curr = enclosing;
-            enclosing
-        });
-
-        self_if_loop_header.chain(strictly_enclosing)
-    }
-
     /// For the given node, yields the subset of its predecessor nodes that
     /// it dominates. If that subset is non-empty, the node is a "loop header",
     /// and each of those predecessors represents an in-edge that jumps back to
@@ -489,126 +440,3 @@ impl<'a, 'tcx> graph::Successors for CoverageRelevantSubgraph<'a, 'tcx> {
         self.coverage_successors(bb).into_iter()
     }
 }
-
-/// State of a node in the coverage graph during ready-first traversal.
-#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
-enum ReadyState {
-    /// This node has not yet been added to the fallback queue or ready queue.
-    Unqueued,
-    /// This node is currently in the fallback queue.
-    InFallbackQueue,
-    /// This node's predecessors have all been visited, so it is in the ready queue.
-    /// (It might also have a stale entry in the fallback queue.)
-    InReadyQueue,
-    /// This node has been visited.
-    /// (It might also have a stale entry in the fallback queue.)
-    Visited,
-}
-
-/// Iterator that visits nodes in the coverage graph, in an order that always
-/// prefers "ready" nodes whose predecessors have already been visited.
-pub(crate) struct ReadyFirstTraversal<'a> {
-    graph: &'a CoverageGraph,
-
-    /// For each node, the number of its predecessor nodes that haven't been visited yet.
-    n_unvisited_preds: IndexVec<BasicCoverageBlock, u32>,
-    /// Indicates whether a node has been visited, or which queue it is in.
-    state: IndexVec<BasicCoverageBlock, ReadyState>,
-
-    /// Holds unvisited nodes whose predecessors have all been visited.
-    ready_queue: VecDeque<BasicCoverageBlock>,
-    /// Holds unvisited nodes with some unvisited predecessors.
-    /// Also contains stale entries for nodes that were upgraded to ready.
-    fallback_queue: VecDeque<BasicCoverageBlock>,
-}
-
-impl<'a> ReadyFirstTraversal<'a> {
-    pub(crate) fn new(graph: &'a CoverageGraph) -> Self {
-        let num_nodes = graph.num_nodes();
-
-        let n_unvisited_preds =
-            IndexVec::from_fn_n(|node| graph.predecessors[node].len() as u32, num_nodes);
-        let mut state = IndexVec::from_elem_n(ReadyState::Unqueued, num_nodes);
-
-        // We know from coverage graph construction that the start node is the
-        // only node with no predecessors.
-        debug_assert!(
-            n_unvisited_preds.iter_enumerated().all(|(node, &n)| (node == START_BCB) == (n == 0))
-        );
-        let ready_queue = VecDeque::from(vec![START_BCB]);
-        state[START_BCB] = ReadyState::InReadyQueue;
-
-        Self { graph, state, n_unvisited_preds, ready_queue, fallback_queue: VecDeque::new() }
-    }
-
-    /// Returns the next node from the ready queue, or else the next unvisited
-    /// node from the fallback queue.
-    fn next_inner(&mut self) -> Option<BasicCoverageBlock> {
-        // Always prefer to yield a ready node if possible.
-        if let Some(node) = self.ready_queue.pop_front() {
-            assert_eq!(self.state[node], ReadyState::InReadyQueue);
-            return Some(node);
-        }
-
-        while let Some(node) = self.fallback_queue.pop_front() {
-            match self.state[node] {
-                // This entry in the fallback queue is not stale, so yield it.
-                ReadyState::InFallbackQueue => return Some(node),
-                // This node was added to the fallback queue, but later became
-                // ready and was visited via the ready queue. Ignore it here.
-                ReadyState::Visited => {}
-                // Unqueued nodes can't be in the fallback queue, by definition.
-                // We know that the ready queue is empty at this point.
-                ReadyState::Unqueued | ReadyState::InReadyQueue => unreachable!(
-                    "unexpected state for {node:?} in the fallback queue: {:?}",
-                    self.state[node]
-                ),
-            }
-        }
-
-        None
-    }
-
-    fn mark_visited_and_enqueue_successors(&mut self, node: BasicCoverageBlock) {
-        assert!(self.state[node] < ReadyState::Visited);
-        self.state[node] = ReadyState::Visited;
-
-        // For each of this node's successors, decrease the successor's
-        // "unvisited predecessors" count, and enqueue it if appropriate.
-        for &succ in &self.graph.successors[node] {
-            let is_unqueued = match self.state[succ] {
-                ReadyState::Unqueued => true,
-                ReadyState::InFallbackQueue => false,
-                ReadyState::InReadyQueue => {
-                    unreachable!("nodes in the ready queue have no unvisited predecessors")
-                }
-                // The successor was already visited via one of its other predecessors.
-                ReadyState::Visited => continue,
-            };
-
-            self.n_unvisited_preds[succ] -= 1;
-            if self.n_unvisited_preds[succ] == 0 {
-                // This node's predecessors have all been visited, so add it to
-                // the ready queue. If it's already in the fallback queue, that
-                // fallback entry will be ignored later.
-                self.state[succ] = ReadyState::InReadyQueue;
-                self.ready_queue.push_back(succ);
-            } else if is_unqueued {
-                // This node has unvisited predecessors, so add it to the
-                // fallback queue in case we run out of ready nodes later.
-                self.state[succ] = ReadyState::InFallbackQueue;
-                self.fallback_queue.push_back(succ);
-            }
-        }
-    }
-}
-
-impl<'a> Iterator for ReadyFirstTraversal<'a> {
-    type Item = BasicCoverageBlock;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let node = self.next_inner()?;
-        self.mark_visited_and_enqueue_successors(node);
-        Some(node)
-    }
-}
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 57956448414..b1b609595b7 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -15,10 +15,7 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::mir::coverage::{
     CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind,
 };
-use rustc_middle::mir::{
-    self, BasicBlock, BasicBlockData, SourceInfo, Statement, StatementKind, Terminator,
-    TerminatorKind,
-};
+use rustc_middle::mir::{self, BasicBlock, Statement, StatementKind, TerminatorKind};
 use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
@@ -248,19 +245,6 @@ fn inject_coverage_statements<'tcx>(
         // to create a new block between the two BCBs, and inject into that.
         let target_bb = match site {
             Site::Node { bcb } => graph[bcb].leader_bb(),
-            Site::Edge { from_bcb, to_bcb } => {
-                // Create a new block between the last block of `from_bcb` and
-                // the first block of `to_bcb`.
-                let from_bb = graph[from_bcb].last_bb();
-                let to_bb = graph[to_bcb].leader_bb();
-
-                let new_bb = inject_edge_counter_basic_block(mir_body, from_bb, to_bb);
-                debug!(
-                    "Edge {from_bcb:?} (last {from_bb:?}) -> {to_bcb:?} (leader {to_bb:?}) \
-                    requires a new MIR BasicBlock {new_bb:?} for counter increment {id:?}",
-                );
-                new_bb
-            }
         };
 
         inject_statement(mir_body, CoverageKind::CounterIncrement { id }, target_bb);
@@ -335,31 +319,6 @@ fn inject_mcdc_statements<'tcx>(
     }
 }
 
-/// Given two basic blocks that have a control-flow edge between them, creates
-/// and returns a new block that sits between those blocks.
-fn inject_edge_counter_basic_block(
-    mir_body: &mut mir::Body<'_>,
-    from_bb: BasicBlock,
-    to_bb: BasicBlock,
-) -> BasicBlock {
-    let span = mir_body[from_bb].terminator().source_info.span.shrink_to_hi();
-    let new_bb = mir_body.basic_blocks_mut().push(BasicBlockData {
-        statements: vec![], // counter will be injected here
-        terminator: Some(Terminator {
-            source_info: SourceInfo::outermost(span),
-            kind: TerminatorKind::Goto { target: to_bb },
-        }),
-        is_cleanup: false,
-    });
-    let edge_ref = mir_body[from_bb]
-        .terminator_mut()
-        .successors_mut()
-        .find(|successor| **successor == to_bb)
-        .expect("from_bb should have a successor for to_bb");
-    *edge_ref = new_bb;
-    new_bb
-}
-
 fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb: BasicBlock) {
     debug!("  injecting statement {counter_kind:?} for {bb:?}");
     let data = &mut mir_body[bb];
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 9459ef99445..db999bea986 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -1,4 +1,5 @@
 // tidy-alphabetical-start
+#![feature(array_windows)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(const_type_name)]
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 9795299ed6d..dc26d4de57a 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1183,7 +1183,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             let in_module_is_extern = !in_module.def_id().is_local();
             in_module.for_each_child(self, |this, ident, ns, name_binding| {
                 // avoid non-importable candidates
-                if !name_binding.is_importable() {
+                if !name_binding.is_importable()
+                    // FIXME(import_trait_associated_functions): remove this when `import_trait_associated_functions` is stable
+                    || name_binding.is_assoc_const_or_fn()
+                        && !this.tcx.features().import_trait_associated_functions()
+                {
                     return;
                 }
 
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 5b1d8d622bd..cad45d3c293 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -17,9 +17,10 @@ use rustc_session::lint::builtin::{
     AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE,
     REDUNDANT_IMPORTS, UNUSED_IMPORTS,
 };
+use rustc_session::parse::feature_err;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::hygiene::LocalExpnId;
-use rustc_span::{Ident, Span, Symbol, kw};
+use rustc_span::{Ident, Span, Symbol, kw, sym};
 use smallvec::SmallVec;
 use tracing::debug;
 
@@ -829,6 +830,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                     // Don't update the resolution, because it was never added.
                     Err(Determined) if target.name == kw::Underscore => {}
                     Ok(binding) if binding.is_importable() => {
+                        if binding.is_assoc_const_or_fn()
+                            && !this.tcx.features().import_trait_associated_functions()
+                        {
+                            feature_err(
+                                this.tcx.sess,
+                                sym::import_trait_associated_functions,
+                                import.span,
+                                "`use` associated items of traits is unstable",
+                            )
+                            .emit();
+                        }
                         let imported_binding = this.import(binding, import);
                         target_bindings[ns].set(Some(imported_binding));
                         this.define(parent, target, ns, imported_binding);
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index cc9ed566eda..8e457e68eec 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -920,10 +920,13 @@ impl<'ra> NameBindingData<'ra> {
     }
 
     fn is_importable(&self) -> bool {
-        !matches!(
-            self.res(),
-            Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _)
-        )
+        !matches!(self.res(), Res::Def(DefKind::AssocTy, _))
+    }
+
+    // FIXME(import_trait_associated_functions): associate `const` or `fn` are not importable unless
+    // the feature `import_trait_associated_functions` is enable
+    fn is_assoc_const_or_fn(&self) -> bool {
+        matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _))
     }
 
     fn macro_kind(&self) -> Option<MacroKind> {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index a5bf5e06485..0c8c722e4d8 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1095,6 +1095,7 @@ symbols! {
         import,
         import_name_type,
         import_shadowing,
+        import_trait_associated_functions,
         imported_main,
         in_band_lifetimes,
         include,
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 83730285636..71044190f0c 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -331,7 +331,7 @@
 //!
 //! Note that this invariant is enforced by simply making it impossible to call code that would
 //! perform a move on the pinned value. This is the case since the only way to access that pinned
-//! value is through the pinning <code>[Pin]<[&mut] T>></code>, which in turn restricts our access.
+//! value is through the pinning <code>[Pin]<[&mut] T></code>, which in turn restricts our access.
 //!
 //! ## [`Unpin`]
 //!
@@ -379,7 +379,7 @@
 //!
 //! Exposing access to the inner field which you want to remain pinned must then be carefully
 //! considered as well! Remember, exposing a method that gives access to a
-//! <code>[Pin]<[&mut] InnerT>></code> where <code>InnerT: [Unpin]</code> would allow safe code to
+//! <code>[Pin]<[&mut] InnerT></code> where <code>InnerT: [Unpin]</code> would allow safe code to
 //! trivially move the inner value out of that pinning pointer, which is precisely what you're
 //! seeking to prevent! Exposing a field of a pinned value through a pinning pointer is called
 //! "projecting" a pin, and the more general case of deciding in which cases a pin should be able
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index 74a1d40f4e7..2da94e72566 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -42,9 +42,10 @@ impl Alignment {
     /// but in an `Alignment` instead of a `usize`.
     #[unstable(feature = "ptr_alignment_type", issue = "102070")]
     #[inline]
+    #[must_use]
     pub const fn of<T>() -> Self {
-        // SAFETY: rustc ensures that type alignment is always a power of two.
-        unsafe { Alignment::new_unchecked(mem::align_of::<T>()) }
+        // This can't actually panic since type alignment is always a power of two.
+        const { Alignment::new(mem::align_of::<T>()).unwrap() }
     }
 
     /// Creates an `Alignment` from a `usize`, or returns `None` if it's
@@ -95,8 +96,13 @@ impl Alignment {
     #[unstable(feature = "ptr_alignment_type", issue = "102070")]
     #[inline]
     pub const fn as_nonzero(self) -> NonZero<usize> {
+        // This transmutes directly to avoid the UbCheck in `NonZero::new_unchecked`
+        // since there's no way for the user to trip that check anyway -- the
+        // validity invariant of the type would have to have been broken earlier --
+        // and emitting it in an otherwise simple method is bad for compile time.
+
         // SAFETY: All the discriminants are non-zero.
-        unsafe { NonZero::new_unchecked(self.as_usize()) }
+        unsafe { mem::transmute::<Alignment, NonZero<usize>>(self) }
     }
 
     /// Returns the base-2 logarithm of the alignment.
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index f58c0e12411..e1348552b65 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -596,12 +596,7 @@ pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
 #[stable(feature = "strict_provenance", since = "1.84.0")]
 #[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")]
 pub const fn without_provenance<T>(addr: usize) -> *const T {
-    // An int-to-pointer transmute currently has exactly the intended semantics: it creates a
-    // pointer without provenance. Note that this is *not* a stable guarantee about transmute
-    // semantics, it relies on sysroot crates having special status.
-    // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
-    // pointer).
-    unsafe { mem::transmute(addr) }
+    without_provenance_mut(addr)
 }
 
 /// Creates a new pointer that is dangling, but non-null and well-aligned.
@@ -618,7 +613,7 @@ pub const fn without_provenance<T>(addr: usize) -> *const T {
 #[stable(feature = "strict_provenance", since = "1.84.0")]
 #[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")]
 pub const fn dangling<T>() -> *const T {
-    without_provenance(mem::align_of::<T>())
+    dangling_mut()
 }
 
 /// Creates a pointer with the given address and no [provenance][crate::ptr#provenance].
@@ -661,7 +656,7 @@ pub const fn without_provenance_mut<T>(addr: usize) -> *mut T {
 #[stable(feature = "strict_provenance", since = "1.84.0")]
 #[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")]
 pub const fn dangling_mut<T>() -> *mut T {
-    without_provenance_mut(mem::align_of::<T>())
+    NonNull::dangling().as_ptr()
 }
 
 /// Converts an address back to a pointer, picking up some previously 'exposed'
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 2c9131254f7..d93069d384e 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -91,12 +91,12 @@ impl<T: Sized> NonNull<T> {
     ///
     /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
     #[unstable(feature = "nonnull_provenance", issue = "135243")]
+    #[must_use]
+    #[inline]
     pub const fn without_provenance(addr: NonZero<usize>) -> Self {
+        let pointer = crate::ptr::without_provenance(addr.get());
         // SAFETY: we know `addr` is non-zero.
-        unsafe {
-            let ptr = crate::ptr::without_provenance_mut(addr.get());
-            NonNull::new_unchecked(ptr)
-        }
+        unsafe { NonNull { pointer } }
     }
 
     /// Creates a new `NonNull` that is dangling, but well-aligned.
@@ -123,11 +123,8 @@ impl<T: Sized> NonNull<T> {
     #[must_use]
     #[inline]
     pub const fn dangling() -> Self {
-        // SAFETY: ptr::dangling_mut() returns a non-null well-aligned pointer.
-        unsafe {
-            let ptr = crate::ptr::dangling_mut::<T>();
-            NonNull::new_unchecked(ptr)
-        }
+        let align = crate::ptr::Alignment::of::<T>();
+        NonNull::without_provenance(align.as_nonzero())
     }
 
     /// Converts an address back to a mutable pointer, picking up some previously 'exposed'
@@ -137,6 +134,7 @@ impl<T: Sized> NonNull<T> {
     ///
     /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
     #[unstable(feature = "nonnull_provenance", issue = "135243")]
+    #[inline]
     pub fn with_exposed_provenance(addr: NonZero<usize>) -> Self {
         // SAFETY: we know `addr` is non-zero.
         unsafe {
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 59512b00273829823da74050d373b8d46dbca55
+Subproject 7e8c93c87c611f21d9bd95100563392f4c18bfe
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index b20d8678d0e..575716eb6dd 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -1,5 +1,4 @@
 run-make/cat-and-grep-sanity-check/Makefile
-run-make/extern-fn-reachable/Makefile
 run-make/jobserver-error/Makefile
 run-make/split-debuginfo/Makefile
 run-make/symbol-mangling-hashed/Makefile
diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map
index 396edec275d..84fae4a595a 100644
--- a/tests/coverage/abort.cov-map
+++ b/tests/coverage/abort.cov-map
@@ -1,40 +1,37 @@
 Function name: abort::main
-Raw bytes (89): 0x[01, 01, 0a, 07, 09, 01, 05, 03, 0d, 03, 13, 0d, 11, 03, 0d, 03, 1f, 0d, 15, 03, 0d, 05, 09, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 22, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0e, 02, 09, 00, 0a, 22, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 1a, 00, 30, 00, 31, 22, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 30, 00, 31, 27, 01, 09, 00, 17, 0d, 02, 05, 01, 02]
+Raw bytes (83): 0x[01, 01, 07, 05, 01, 05, 0b, 01, 09, 05, 13, 01, 0d, 05, 1b, 01, 11, 0d, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 19, 09, 00, 1a, 02, 0a, 06, 02, 09, 00, 0a, 02, 02, 0c, 00, 19, 0d, 00, 1a, 00, 31, 0e, 00, 30, 00, 31, 02, 04, 0c, 00, 19, 11, 00, 1a, 00, 31, 16, 00, 30, 00, 31, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 10
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 3 operands: lhs = Expression(0, Add), rhs = Expression(4, Add)
-- expression 4 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 6 operands: lhs = Expression(0, Add), rhs = Expression(7, Add)
-- expression 7 operands: lhs = Counter(3), rhs = Counter(5)
-- expression 8 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 9 operands: lhs = Counter(1), rhs = Counter(2)
+Number of expressions: 7
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 5 operands: lhs = Counter(1), rhs = Expression(6, Add)
+- expression 6 operands: lhs = Counter(0), rhs = Counter(4)
 Number of file 0 mappings: 13
 - Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27)
-- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
-    = ((c0 + c1) + c2)
-- Code(Expression(8, Sub)) at (prev + 1, 12) to (start + 0, 25)
-    = (((c0 + c1) + c2) - c3)
-- Code(Counter(4)) at (prev + 0, 26) to (start + 2, 10)
-- Code(Expression(3, Sub)) at (prev + 2, 9) to (start + 0, 10)
-    = (((c0 + c1) + c2) - (c3 + c4))
-- Code(Expression(8, Sub)) at (prev + 2, 12) to (start + 0, 25)
-    = (((c0 + c1) + c2) - c3)
-- Code(Counter(5)) at (prev + 0, 26) to (start + 0, 49)
-- Code(Expression(6, Sub)) at (prev + 0, 48) to (start + 0, 49)
-    = (((c0 + c1) + c2) - (c3 + c5))
-- Code(Expression(8, Sub)) at (prev + 4, 12) to (start + 0, 25)
-    = (((c0 + c1) + c2) - c3)
-- Code(Counter(1)) at (prev + 0, 26) to (start + 0, 49)
-- Code(Counter(2)) at (prev + 0, 48) to (start + 0, 49)
-- Code(Expression(9, Add)) at (prev + 1, 9) to (start + 0, 23)
-    = (c1 + c2)
-- Code(Counter(3)) at (prev + 2, 5) to (start + 1, 2)
-Highest counter ID seen: c5
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 25)
+    = (c1 - c0)
+- Code(Counter(2)) at (prev + 0, 26) to (start + 2, 10)
+- Code(Expression(1, Sub)) at (prev + 2, 9) to (start + 0, 10)
+    = (c1 - (c0 + c2))
+- Code(Expression(0, Sub)) at (prev + 2, 12) to (start + 0, 25)
+    = (c1 - c0)
+- Code(Counter(3)) at (prev + 0, 26) to (start + 0, 49)
+- Code(Expression(3, Sub)) at (prev + 0, 48) to (start + 0, 49)
+    = (c1 - (c0 + c3))
+- Code(Expression(0, Sub)) at (prev + 4, 12) to (start + 0, 25)
+    = (c1 - c0)
+- Code(Counter(4)) at (prev + 0, 26) to (start + 0, 49)
+- Code(Expression(5, Sub)) at (prev + 0, 48) to (start + 0, 49)
+    = (c1 - (c0 + c4))
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+Highest counter ID seen: c4
 
 Function name: abort::might_abort
 Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 03, 01, 01, 14, 05, 02, 09, 01, 24, 02, 02, 0c, 03, 02]
diff --git a/tests/coverage/assert-ne.cov-map b/tests/coverage/assert-ne.cov-map
index 906abcd3c2e..b432e63c168 100644
--- a/tests/coverage/assert-ne.cov-map
+++ b/tests/coverage/assert-ne.cov-map
@@ -1,14 +1,16 @@
 Function name: assert_ne::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 08, 01, 03, 1c, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 09, 03, 05, 01, 02]
+Raw bytes (28): 0x[01, 01, 02, 01, 05, 01, 09, 04, 01, 08, 01, 03, 1c, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 06, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
+Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28)
 - Code(Counter(1)) at (prev + 4, 13) to (start + 0, 19)
 - Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 19)
     = (c0 - c1)
-- Code(Counter(2)) at (prev + 3, 5) to (start + 1, 2)
-Highest counter ID seen: c2
+- Code(Expression(1, Sub)) at (prev + 3, 5) to (start + 1, 2)
+    = (c0 - c2)
+Highest counter ID seen: c1
 
diff --git a/tests/coverage/assert.cov-map b/tests/coverage/assert.cov-map
index 3bbf7a43e6d..903cccfe9cb 100644
--- a/tests/coverage/assert.cov-map
+++ b/tests/coverage/assert.cov-map
@@ -1,32 +1,29 @@
 Function name: assert::main
-Raw bytes (67): 0x[01, 01, 09, 07, 0d, 0b, 09, 01, 05, 03, 11, 17, 11, 1b, 0d, 01, 09, 23, 0d, 05, 09, 09, 01, 09, 01, 01, 1b, 03, 02, 0b, 00, 18, 0e, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 09, 00, 0a, 1f, 01, 09, 00, 17, 11, 02, 05, 01, 02]
+Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 09, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 9
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
-- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(2)
-- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 3 operands: lhs = Expression(0, Add), rhs = Counter(4)
-- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(4)
-- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(3)
-- expression 6 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(3)
-- expression 8 operands: lhs = Counter(1), rhs = Counter(2)
+Number of expressions: 6
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
+- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
+- expression 5 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 9, 1) to (start + 1, 27)
-- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
-    = (((c0 + c1) + c2) + c3)
-- Code(Expression(3, Sub)) at (prev + 1, 12) to (start + 0, 26)
-    = ((((c0 + c1) + c2) + c3) - c4)
-- Code(Counter(1)) at (prev + 0, 27) to (start + 2, 10)
-- Code(Expression(4, Sub)) at (prev + 2, 19) to (start + 0, 32)
-    = (((c0 + c2) + c3) - c4)
-- Code(Counter(2)) at (prev + 0, 33) to (start + 2, 10)
-- Code(Counter(3)) at (prev + 2, 9) to (start + 0, 10)
-- Code(Expression(7, Add)) at (prev + 1, 9) to (start + 0, 23)
-    = ((c1 + c2) + c3)
-- Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2)
-Highest counter ID seen: c4
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26)
+    = (c1 - c0)
+- Code(Counter(2)) at (prev + 0, 27) to (start + 2, 10)
+- Code(Expression(1, Sub)) at (prev + 2, 19) to (start + 0, 32)
+    = (c1 - (c0 + c2))
+- Code(Counter(3)) at (prev + 0, 33) to (start + 2, 10)
+- Code(Expression(3, Sub)) at (prev + 2, 9) to (start + 0, 10)
+    = (c1 - ((c0 + c2) + c3))
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+Highest counter ID seen: c3
 
 Function name: assert::might_fail_assert
 Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 02, 0f, 02, 02, 25, 00, 3d, 05, 01, 01, 00, 02]
diff --git a/tests/coverage/assert.coverage b/tests/coverage/assert.coverage
index 22fb6821fba..dfd919660f5 100644
--- a/tests/coverage/assert.coverage
+++ b/tests/coverage/assert.coverage
@@ -9,16 +9,16 @@
    LL|       |
    LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let mut countdown = 10;
-   LL|     11|    while countdown > 0 {
-   LL|     11|        if countdown == 1 {
+   LL|     10|    while countdown > 0 {
+   LL|      9|        if countdown == 1 {
    LL|      1|            might_fail_assert(3);
-   LL|     10|        } else if countdown < 5 {
+   LL|      8|        } else if countdown < 5 {
    LL|      3|            might_fail_assert(2);
-   LL|      6|        }
-   LL|     10|        countdown -= 1;
+   LL|      5|        }
+   LL|      9|        countdown -= 1;
    LL|       |    }
-   LL|      0|    Ok(())
-   LL|      0|}
+   LL|      1|    Ok(())
+   LL|      1|}
    LL|       |
    LL|       |// Notes:
    LL|       |//   1. Compare this program and its coverage results to those of the very similar test
diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map
index 401dd6450e9..397eaa17caf 100644
--- a/tests/coverage/assert_not.cov-map
+++ b/tests/coverage/assert_not.cov-map
@@ -1,17 +1,15 @@
 Function name: assert_not::main
-Raw bytes (33): 0x[01, 01, 02, 05, 00, 0d, 00, 05, 01, 06, 01, 01, 12, 05, 02, 05, 00, 14, 02, 01, 05, 00, 14, 0d, 01, 05, 00, 16, 06, 01, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 0d, 00, 05, 01, 06, 01, 01, 12, 05, 02, 05, 00, 14, 09, 01, 05, 00, 14, 0d, 01, 05, 00, 16, 02, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 2
-- expression 0 operands: lhs = Counter(1), rhs = Zero
-- expression 1 operands: lhs = Counter(3), rhs = Zero
+Number of expressions: 1
+- expression 0 operands: lhs = Counter(3), rhs = Zero
 Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 6, 1) to (start + 1, 18)
 - Code(Counter(1)) at (prev + 2, 5) to (start + 0, 20)
-- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 20)
-    = (c1 - Zero)
+- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 20)
 - Code(Counter(3)) at (prev + 1, 5) to (start + 0, 22)
-- Code(Expression(1, Sub)) at (prev + 1, 1) to (start + 0, 2)
+- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2)
     = (c3 - Zero)
 Highest counter ID seen: c3
 
diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map
index d3eed6c4f2a..521562f6b91 100644
--- a/tests/coverage/async.cov-map
+++ b/tests/coverage/async.cov-map
@@ -155,34 +155,38 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: async::i::{closure#0}
-Raw bytes (63): 0x[01, 01, 02, 07, 15, 0d, 11, 0b, 01, 2c, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 11, 01, 09, 00, 0a, 19, 00, 0e, 00, 17, 1d, 00, 1b, 00, 20, 11, 00, 24, 00, 26, 15, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 03, 05, 09, 11, 15, 0d, 11, 0b, 01, 2c, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 02, 00, 0e, 00, 17, 11, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 06, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 2
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(5)
-- expression 1 operands: lhs = Counter(3), rhs = Counter(4)
+Number of expressions: 3
+- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 2 operands: lhs = Counter(3), rhs = Counter(4)
 Number of file 0 mappings: 11
 - Code(Counter(0)) at (prev + 44, 19) to (start + 4, 12)
 - Code(Counter(2)) at (prev + 5, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 24)
 - Code(Counter(1)) at (prev + 0, 28) to (start + 0, 33)
 - Code(Counter(2)) at (prev + 0, 39) to (start + 0, 48)
-- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 10)
-- Code(Counter(6)) at (prev + 0, 14) to (start + 0, 23)
-- Code(Counter(7)) at (prev + 0, 27) to (start + 0, 32)
-- Code(Counter(4)) at (prev + 0, 36) to (start + 0, 38)
-- Code(Counter(5)) at (prev + 1, 14) to (start + 0, 16)
-- Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = ((c3 + c4) + c5)
-Highest counter ID seen: c7
+- Code(Counter(5)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 23)
+    = (c1 - c2)
+- Code(Counter(4)) at (prev + 0, 27) to (start + 0, 32)
+- Code(Counter(5)) at (prev + 0, 36) to (start + 0, 38)
+- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 16)
+    = (c4 - c5)
+- Code(Expression(2, Add)) at (prev + 2, 1) to (start + 0, 2)
+    = (c3 + c4)
+Highest counter ID seen: c5
 
 Function name: async::j
-Raw bytes (58): 0x[01, 01, 02, 07, 0d, 05, 09, 0a, 01, 37, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
+Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 0b, 05, 09, 0a, 01, 37, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 02, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 06, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 2
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
-- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+Number of expressions: 3
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
+- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 10
 - Code(Counter(0)) at (prev + 55, 1) to (start + 0, 13)
 - Code(Counter(0)) at (prev + 11, 11) to (start + 0, 12)
@@ -190,12 +194,13 @@ Number of file 0 mappings: 10
 - Code(Counter(0)) at (prev + 0, 14) to (start + 0, 27)
 - Code(Counter(1)) at (prev + 0, 31) to (start + 0, 39)
 - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 10)
-- Code(Counter(4)) at (prev + 0, 14) to (start + 0, 26)
+- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 26)
+    = (c0 - c1)
 - Code(Counter(2)) at (prev + 0, 30) to (start + 0, 32)
-- Code(Counter(3)) at (prev + 1, 14) to (start + 0, 16)
-- Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = ((c1 + c2) + c3)
-Highest counter ID seen: c4
+- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 16)
+    = (c0 - (c1 + c2))
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
+Highest counter ID seen: c2
 
 Function name: async::j::c
 Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 39, 05, 01, 12, 05, 02, 0d, 00, 0e, 02, 02, 0d, 00, 0e, 01, 02, 05, 00, 06]
diff --git a/tests/coverage/async_block.cov-map b/tests/coverage/async_block.cov-map
index 14ed4850d4a..5eb69e668ca 100644
--- a/tests/coverage/async_block.cov-map
+++ b/tests/coverage/async_block.cov-map
@@ -1,16 +1,18 @@
 Function name: async_block::main
-Raw bytes (36): 0x[01, 01, 01, 01, 05, 06, 01, 07, 01, 00, 0b, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 13, 05, 00, 14, 01, 16, 05, 07, 0a, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (36): 0x[01, 01, 01, 05, 01, 06, 01, 07, 01, 00, 0b, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 13, 02, 00, 14, 01, 16, 02, 07, 0a, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 7, 1) to (start + 0, 11)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
-- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 19)
-    = (c0 + c1)
-- Code(Counter(1)) at (prev + 0, 20) to (start + 1, 22)
-- Code(Counter(1)) at (prev + 7, 10) to (start + 2, 6)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
+    = (c1 - c0)
+- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19)
+- Code(Expression(0, Sub)) at (prev + 0, 20) to (start + 1, 22)
+    = (c1 - c0)
+- Code(Expression(0, Sub)) at (prev + 7, 10) to (start + 2, 6)
+    = (c1 - c0)
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map
index 04c05ba098b..9144a938a9e 100644
--- a/tests/coverage/async_closure.cov-map
+++ b/tests/coverage/async_closure.cov-map
@@ -8,14 +8,16 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: async_closure::call_once::<async_closure::main::{closure#0}>::{closure#0}
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 06, 2b, 01, 0e, 05, 02, 01, 00, 02]
+Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 06, 2b, 01, 0e, 02, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 0
+Number of expressions: 1
+- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 2
 - Code(Counter(0)) at (prev + 6, 43) to (start + 1, 14)
-- Code(Counter(1)) at (prev + 2, 1) to (start + 0, 2)
-Highest counter ID seen: c1
+- Code(Expression(0, Sub)) at (prev + 2, 1) to (start + 0, 2)
+    = (c1 - c2)
+Highest counter ID seen: c0
 
 Function name: async_closure::main
 Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 01, 16, 01, 02, 05, 02, 02]
diff --git a/tests/coverage/await_ready.cov-map b/tests/coverage/await_ready.cov-map
index bc1af4e42e8..61fd4c7814d 100644
--- a/tests/coverage/await_ready.cov-map
+++ b/tests/coverage/await_ready.cov-map
@@ -8,12 +8,14 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: await_ready::await_ready::{closure#0}
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 0e, 1e, 03, 0f, 05, 04, 01, 00, 02]
+Raw bytes (16): 0x[01, 01, 01, 05, 09, 02, 01, 0e, 1e, 03, 0f, 02, 04, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 0
+Number of expressions: 1
+- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 2
 - Code(Counter(0)) at (prev + 14, 30) to (start + 3, 15)
-- Code(Counter(1)) at (prev + 4, 1) to (start + 0, 2)
-Highest counter ID seen: c1
+- Code(Expression(0, Sub)) at (prev + 4, 1) to (start + 0, 2)
+    = (c1 - c2)
+Highest counter ID seen: c0
 
diff --git a/tests/coverage/branch/guard.cov-map b/tests/coverage/branch/guard.cov-map
index 7ca499bd847..55f45daa9c9 100644
--- a/tests/coverage/branch/guard.cov-map
+++ b/tests/coverage/branch/guard.cov-map
@@ -1,21 +1,22 @@
 Function name: guard::branch_match_guard
-Raw bytes (89): 0x[01, 01, 08, 05, 0d, 05, 17, 0d, 11, 1f, 17, 05, 09, 0d, 11, 1f, 15, 05, 09, 0d, 01, 0c, 01, 01, 10, 02, 03, 0b, 00, 0c, 15, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 06, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 0e, 03, 0e, 02, 0a, 1b, 04, 01, 00, 02]
+Raw bytes (89): 0x[01, 01, 08, 05, 0d, 09, 05, 05, 0f, 0d, 11, 17, 1b, 01, 05, 1f, 11, 09, 0d, 0d, 01, 0c, 01, 01, 10, 02, 03, 0b, 00, 0c, 06, 01, 14, 02, 0a, 0d, 03, 0e, 00, 0f, 05, 00, 14, 00, 19, 20, 0d, 02, 00, 14, 00, 1e, 0d, 00, 1d, 02, 0a, 11, 03, 0e, 00, 0f, 02, 00, 14, 00, 19, 20, 11, 0a, 00, 14, 00, 1e, 11, 00, 1d, 02, 0a, 12, 03, 0e, 02, 0a, 01, 04, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
 - expression 0 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
-- expression 2 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 3 operands: lhs = Expression(7, Add), rhs = Expression(5, Add)
-- expression 4 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 5 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(5)
-- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(2), rhs = Counter(1)
+- expression 2 operands: lhs = Counter(1), rhs = Expression(3, Add)
+- expression 3 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 4 operands: lhs = Expression(5, Add), rhs = Expression(6, Add)
+- expression 5 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4)
+- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 13
 - Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
 - Code(Expression(0, Sub)) at (prev + 3, 11) to (start + 0, 12)
     = (c1 - c3)
-- Code(Counter(5)) at (prev + 1, 20) to (start + 2, 10)
+- Code(Expression(1, Sub)) at (prev + 1, 20) to (start + 2, 10)
+    = (c2 - c1)
 - Code(Counter(3)) at (prev + 3, 14) to (start + 0, 15)
 - Code(Counter(1)) at (prev + 0, 20) to (start + 0, 25)
 - Branch { true: Counter(3), false: Expression(0, Sub) } at (prev + 0, 20) to (start + 0, 30)
@@ -25,13 +26,12 @@ Number of file 0 mappings: 13
 - Code(Counter(4)) at (prev + 3, 14) to (start + 0, 15)
 - Code(Expression(0, Sub)) at (prev + 0, 20) to (start + 0, 25)
     = (c1 - c3)
-- Branch { true: Counter(4), false: Expression(1, Sub) } at (prev + 0, 20) to (start + 0, 30)
+- Branch { true: Counter(4), false: Expression(2, Sub) } at (prev + 0, 20) to (start + 0, 30)
     true  = c4
     false = (c1 - (c3 + c4))
 - Code(Counter(4)) at (prev + 0, 29) to (start + 2, 10)
-- Code(Expression(3, Sub)) at (prev + 3, 14) to (start + 2, 10)
-    = ((c1 + c2) - (c3 + c4))
-- Code(Expression(6, Add)) at (prev + 4, 1) to (start + 0, 2)
-    = ((c1 + c2) + c5)
-Highest counter ID seen: c5
+- Code(Expression(4, Sub)) at (prev + 3, 14) to (start + 2, 10)
+    = ((c0 + c1) - ((c2 + c3) + c4))
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2)
+Highest counter ID seen: c4
 
diff --git a/tests/coverage/branch/if-let.cov-map b/tests/coverage/branch/if-let.cov-map
index 773c5392465..db45df2a5cd 100644
--- a/tests/coverage/branch/if-let.cov-map
+++ b/tests/coverage/branch/if-let.cov-map
@@ -1,22 +1,22 @@
 Function name: if_let::if_let
-Raw bytes (43): 0x[01, 01, 01, 05, 09, 07, 01, 0c, 01, 01, 10, 20, 02, 09, 03, 0c, 00, 13, 02, 00, 11, 00, 12, 05, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 09, 02, 0c, 02, 06, 05, 03, 05, 01, 02]
+Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 10, 20, 02, 05, 03, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 1b, 02, 00, 1c, 02, 06, 05, 02, 0c, 02, 06, 01, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
-- Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 3, 12) to (start + 0, 19)
-    true  = (c1 - c2)
-    false = c2
+- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 12) to (start + 0, 19)
+    true  = (c0 - c1)
+    false = c1
 - Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 0, 18)
-    = (c1 - c2)
-- Code(Counter(1)) at (prev + 0, 22) to (start + 0, 27)
+    = (c0 - c1)
+- Code(Counter(0)) 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(Counter(1)) at (prev + 3, 5) to (start + 1, 2)
-Highest counter ID seen: c2
+    = (c0 - c1)
+- Code(Counter(1)) at (prev + 2, 12) to (start + 2, 6)
+- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+Highest counter ID seen: c1
 
 Function name: if_let::if_let_chain
 Raw bytes (74): 0x[01, 01, 08, 01, 05, 01, 1f, 05, 09, 01, 1f, 05, 09, 01, 1f, 05, 09, 05, 09, 0a, 01, 17, 01, 00, 33, 20, 02, 05, 01, 0c, 00, 13, 02, 00, 11, 00, 12, 01, 00, 16, 00, 17, 20, 16, 09, 01, 10, 00, 17, 16, 00, 15, 00, 16, 02, 00, 1a, 00, 1b, 16, 01, 05, 03, 06, 1f, 03, 0c, 02, 06, 01, 03, 05, 01, 02]
diff --git a/tests/coverage/branch/if.cov-map b/tests/coverage/branch/if.cov-map
index 3d9a1d2e1ab..a6b865318c6 100644
--- a/tests/coverage/branch/if.cov-map
+++ b/tests/coverage/branch/if.cov-map
@@ -1,134 +1,134 @@
 Function name: if::branch_and
-Raw bytes (54): 0x[01, 01, 03, 05, 09, 09, 0d, 05, 0d, 08, 01, 2b, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 00, 0d, 00, 0e, 20, 0d, 06, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 05, 03, 01, 00, 02]
+Raw bytes (54): 0x[01, 01, 03, 01, 05, 05, 09, 01, 09, 08, 01, 2b, 01, 01, 10, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 09, 06, 00, 0d, 00, 0e, 09, 00, 0f, 02, 06, 0a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 2 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 8
 - Code(Counter(0)) at (prev + 43, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9)
-- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
+- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
+    true  = c1
+    false = (c0 - c1)
+- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14)
+- Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 13) to (start + 0, 14)
     true  = c2
     false = (c1 - c2)
-- Code(Counter(2)) at (prev + 0, 13) to (start + 0, 14)
-- Branch { true: Counter(3), false: Expression(1, Sub) } at (prev + 0, 13) to (start + 0, 14)
-    true  = c3
-    false = (c2 - c3)
-- Code(Counter(3)) at (prev + 0, 15) to (start + 2, 6)
+- Code(Counter(2)) at (prev + 0, 15) to (start + 2, 6)
 - Code(Expression(2, Sub)) at (prev + 2, 12) to (start + 2, 6)
-    = (c1 - c3)
-- Code(Counter(1)) at (prev + 3, 1) to (start + 0, 2)
-Highest counter ID seen: c3
+    = (c0 - c2)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c2
 
 Function name: if::branch_not
-Raw bytes (116): 0x[01, 01, 07, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 05, 15, 05, 15, 12, 01, 0c, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 01, 09, 00, 11, 02, 01, 05, 00, 06, 05, 01, 08, 00, 0a, 20, 0a, 0d, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 0d, 02, 05, 00, 06, 05, 01, 08, 00, 0b, 20, 11, 12, 00, 08, 00, 0b, 11, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 05, 01, 08, 00, 0c, 20, 1a, 15, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 15, 02, 05, 00, 06, 05, 01, 01, 00, 02]
+Raw bytes (116): 0x[01, 01, 07, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 01, 11, 01, 11, 12, 01, 0c, 01, 01, 10, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 05, 01, 09, 00, 11, 02, 01, 05, 00, 06, 01, 01, 08, 00, 0a, 20, 0a, 09, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 09, 02, 05, 00, 06, 01, 01, 08, 00, 0b, 20, 0d, 12, 00, 08, 00, 0b, 0d, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 01, 01, 08, 00, 0c, 20, 1a, 11, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 11, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 7
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 2 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(1), rhs = Counter(4)
-- expression 4 operands: lhs = Counter(1), rhs = Counter(4)
-- expression 5 operands: lhs = Counter(1), rhs = Counter(5)
-- expression 6 operands: lhs = Counter(1), rhs = Counter(5)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 5 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 6 operands: lhs = Counter(0), rhs = Counter(4)
 Number of file 0 mappings: 18
 - Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9)
-- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
-    true  = c2
-    false = (c1 - c2)
-- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
+    true  = c1
+    false = (c0 - c1)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 17)
 - Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
-    = (c1 - c2)
-- Code(Counter(1)) at (prev + 1, 8) to (start + 0, 10)
-- Branch { true: Expression(2, Sub), false: Counter(3) } at (prev + 0, 8) to (start + 0, 10)
-    true  = (c1 - c3)
-    false = c3
+    = (c0 - c1)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 10)
+- Branch { true: Expression(2, Sub), false: Counter(2) } at (prev + 0, 8) to (start + 0, 10)
+    true  = (c0 - c2)
+    false = c2
 - Code(Expression(2, Sub)) at (prev + 0, 11) to (start + 2, 6)
-    = (c1 - c3)
-- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 6)
-- Code(Counter(1)) at (prev + 1, 8) to (start + 0, 11)
-- Branch { true: Counter(4), false: Expression(4, Sub) } at (prev + 0, 8) to (start + 0, 11)
-    true  = c4
-    false = (c1 - c4)
-- Code(Counter(4)) at (prev + 0, 12) to (start + 2, 6)
+    = (c0 - c2)
+- Code(Counter(2)) at (prev + 2, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 11)
+- Branch { true: Counter(3), false: Expression(4, Sub) } at (prev + 0, 8) to (start + 0, 11)
+    true  = c3
+    false = (c0 - c3)
+- Code(Counter(3)) at (prev + 0, 12) to (start + 2, 6)
 - Code(Expression(4, Sub)) at (prev + 2, 5) to (start + 0, 6)
-    = (c1 - c4)
-- Code(Counter(1)) at (prev + 1, 8) to (start + 0, 12)
-- Branch { true: Expression(6, Sub), false: Counter(5) } at (prev + 0, 8) to (start + 0, 12)
-    true  = (c1 - c5)
-    false = c5
+    = (c0 - c3)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 12)
+- Branch { true: Expression(6, Sub), false: Counter(4) } at (prev + 0, 8) to (start + 0, 12)
+    true  = (c0 - c4)
+    false = c4
 - Code(Expression(6, Sub)) at (prev + 0, 13) to (start + 2, 6)
-    = (c1 - c5)
-- Code(Counter(5)) at (prev + 2, 5) to (start + 0, 6)
-- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
-Highest counter ID seen: c5
+    = (c0 - c4)
+- Code(Counter(4)) at (prev + 2, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
+Highest counter ID seen: c4
 
 Function name: if::branch_not_as
-Raw bytes (90): 0x[01, 01, 05, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 0e, 01, 1d, 01, 01, 10, 05, 03, 08, 00, 14, 20, 02, 09, 00, 08, 00, 14, 02, 00, 15, 02, 06, 09, 02, 05, 00, 06, 05, 01, 08, 00, 15, 20, 0d, 0a, 00, 08, 00, 15, 0d, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 05, 01, 08, 00, 16, 20, 12, 11, 00, 08, 00, 16, 12, 00, 17, 02, 06, 11, 02, 05, 00, 06, 05, 01, 01, 00, 02]
+Raw bytes (90): 0x[01, 01, 05, 01, 05, 01, 09, 01, 09, 01, 0d, 01, 0d, 0e, 01, 1d, 01, 01, 10, 01, 03, 08, 00, 14, 20, 02, 05, 00, 08, 00, 14, 02, 00, 15, 02, 06, 05, 02, 05, 00, 06, 01, 01, 08, 00, 15, 20, 09, 0a, 00, 08, 00, 15, 09, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 01, 01, 08, 00, 16, 20, 12, 0d, 00, 08, 00, 16, 12, 00, 17, 02, 06, 0d, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 2 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(1), rhs = Counter(4)
-- expression 4 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
 Number of file 0 mappings: 14
 - Code(Counter(0)) at (prev + 29, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 3, 8) to (start + 0, 20)
-- Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 0, 8) to (start + 0, 20)
-    true  = (c1 - c2)
-    false = c2
+- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 20)
+- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 0, 8) to (start + 0, 20)
+    true  = (c0 - c1)
+    false = c1
 - Code(Expression(0, Sub)) at (prev + 0, 21) to (start + 2, 6)
-    = (c1 - c2)
-- Code(Counter(2)) at (prev + 2, 5) to (start + 0, 6)
-- Code(Counter(1)) at (prev + 1, 8) to (start + 0, 21)
-- Branch { true: Counter(3), false: Expression(2, Sub) } at (prev + 0, 8) to (start + 0, 21)
-    true  = c3
-    false = (c1 - c3)
-- Code(Counter(3)) at (prev + 0, 22) to (start + 2, 6)
+    = (c0 - c1)
+- Code(Counter(1)) at (prev + 2, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 21)
+- Branch { true: Counter(2), false: Expression(2, Sub) } at (prev + 0, 8) to (start + 0, 21)
+    true  = c2
+    false = (c0 - c2)
+- Code(Counter(2)) at (prev + 0, 22) to (start + 2, 6)
 - Code(Expression(2, Sub)) at (prev + 2, 5) to (start + 0, 6)
-    = (c1 - c3)
-- Code(Counter(1)) at (prev + 1, 8) to (start + 0, 22)
-- Branch { true: Expression(4, Sub), false: Counter(4) } at (prev + 0, 8) to (start + 0, 22)
-    true  = (c1 - c4)
-    false = c4
+    = (c0 - c2)
+- Code(Counter(0)) at (prev + 1, 8) to (start + 0, 22)
+- Branch { true: Expression(4, Sub), false: Counter(3) } at (prev + 0, 8) to (start + 0, 22)
+    true  = (c0 - c3)
+    false = c3
 - Code(Expression(4, Sub)) at (prev + 0, 23) to (start + 2, 6)
-    = (c1 - c4)
-- Code(Counter(4)) at (prev + 2, 5) to (start + 0, 6)
-- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
-Highest counter ID seen: c4
+    = (c0 - c3)
+- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 6)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
+Highest counter ID seen: c3
 
 Function name: if::branch_or
-Raw bytes (60): 0x[01, 01, 06, 05, 09, 05, 17, 09, 0d, 09, 0d, 05, 17, 09, 0d, 08, 01, 35, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 0d, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 05, 03, 01, 00, 02]
+Raw bytes (60): 0x[01, 01, 06, 01, 05, 01, 17, 05, 09, 05, 09, 01, 17, 05, 09, 08, 01, 35, 01, 01, 10, 01, 03, 08, 00, 09, 20, 05, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 20, 09, 12, 00, 0d, 00, 0e, 17, 00, 0f, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 6
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
-- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 4 operands: lhs = Counter(1), rhs = Expression(5, Add)
-- expression 5 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(0), rhs = Expression(5, Add)
+- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 4 operands: lhs = Counter(0), rhs = Expression(5, Add)
+- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 8
 - Code(Counter(0)) at (prev + 53, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 3, 8) to (start + 0, 9)
-- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
-    true  = c2
-    false = (c1 - c2)
+- Code(Counter(0)) at (prev + 3, 8) to (start + 0, 9)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 8) to (start + 0, 9)
+    true  = c1
+    false = (c0 - c1)
 - Code(Expression(0, Sub)) at (prev + 0, 13) to (start + 0, 14)
-    = (c1 - c2)
-- Branch { true: Counter(3), false: Expression(4, Sub) } at (prev + 0, 13) to (start + 0, 14)
-    true  = c3
-    false = (c1 - (c2 + c3))
+    = (c0 - c1)
+- Branch { true: Counter(2), false: Expression(4, Sub) } at (prev + 0, 13) to (start + 0, 14)
+    true  = c2
+    false = (c0 - (c1 + c2))
 - Code(Expression(5, Add)) at (prev + 0, 15) to (start + 2, 6)
-    = (c2 + c3)
+    = (c1 + c2)
 - Code(Expression(4, Sub)) at (prev + 2, 12) to (start + 2, 6)
-    = (c1 - (c2 + c3))
-- Code(Counter(1)) at (prev + 3, 1) to (start + 0, 2)
-Highest counter ID seen: c3
+    = (c0 - (c1 + c2))
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c2
 
diff --git a/tests/coverage/branch/lazy-boolean.cov-map b/tests/coverage/branch/lazy-boolean.cov-map
index 94522734bcd..622f30e2b56 100644
--- a/tests/coverage/branch/lazy-boolean.cov-map
+++ b/tests/coverage/branch/lazy-boolean.cov-map
@@ -1,148 +1,148 @@
 Function name: lazy_boolean::branch_and
-Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 13, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0d, 00, 0e, 20, 09, 02, 00, 0d, 00, 0e, 09, 00, 12, 00, 13, 05, 01, 05, 01, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 13, 01, 01, 10, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 19, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 4, 9) to (start + 0, 10)
-- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14)
-- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
-    true  = c2
-    false = (c1 - c2)
-- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 19)
-- Code(Counter(1)) at (prev + 1, 5) to (start + 1, 2)
-Highest counter ID seen: c2
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
+    true  = c1
+    false = (c0 - c1)
+- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+Highest counter ID seen: c1
 
 Function name: lazy_boolean::branch_or
-Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 1b, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0d, 00, 0e, 20, 09, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 05, 01, 05, 01, 02]
+Raw bytes (38): 0x[01, 01, 01, 01, 05, 06, 01, 1b, 01, 01, 10, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 0e, 20, 05, 02, 00, 0d, 00, 0e, 02, 00, 12, 00, 13, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 27, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 4, 9) to (start + 0, 10)
-- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 14)
-- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
-    true  = c2
-    false = (c1 - c2)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 14)
+    true  = c1
+    false = (c0 - c1)
 - Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19)
-    = (c1 - c2)
-- Code(Counter(1)) at (prev + 1, 5) to (start + 1, 2)
-Highest counter ID seen: c2
+    = (c0 - c1)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+Highest counter ID seen: c1
 
 Function name: lazy_boolean::chain
-Raw bytes (141): 0x[01, 01, 0f, 05, 09, 09, 0d, 0d, 11, 05, 15, 05, 15, 05, 3b, 15, 19, 05, 3b, 15, 19, 05, 37, 3b, 1d, 15, 19, 05, 37, 3b, 1d, 15, 19, 13, 01, 24, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0d, 00, 12, 20, 09, 02, 00, 0d, 00, 12, 09, 00, 16, 00, 1b, 20, 0d, 06, 00, 16, 00, 1b, 0d, 00, 1f, 00, 24, 20, 11, 0a, 00, 1f, 00, 24, 11, 00, 28, 00, 2d, 05, 01, 05, 00, 11, 05, 03, 09, 00, 0a, 05, 00, 0d, 00, 12, 20, 15, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 19, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 1d, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 05, 01, 05, 01, 02]
+Raw bytes (141): 0x[01, 01, 0f, 01, 05, 05, 09, 09, 0d, 01, 11, 01, 11, 01, 3b, 11, 15, 01, 3b, 11, 15, 01, 37, 3b, 19, 11, 15, 01, 37, 3b, 19, 11, 15, 13, 01, 24, 01, 01, 10, 01, 04, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 05, 02, 00, 0d, 00, 12, 05, 00, 16, 00, 1b, 20, 09, 06, 00, 16, 00, 1b, 09, 00, 1f, 00, 24, 20, 0d, 0a, 00, 1f, 00, 24, 0d, 00, 28, 00, 2d, 01, 01, 05, 00, 11, 01, 03, 09, 00, 0a, 01, 00, 0d, 00, 12, 20, 11, 12, 00, 0d, 00, 12, 12, 00, 16, 00, 1b, 20, 15, 1e, 00, 16, 00, 1b, 1e, 00, 1f, 00, 24, 20, 19, 32, 00, 1f, 00, 24, 32, 00, 28, 00, 2d, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 15
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 2 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 3 operands: lhs = Counter(1), rhs = Counter(5)
-- expression 4 operands: lhs = Counter(1), rhs = Counter(5)
-- expression 5 operands: lhs = Counter(1), rhs = Expression(14, Add)
-- expression 6 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 7 operands: lhs = Counter(1), rhs = Expression(14, Add)
-- expression 8 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 9 operands: lhs = Counter(1), rhs = Expression(13, Add)
-- expression 10 operands: lhs = Expression(14, Add), rhs = Counter(7)
-- expression 11 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add)
-- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(7)
-- expression 14 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 5 operands: lhs = Counter(0), rhs = Expression(14, Add)
+- expression 6 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 7 operands: lhs = Counter(0), rhs = Expression(14, Add)
+- expression 8 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 9 operands: lhs = Counter(0), rhs = Expression(13, Add)
+- expression 10 operands: lhs = Expression(14, Add), rhs = Counter(6)
+- expression 11 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 12 operands: lhs = Counter(0), rhs = Expression(13, Add)
+- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(6)
+- expression 14 operands: lhs = Counter(4), rhs = Counter(5)
 Number of file 0 mappings: 19
 - Code(Counter(0)) at (prev + 36, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 4, 9) to (start + 0, 10)
-- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 18)
-- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 18)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 13) to (start + 0, 18)
+    true  = c1
+    false = (c0 - c1)
+- Code(Counter(1)) at (prev + 0, 22) to (start + 0, 27)
+- Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 22) to (start + 0, 27)
     true  = c2
     false = (c1 - c2)
-- Code(Counter(2)) at (prev + 0, 22) to (start + 0, 27)
-- Branch { true: Counter(3), false: Expression(1, Sub) } at (prev + 0, 22) to (start + 0, 27)
+- Code(Counter(2)) at (prev + 0, 31) to (start + 0, 36)
+- Branch { true: Counter(3), false: Expression(2, Sub) } at (prev + 0, 31) to (start + 0, 36)
     true  = c3
     false = (c2 - c3)
-- Code(Counter(3)) at (prev + 0, 31) to (start + 0, 36)
-- Branch { true: Counter(4), false: Expression(2, Sub) } at (prev + 0, 31) to (start + 0, 36)
+- Code(Counter(3)) at (prev + 0, 40) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 18)
+- Branch { true: Counter(4), false: Expression(4, Sub) } at (prev + 0, 13) to (start + 0, 18)
     true  = c4
-    false = (c3 - c4)
-- Code(Counter(4)) at (prev + 0, 40) to (start + 0, 45)
-- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 17)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 0, 10)
-- Code(Counter(1)) at (prev + 0, 13) to (start + 0, 18)
-- Branch { true: Counter(5), false: Expression(4, Sub) } at (prev + 0, 13) to (start + 0, 18)
-    true  = c5
-    false = (c1 - c5)
+    false = (c0 - c4)
 - Code(Expression(4, Sub)) at (prev + 0, 22) to (start + 0, 27)
-    = (c1 - c5)
-- Branch { true: Counter(6), false: Expression(7, Sub) } at (prev + 0, 22) to (start + 0, 27)
-    true  = c6
-    false = (c1 - (c5 + c6))
+    = (c0 - c4)
+- Branch { true: Counter(5), false: Expression(7, Sub) } at (prev + 0, 22) to (start + 0, 27)
+    true  = c5
+    false = (c0 - (c4 + c5))
 - Code(Expression(7, Sub)) at (prev + 0, 31) to (start + 0, 36)
-    = (c1 - (c5 + c6))
-- Branch { true: Counter(7), false: Expression(12, Sub) } at (prev + 0, 31) to (start + 0, 36)
-    true  = c7
-    false = (c1 - ((c5 + c6) + c7))
+    = (c0 - (c4 + c5))
+- Branch { true: Counter(6), false: Expression(12, Sub) } at (prev + 0, 31) to (start + 0, 36)
+    true  = c6
+    false = (c0 - ((c4 + c5) + c6))
 - Code(Expression(12, Sub)) at (prev + 0, 40) to (start + 0, 45)
-    = (c1 - ((c5 + c6) + c7))
-- Code(Counter(1)) at (prev + 1, 5) to (start + 1, 2)
-Highest counter ID seen: c7
+    = (c0 - ((c4 + c5) + c6))
+- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+Highest counter ID seen: c6
 
 Function name: lazy_boolean::nested_mixed
-Raw bytes (137): 0x[01, 01, 0d, 05, 09, 05, 1f, 09, 0d, 09, 0d, 1f, 11, 09, 0d, 1f, 11, 09, 0d, 05, 15, 15, 19, 05, 19, 05, 33, 19, 1d, 13, 01, 31, 01, 01, 10, 05, 04, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 09, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 0d, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 11, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 05, 01, 05, 00, 11, 05, 03, 09, 00, 0a, 05, 00, 0e, 00, 13, 20, 15, 22, 00, 0e, 00, 13, 15, 00, 17, 00, 1c, 20, 19, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 1d, 2e, 00, 22, 00, 28, 1d, 00, 2c, 00, 33, 05, 01, 05, 01, 02]
+Raw bytes (137): 0x[01, 01, 0d, 01, 05, 01, 1f, 05, 09, 05, 09, 1f, 0d, 05, 09, 1f, 0d, 05, 09, 01, 11, 11, 15, 01, 15, 01, 33, 15, 19, 13, 01, 31, 01, 01, 10, 01, 04, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 05, 02, 00, 0e, 00, 13, 02, 00, 17, 00, 1d, 20, 09, 06, 00, 17, 00, 1d, 1f, 00, 23, 00, 28, 20, 0d, 1a, 00, 23, 00, 28, 1a, 00, 2c, 00, 33, 01, 01, 05, 00, 11, 01, 03, 09, 00, 0a, 01, 00, 0e, 00, 13, 20, 11, 22, 00, 0e, 00, 13, 11, 00, 17, 00, 1c, 20, 15, 26, 00, 17, 00, 1c, 2a, 00, 22, 00, 28, 20, 19, 2e, 00, 22, 00, 28, 19, 00, 2c, 00, 33, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 13
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(1), rhs = Expression(7, Add)
-- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 4 operands: lhs = Expression(7, Add), rhs = Counter(4)
-- expression 5 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4)
-- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 8 operands: lhs = Counter(1), rhs = Counter(5)
-- expression 9 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 10 operands: lhs = Counter(1), rhs = Counter(6)
-- expression 11 operands: lhs = Counter(1), rhs = Expression(12, Add)
-- expression 12 operands: lhs = Counter(6), rhs = Counter(7)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(0), rhs = Expression(7, Add)
+- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 4 operands: lhs = Expression(7, Add), rhs = Counter(3)
+- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3)
+- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 8 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 9 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 10 operands: lhs = Counter(0), rhs = Counter(5)
+- expression 11 operands: lhs = Counter(0), rhs = Expression(12, Add)
+- expression 12 operands: lhs = Counter(5), rhs = Counter(6)
 Number of file 0 mappings: 19
 - Code(Counter(0)) at (prev + 49, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 4, 9) to (start + 0, 10)
-- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19)
-- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 14) to (start + 0, 19)
-    true  = c2
-    false = (c1 - c2)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 14) to (start + 0, 19)
+    true  = c1
+    false = (c0 - c1)
 - Code(Expression(0, Sub)) at (prev + 0, 23) to (start + 0, 29)
-    = (c1 - c2)
-- Branch { true: Counter(3), false: Expression(1, Sub) } at (prev + 0, 23) to (start + 0, 29)
-    true  = c3
-    false = (c1 - (c2 + c3))
+    = (c0 - c1)
+- Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 23) to (start + 0, 29)
+    true  = c2
+    false = (c0 - (c1 + c2))
 - Code(Expression(7, Add)) at (prev + 0, 35) to (start + 0, 40)
-    = (c2 + c3)
-- Branch { true: Counter(4), false: Expression(6, Sub) } at (prev + 0, 35) to (start + 0, 40)
-    true  = c4
-    false = ((c2 + c3) - c4)
+    = (c1 + c2)
+- Branch { true: Counter(3), false: Expression(6, Sub) } at (prev + 0, 35) to (start + 0, 40)
+    true  = c3
+    false = ((c1 + c2) - c3)
 - Code(Expression(6, Sub)) at (prev + 0, 44) to (start + 0, 51)
-    = ((c2 + c3) - c4)
-- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 17)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 0, 10)
-- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 19)
-- Branch { true: Counter(5), false: Expression(8, Sub) } at (prev + 0, 14) to (start + 0, 19)
+    = ((c1 + c2) - c3)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 17)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19)
+- Branch { true: Counter(4), false: Expression(8, Sub) } at (prev + 0, 14) to (start + 0, 19)
+    true  = c4
+    false = (c0 - c4)
+- Code(Counter(4)) at (prev + 0, 23) to (start + 0, 28)
+- Branch { true: Counter(5), false: Expression(9, Sub) } at (prev + 0, 23) to (start + 0, 28)
     true  = c5
-    false = (c1 - c5)
-- Code(Counter(5)) at (prev + 0, 23) to (start + 0, 28)
-- Branch { true: Counter(6), false: Expression(9, Sub) } at (prev + 0, 23) to (start + 0, 28)
-    true  = c6
-    false = (c5 - c6)
+    false = (c4 - c5)
 - Code(Expression(10, Sub)) at (prev + 0, 34) to (start + 0, 40)
-    = (c1 - c6)
-- Branch { true: Counter(7), false: Expression(11, Sub) } at (prev + 0, 34) to (start + 0, 40)
-    true  = c7
-    false = (c1 - (c6 + c7))
-- Code(Counter(7)) at (prev + 0, 44) to (start + 0, 51)
-- Code(Counter(1)) at (prev + 1, 5) to (start + 1, 2)
-Highest counter ID seen: c7
+    = (c0 - c5)
+- Branch { true: Counter(6), false: Expression(11, Sub) } at (prev + 0, 34) to (start + 0, 40)
+    true  = c6
+    false = (c0 - (c5 + c6))
+- Code(Counter(6)) at (prev + 0, 44) to (start + 0, 51)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
+Highest counter ID seen: c6
 
diff --git a/tests/coverage/branch/let-else.cov-map b/tests/coverage/branch/let-else.cov-map
index e6bf7ed6a92..215d71599e4 100644
--- a/tests/coverage/branch/let-else.cov-map
+++ b/tests/coverage/branch/let-else.cov-map
@@ -1,20 +1,20 @@
 Function name: let_else::let_else
-Raw bytes (43): 0x[01, 01, 01, 05, 09, 07, 01, 0c, 01, 01, 10, 20, 02, 09, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 05, 00, 13, 00, 18, 09, 01, 09, 01, 0f, 02, 04, 05, 00, 0b, 05, 01, 01, 00, 02]
+Raw bytes (43): 0x[01, 01, 01, 01, 05, 07, 01, 0c, 01, 01, 10, 20, 02, 05, 03, 09, 00, 10, 02, 00, 0e, 00, 0f, 01, 00, 13, 00, 18, 05, 01, 09, 01, 0f, 02, 04, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
-- Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 3, 9) to (start + 0, 16)
-    true  = (c1 - c2)
-    false = c2
+- Branch { true: Expression(0, Sub), false: Counter(1) } at (prev + 3, 9) to (start + 0, 16)
+    true  = (c0 - c1)
+    false = c1
 - Code(Expression(0, Sub)) at (prev + 0, 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)
+    = (c0 - c1)
+- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 24)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 1, 15)
 - Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 11)
-    = (c1 - c2)
-- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
-Highest counter ID seen: c2
+    = (c0 - c1)
+- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
+Highest counter ID seen: c1
 
diff --git a/tests/coverage/branch/match-arms.cov-map b/tests/coverage/branch/match-arms.cov-map
index 53d0a4edbd0..d5b4d04d401 100644
--- a/tests/coverage/branch/match-arms.cov-map
+++ b/tests/coverage/branch/match-arms.cov-map
@@ -1,86 +1,80 @@
 Function name: match_arms::guards
-Raw bytes (98): 0x[01, 01, 0d, 11, 19, 27, 19, 2b, 00, 2f, 11, 33, 0d, 05, 09, 1f, 25, 23, 21, 27, 1d, 2b, 00, 2f, 11, 33, 0d, 05, 09, 0c, 01, 30, 01, 01, 10, 11, 03, 0b, 00, 10, 1d, 01, 11, 00, 29, 20, 1d, 05, 00, 17, 00, 1b, 21, 01, 11, 00, 29, 20, 21, 09, 00, 17, 00, 1b, 25, 01, 11, 00, 29, 20, 25, 0d, 00, 17, 00, 1b, 19, 01, 11, 00, 29, 20, 19, 02, 00, 17, 00, 1b, 06, 01, 0e, 00, 18, 1b, 03, 05, 01, 02]
+Raw bytes (88): 0x[01, 01, 08, 15, 05, 19, 09, 1d, 0d, 21, 11, 01, 17, 1b, 11, 1f, 0d, 05, 09, 0c, 01, 30, 01, 01, 10, 21, 03, 0b, 00, 10, 05, 01, 11, 00, 29, 20, 05, 02, 00, 17, 00, 1b, 09, 01, 11, 00, 29, 20, 09, 06, 00, 17, 00, 1b, 0d, 01, 11, 00, 29, 20, 0d, 0a, 00, 17, 00, 1b, 11, 01, 11, 00, 29, 20, 11, 0e, 00, 17, 00, 1b, 12, 01, 0e, 00, 18, 01, 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(6)
-- expression 1 operands: lhs = Expression(9, Add), rhs = Counter(6)
-- expression 2 operands: lhs = Expression(10, Add), rhs = Zero
-- expression 3 operands: lhs = Expression(11, Add), rhs = Counter(4)
-- expression 4 operands: lhs = Expression(12, Add), rhs = Counter(3)
-- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(9)
-- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(8)
-- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(7)
-- expression 9 operands: lhs = Expression(10, Add), rhs = Zero
-- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(4)
-- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(3)
-- expression 12 operands: lhs = Counter(1), rhs = Counter(2)
+Number of expressions: 8
+- expression 0 operands: lhs = Counter(5), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(6), rhs = Counter(2)
+- expression 2 operands: lhs = Counter(7), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(8), rhs = Counter(4)
+- expression 4 operands: lhs = Counter(0), rhs = Expression(5, Add)
+- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(4)
+- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3)
+- expression 7 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 12
 - Code(Counter(0)) at (prev + 48, 1) to (start + 1, 16)
-- Code(Counter(4)) at (prev + 3, 11) to (start + 0, 16)
-- Code(Counter(7)) at (prev + 1, 17) to (start + 0, 41)
-- Branch { true: Counter(7), false: Counter(1) } at (prev + 0, 23) to (start + 0, 27)
-    true  = c7
-    false = c1
-- Code(Counter(8)) at (prev + 1, 17) to (start + 0, 41)
-- Branch { true: Counter(8), false: Counter(2) } at (prev + 0, 23) to (start + 0, 27)
-    true  = c8
-    false = c2
-- Code(Counter(9)) at (prev + 1, 17) to (start + 0, 41)
-- Branch { true: Counter(9), false: Counter(3) } at (prev + 0, 23) to (start + 0, 27)
-    true  = c9
-    false = c3
-- Code(Counter(6)) at (prev + 1, 17) to (start + 0, 41)
-- Branch { true: Counter(6), false: Expression(0, Sub) } at (prev + 0, 23) to (start + 0, 27)
-    true  = c6
-    false = (c4 - c6)
-- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 24)
-    = (((((c1 + c2) + c3) + c4) + Zero) - c6)
-- Code(Expression(6, Add)) at (prev + 3, 5) to (start + 1, 2)
-    = (((((((c1 + c2) + c3) + c4) + Zero) + c7) + c8) + c9)
-Highest counter ID seen: c9
+- Code(Counter(8)) at (prev + 3, 11) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 41)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 0, 23) to (start + 0, 27)
+    true  = c1
+    false = (c5 - c1)
+- Code(Counter(2)) at (prev + 1, 17) to (start + 0, 41)
+- Branch { true: Counter(2), false: Expression(1, Sub) } at (prev + 0, 23) to (start + 0, 27)
+    true  = c2
+    false = (c6 - c2)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 41)
+- Branch { true: Counter(3), false: Expression(2, Sub) } at (prev + 0, 23) to (start + 0, 27)
+    true  = c3
+    false = (c7 - c3)
+- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 41)
+- Branch { true: Counter(4), false: Expression(3, Sub) } at (prev + 0, 23) to (start + 0, 27)
+    true  = c4
+    false = (c8 - c4)
+- Code(Expression(4, Sub)) at (prev + 1, 14) to (start + 0, 24)
+    = (c0 - (((c1 + c2) + c3) + c4))
+- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+Highest counter ID seen: c8
 
 Function name: match_arms::match_arms
-Raw bytes (45): 0x[01, 01, 03, 05, 07, 0b, 11, 09, 0d, 07, 01, 18, 01, 01, 10, 05, 03, 0b, 00, 10, 09, 01, 11, 00, 21, 0d, 01, 11, 00, 21, 11, 01, 11, 00, 21, 02, 01, 11, 00, 21, 05, 03, 05, 01, 02]
+Raw bytes (45): 0x[01, 01, 03, 01, 07, 0b, 0d, 05, 09, 07, 01, 18, 01, 01, 10, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 21, 09, 01, 11, 00, 21, 0d, 01, 11, 00, 21, 02, 01, 11, 00, 21, 01, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
-- 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 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
+- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(3)
+- expression 2 operands: lhs = Counter(1), rhs = Counter(2)
 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(0)) at (prev + 3, 11) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 33)
 - Code(Counter(2)) at (prev + 1, 17) to (start + 0, 33)
 - Code(Counter(3)) at (prev + 1, 17) to (start + 0, 33)
-- Code(Counter(4)) 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(Counter(1)) at (prev + 3, 5) to (start + 1, 2)
-Highest counter ID seen: c4
+    = (c0 - ((c1 + c2) + c3))
+- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+Highest counter ID seen: c3
 
 Function name: match_arms::or_patterns
-Raw bytes (57): 0x[01, 01, 04, 09, 0d, 05, 0b, 03, 11, 05, 03, 09, 01, 25, 01, 01, 10, 05, 03, 0b, 00, 10, 09, 01, 11, 00, 12, 0d, 00, 1e, 00, 1f, 03, 00, 24, 00, 2e, 11, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2e, 05, 03, 05, 01, 02]
+Raw bytes (57): 0x[01, 01, 04, 05, 09, 01, 0b, 03, 0d, 01, 03, 09, 01, 25, 01, 01, 10, 01, 03, 0b, 00, 10, 05, 01, 11, 00, 12, 09, 00, 1e, 00, 1f, 03, 00, 24, 00, 2e, 0d, 01, 11, 00, 12, 06, 00, 1e, 00, 1f, 0e, 00, 24, 00, 2e, 01, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
-- expression 0 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(4)
-- expression 3 operands: lhs = Counter(1), rhs = Expression(0, Add)
+- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
+- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(0), rhs = Expression(0, Add)
 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(2)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Counter(3)) at (prev + 0, 30) to (start + 0, 31)
+- Code(Counter(0)) at (prev + 3, 11) to (start + 0, 16)
+- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Counter(2)) at (prev + 0, 30) to (start + 0, 31)
 - Code(Expression(0, Add)) at (prev + 0, 36) to (start + 0, 46)
-    = (c2 + c3)
-- Code(Counter(4)) at (prev + 1, 17) to (start + 0, 18)
+    = (c1 + c2)
+- Code(Counter(3)) at (prev + 1, 17) to (start + 0, 18)
 - Code(Expression(1, Sub)) at (prev + 0, 30) to (start + 0, 31)
-    = (c1 - ((c2 + c3) + c4))
+    = (c0 - ((c1 + c2) + c3))
 - Code(Expression(3, Sub)) at (prev + 0, 36) to (start + 0, 46)
-    = (c1 - (c2 + c3))
-- Code(Counter(1)) at (prev + 3, 5) to (start + 1, 2)
-Highest counter ID seen: c4
+    = (c0 - (c1 + c2))
+- Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
+Highest counter ID seen: c3
 
diff --git a/tests/coverage/branch/match-trivial.cov-map b/tests/coverage/branch/match-trivial.cov-map
index 6af8ce46f5f..31322f127af 100644
--- a/tests/coverage/branch/match-trivial.cov-map
+++ b/tests/coverage/branch/match-trivial.cov-map
@@ -8,12 +8,12 @@ Number of file 0 mappings: 1
 Highest counter ID seen: (none)
 
 Function name: match_trivial::trivial
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 10, 05, 03, 0b, 05, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 1e, 01, 01, 10, 01, 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)
-Highest counter ID seen: c1
+- Code(Counter(0)) at (prev + 3, 11) to (start + 5, 2)
+Highest counter ID seen: c0
 
diff --git a/tests/coverage/branch/no-mir-spans.cov-map b/tests/coverage/branch/no-mir-spans.cov-map
index 6003efc36ca..8fb44ef30fd 100644
--- a/tests/coverage/branch/no-mir-spans.cov-map
+++ b/tests/coverage/branch/no-mir-spans.cov-map
@@ -1,56 +1,63 @@
 Function name: no_mir_spans::while_cond
-Raw bytes (16): 0x[01, 01, 00, 02, 01, 10, 01, 00, 11, 20, 05, 09, 04, 0b, 00, 10]
+Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 10, 01, 00, 11, 20, 02, 01, 04, 0b, 00, 10]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 0
+Number of expressions: 1
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 2
 - Code(Counter(0)) at (prev + 16, 1) to (start + 0, 17)
-- Branch { true: Counter(1), false: Counter(2) } at (prev + 4, 11) to (start + 0, 16)
-    true  = c1
-    false = c2
-Highest counter ID seen: c2
+- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 16)
+    true  = (c1 - c0)
+    false = c0
+Highest counter ID seen: c0
 
 Function name: no_mir_spans::while_cond_not
-Raw bytes (16): 0x[01, 01, 00, 02, 01, 19, 01, 00, 15, 20, 09, 05, 04, 0b, 00, 14]
+Raw bytes (18): 0x[01, 01, 01, 05, 01, 02, 01, 19, 01, 00, 15, 20, 02, 01, 04, 0b, 00, 14]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 0
+Number of expressions: 1
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 2
 - Code(Counter(0)) at (prev + 25, 1) to (start + 0, 21)
-- Branch { true: Counter(2), false: Counter(1) } at (prev + 4, 11) to (start + 0, 20)
-    true  = c2
-    false = c1
-Highest counter ID seen: c2
+- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 4, 11) to (start + 0, 20)
+    true  = (c1 - c0)
+    false = c0
+Highest counter ID seen: c0
 
 Function name: no_mir_spans::while_op_and
-Raw bytes (25): 0x[01, 01, 01, 05, 09, 03, 01, 22, 01, 00, 13, 20, 05, 0d, 05, 0b, 00, 10, 20, 02, 09, 00, 14, 00, 19]
+Raw bytes (31): 0x[01, 01, 04, 09, 05, 09, 01, 0f, 09, 01, 05, 03, 01, 22, 01, 00, 13, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 0a, 00, 14, 00, 19]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+Number of expressions: 4
+- expression 0 operands: lhs = Counter(2), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(2), rhs = Counter(0)
+- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 34, 1) to (start + 0, 19)
-- Branch { true: Counter(1), false: Counter(3) } at (prev + 5, 11) to (start + 0, 16)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16)
     true  = c1
-    false = c3
-- Branch { true: Expression(0, Sub), false: Counter(2) } at (prev + 0, 20) to (start + 0, 25)
-    true  = (c1 - c2)
-    false = c2
-Highest counter ID seen: c3
+    false = (c2 - c1)
+- Branch { true: Expression(1, Sub), false: Expression(2, Sub) } at (prev + 0, 20) to (start + 0, 25)
+    true  = (c2 - c0)
+    false = ((c0 + c1) - c2)
+Highest counter ID seen: c1
 
 Function name: no_mir_spans::while_op_or
-Raw bytes (25): 0x[01, 01, 01, 09, 0d, 03, 01, 2d, 01, 00, 12, 20, 05, 09, 05, 0b, 00, 10, 20, 0d, 02, 00, 14, 00, 19]
+Raw bytes (29): 0x[01, 01, 03, 09, 05, 09, 0b, 01, 05, 03, 01, 2d, 01, 00, 12, 20, 05, 02, 05, 0b, 00, 10, 20, 06, 01, 00, 14, 00, 19]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(2), rhs = Counter(3)
+Number of expressions: 3
+- expression 0 operands: lhs = Counter(2), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(2), rhs = Expression(2, Add)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 45, 1) to (start + 0, 18)
-- Branch { true: Counter(1), false: Counter(2) } at (prev + 5, 11) to (start + 0, 16)
+- Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 5, 11) to (start + 0, 16)
     true  = c1
-    false = c2
-- Branch { true: Counter(3), false: Expression(0, Sub) } at (prev + 0, 20) to (start + 0, 25)
-    true  = c3
-    false = (c2 - c3)
-Highest counter ID seen: c3
+    false = (c2 - c1)
+- Branch { true: Expression(1, Sub), false: Counter(0) } at (prev + 0, 20) to (start + 0, 25)
+    true  = (c2 - (c0 + c1))
+    false = c0
+Highest counter ID seen: c1
 
diff --git a/tests/coverage/branch/while.cov-map b/tests/coverage/branch/while.cov-map
index 5eb08a42803..5ce92c72b51 100644
--- a/tests/coverage/branch/while.cov-map
+++ b/tests/coverage/branch/while.cov-map
@@ -1,90 +1,88 @@
 Function name: while::while_cond
-Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 0c, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 10, 20, 09, 05, 00, 0b, 00, 10, 09, 00, 11, 02, 06, 05, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 0c, 01, 01, 10, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 10, 20, 02, 01, 00, 0b, 00, 10, 02, 00, 11, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 12, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 0, 18)
-- Code(Expression(0, Add)) at (prev + 1, 11) to (start + 0, 16)
-    = (c1 + c2)
-- Branch { true: Counter(2), false: Counter(1) } at (prev + 0, 11) to (start + 0, 16)
-    true  = c2
-    false = c1
-- Code(Counter(2)) at (prev + 0, 17) to (start + 2, 6)
-- Code(Counter(1)) at (prev + 3, 1) to (start + 0, 2)
-Highest counter ID seen: c2
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 16)
+- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 16)
+    true  = (c1 - c0)
+    false = c0
+- Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 2, 6)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c1
 
 Function name: while::while_cond_not
-Raw bytes (38): 0x[01, 01, 01, 05, 09, 06, 01, 15, 01, 01, 10, 05, 03, 09, 00, 12, 03, 01, 0b, 00, 14, 20, 09, 05, 00, 0b, 00, 14, 09, 00, 15, 02, 06, 05, 03, 01, 00, 02]
+Raw bytes (38): 0x[01, 01, 01, 05, 01, 06, 01, 15, 01, 01, 10, 01, 03, 09, 00, 12, 05, 01, 0b, 00, 14, 20, 02, 01, 00, 0b, 00, 14, 02, 00, 15, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 21, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 0, 18)
-- Code(Expression(0, Add)) at (prev + 1, 11) to (start + 0, 20)
-    = (c1 + c2)
-- Branch { true: Counter(2), false: Counter(1) } at (prev + 0, 11) to (start + 0, 20)
-    true  = c2
-    false = c1
-- Code(Counter(2)) at (prev + 0, 21) to (start + 2, 6)
-- Code(Counter(1)) at (prev + 3, 1) to (start + 0, 2)
-Highest counter ID seen: c2
+- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 18)
+- Code(Counter(1)) at (prev + 1, 11) to (start + 0, 20)
+- Branch { true: Expression(0, Sub), false: Counter(0) } at (prev + 0, 11) to (start + 0, 20)
+    true  = (c1 - c0)
+    false = c0
+- Code(Expression(0, Sub)) at (prev + 0, 21) to (start + 2, 6)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c1
 
 Function name: while::while_op_and
-Raw bytes (56): 0x[01, 01, 04, 05, 09, 03, 0d, 03, 0d, 05, 0d, 08, 01, 1e, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 0a, 0d, 00, 0b, 00, 10, 0a, 00, 14, 00, 19, 20, 09, 0e, 00, 14, 00, 19, 09, 00, 1a, 03, 06, 05, 04, 01, 00, 02]
+Raw bytes (58): 0x[01, 01, 05, 05, 09, 05, 01, 0f, 05, 01, 09, 05, 01, 08, 01, 1e, 01, 01, 10, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 09, 00, 14, 00, 19, 20, 12, 0a, 00, 14, 00, 19, 12, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 4
+Number of expressions: 5
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(1)
+- expression 3 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 4 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 8
 - Code(Counter(0)) at (prev + 30, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 18)
-- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 16)
-    = (c1 + c2)
-- Branch { true: Expression(2, Sub), false: Counter(3) } at (prev + 0, 11) to (start + 0, 16)
-    true  = ((c1 + c2) - c3)
-    false = c3
-- Code(Expression(2, Sub)) at (prev + 0, 20) to (start + 0, 25)
-    = ((c1 + c2) - c3)
-- Branch { true: Counter(2), false: Expression(3, Sub) } at (prev + 0, 20) to (start + 0, 25)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18)
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16)
+- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16)
     true  = c2
-    false = (c1 - c3)
-- Code(Counter(2)) at (prev + 0, 26) to (start + 3, 6)
-- Code(Counter(1)) at (prev + 4, 1) to (start + 0, 2)
-Highest counter ID seen: c3
+    false = (c1 - c2)
+- Code(Counter(2)) at (prev + 0, 20) to (start + 0, 25)
+- Branch { true: Expression(4, Sub), false: Expression(2, Sub) } at (prev + 0, 20) to (start + 0, 25)
+    true  = (c1 - c0)
+    false = ((c0 + c2) - c1)
+- Code(Expression(4, Sub)) at (prev + 0, 26) to (start + 3, 6)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2)
+Highest counter ID seen: c2
 
 Function name: while::while_op_or
-Raw bytes (58): 0x[01, 01, 05, 07, 0d, 05, 09, 05, 0d, 05, 0d, 09, 0d, 08, 01, 29, 01, 01, 10, 05, 03, 09, 01, 12, 03, 02, 0b, 00, 10, 20, 09, 0f, 00, 0b, 00, 10, 0f, 00, 14, 00, 19, 20, 0d, 05, 00, 14, 00, 19, 13, 00, 1a, 03, 06, 05, 04, 01, 00, 02]
+Raw bytes (56): 0x[01, 01, 04, 05, 09, 05, 0b, 01, 09, 05, 01, 08, 01, 29, 01, 01, 10, 01, 03, 09, 01, 12, 05, 02, 0b, 00, 10, 20, 09, 02, 00, 0b, 00, 10, 02, 00, 14, 00, 19, 20, 06, 01, 00, 14, 00, 19, 0e, 00, 1a, 03, 06, 01, 04, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
-- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 2 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
+Number of expressions: 4
+- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 8
 - Code(Counter(0)) at (prev + 41, 1) to (start + 1, 16)
-- Code(Counter(1)) at (prev + 3, 9) to (start + 1, 18)
-- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 16)
-    = ((c1 + c2) + c3)
-- Branch { true: Counter(2), false: Expression(3, Add) } at (prev + 0, 11) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 3, 9) to (start + 1, 18)
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 16)
+- Branch { true: Counter(2), false: Expression(0, Sub) } at (prev + 0, 11) to (start + 0, 16)
     true  = c2
-    false = (c1 + c3)
-- Code(Expression(3, Add)) at (prev + 0, 20) to (start + 0, 25)
-    = (c1 + c3)
-- Branch { true: Counter(3), false: Counter(1) } at (prev + 0, 20) to (start + 0, 25)
-    true  = c3
-    false = c1
-- Code(Expression(4, Add)) at (prev + 0, 26) to (start + 3, 6)
-    = (c2 + c3)
-- Code(Counter(1)) at (prev + 4, 1) to (start + 0, 2)
-Highest counter ID seen: c3
+    false = (c1 - c2)
+- Code(Expression(0, Sub)) at (prev + 0, 20) to (start + 0, 25)
+    = (c1 - c2)
+- Branch { true: Expression(1, Sub), false: Counter(0) } at (prev + 0, 20) to (start + 0, 25)
+    true  = (c1 - (c0 + c2))
+    false = c0
+- Code(Expression(3, Sub)) at (prev + 0, 26) to (start + 3, 6)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 4, 1) to (start + 0, 2)
+Highest counter ID seen: c2
 
diff --git a/tests/coverage/continue.cov-map b/tests/coverage/continue.cov-map
index eb968fbb747..d926741cbcb 100644
--- a/tests/coverage/continue.cov-map
+++ b/tests/coverage/continue.cov-map
@@ -1,80 +1,75 @@
 Function name: continue::main
-Raw bytes (210): 0x[01, 01, 1c, 07, 09, 01, 05, 03, 0d, 1f, 15, 0d, 11, 1b, 19, 1f, 15, 0d, 11, 33, 21, 19, 1d, 2f, 25, 33, 21, 19, 1d, 47, 2d, 25, 29, 43, 31, 47, 2d, 25, 29, 5b, 39, 31, 35, 57, 3d, 5b, 39, 31, 35, 35, 39, 3d, 41, 6b, 45, 3d, 41, 3d, 45, 1e, 01, 03, 01, 03, 12, 03, 04, 0e, 00, 13, 0a, 01, 0f, 00, 16, 05, 02, 11, 00, 19, 09, 02, 12, 04, 0e, 1b, 06, 0e, 00, 13, 16, 01, 0f, 00, 16, 15, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 15, 03, 09, 00, 0e, 2f, 02, 0e, 00, 13, 2a, 01, 0f, 00, 16, 1d, 01, 15, 02, 0e, 21, 04, 11, 00, 19, 1d, 03, 09, 00, 0e, 43, 02, 0e, 00, 13, 3e, 01, 0c, 00, 13, 29, 01, 0d, 00, 15, 2d, 01, 0a, 01, 0e, 57, 03, 0e, 00, 13, 52, 01, 0f, 00, 16, 39, 01, 16, 02, 0e, 35, 03, 12, 02, 0e, 5f, 04, 09, 00, 0e, 6b, 02, 0e, 00, 13, 66, 01, 0f, 00, 16, 41, 01, 16, 02, 0e, 6e, 04, 11, 00, 16, 41, 03, 09, 00, 0e, 3d, 02, 0d, 01, 02]
+Raw bytes (198): 0x[01, 01, 16, 05, 01, 05, 0b, 01, 09, 0d, 01, 0d, 1f, 01, 11, 0d, 1f, 01, 11, 15, 01, 15, 2b, 01, 19, 1d, 01, 1d, 37, 01, 21, 25, 01, 25, 43, 01, 29, 25, 01, 2d, 01, 53, 2d, 01, 31, 2d, 01, 1e, 01, 03, 01, 03, 12, 05, 04, 0e, 00, 13, 02, 01, 0f, 00, 16, 09, 02, 11, 00, 19, 06, 02, 12, 04, 0e, 0d, 06, 0e, 00, 13, 0e, 01, 0f, 00, 16, 1a, 01, 16, 02, 0e, 11, 04, 11, 00, 19, 1a, 03, 09, 00, 0e, 15, 02, 0e, 00, 13, 22, 01, 0f, 00, 16, 19, 01, 15, 02, 0e, 26, 04, 11, 00, 19, 19, 03, 09, 00, 0e, 1d, 02, 0e, 00, 13, 2e, 01, 0c, 00, 13, 21, 01, 0d, 00, 15, 32, 01, 0a, 01, 0e, 25, 03, 0e, 00, 13, 46, 01, 0f, 00, 16, 3e, 01, 16, 02, 0e, 29, 03, 12, 02, 0e, 46, 04, 09, 00, 0e, 2d, 02, 0e, 00, 13, 31, 01, 0f, 00, 16, 56, 01, 16, 02, 0e, 4e, 04, 11, 00, 16, 56, 03, 09, 00, 0e, 01, 02, 0d, 01, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 28
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 3 operands: lhs = Expression(7, Add), rhs = Counter(5)
-- expression 4 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(6)
-- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(5)
-- expression 7 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 8 operands: lhs = Expression(12, Add), rhs = Counter(8)
-- expression 9 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(9)
-- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(8)
-- expression 12 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 13 operands: lhs = Expression(17, Add), rhs = Counter(11)
-- expression 14 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 15 operands: lhs = Expression(16, Add), rhs = Counter(12)
-- expression 16 operands: lhs = Expression(17, Add), rhs = Counter(11)
-- expression 17 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 18 operands: lhs = Expression(22, Add), rhs = Counter(14)
-- expression 19 operands: lhs = Counter(12), rhs = Counter(13)
-- expression 20 operands: lhs = Expression(21, Add), rhs = Counter(15)
-- expression 21 operands: lhs = Expression(22, Add), rhs = Counter(14)
-- expression 22 operands: lhs = Counter(12), rhs = Counter(13)
-- expression 23 operands: lhs = Counter(13), rhs = Counter(14)
-- expression 24 operands: lhs = Counter(15), rhs = Counter(16)
-- expression 25 operands: lhs = Expression(26, Add), rhs = Counter(17)
-- expression 26 operands: lhs = Counter(15), rhs = Counter(16)
-- expression 27 operands: lhs = Counter(15), rhs = Counter(17)
+Number of expressions: 22
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(3), rhs = Counter(0)
+- expression 4 operands: lhs = Counter(3), rhs = Expression(7, Add)
+- expression 5 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 6 operands: lhs = Counter(3), rhs = Expression(7, Add)
+- expression 7 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 8 operands: lhs = Counter(5), rhs = Counter(0)
+- expression 9 operands: lhs = Counter(5), rhs = Expression(10, Add)
+- expression 10 operands: lhs = Counter(0), rhs = Counter(6)
+- expression 11 operands: lhs = Counter(7), rhs = Counter(0)
+- expression 12 operands: lhs = Counter(7), rhs = Expression(13, Add)
+- expression 13 operands: lhs = Counter(0), rhs = Counter(8)
+- expression 14 operands: lhs = Counter(9), rhs = Counter(0)
+- expression 15 operands: lhs = Counter(9), rhs = Expression(16, Add)
+- expression 16 operands: lhs = Counter(0), rhs = Counter(10)
+- expression 17 operands: lhs = Counter(9), rhs = Counter(0)
+- expression 18 operands: lhs = Counter(11), rhs = Counter(0)
+- expression 19 operands: lhs = Expression(20, Add), rhs = Counter(11)
+- expression 20 operands: lhs = Counter(0), rhs = Counter(12)
+- expression 21 operands: lhs = Counter(11), rhs = Counter(0)
 Number of file 0 mappings: 30
 - Code(Counter(0)) at (prev + 3, 1) to (start + 3, 18)
-- Code(Expression(0, Add)) at (prev + 4, 14) to (start + 0, 19)
-    = ((c0 + c1) + c2)
-- Code(Expression(2, Sub)) at (prev + 1, 15) to (start + 0, 22)
-    = (((c0 + c1) + c2) - c3)
-- Code(Counter(1)) at (prev + 2, 17) to (start + 0, 25)
-- Code(Counter(2)) at (prev + 2, 18) to (start + 4, 14)
-- Code(Expression(6, Add)) at (prev + 6, 14) to (start + 0, 19)
-    = ((c3 + c4) + c5)
-- Code(Expression(5, Sub)) at (prev + 1, 15) to (start + 0, 22)
-    = (((c3 + c4) + c5) - c6)
-- Code(Counter(5)) at (prev + 1, 22) to (start + 2, 14)
+- Code(Counter(1)) at (prev + 4, 14) to (start + 0, 19)
+- Code(Expression(0, Sub)) at (prev + 1, 15) to (start + 0, 22)
+    = (c1 - c0)
+- Code(Counter(2)) at (prev + 2, 17) to (start + 0, 25)
+- Code(Expression(1, Sub)) at (prev + 2, 18) to (start + 4, 14)
+    = (c1 - (c0 + c2))
+- Code(Counter(3)) at (prev + 6, 14) to (start + 0, 19)
+- Code(Expression(3, Sub)) at (prev + 1, 15) to (start + 0, 22)
+    = (c3 - c0)
+- Code(Expression(6, Sub)) at (prev + 1, 22) to (start + 2, 14)
+    = (c3 - (c0 + c4))
 - Code(Counter(4)) at (prev + 4, 17) to (start + 0, 25)
-- Code(Counter(5)) at (prev + 3, 9) to (start + 0, 14)
-- Code(Expression(11, Add)) at (prev + 2, 14) to (start + 0, 19)
-    = ((c6 + c7) + c8)
-- Code(Expression(10, Sub)) at (prev + 1, 15) to (start + 0, 22)
-    = (((c6 + c7) + c8) - c9)
-- Code(Counter(7)) at (prev + 1, 21) to (start + 2, 14)
-- Code(Counter(8)) at (prev + 4, 17) to (start + 0, 25)
-- Code(Counter(7)) at (prev + 3, 9) to (start + 0, 14)
-- Code(Expression(16, Add)) at (prev + 2, 14) to (start + 0, 19)
-    = ((c9 + c10) + c11)
-- Code(Expression(15, Sub)) at (prev + 1, 12) to (start + 0, 19)
-    = (((c9 + c10) + c11) - c12)
-- Code(Counter(10)) at (prev + 1, 13) to (start + 0, 21)
-- Code(Counter(11)) at (prev + 1, 10) to (start + 1, 14)
-- Code(Expression(21, Add)) at (prev + 3, 14) to (start + 0, 19)
-    = ((c12 + c13) + c14)
-- Code(Expression(20, Sub)) at (prev + 1, 15) to (start + 0, 22)
-    = (((c12 + c13) + c14) - c15)
-- Code(Counter(14)) at (prev + 1, 22) to (start + 2, 14)
-- Code(Counter(13)) at (prev + 3, 18) to (start + 2, 14)
-- Code(Expression(23, Add)) at (prev + 4, 9) to (start + 0, 14)
-    = (c13 + c14)
-- Code(Expression(26, Add)) at (prev + 2, 14) to (start + 0, 19)
-    = (c15 + c16)
-- Code(Expression(25, Sub)) at (prev + 1, 15) to (start + 0, 22)
-    = ((c15 + c16) - c17)
-- Code(Counter(16)) at (prev + 1, 22) to (start + 2, 14)
-- Code(Expression(27, Sub)) at (prev + 4, 17) to (start + 0, 22)
-    = (c15 - c17)
-- Code(Counter(16)) at (prev + 3, 9) to (start + 0, 14)
-- Code(Counter(15)) at (prev + 2, 13) to (start + 1, 2)
-Highest counter ID seen: c16
+- Code(Expression(6, Sub)) at (prev + 3, 9) to (start + 0, 14)
+    = (c3 - (c0 + c4))
+- Code(Counter(5)) at (prev + 2, 14) to (start + 0, 19)
+- Code(Expression(8, Sub)) at (prev + 1, 15) to (start + 0, 22)
+    = (c5 - c0)
+- Code(Counter(6)) at (prev + 1, 21) to (start + 2, 14)
+- Code(Expression(9, Sub)) at (prev + 4, 17) to (start + 0, 25)
+    = (c5 - (c0 + c6))
+- Code(Counter(6)) at (prev + 3, 9) to (start + 0, 14)
+- Code(Counter(7)) at (prev + 2, 14) to (start + 0, 19)
+- Code(Expression(11, Sub)) at (prev + 1, 12) to (start + 0, 19)
+    = (c7 - c0)
+- Code(Counter(8)) at (prev + 1, 13) to (start + 0, 21)
+- Code(Expression(12, Sub)) at (prev + 1, 10) to (start + 1, 14)
+    = (c7 - (c0 + c8))
+- Code(Counter(9)) at (prev + 3, 14) to (start + 0, 19)
+- Code(Expression(17, Sub)) at (prev + 1, 15) to (start + 0, 22)
+    = (c9 - c0)
+- Code(Expression(15, Sub)) at (prev + 1, 22) to (start + 2, 14)
+    = (c9 - (c0 + c10))
+- Code(Counter(10)) at (prev + 3, 18) to (start + 2, 14)
+- Code(Expression(17, Sub)) at (prev + 4, 9) to (start + 0, 14)
+    = (c9 - c0)
+- Code(Counter(11)) at (prev + 2, 14) to (start + 0, 19)
+- Code(Counter(12)) at (prev + 1, 15) to (start + 0, 22)
+- Code(Expression(21, Sub)) at (prev + 1, 22) to (start + 2, 14)
+    = (c11 - c0)
+- Code(Expression(19, Sub)) at (prev + 4, 17) to (start + 0, 22)
+    = ((c0 + c12) - c11)
+- Code(Expression(21, Sub)) at (prev + 3, 9) to (start + 0, 14)
+    = (c11 - c0)
+- Code(Counter(0)) at (prev + 2, 13) to (start + 1, 2)
+Highest counter ID seen: c12
 
diff --git a/tests/coverage/coroutine.cov-map b/tests/coverage/coroutine.cov-map
index 7457a528a86..c6f2d415056 100644
--- a/tests/coverage/coroutine.cov-map
+++ b/tests/coverage/coroutine.cov-map
@@ -13,28 +13,25 @@ Number of file 0 mappings: 4
 Highest counter ID seen: c1
 
 Function name: coroutine::main
-Raw bytes (57): 0x[01, 01, 04, 07, 0d, 05, 09, 11, 19, 11, 15, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 03, 01, 0e, 00, 35, 11, 02, 0b, 00, 2e, 0a, 01, 22, 00, 27, 15, 00, 2c, 00, 2e, 0e, 01, 0e, 00, 35, 15, 02, 01, 00, 02]
+Raw bytes (53): 0x[01, 01, 02, 01, 05, 05, 09, 09, 01, 13, 01, 02, 16, 01, 08, 0b, 00, 2e, 05, 01, 2b, 00, 2d, 02, 01, 0e, 00, 35, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 35, 09, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 4
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
+Number of expressions: 2
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 2 operands: lhs = Counter(4), rhs = Counter(6)
-- expression 3 operands: lhs = Counter(4), rhs = Counter(5)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 19, 1) to (start + 2, 22)
 - Code(Counter(0)) at (prev + 8, 11) to (start + 0, 46)
-- Code(Counter(4)) at (prev + 1, 43) to (start + 0, 45)
-- Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 53)
-    = ((c1 + c2) + c3)
-- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46)
-- Code(Expression(2, Sub)) at (prev + 1, 34) to (start + 0, 39)
-    = (c4 - c6)
-- Code(Counter(5)) at (prev + 0, 44) to (start + 0, 46)
-- Code(Expression(3, Sub)) at (prev + 1, 14) to (start + 0, 53)
-    = (c4 - c5)
-- Code(Counter(5)) at (prev + 2, 1) to (start + 0, 2)
-Highest counter ID seen: c5
+- Code(Counter(1)) at (prev + 1, 43) to (start + 0, 45)
+- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 53)
+    = (c0 - c1)
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39)
+- Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46)
+- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 53)
+    = (c1 - c2)
+- Code(Counter(2)) at (prev + 2, 1) to (start + 0, 2)
+Highest counter ID seen: c3
 
 Function name: coroutine::main::{closure#0}
 Raw bytes (14): 0x[01, 01, 00, 02, 01, 16, 08, 01, 1f, 05, 02, 10, 01, 06]
diff --git a/tests/coverage/inline.cov-map b/tests/coverage/inline.cov-map
index 39ba2b2d99b..a569ad53cbc 100644
--- a/tests/coverage/inline.cov-map
+++ b/tests/coverage/inline.cov-map
@@ -1,15 +1,16 @@
 Function name: inline::display::<char>
-Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 29, 01, 00, 22, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 10, 05, 00, 11, 02, 06, 01, 03, 05, 01, 02]
+Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 29, 01, 00, 22, 02, 01, 09, 00, 0a, 05, 00, 0e, 00, 10, 02, 00, 11, 02, 06, 01, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 41, 1) to (start + 0, 34)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
-- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 16)
-    = (c0 + c1)
-- Code(Counter(1)) at (prev + 0, 17) to (start + 2, 6)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
+    = (c1 - c0)
+- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 16)
+- Code(Expression(0, Sub)) at (prev + 0, 17) to (start + 2, 6)
+    = (c1 - c0)
 - Code(Counter(0)) at (prev + 3, 5) to (start + 1, 2)
 Highest counter ID seen: c1
 
@@ -41,28 +42,29 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: inline::permutate::<char>
-Raw bytes (54): 0x[01, 01, 05, 01, 05, 01, 0b, 05, 0d, 13, 0d, 01, 09, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 11, 01, 0d, 00, 0e, 0d, 00, 12, 00, 16, 11, 00, 17, 04, 0a, 06, 05, 0c, 02, 06, 0e, 03, 01, 00, 02]
+Raw bytes (54): 0x[01, 01, 05, 01, 05, 0d, 09, 0d, 09, 01, 13, 05, 09, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 0a, 01, 0d, 00, 0e, 09, 00, 12, 00, 16, 0a, 00, 17, 04, 0a, 0e, 05, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(0), rhs = Expression(2, Add)
-- expression 2 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(3)
-- expression 4 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 2 operands: lhs = Counter(3), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add)
+- expression 4 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 8
 - Code(Counter(0)) at (prev + 15, 1) to (start + 2, 14)
 - Code(Counter(1)) at (prev + 2, 15) to (start + 2, 6)
 - Code(Expression(0, Sub)) at (prev + 2, 15) to (start + 0, 20)
     = (c0 - c1)
-- Code(Counter(4)) at (prev + 1, 13) to (start + 0, 14)
-- Code(Counter(3)) at (prev + 0, 18) to (start + 0, 22)
-- Code(Counter(4)) at (prev + 0, 23) to (start + 4, 10)
-- Code(Expression(1, Sub)) at (prev + 5, 12) to (start + 2, 6)
-    = (c0 - (c1 + c3))
-- Code(Expression(3, Sub)) at (prev + 3, 1) to (start + 0, 2)
-    = ((c0 + c2) - c3)
-Highest counter ID seen: c4
+- Code(Expression(2, Sub)) at (prev + 1, 13) to (start + 0, 14)
+    = (c3 - c2)
+- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 22)
+- Code(Expression(2, Sub)) at (prev + 0, 23) to (start + 4, 10)
+    = (c3 - c2)
+- Code(Expression(3, Sub)) at (prev + 5, 12) to (start + 2, 6)
+    = (c0 - (c1 + c2))
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c2
 
 Function name: inline::permutations::<char>
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 03, 02]
diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map
index a2ab558f960..efb9d43bf5b 100644
--- a/tests/coverage/issue-84561.cov-map
+++ b/tests/coverage/issue-84561.cov-map
@@ -59,147 +59,109 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: issue_84561::test3
-Raw bytes (409): 0x[01, 01, 3b, 05, 09, 0d, 11, 15, 19, 15, 1f, 19, 1d, 15, 1b, 1f, 21, 19, 1d, 25, 29, 21, 25, 2d, 31, 21, 33, 25, 2d, 35, 39, 3d, 41, 3d, 43, 41, 45, 5f, 4d, 45, 49, 5f, 67, 45, 49, 4d, 51, 5f, 63, 45, 49, 67, 59, 4d, 51, 97, 01, 55, 51, 59, 97, 01, 55, 51, 59, 97, 01, 83, 01, 51, 59, 55, 5d, 97, 01, 9f, 01, 51, 59, 55, 61, 97, 01, 9b, 01, 51, 59, 9f, 01, 65, 55, 61, db, 01, e7, 01, 69, 71, 6d, 75, 69, 6d, 69, 6d, 69, bb, 01, 6d, 00, 69, e7, 01, 6d, 75, db, 01, e3, 01, 69, 71, e7, 01, 79, 6d, 75, db, 01, df, 01, 69, 71, e3, 01, 7d, e7, 01, 79, 6d, 75, 7d, 81, 01, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 02, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 06, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 0a, 02, 05, 00, 1f, 0e, 01, 05, 00, 0f, 16, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 25, 03, 20, 00, 30, 29, 00, 33, 00, 41, 22, 00, 4b, 00, 5a, 26, 01, 05, 00, 0f, 2d, 05, 09, 03, 10, 31, 05, 0d, 00, 1b, 2a, 02, 0d, 00, 1c, 2e, 04, 09, 05, 06, 35, 06, 05, 03, 06, 36, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 3a, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 3e, 05, 09, 03, 0a, 46, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 55, 03, 0d, 00, 1d, 4e, 03, 09, 00, 13, 5a, 03, 0d, 00, 1d, 72, 03, 05, 00, 0f, 72, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 7a, 02, 0d, 00, 13, 86, 01, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 92, 01, 02, 0d, 00, 13, a2, 01, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 71, 04, 0d, 00, 13, b2, 01, 02, 0d, 00, 17, b2, 01, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, b6, 01, 02, 15, 00, 1b, be, 01, 04, 0d, 00, 13, 79, 03, 09, 00, 19, c6, 01, 02, 05, 00, 0f, d6, 01, 03, 09, 00, 22, 7d, 02, 05, 00, 0f, ea, 01, 03, 09, 00, 2c, 81, 01, 02, 01, 00, 02]
+Raw bytes (317): 0x[01, 01, 1c, 1d, 21, 25, 29, 21, 25, 2d, 31, 21, 17, 25, 2d, 41, 45, 49, 4d, 51, 55, 33, 51, 49, 4d, 33, 37, 49, 4d, 51, 59, 55, 59, 55, 59, 47, 5d, 55, 59, 61, 65, 71, 75, 69, 6d, 69, 6d, 69, 5f, 6d, 00, 67, 79, 71, 75, 79, 7d, 7d, 81, 01, 33, 01, 08, 01, 03, 1c, 05, 04, 09, 01, 1c, 09, 02, 05, 04, 1f, 0d, 05, 05, 00, 1f, 11, 01, 05, 00, 1f, 15, 01, 09, 01, 1c, 19, 02, 05, 00, 1f, 1d, 01, 05, 00, 0f, 02, 00, 20, 00, 30, 21, 01, 05, 03, 0f, 25, 03, 20, 00, 30, 29, 00, 33, 00, 41, 06, 00, 4b, 00, 5a, 0a, 01, 05, 00, 0f, 2d, 05, 09, 03, 10, 31, 05, 0d, 00, 1b, 0e, 02, 0d, 00, 1c, 12, 04, 09, 05, 06, 35, 06, 05, 03, 06, 39, 04, 05, 03, 06, 3d, 04, 09, 04, 06, 41, 05, 08, 00, 0f, 45, 01, 09, 03, 0a, 1a, 05, 09, 03, 0a, 33, 05, 08, 00, 0f, 51, 01, 09, 00, 13, 22, 03, 0d, 00, 1d, 26, 03, 09, 00, 13, 2e, 03, 0d, 00, 1d, 47, 03, 05, 00, 0f, 47, 01, 0c, 00, 13, 5d, 01, 0d, 00, 13, 42, 02, 0d, 00, 13, 61, 04, 05, 02, 13, 65, 03, 0d, 00, 13, 4a, 02, 0d, 00, 13, 67, 03, 05, 00, 0f, 69, 01, 0c, 00, 13, 6d, 01, 0d, 03, 0e, 71, 04, 0d, 00, 13, 56, 02, 0d, 00, 17, 56, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 5a, 02, 15, 00, 1b, 75, 04, 0d, 00, 13, 62, 03, 09, 00, 19, 79, 02, 05, 00, 0f, 6a, 03, 09, 00, 22, 7d, 02, 05, 00, 0f, 6e, 03, 09, 00, 2c, 81, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 59
-- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 2 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 3 operands: lhs = Counter(5), rhs = Expression(7, Add)
-- expression 4 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 5 operands: lhs = Counter(5), rhs = Expression(6, Add)
-- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(8)
-- expression 7 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 8 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 9 operands: lhs = Counter(8), rhs = Counter(9)
-- expression 10 operands: lhs = Counter(11), rhs = Counter(12)
-- expression 11 operands: lhs = Counter(8), rhs = Expression(12, Add)
-- expression 12 operands: lhs = Counter(9), rhs = Counter(11)
-- expression 13 operands: lhs = Counter(13), rhs = Counter(14)
-- expression 14 operands: lhs = Counter(15), rhs = Counter(16)
-- expression 15 operands: lhs = Counter(15), rhs = Expression(16, Add)
-- expression 16 operands: lhs = Counter(16), rhs = Counter(17)
-- expression 17 operands: lhs = Expression(23, Add), rhs = Counter(19)
-- expression 18 operands: lhs = Counter(17), rhs = Counter(18)
-- expression 19 operands: lhs = Expression(23, Add), rhs = Expression(25, Add)
-- expression 20 operands: lhs = Counter(17), rhs = Counter(18)
-- expression 21 operands: lhs = Counter(19), rhs = Counter(20)
-- expression 22 operands: lhs = Expression(23, Add), rhs = Expression(24, Add)
-- expression 23 operands: lhs = Counter(17), rhs = Counter(18)
-- expression 24 operands: lhs = Expression(25, Add), rhs = Counter(22)
-- expression 25 operands: lhs = Counter(19), rhs = Counter(20)
-- expression 26 operands: lhs = Expression(37, Add), rhs = Counter(21)
-- expression 27 operands: lhs = Counter(20), rhs = Counter(22)
-- expression 28 operands: lhs = Expression(37, Add), rhs = Counter(21)
-- expression 29 operands: lhs = Counter(20), rhs = Counter(22)
-- expression 30 operands: lhs = Expression(37, Add), rhs = Expression(32, Add)
-- expression 31 operands: lhs = Counter(20), rhs = Counter(22)
-- expression 32 operands: lhs = Counter(21), rhs = Counter(23)
-- expression 33 operands: lhs = Expression(37, Add), rhs = Expression(39, Add)
-- expression 34 operands: lhs = Counter(20), rhs = Counter(22)
-- expression 35 operands: lhs = Counter(21), rhs = Counter(24)
-- expression 36 operands: lhs = Expression(37, Add), rhs = Expression(38, Add)
-- expression 37 operands: lhs = Counter(20), rhs = Counter(22)
-- expression 38 operands: lhs = Expression(39, Add), rhs = Counter(25)
-- expression 39 operands: lhs = Counter(21), rhs = Counter(24)
-- expression 40 operands: lhs = Expression(54, Add), rhs = Expression(57, Add)
-- expression 41 operands: lhs = Counter(26), rhs = Counter(28)
-- expression 42 operands: lhs = Counter(27), rhs = Counter(29)
-- expression 43 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 44 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 45 operands: lhs = Counter(26), rhs = Expression(46, Add)
-- expression 46 operands: lhs = Counter(27), rhs = Zero
-- expression 47 operands: lhs = Counter(26), rhs = Expression(57, Add)
-- expression 48 operands: lhs = Counter(27), rhs = Counter(29)
-- expression 49 operands: lhs = Expression(54, Add), rhs = Expression(56, Add)
-- expression 50 operands: lhs = Counter(26), rhs = Counter(28)
-- expression 51 operands: lhs = Expression(57, Add), rhs = Counter(30)
-- expression 52 operands: lhs = Counter(27), rhs = Counter(29)
-- expression 53 operands: lhs = Expression(54, Add), rhs = Expression(55, Add)
-- expression 54 operands: lhs = Counter(26), rhs = Counter(28)
-- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(31)
-- expression 56 operands: lhs = Expression(57, Add), rhs = Counter(30)
-- expression 57 operands: lhs = Counter(27), rhs = Counter(29)
-- expression 58 operands: lhs = Counter(31), rhs = Counter(32)
+Number of expressions: 28
+- expression 0 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 1 operands: lhs = Counter(9), rhs = Counter(10)
+- expression 2 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 3 operands: lhs = Counter(11), rhs = Counter(12)
+- expression 4 operands: lhs = Counter(8), rhs = Expression(5, Add)
+- expression 5 operands: lhs = Counter(9), rhs = Counter(11)
+- expression 6 operands: lhs = Counter(16), rhs = Counter(17)
+- expression 7 operands: lhs = Counter(18), rhs = Counter(19)
+- expression 8 operands: lhs = Counter(20), rhs = Counter(21)
+- expression 9 operands: lhs = Expression(12, Add), rhs = Counter(20)
+- expression 10 operands: lhs = Counter(18), rhs = Counter(19)
+- expression 11 operands: lhs = Expression(12, Add), rhs = Expression(13, Add)
+- expression 12 operands: lhs = Counter(18), rhs = Counter(19)
+- expression 13 operands: lhs = Counter(20), rhs = Counter(22)
+- expression 14 operands: lhs = Counter(21), rhs = Counter(22)
+- expression 15 operands: lhs = Counter(21), rhs = Counter(22)
+- expression 16 operands: lhs = Expression(17, Add), rhs = Counter(23)
+- expression 17 operands: lhs = Counter(21), rhs = Counter(22)
+- expression 18 operands: lhs = Counter(24), rhs = Counter(25)
+- expression 19 operands: lhs = Counter(28), rhs = Counter(29)
+- expression 20 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 21 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 22 operands: lhs = Counter(26), rhs = Expression(23, Add)
+- expression 23 operands: lhs = Counter(27), rhs = Zero
+- expression 24 operands: lhs = Expression(25, Add), rhs = Counter(30)
+- expression 25 operands: lhs = Counter(28), rhs = Counter(29)
+- expression 26 operands: lhs = Counter(30), rhs = Counter(31)
+- expression 27 operands: lhs = Counter(31), rhs = Counter(32)
 Number of file 0 mappings: 51
 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28)
 - Code(Counter(1)) at (prev + 4, 9) to (start + 1, 28)
-- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 4, 31)
-    = (c1 - c2)
+- Code(Counter(2)) at (prev + 2, 5) to (start + 4, 31)
 - Code(Counter(3)) at (prev + 5, 5) to (start + 0, 31)
-- Code(Expression(1, Sub)) at (prev + 1, 5) to (start + 0, 31)
-    = (c3 - c4)
+- Code(Counter(4)) at (prev + 1, 5) to (start + 0, 31)
 - Code(Counter(5)) at (prev + 1, 9) to (start + 1, 28)
-- Code(Expression(2, Sub)) at (prev + 2, 5) to (start + 0, 31)
-    = (c5 - c6)
-- Code(Expression(3, Sub)) at (prev + 1, 5) to (start + 0, 15)
-    = (c5 - (c6 + c7))
-- Code(Expression(5, Sub)) at (prev + 0, 32) to (start + 0, 48)
-    = (c5 - ((c6 + c7) + c8))
+- Code(Counter(6)) at (prev + 2, 5) to (start + 0, 31)
+- Code(Counter(7)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 0, 32) to (start + 0, 48)
+    = (c7 - c8)
 - Code(Counter(8)) at (prev + 1, 5) to (start + 3, 15)
 - Code(Counter(9)) at (prev + 3, 32) to (start + 0, 48)
 - Code(Counter(10)) at (prev + 0, 51) to (start + 0, 65)
-- Code(Expression(8, Sub)) at (prev + 0, 75) to (start + 0, 90)
+- Code(Expression(1, Sub)) at (prev + 0, 75) to (start + 0, 90)
     = (c9 - c10)
-- Code(Expression(9, Sub)) at (prev + 1, 5) to (start + 0, 15)
+- Code(Expression(2, Sub)) at (prev + 1, 5) to (start + 0, 15)
     = (c8 - c9)
 - Code(Counter(11)) at (prev + 5, 9) to (start + 3, 16)
 - Code(Counter(12)) at (prev + 5, 13) to (start + 0, 27)
-- Code(Expression(10, Sub)) at (prev + 2, 13) to (start + 0, 28)
+- Code(Expression(3, Sub)) at (prev + 2, 13) to (start + 0, 28)
     = (c11 - c12)
-- Code(Expression(11, Sub)) at (prev + 4, 9) to (start + 5, 6)
+- Code(Expression(4, Sub)) at (prev + 4, 9) to (start + 5, 6)
     = (c8 - (c9 + c11))
 - Code(Counter(13)) at (prev + 6, 5) to (start + 3, 6)
-- Code(Expression(13, Sub)) at (prev + 4, 5) to (start + 3, 6)
-    = (c13 - c14)
+- Code(Counter(14)) at (prev + 4, 5) to (start + 3, 6)
 - Code(Counter(15)) at (prev + 4, 9) to (start + 4, 6)
-- Code(Expression(14, Sub)) at (prev + 5, 8) to (start + 0, 15)
-    = (c15 - c16)
+- Code(Counter(16)) at (prev + 5, 8) to (start + 0, 15)
 - Code(Counter(17)) at (prev + 1, 9) to (start + 3, 10)
-- Code(Expression(15, Sub)) at (prev + 5, 9) to (start + 3, 10)
-    = (c15 - (c16 + c17))
-- Code(Expression(17, Sub)) at (prev + 5, 8) to (start + 0, 15)
-    = ((c17 + c18) - c19)
+- Code(Expression(6, Sub)) at (prev + 5, 9) to (start + 3, 10)
+    = (c16 - c17)
+- Code(Expression(12, Add)) at (prev + 5, 8) to (start + 0, 15)
+    = (c18 + c19)
 - Code(Counter(20)) at (prev + 1, 9) to (start + 0, 19)
-- Code(Counter(21)) at (prev + 3, 13) to (start + 0, 29)
-- Code(Expression(19, Sub)) at (prev + 3, 9) to (start + 0, 19)
-    = ((c17 + c18) - (c19 + c20))
-- Code(Expression(22, Sub)) at (prev + 3, 13) to (start + 0, 29)
-    = ((c17 + c18) - ((c19 + c20) + c22))
-- Code(Expression(28, Sub)) at (prev + 3, 5) to (start + 0, 15)
-    = ((c20 + c22) - c21)
-- Code(Expression(28, Sub)) at (prev + 1, 12) to (start + 0, 19)
-    = ((c20 + c22) - c21)
+- Code(Expression(8, Sub)) at (prev + 3, 13) to (start + 0, 29)
+    = (c20 - c21)
+- Code(Expression(9, Sub)) at (prev + 3, 9) to (start + 0, 19)
+    = ((c18 + c19) - c20)
+- Code(Expression(11, Sub)) at (prev + 3, 13) to (start + 0, 29)
+    = ((c18 + c19) - (c20 + c22))
+- Code(Expression(17, Add)) at (prev + 3, 5) to (start + 0, 15)
+    = (c21 + c22)
+- Code(Expression(17, Add)) at (prev + 1, 12) to (start + 0, 19)
+    = (c21 + c22)
 - Code(Counter(23)) at (prev + 1, 13) to (start + 0, 19)
-- Code(Expression(30, Sub)) at (prev + 2, 13) to (start + 0, 19)
-    = ((c20 + c22) - (c21 + c23))
-- Code(Expression(33, Sub)) at (prev + 4, 5) to (start + 2, 19)
-    = ((c20 + c22) - (c21 + c24))
+- Code(Expression(16, Sub)) at (prev + 2, 13) to (start + 0, 19)
+    = ((c21 + c22) - c23)
+- Code(Counter(24)) at (prev + 4, 5) to (start + 2, 19)
 - Code(Counter(25)) at (prev + 3, 13) to (start + 0, 19)
-- Code(Expression(36, Sub)) at (prev + 2, 13) to (start + 0, 19)
-    = ((c20 + c22) - ((c21 + c24) + c25))
-- Code(Expression(40, Sub)) at (prev + 3, 5) to (start + 0, 15)
-    = ((c26 + c28) - (c27 + c29))
+- Code(Expression(18, Sub)) at (prev + 2, 13) to (start + 0, 19)
+    = (c24 - c25)
+- Code(Expression(25, Add)) at (prev + 3, 5) to (start + 0, 15)
+    = (c28 + c29)
 - Code(Counter(26)) at (prev + 1, 12) to (start + 0, 19)
 - Code(Counter(27)) at (prev + 1, 13) to (start + 3, 14)
 - Code(Counter(28)) at (prev + 4, 13) to (start + 0, 19)
-- Code(Expression(44, Sub)) at (prev + 2, 13) to (start + 0, 23)
+- Code(Expression(21, Sub)) at (prev + 2, 13) to (start + 0, 23)
     = (c26 - c27)
-- Code(Expression(44, Sub)) at (prev + 1, 20) to (start + 0, 27)
+- Code(Expression(21, Sub)) at (prev + 1, 20) to (start + 0, 27)
     = (c26 - c27)
 - Code(Zero) at (prev + 1, 21) to (start + 0, 27)
-- Code(Expression(45, Sub)) at (prev + 2, 21) to (start + 0, 27)
+- Code(Expression(22, Sub)) at (prev + 2, 21) to (start + 0, 27)
     = (c26 - (c27 + Zero))
-- Code(Expression(47, Sub)) at (prev + 4, 13) to (start + 0, 19)
-    = (c26 - (c27 + c29))
-- Code(Counter(30)) at (prev + 3, 9) to (start + 0, 25)
-- Code(Expression(49, Sub)) at (prev + 2, 5) to (start + 0, 15)
-    = ((c26 + c28) - ((c27 + c29) + c30))
-- Code(Expression(53, Sub)) at (prev + 3, 9) to (start + 0, 34)
-    = ((c26 + c28) - (((c27 + c29) + c30) + c31))
+- Code(Counter(29)) at (prev + 4, 13) to (start + 0, 19)
+- Code(Expression(24, Sub)) at (prev + 3, 9) to (start + 0, 25)
+    = ((c28 + c29) - c30)
+- Code(Counter(30)) at (prev + 2, 5) to (start + 0, 15)
+- Code(Expression(26, Sub)) at (prev + 3, 9) to (start + 0, 34)
+    = (c30 - c31)
 - Code(Counter(31)) at (prev + 2, 5) to (start + 0, 15)
-- Code(Expression(58, Sub)) at (prev + 3, 9) to (start + 0, 44)
+- Code(Expression(27, Sub)) at (prev + 3, 9) to (start + 0, 44)
     = (c31 - c32)
 - Code(Counter(32)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c32
diff --git a/tests/coverage/loop-break.cov-map b/tests/coverage/loop-break.cov-map
index 0b4c42a43da..f13e82da151 100644
--- a/tests/coverage/loop-break.cov-map
+++ b/tests/coverage/loop-break.cov-map
@@ -1,15 +1,15 @@
 Function name: loop_break::main
-Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 03, 01, 00, 0b, 03, 02, 0c, 00, 27, 01, 01, 0d, 00, 12, 05, 01, 09, 00, 0a, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 05, 01, 05, 01, 03, 01, 00, 0b, 05, 02, 0c, 00, 27, 01, 01, 0d, 00, 12, 02, 01, 09, 00, 0a, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 11)
-- Code(Expression(0, Add)) at (prev + 2, 12) to (start + 0, 39)
-    = (c0 + c1)
+- Code(Counter(1)) at (prev + 2, 12) to (start + 0, 39)
 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 10)
+    = (c1 - c0)
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map
index 0279a1a5157..912141b6d5f 100644
--- a/tests/coverage/loops_branches.cov-map
+++ b/tests/coverage/loops_branches.cov-map
@@ -1,32 +1,14 @@
 Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt
-Raw bytes (152): 0x[01, 01, 18, 05, 00, 27, 57, 53, 00, 01, 1d, 11, 19, 27, 11, 53, 00, 01, 1d, 27, 57, 53, 00, 01, 1d, 11, 19, 53, 57, 01, 1d, 11, 19, 53, 47, 01, 1d, 57, 00, 11, 19, 53, 57, 01, 1d, 11, 19, 5f, 19, 11, 15, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0d, 00, 0e, 05, 01, 0d, 00, 1e, 11, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 22, 03, 0d, 00, 0e, 16, 00, 12, 00, 17, 22, 01, 10, 00, 14, 4e, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 3e, 01, 11, 00, 12, 4e, 01, 11, 00, 22, 15, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, 5b, 01, 05, 00, 06]
+Raw bytes (116): 0x[01, 01, 06, 05, 00, 1d, 00, 0f, 13, 01, 19, 11, 15, 15, 19, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0d, 00, 0e, 05, 01, 0d, 00, 1e, 11, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 19, 03, 0d, 00, 0e, 15, 00, 12, 00, 17, 19, 01, 10, 00, 14, 1d, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 06, 01, 11, 00, 12, 1d, 01, 11, 00, 22, 0a, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 16, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 24
+Number of expressions: 6
 - expression 0 operands: lhs = Counter(1), rhs = Zero
-- expression 1 operands: lhs = Expression(9, Add), rhs = Expression(21, Add)
-- expression 2 operands: lhs = Expression(20, Add), rhs = Zero
-- expression 3 operands: lhs = Counter(0), rhs = Counter(7)
-- expression 4 operands: lhs = Counter(4), rhs = Counter(6)
-- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(4)
-- expression 6 operands: lhs = Expression(20, Add), rhs = Zero
-- expression 7 operands: lhs = Counter(0), rhs = Counter(7)
-- expression 8 operands: lhs = Expression(9, Add), rhs = Expression(21, Add)
-- expression 9 operands: lhs = Expression(20, Add), rhs = Zero
-- expression 10 operands: lhs = Counter(0), rhs = Counter(7)
-- expression 11 operands: lhs = Counter(4), rhs = Counter(6)
-- expression 12 operands: lhs = Expression(20, Add), rhs = Expression(21, Add)
-- expression 13 operands: lhs = Counter(0), rhs = Counter(7)
-- expression 14 operands: lhs = Counter(4), rhs = Counter(6)
-- expression 15 operands: lhs = Expression(20, Add), rhs = Expression(17, Add)
-- expression 16 operands: lhs = Counter(0), rhs = Counter(7)
-- expression 17 operands: lhs = Expression(21, Add), rhs = Zero
-- expression 18 operands: lhs = Counter(4), rhs = Counter(6)
-- expression 19 operands: lhs = Expression(20, Add), rhs = Expression(21, Add)
-- expression 20 operands: lhs = Counter(0), rhs = Counter(7)
-- expression 21 operands: lhs = Counter(4), rhs = Counter(6)
-- expression 22 operands: lhs = Expression(23, Add), rhs = Counter(6)
-- expression 23 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 1 operands: lhs = Counter(7), rhs = Zero
+- expression 2 operands: lhs = Expression(3, Add), rhs = Expression(4, Add)
+- expression 3 operands: lhs = Counter(0), rhs = Counter(6)
+- expression 4 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 5 operands: lhs = Counter(5), rhs = Counter(6)
 Number of file 0 mappings: 20
 - Code(Counter(0)) at (prev + 9, 5) to (start + 1, 16)
 - Code(Counter(1)) at (prev + 2, 16) to (start + 0, 21)
@@ -37,57 +19,37 @@ Number of file 0 mappings: 20
 - Code(Counter(1)) at (prev + 1, 13) to (start + 0, 30)
 - Code(Counter(4)) at (prev + 0, 30) to (start + 0, 31)
 - Code(Zero) at (prev + 1, 16) to (start + 1, 10)
-- Code(Expression(8, Sub)) at (prev + 3, 13) to (start + 0, 14)
-    = (((c0 + c7) + Zero) - (c4 + c6))
-- Code(Expression(5, Sub)) at (prev + 0, 18) to (start + 0, 23)
-    = (((c0 + c7) + Zero) - c4)
-- Code(Expression(8, Sub)) at (prev + 1, 16) to (start + 0, 20)
-    = (((c0 + c7) + Zero) - (c4 + c6))
-- Code(Expression(19, Sub)) at (prev + 1, 20) to (start + 0, 25)
-    = ((c0 + c7) - (c4 + c6))
+- Code(Counter(6)) at (prev + 3, 13) to (start + 0, 14)
+- Code(Counter(5)) at (prev + 0, 18) to (start + 0, 23)
+- Code(Counter(6)) at (prev + 1, 16) to (start + 0, 20)
+- Code(Counter(7)) at (prev + 1, 20) to (start + 0, 25)
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
-- Code(Expression(15, Sub)) at (prev + 1, 17) to (start + 0, 18)
-    = ((c0 + c7) - ((c4 + c6) + Zero))
-- Code(Expression(19, Sub)) at (prev + 1, 17) to (start + 0, 34)
-    = ((c0 + c7) - (c4 + c6))
-- Code(Counter(5)) at (prev + 0, 34) to (start + 0, 35)
+- Code(Expression(1, Sub)) at (prev + 1, 17) to (start + 0, 18)
+    = (c7 - Zero)
+- Code(Counter(7)) at (prev + 1, 17) to (start + 0, 34)
+- Code(Expression(2, Sub)) at (prev + 0, 34) to (start + 0, 35)
+    = ((c0 + c6) - (c4 + c5))
 - Code(Zero) at (prev + 1, 20) to (start + 1, 14)
-- Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15)
-- Code(Expression(22, Add)) at (prev + 1, 5) to (start + 0, 6)
-    = ((c4 + c5) + c6)
-Highest counter ID seen: c6
+- Code(Expression(5, Sub)) at (prev + 3, 9) to (start + 0, 15)
+    = (c5 - c6)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: c7
 
 Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt
-Raw bytes (154): 0x[01, 01, 19, 01, 00, 01, 00, 2b, 63, 2f, 0d, 01, 00, 11, 15, 2b, 11, 2f, 0d, 01, 00, 2b, 63, 2f, 0d, 01, 00, 11, 15, 57, 63, 01, 0d, 11, 15, 57, 4b, 01, 0d, 63, 00, 11, 15, 57, 63, 01, 0d, 11, 15, 63, 21, 11, 15, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 06, 01, 0d, 00, 0e, 02, 01, 0d, 00, 1e, 11, 00, 1e, 00, 1f, 26, 02, 0d, 00, 0e, 1a, 00, 12, 00, 17, 26, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 52, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 42, 01, 11, 00, 12, 52, 01, 11, 00, 22, 21, 00, 22, 00, 23, 15, 03, 09, 00, 0f, 5f, 01, 05, 00, 06]
+Raw bytes (122): 0x[01, 01, 09, 01, 00, 01, 00, 0d, 00, 0d, 00, 0d, 00, 1b, 1f, 01, 0d, 09, 1d, 09, 0d, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 06, 01, 0d, 00, 0e, 02, 01, 0d, 00, 1e, 1d, 00, 1e, 00, 1f, 0d, 02, 0d, 00, 0e, 09, 00, 12, 00, 17, 0d, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 12, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 0e, 01, 11, 00, 12, 12, 01, 11, 00, 22, 16, 00, 22, 00, 23, 22, 03, 09, 00, 0f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 25
+Number of expressions: 9
 - expression 0 operands: lhs = Counter(0), rhs = Zero
 - expression 1 operands: lhs = Counter(0), rhs = Zero
-- expression 2 operands: lhs = Expression(10, Add), rhs = Expression(24, Add)
-- expression 3 operands: lhs = Expression(11, Add), rhs = Counter(3)
-- expression 4 operands: lhs = Counter(0), rhs = Zero
-- expression 5 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 6 operands: lhs = Expression(10, Add), rhs = Counter(4)
-- expression 7 operands: lhs = Expression(11, Add), rhs = Counter(3)
-- expression 8 operands: lhs = Counter(0), rhs = Zero
-- expression 9 operands: lhs = Expression(10, Add), rhs = Expression(24, Add)
-- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(3)
-- expression 11 operands: lhs = Counter(0), rhs = Zero
-- expression 12 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 13 operands: lhs = Expression(21, Add), rhs = Expression(24, Add)
-- expression 14 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 15 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 16 operands: lhs = Expression(21, Add), rhs = Expression(18, Add)
-- expression 17 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 18 operands: lhs = Expression(24, Add), rhs = Zero
-- expression 19 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 20 operands: lhs = Expression(21, Add), rhs = Expression(24, Add)
-- expression 21 operands: lhs = Counter(0), rhs = Counter(3)
-- expression 22 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(8)
-- expression 24 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 2 operands: lhs = Counter(3), rhs = Zero
+- expression 3 operands: lhs = Counter(3), rhs = Zero
+- expression 4 operands: lhs = Counter(3), rhs = Zero
+- expression 5 operands: lhs = Expression(6, Add), rhs = Expression(7, Add)
+- expression 6 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 7 operands: lhs = Counter(2), rhs = Counter(7)
+- expression 8 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 20
 - Code(Counter(0)) at (prev + 34, 5) to (start + 1, 17)
 - Code(Zero) at (prev + 1, 18) to (start + 1, 10)
@@ -99,27 +61,25 @@ Number of file 0 mappings: 20
     = (c0 - Zero)
 - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 30)
     = (c0 - Zero)
-- Code(Counter(4)) at (prev + 0, 30) to (start + 0, 31)
-- Code(Expression(9, Sub)) at (prev + 2, 13) to (start + 0, 14)
-    = (((c0 + Zero) + c3) - (c4 + c5))
-- Code(Expression(6, Sub)) at (prev + 0, 18) to (start + 0, 23)
-    = (((c0 + Zero) + c3) - c4)
-- Code(Expression(9, Sub)) at (prev + 1, 16) to (start + 0, 21)
-    = (((c0 + Zero) + c3) - (c4 + c5))
+- Code(Counter(7)) at (prev + 0, 30) to (start + 0, 31)
+- Code(Counter(3)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Counter(2)) at (prev + 0, 18) to (start + 0, 23)
+- Code(Counter(3)) at (prev + 1, 16) to (start + 0, 21)
 - Code(Zero) at (prev + 0, 22) to (start + 1, 14)
-- Code(Expression(20, Sub)) at (prev + 2, 20) to (start + 0, 25)
-    = ((c0 + c3) - (c4 + c5))
+- Code(Expression(4, Sub)) at (prev + 2, 20) to (start + 0, 25)
+    = (c3 - Zero)
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
-- Code(Expression(16, Sub)) at (prev + 1, 17) to (start + 0, 18)
-    = ((c0 + c3) - ((c4 + c5) + Zero))
-- Code(Expression(20, Sub)) at (prev + 1, 17) to (start + 0, 34)
-    = ((c0 + c3) - (c4 + c5))
-- Code(Counter(8)) at (prev + 0, 34) to (start + 0, 35)
-- Code(Counter(5)) at (prev + 3, 9) to (start + 0, 15)
-- Code(Expression(23, Add)) at (prev + 1, 5) to (start + 0, 6)
-    = ((c4 + c5) + c8)
-Highest counter ID seen: c8
+- Code(Expression(3, Sub)) at (prev + 1, 17) to (start + 0, 18)
+    = (c3 - Zero)
+- Code(Expression(4, Sub)) at (prev + 1, 17) to (start + 0, 34)
+    = (c3 - Zero)
+- Code(Expression(5, Sub)) at (prev + 0, 34) to (start + 0, 35)
+    = ((c0 + c3) - (c2 + c7))
+- Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 15)
+    = (c2 - c3)
+- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
+Highest counter ID seen: c7
 
 Function name: loops_branches::main
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 37, 01, 05, 02]
diff --git a/tests/coverage/match_or_pattern.cov-map b/tests/coverage/match_or_pattern.cov-map
index 2beb327bc05..ae77eedfe72 100644
--- a/tests/coverage/match_or_pattern.cov-map
+++ b/tests/coverage/match_or_pattern.cov-map
@@ -1,76 +1,49 @@
 Function name: match_or_pattern::main
-Raw bytes (185): 0x[01, 01, 1c, 01, 05, 09, 0d, 23, 11, 09, 0d, 1f, 15, 23, 11, 09, 0d, 23, 11, 09, 0d, 19, 1d, 43, 21, 19, 1d, 3f, 25, 43, 21, 19, 1d, 43, 21, 19, 1d, 29, 2d, 63, 31, 29, 2d, 5f, 35, 63, 31, 29, 2d, 63, 31, 29, 2d, 39, 3d, 6f, 41, 39, 3d, 19, 01, 01, 01, 08, 0f, 05, 08, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 11, 03, 1b, 00, 1d, 23, 01, 0e, 00, 10, 1f, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 1f, 01, 0b, 00, 11, 21, 01, 1b, 00, 1d, 43, 01, 0e, 00, 10, 3f, 02, 08, 00, 0f, 25, 00, 10, 03, 06, 32, 03, 05, 00, 06, 3f, 01, 0b, 00, 11, 31, 01, 1b, 00, 1d, 63, 01, 0e, 00, 10, 5f, 02, 08, 00, 0f, 35, 00, 10, 03, 06, 52, 03, 05, 00, 06, 5f, 01, 0b, 00, 11, 41, 01, 1b, 00, 1d, 6f, 01, 0e, 00, 10, 6b, 02, 01, 00, 02]
+Raw bytes (145): 0x[01, 01, 08, 01, 05, 01, 09, 01, 0d, 01, 11, 01, 15, 01, 19, 01, 1d, 01, 21, 19, 01, 01, 01, 08, 0f, 05, 08, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 06, 03, 1b, 00, 1d, 09, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 0d, 00, 10, 03, 06, 0a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 0e, 01, 1b, 00, 1d, 11, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 16, 01, 1b, 00, 1d, 19, 01, 0e, 00, 10, 01, 02, 08, 00, 0f, 1d, 00, 10, 03, 06, 1a, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 1e, 01, 1b, 00, 1d, 21, 01, 0e, 00, 10, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 28
+Number of expressions: 8
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 2 operands: lhs = Expression(8, Add), rhs = Counter(4)
-- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 4 operands: lhs = Expression(7, Add), rhs = Counter(5)
-- expression 5 operands: lhs = Expression(8, Add), rhs = Counter(4)
-- expression 6 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(4)
-- expression 8 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 9 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 10 operands: lhs = Expression(16, Add), rhs = Counter(8)
-- expression 11 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 12 operands: lhs = Expression(15, Add), rhs = Counter(9)
-- expression 13 operands: lhs = Expression(16, Add), rhs = Counter(8)
-- expression 14 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 15 operands: lhs = Expression(16, Add), rhs = Counter(8)
-- expression 16 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 17 operands: lhs = Counter(10), rhs = Counter(11)
-- expression 18 operands: lhs = Expression(24, Add), rhs = Counter(12)
-- expression 19 operands: lhs = Counter(10), rhs = Counter(11)
-- expression 20 operands: lhs = Expression(23, Add), rhs = Counter(13)
-- expression 21 operands: lhs = Expression(24, Add), rhs = Counter(12)
-- expression 22 operands: lhs = Counter(10), rhs = Counter(11)
-- expression 23 operands: lhs = Expression(24, Add), rhs = Counter(12)
-- expression 24 operands: lhs = Counter(10), rhs = Counter(11)
-- expression 25 operands: lhs = Counter(14), rhs = Counter(15)
-- expression 26 operands: lhs = Expression(27, Add), rhs = Counter(16)
-- expression 27 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(5)
+- expression 5 operands: lhs = Counter(0), rhs = Counter(6)
+- expression 6 operands: lhs = Counter(0), rhs = Counter(7)
+- expression 7 operands: lhs = Counter(0), rhs = Counter(8)
 Number of file 0 mappings: 25
 - Code(Counter(0)) at (prev + 1, 1) to (start + 8, 15)
 - Code(Counter(1)) at (prev + 8, 16) to (start + 3, 6)
 - Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 11) to (start + 0, 17)
-- Code(Counter(4)) at (prev + 3, 27) to (start + 0, 29)
-- Code(Expression(8, Add)) at (prev + 1, 14) to (start + 0, 16)
-    = (c2 + c3)
-- Code(Expression(7, Add)) at (prev + 2, 8) to (start + 0, 15)
-    = ((c2 + c3) + c4)
+- Code(Expression(1, Sub)) at (prev + 3, 27) to (start + 0, 29)
+    = (c0 - c2)
+- Code(Counter(2)) at (prev + 1, 14) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 15)
+- Code(Counter(3)) at (prev + 0, 16) to (start + 3, 6)
+- Code(Expression(2, Sub)) at (prev + 3, 5) to (start + 0, 6)
+    = (c0 - c3)
+- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 17)
+- Code(Expression(3, Sub)) at (prev + 1, 27) to (start + 0, 29)
+    = (c0 - c4)
+- Code(Counter(4)) at (prev + 1, 14) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 15)
 - Code(Counter(5)) at (prev + 0, 16) to (start + 3, 6)
 - Code(Expression(4, Sub)) at (prev + 3, 5) to (start + 0, 6)
-    = (((c2 + c3) + c4) - c5)
-- Code(Expression(7, Add)) at (prev + 1, 11) to (start + 0, 17)
-    = ((c2 + c3) + c4)
-- Code(Counter(8)) at (prev + 1, 27) to (start + 0, 29)
-- Code(Expression(16, Add)) at (prev + 1, 14) to (start + 0, 16)
-    = (c6 + c7)
-- Code(Expression(15, Add)) at (prev + 2, 8) to (start + 0, 15)
-    = ((c6 + c7) + c8)
-- Code(Counter(9)) at (prev + 0, 16) to (start + 3, 6)
-- Code(Expression(12, Sub)) at (prev + 3, 5) to (start + 0, 6)
-    = (((c6 + c7) + c8) - c9)
-- Code(Expression(15, Add)) at (prev + 1, 11) to (start + 0, 17)
-    = ((c6 + c7) + c8)
-- Code(Counter(12)) at (prev + 1, 27) to (start + 0, 29)
-- Code(Expression(24, Add)) at (prev + 1, 14) to (start + 0, 16)
-    = (c10 + c11)
-- Code(Expression(23, Add)) at (prev + 2, 8) to (start + 0, 15)
-    = ((c10 + c11) + c12)
-- Code(Counter(13)) at (prev + 0, 16) to (start + 3, 6)
-- Code(Expression(20, Sub)) at (prev + 3, 5) to (start + 0, 6)
-    = (((c10 + c11) + c12) - c13)
-- Code(Expression(23, Add)) at (prev + 1, 11) to (start + 0, 17)
-    = ((c10 + c11) + c12)
-- Code(Counter(16)) at (prev + 1, 27) to (start + 0, 29)
-- Code(Expression(27, Add)) at (prev + 1, 14) to (start + 0, 16)
-    = (c14 + c15)
-- Code(Expression(26, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = ((c14 + c15) + c16)
-Highest counter ID seen: c16
+    = (c0 - c5)
+- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 17)
+- Code(Expression(5, Sub)) at (prev + 1, 27) to (start + 0, 29)
+    = (c0 - c6)
+- Code(Counter(6)) at (prev + 1, 14) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 2, 8) to (start + 0, 15)
+- Code(Counter(7)) at (prev + 0, 16) to (start + 3, 6)
+- Code(Expression(6, Sub)) at (prev + 3, 5) to (start + 0, 6)
+    = (c0 - c7)
+- Code(Counter(0)) at (prev + 1, 11) to (start + 0, 17)
+- Code(Expression(7, Sub)) at (prev + 1, 27) to (start + 0, 29)
+    = (c0 - c8)
+- Code(Counter(8)) at (prev + 1, 14) to (start + 0, 16)
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
+Highest counter ID seen: c8
 
diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map
index 72c7d68840d..a231ac7b4c9 100644
--- a/tests/coverage/mcdc/nested_if.cov-map
+++ b/tests/coverage/mcdc/nested_if.cov-map
@@ -1,207 +1,196 @@
 Function name: nested_if::doubly_nested_if_in_condition
-Raw bytes (168): 0x[01, 01, 0e, 01, 05, 05, 09, 05, 09, 05, 13, 09, 19, 19, 1d, 05, 1f, 09, 1d, 09, 0d, 2b, 05, 01, 15, 33, 05, 37, 15, 01, 11, 14, 01, 0f, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 15, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 21, 02, 00, 00, 00, 15, 00, 36, 0a, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 19, 0e, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1d, 16, 02, 00, 00, 00, 1d, 00, 1e, 1d, 00, 21, 00, 25, 1a, 00, 2f, 00, 34, 23, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 26, 02, 0c, 02, 06, 2e, 03, 01, 00, 02]
+Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 11, 05, 09, 05, 37, 09, 0d, 05, 09, 05, 1f, 09, 15, 15, 19, 05, 2b, 09, 19, 09, 0d, 05, 37, 09, 0d, 01, 11, 14, 01, 0f, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 06, 02, 00, 10, 00, 36, 30, 09, 16, 01, 00, 02, 00, 10, 00, 11, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 36, 16, 00, 18, 00, 19, 28, 03, 02, 00, 18, 00, 1e, 30, 15, 1a, 01, 02, 00, 00, 18, 00, 19, 15, 00, 1d, 00, 1e, 30, 19, 22, 02, 00, 00, 00, 1d, 00, 1e, 19, 00, 21, 00, 25, 26, 00, 2f, 00, 34, 37, 00, 39, 00, 3e, 32, 00, 48, 00, 4c, 11, 00, 4f, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 14
+Number of expressions: 15
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(4)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
-- expression 4 operands: lhs = Counter(2), rhs = Counter(6)
-- expression 5 operands: lhs = Counter(6), rhs = Counter(7)
+- expression 3 operands: lhs = Counter(1), rhs = Expression(13, Add)
+- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 6 operands: lhs = Counter(1), rhs = Expression(7, Add)
-- expression 7 operands: lhs = Counter(2), rhs = Counter(7)
-- expression 8 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 9 operands: lhs = Expression(10, Add), rhs = Counter(1)
-- expression 10 operands: lhs = Counter(0), rhs = Counter(5)
-- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(1)
-- expression 12 operands: lhs = Expression(13, Add), rhs = Counter(5)
-- expression 13 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 7 operands: lhs = Counter(2), rhs = Counter(5)
+- expression 8 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 9 operands: lhs = Counter(1), rhs = Expression(10, Add)
+- expression 10 operands: lhs = Counter(2), rhs = Counter(6)
+- expression 11 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add)
+- expression 13 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 14 operands: lhs = Counter(0), rhs = Counter(4)
 Number of file 0 mappings: 20
 - Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
-- MCDCBranch { true: Counter(4), false: Counter(5), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 78)
+- MCDCBranch { true: Counter(4), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 78)
     true  = c4
-    false = c5
+    false = (c1 - c4)
 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17)
 - MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 54)
-- MCDCBranch { true: Counter(2), false: Expression(2, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17)
+- MCDCBranch { true: Counter(2), false: Expression(5, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17)
     true  = c2
     false = (c1 - c2)
-- MCDCBranch { true: Counter(3), false: Counter(8), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 54)
+- MCDCBranch { true: Counter(3), false: Expression(12, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 54)
     true  = c3
-    false = c8
-- Code(Expression(2, Sub)) at (prev + 0, 24) to (start + 0, 25)
+    false = (c1 - (c2 + c3))
+- Code(Expression(5, Sub)) at (prev + 0, 24) to (start + 0, 25)
     = (c1 - c2)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 24) to (start + 0, 30)
-- MCDCBranch { true: Counter(6), false: Expression(3, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 24) to (start + 0, 25)
+- MCDCBranch { true: Counter(5), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 24) to (start + 0, 25)
+    true  = c5
+    false = (c1 - (c2 + c5))
+- Code(Counter(5)) at (prev + 0, 29) to (start + 0, 30)
+- MCDCBranch { true: Counter(6), false: Expression(8, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 29) to (start + 0, 30)
     true  = c6
-    false = (c1 - (c2 + c6))
-- Code(Counter(6)) at (prev + 0, 29) to (start + 0, 30)
-- MCDCBranch { true: Counter(7), false: Expression(5, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 29) to (start + 0, 30)
-    true  = c7
-    false = (c6 - c7)
-- Code(Counter(7)) at (prev + 0, 33) to (start + 0, 37)
-- Code(Expression(6, Sub)) at (prev + 0, 47) to (start + 0, 52)
-    = (c1 - (c2 + c7))
-- Code(Expression(8, Add)) at (prev + 0, 57) to (start + 0, 62)
+    false = (c5 - c6)
+- Code(Counter(6)) at (prev + 0, 33) to (start + 0, 37)
+- Code(Expression(9, Sub)) at (prev + 0, 47) to (start + 0, 52)
+    = (c1 - (c2 + c6))
+- Code(Expression(13, Add)) at (prev + 0, 57) to (start + 0, 62)
     = (c2 + c3)
-- Code(Counter(8)) at (prev + 0, 72) to (start + 0, 76)
+- Code(Expression(12, Sub)) at (prev + 0, 72) to (start + 0, 76)
+    = (c1 - (c2 + c3))
 - Code(Counter(4)) at (prev + 0, 79) to (start + 2, 6)
-- Code(Expression(9, Sub)) at (prev + 2, 12) to (start + 2, 6)
-    = ((c0 + c5) - c1)
-- Code(Expression(11, Sub)) at (prev + 3, 1) to (start + 0, 2)
-    = (((c0 + c4) + c5) - c1)
-Highest counter ID seen: c8
+- Code(Expression(14, Sub)) at (prev + 2, 12) to (start + 2, 6)
+    = (c0 - c4)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c6
 
 Function name: nested_if::nested_if_in_condition
-Raw bytes (124): 0x[01, 01, 0d, 01, 05, 05, 09, 05, 09, 05, 1f, 09, 0d, 09, 0d, 05, 1f, 09, 0d, 27, 05, 01, 15, 2f, 05, 33, 15, 01, 11, 0e, 01, 07, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 15, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 0a, 00, 15, 00, 16, 30, 0d, 1a, 02, 00, 00, 00, 15, 00, 16, 1f, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 22, 02, 0c, 02, 06, 2a, 03, 01, 00, 02]
+Raw bytes (118): 0x[01, 01, 0a, 01, 05, 05, 11, 05, 09, 05, 09, 05, 23, 09, 0d, 09, 0d, 05, 23, 09, 0d, 01, 11, 0e, 01, 07, 01, 01, 09, 28, 06, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 11, 06, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 1e, 02, 00, 00, 00, 15, 00, 16, 23, 00, 19, 00, 1d, 1e, 00, 27, 00, 2c, 11, 00, 2f, 02, 06, 26, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 13
+Number of expressions: 10
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(4)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(1), rhs = Expression(7, Add)
-- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 4 operands: lhs = Counter(1), rhs = Expression(8, Add)
 - expression 5 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 6 operands: lhs = Counter(1), rhs = Expression(7, Add)
-- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(1)
-- expression 9 operands: lhs = Counter(0), rhs = Counter(5)
-- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(1)
-- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(5)
-- expression 12 operands: lhs = Counter(0), rhs = Counter(4)
+- expression 6 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 7 operands: lhs = Counter(1), rhs = Expression(8, Add)
+- expression 8 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 9 operands: lhs = Counter(0), rhs = Counter(4)
 Number of file 0 mappings: 14
 - Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
-- MCDCBranch { true: Counter(4), false: Counter(5), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 46)
+- MCDCBranch { true: Counter(4), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 46)
     true  = c4
-    false = c5
+    false = (c1 - c4)
 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22)
-- MCDCBranch { true: Counter(2), false: Expression(2, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17)
+- MCDCBranch { true: Counter(2), false: Expression(3, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17)
     true  = c2
     false = (c1 - c2)
-- Code(Expression(2, Sub)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Expression(3, Sub)) at (prev + 0, 21) to (start + 0, 22)
     = (c1 - c2)
-- MCDCBranch { true: Counter(3), false: Expression(6, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22)
+- MCDCBranch { true: Counter(3), false: Expression(7, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22)
     true  = c3
     false = (c1 - (c2 + c3))
-- Code(Expression(7, Add)) at (prev + 0, 25) to (start + 0, 29)
+- Code(Expression(8, Add)) at (prev + 0, 25) to (start + 0, 29)
     = (c2 + c3)
-- Code(Expression(6, Sub)) at (prev + 0, 39) to (start + 0, 44)
+- Code(Expression(7, Sub)) at (prev + 0, 39) to (start + 0, 44)
     = (c1 - (c2 + c3))
 - Code(Counter(4)) at (prev + 0, 47) to (start + 2, 6)
-- Code(Expression(8, Sub)) at (prev + 2, 12) to (start + 2, 6)
-    = ((c0 + c5) - c1)
-- Code(Expression(10, Sub)) at (prev + 3, 1) to (start + 0, 2)
-    = (((c0 + c4) + c5) - c1)
-Highest counter ID seen: c5
+- Code(Expression(9, Sub)) at (prev + 2, 12) to (start + 2, 6)
+    = (c0 - c4)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c4
 
 Function name: nested_if::nested_in_then_block_in_condition
-Raw bytes (176): 0x[01, 01, 12, 01, 05, 05, 09, 05, 09, 05, 33, 09, 0d, 09, 0d, 33, 11, 09, 0d, 11, 15, 33, 15, 09, 0d, 05, 33, 09, 0d, 3b, 05, 01, 1d, 43, 05, 47, 1d, 01, 19, 14, 01, 22, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 1d, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0a, 01, 00, 02, 00, 10, 00, 11, 0a, 00, 15, 00, 16, 30, 0d, 2e, 02, 00, 00, 00, 15, 00, 16, 33, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1a, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 22, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 26, 00, 33, 00, 38, 2e, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 36, 02, 0c, 02, 06, 3e, 03, 01, 00, 02]
+Raw bytes (170): 0x[01, 01, 0f, 01, 05, 05, 19, 05, 09, 05, 09, 05, 37, 09, 0d, 09, 0d, 37, 11, 09, 0d, 11, 15, 37, 15, 09, 0d, 05, 37, 09, 0d, 01, 19, 14, 01, 22, 01, 01, 09, 28, 09, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 19, 06, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 03, 02, 00, 10, 00, 16, 30, 09, 0e, 01, 00, 02, 00, 10, 00, 11, 0e, 00, 15, 00, 16, 30, 0d, 32, 02, 00, 00, 00, 15, 00, 16, 37, 00, 1c, 00, 1d, 28, 06, 02, 00, 1c, 00, 22, 30, 11, 1e, 01, 02, 00, 00, 1c, 00, 1d, 11, 00, 21, 00, 22, 30, 15, 26, 02, 00, 00, 00, 21, 00, 22, 15, 00, 25, 00, 29, 2a, 00, 33, 00, 38, 32, 00, 44, 00, 49, 19, 00, 4c, 02, 06, 3a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 18
+Number of expressions: 15
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(6)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(1), rhs = Expression(12, Add)
-- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 4 operands: lhs = Counter(1), rhs = Expression(13, Add)
 - expression 5 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 6 operands: lhs = Expression(12, Add), rhs = Counter(4)
-- expression 7 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 8 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 9 operands: lhs = Expression(12, Add), rhs = Counter(5)
-- expression 10 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 11 operands: lhs = Counter(1), rhs = Expression(12, Add)
-- expression 12 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(1)
-- expression 14 operands: lhs = Counter(0), rhs = Counter(7)
-- expression 15 operands: lhs = Expression(16, Add), rhs = Counter(1)
-- expression 16 operands: lhs = Expression(17, Add), rhs = Counter(7)
-- expression 17 operands: lhs = Counter(0), rhs = Counter(6)
+- expression 6 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 7 operands: lhs = Expression(13, Add), rhs = Counter(4)
+- expression 8 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 9 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 10 operands: lhs = Expression(13, Add), rhs = Counter(5)
+- expression 11 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 12 operands: lhs = Counter(1), rhs = Expression(13, Add)
+- expression 13 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 14 operands: lhs = Counter(0), rhs = Counter(6)
 Number of file 0 mappings: 20
 - Code(Counter(0)) at (prev + 34, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 9, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
-- MCDCBranch { true: Counter(6), false: Counter(7), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 75)
+- MCDCBranch { true: Counter(6), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 75)
     true  = c6
-    false = c7
+    false = (c1 - c6)
 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 0, 16) to (start + 0, 22)
-- MCDCBranch { true: Counter(2), false: Expression(2, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17)
+- MCDCBranch { true: Counter(2), false: Expression(3, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 16) to (start + 0, 17)
     true  = c2
     false = (c1 - c2)
-- Code(Expression(2, Sub)) at (prev + 0, 21) to (start + 0, 22)
+- Code(Expression(3, Sub)) at (prev + 0, 21) to (start + 0, 22)
     = (c1 - c2)
-- MCDCBranch { true: Counter(3), false: Expression(11, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22)
+- MCDCBranch { true: Counter(3), false: Expression(12, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 21) to (start + 0, 22)
     true  = c3
     false = (c1 - (c2 + c3))
-- Code(Expression(12, Add)) at (prev + 0, 28) to (start + 0, 29)
+- Code(Expression(13, Add)) at (prev + 0, 28) to (start + 0, 29)
     = (c2 + c3)
 - MCDCDecision { bitmap_idx: 6, conditions_num: 2 } at (prev + 0, 28) to (start + 0, 34)
-- MCDCBranch { true: Counter(4), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29)
+- MCDCBranch { true: Counter(4), false: Expression(7, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 28) to (start + 0, 29)
     true  = c4
     false = ((c2 + c3) - c4)
 - Code(Counter(4)) at (prev + 0, 33) to (start + 0, 34)
-- MCDCBranch { true: Counter(5), false: Expression(8, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34)
+- MCDCBranch { true: Counter(5), false: Expression(9, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 33) to (start + 0, 34)
     true  = c5
     false = (c4 - c5)
 - Code(Counter(5)) at (prev + 0, 37) to (start + 0, 41)
-- Code(Expression(9, Sub)) at (prev + 0, 51) to (start + 0, 56)
+- Code(Expression(10, Sub)) at (prev + 0, 51) to (start + 0, 56)
     = ((c2 + c3) - c5)
-- Code(Expression(11, Sub)) at (prev + 0, 68) to (start + 0, 73)
+- Code(Expression(12, Sub)) at (prev + 0, 68) to (start + 0, 73)
     = (c1 - (c2 + c3))
 - Code(Counter(6)) at (prev + 0, 76) to (start + 2, 6)
-- Code(Expression(13, Sub)) at (prev + 2, 12) to (start + 2, 6)
-    = ((c0 + c7) - c1)
-- Code(Expression(15, Sub)) at (prev + 3, 1) to (start + 0, 2)
-    = (((c0 + c6) + c7) - c1)
-Highest counter ID seen: c7
+- Code(Expression(14, Sub)) at (prev + 2, 12) to (start + 2, 6)
+    = (c0 - c6)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c6
 
 Function name: nested_if::nested_single_condition_decision
-Raw bytes (89): 0x[01, 01, 08, 01, 05, 05, 09, 05, 09, 13, 05, 01, 11, 1b, 05, 1f, 11, 01, 0d, 0b, 01, 17, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 11, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0a, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 0e, 02, 0c, 02, 06, 16, 03, 01, 00, 02]
+Raw bytes (83): 0x[01, 01, 05, 01, 05, 05, 0d, 05, 09, 05, 09, 01, 0d, 0b, 01, 17, 01, 04, 09, 28, 03, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 06, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 09, 0e, 00, 10, 00, 11, 09, 00, 14, 00, 19, 0e, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 12, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 8
+Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(3)
 - expression 2 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(1)
-- expression 4 operands: lhs = Counter(0), rhs = Counter(4)
-- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(1)
-- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4)
-- expression 7 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
 Number of file 0 mappings: 11
 - Code(Counter(0)) at (prev + 23, 1) to (start + 4, 9)
 - MCDCDecision { bitmap_idx: 3, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
-- MCDCBranch { true: Counter(3), false: Counter(4), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 41)
+- MCDCBranch { true: Counter(3), false: Expression(1, Sub), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 41)
     true  = c3
-    false = c4
+    false = (c1 - c3)
 - Code(Counter(1)) at (prev + 0, 16) to (start + 0, 17)
-- Branch { true: Counter(2), false: Expression(2, Sub) } at (prev + 0, 16) to (start + 0, 17)
+- Branch { true: Counter(2), false: Expression(3, Sub) } at (prev + 0, 16) to (start + 0, 17)
     true  = c2
     false = (c1 - c2)
 - Code(Counter(2)) at (prev + 0, 20) to (start + 0, 25)
-- Code(Expression(2, Sub)) at (prev + 0, 35) to (start + 0, 39)
+- Code(Expression(3, Sub)) at (prev + 0, 35) to (start + 0, 39)
     = (c1 - c2)
 - Code(Counter(3)) at (prev + 0, 42) to (start + 2, 6)
-- Code(Expression(3, Sub)) at (prev + 2, 12) to (start + 2, 6)
-    = ((c0 + c4) - c1)
-- Code(Expression(5, Sub)) at (prev + 3, 1) to (start + 0, 2)
-    = (((c0 + c3) + c4) - c1)
-Highest counter ID seen: c4
+- Code(Expression(4, Sub)) at (prev + 2, 12) to (start + 2, 6)
+    = (c0 - c3)
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c3
 
diff --git a/tests/coverage/nested_loops.cov-map b/tests/coverage/nested_loops.cov-map
index 6ba5887d243..e9e41bd53e7 100644
--- a/tests/coverage/nested_loops.cov-map
+++ b/tests/coverage/nested_loops.cov-map
@@ -1,46 +1,41 @@
 Function name: nested_loops::main
-Raw bytes (103): 0x[01, 01, 11, 27, 09, 01, 05, 03, 0d, 13, 0d, 17, 15, 03, 11, 1f, 0d, 23, 15, 27, 11, 01, 05, 2f, 0d, 3b, 15, 01, 11, 3b, 0d, 01, 11, 05, 09, 0d, 19, 0d, 01, 01, 01, 02, 1b, 03, 04, 13, 00, 20, 0a, 01, 0d, 01, 18, 0e, 02, 12, 00, 17, 1a, 01, 10, 00, 16, 05, 01, 11, 00, 16, 2a, 01, 0e, 03, 16, 36, 04, 11, 01, 1b, 19, 02, 15, 00, 21, 11, 01, 18, 02, 12, 15, 03, 0d, 00, 0e, 3f, 02, 09, 00, 17, 43, 02, 01, 00, 02]
+Raw bytes (97): 0x[01, 01, 0e, 07, 2f, 05, 11, 01, 0d, 2f, 05, 01, 0d, 27, 05, 01, 09, 33, 27, 05, 15, 01, 09, 2f, 33, 01, 0d, 05, 15, 05, 01, 0d, 01, 01, 01, 02, 1b, 05, 04, 13, 00, 20, 09, 01, 0d, 01, 18, 0d, 02, 12, 00, 17, 11, 01, 10, 00, 16, 02, 01, 11, 00, 16, 0e, 01, 0e, 03, 16, 15, 04, 11, 01, 1b, 16, 02, 15, 00, 21, 1e, 01, 18, 02, 12, 2a, 03, 0d, 00, 0e, 36, 02, 09, 00, 17, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 17
-- expression 0 operands: lhs = Expression(9, Add), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(3)
-- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(5)
-- expression 5 operands: lhs = Expression(0, Add), rhs = Counter(4)
-- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(3)
-- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(5)
-- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(4)
-- expression 9 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(3)
-- expression 11 operands: lhs = Expression(14, Add), rhs = Counter(5)
-- expression 12 operands: lhs = Counter(0), rhs = Counter(4)
-- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(3)
-- expression 14 operands: lhs = Counter(0), rhs = Counter(4)
-- expression 15 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 16 operands: lhs = Counter(3), rhs = Counter(6)
+Number of expressions: 14
+- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(11, Add)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(4)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 3 operands: lhs = Expression(11, Add), rhs = Counter(1)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(1)
+- expression 6 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 7 operands: lhs = Expression(12, Add), rhs = Expression(9, Add)
+- expression 8 operands: lhs = Counter(1), rhs = Counter(5)
+- expression 9 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 10 operands: lhs = Expression(11, Add), rhs = Expression(12, Add)
+- expression 11 operands: lhs = Counter(0), rhs = Counter(3)
+- expression 12 operands: lhs = Counter(1), rhs = Counter(5)
+- expression 13 operands: lhs = Counter(1), rhs = Counter(0)
 Number of file 0 mappings: 13
 - Code(Counter(0)) at (prev + 1, 1) to (start + 2, 27)
-- Code(Expression(0, Add)) at (prev + 4, 19) to (start + 0, 32)
-    = ((c0 + c1) + c2)
-- Code(Expression(2, Sub)) at (prev + 1, 13) to (start + 1, 24)
-    = (((c0 + c1) + c2) - c3)
-- Code(Expression(3, Sub)) at (prev + 2, 18) to (start + 0, 23)
-    = (((((c0 + c1) + c2) + c4) + c5) - c3)
-- Code(Expression(6, Sub)) at (prev + 1, 16) to (start + 0, 22)
-    = ((((c0 + c1) + c4) + c5) - c3)
-- Code(Counter(1)) at (prev + 1, 17) to (start + 0, 22)
-- Code(Expression(10, Sub)) at (prev + 1, 14) to (start + 3, 22)
-    = (((c0 + c4) + c5) - c3)
-- Code(Expression(13, Sub)) at (prev + 4, 17) to (start + 1, 27)
-    = ((c0 + c4) - c3)
-- Code(Counter(6)) at (prev + 2, 21) to (start + 0, 33)
-- Code(Counter(4)) at (prev + 1, 24) to (start + 2, 18)
-- Code(Counter(5)) at (prev + 3, 13) to (start + 0, 14)
-- Code(Expression(15, Add)) at (prev + 2, 9) to (start + 0, 23)
-    = (c1 + c2)
-- Code(Expression(16, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = (c3 + c6)
-Highest counter ID seen: c6
+- Code(Counter(1)) at (prev + 4, 19) to (start + 0, 32)
+- Code(Counter(2)) at (prev + 1, 13) to (start + 1, 24)
+- Code(Counter(3)) at (prev + 2, 18) to (start + 0, 23)
+- Code(Counter(4)) at (prev + 1, 16) to (start + 0, 22)
+- Code(Expression(0, Sub)) at (prev + 1, 17) to (start + 0, 22)
+    = ((c1 + c4) - (c0 + c3))
+- Code(Expression(3, Sub)) at (prev + 1, 14) to (start + 3, 22)
+    = ((c0 + c3) - c1)
+- Code(Counter(5)) at (prev + 4, 17) to (start + 1, 27)
+- Code(Expression(5, Sub)) at (prev + 2, 21) to (start + 0, 33)
+    = ((c0 + c2) - c1)
+- Code(Expression(7, Sub)) at (prev + 1, 24) to (start + 2, 18)
+    = ((c1 + c5) - (c0 + c2))
+- Code(Expression(10, Sub)) at (prev + 3, 13) to (start + 0, 14)
+    = ((c0 + c3) - (c1 + c5))
+- Code(Expression(13, Sub)) at (prev + 2, 9) to (start + 0, 23)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
+Highest counter ID seen: c5
 
diff --git a/tests/coverage/overflow.cov-map b/tests/coverage/overflow.cov-map
index 01abcc15003..1178d65de10 100644
--- a/tests/coverage/overflow.cov-map
+++ b/tests/coverage/overflow.cov-map
@@ -1,32 +1,29 @@
 Function name: overflow::main
-Raw bytes (67): 0x[01, 01, 09, 07, 0d, 0b, 09, 01, 05, 03, 11, 17, 11, 1b, 0d, 01, 09, 23, 0d, 05, 09, 09, 01, 10, 01, 01, 1b, 03, 02, 0b, 00, 18, 0e, 01, 0c, 00, 1a, 05, 00, 1b, 03, 0a, 12, 03, 13, 00, 20, 09, 00, 21, 03, 0a, 0d, 03, 09, 00, 0a, 1f, 01, 09, 00, 17, 11, 02, 05, 01, 02]
+Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 10, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 03, 0a, 06, 03, 13, 00, 20, 0d, 00, 21, 03, 0a, 0e, 03, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 9
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
-- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(2)
-- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 3 operands: lhs = Expression(0, Add), rhs = Counter(4)
-- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(4)
-- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(3)
-- expression 6 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(3)
-- expression 8 operands: lhs = Counter(1), rhs = Counter(2)
+Number of expressions: 6
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
+- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
+- expression 5 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 16, 1) to (start + 1, 27)
-- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
-    = (((c0 + c1) + c2) + c3)
-- Code(Expression(3, Sub)) at (prev + 1, 12) to (start + 0, 26)
-    = ((((c0 + c1) + c2) + c3) - c4)
-- Code(Counter(1)) at (prev + 0, 27) to (start + 3, 10)
-- Code(Expression(4, Sub)) at (prev + 3, 19) to (start + 0, 32)
-    = (((c0 + c2) + c3) - c4)
-- Code(Counter(2)) at (prev + 0, 33) to (start + 3, 10)
-- Code(Counter(3)) at (prev + 3, 9) to (start + 0, 10)
-- Code(Expression(7, Add)) at (prev + 1, 9) to (start + 0, 23)
-    = ((c1 + c2) + c3)
-- Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2)
-Highest counter ID seen: c4
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26)
+    = (c1 - c0)
+- Code(Counter(2)) at (prev + 0, 27) to (start + 3, 10)
+- Code(Expression(1, Sub)) at (prev + 3, 19) to (start + 0, 32)
+    = (c1 - (c0 + c2))
+- Code(Counter(3)) at (prev + 0, 33) to (start + 3, 10)
+- Code(Expression(3, Sub)) at (prev + 3, 9) to (start + 0, 10)
+    = (c1 - ((c0 + c2) + c3))
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+Highest counter ID seen: c3
 
 Function name: overflow::might_overflow
 Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 12, 05, 01, 13, 02, 06, 02, 02, 05, 00, 06, 01, 01, 09, 05, 02]
diff --git a/tests/coverage/overflow.coverage b/tests/coverage/overflow.coverage
index 9057c244ccf..bd3d436f458 100644
--- a/tests/coverage/overflow.coverage
+++ b/tests/coverage/overflow.coverage
@@ -15,18 +15,18 @@
    LL|       |
    LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let mut countdown = 10;
-   LL|     11|    while countdown > 0 {
-   LL|     11|        if countdown == 1 {
+   LL|     10|    while countdown > 0 {
+   LL|      9|        if countdown == 1 {
    LL|      1|            let result = might_overflow(10);
    LL|      1|            println!("Result: {}", result);
-   LL|     10|        } else if countdown < 5 {
+   LL|      8|        } else if countdown < 5 {
    LL|      3|            let result = might_overflow(1);
    LL|      3|            println!("Result: {}", result);
-   LL|      6|        }
-   LL|     10|        countdown -= 1;
+   LL|      5|        }
+   LL|      9|        countdown -= 1;
    LL|       |    }
-   LL|      0|    Ok(())
-   LL|      0|}
+   LL|      1|    Ok(())
+   LL|      1|}
    LL|       |
    LL|       |// Notes:
    LL|       |//   1. Compare this program and its coverage results to those of the very similar test `assert.rs`,
diff --git a/tests/coverage/panic_unwind.cov-map b/tests/coverage/panic_unwind.cov-map
index 005c4babbea..4628a24689e 100644
--- a/tests/coverage/panic_unwind.cov-map
+++ b/tests/coverage/panic_unwind.cov-map
@@ -1,32 +1,29 @@
 Function name: panic_unwind::main
-Raw bytes (67): 0x[01, 01, 09, 07, 0d, 0b, 09, 01, 05, 03, 11, 17, 11, 1b, 0d, 01, 09, 23, 0d, 05, 09, 09, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 0e, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 09, 00, 0a, 1f, 01, 09, 00, 17, 11, 02, 05, 01, 02]
+Raw bytes (61): 0x[01, 01, 06, 05, 01, 05, 17, 01, 09, 05, 13, 17, 0d, 01, 09, 09, 01, 0d, 01, 01, 1b, 05, 02, 0b, 00, 18, 02, 01, 0c, 00, 1a, 09, 00, 1b, 02, 0a, 06, 02, 13, 00, 20, 0d, 00, 21, 02, 0a, 0e, 02, 09, 00, 0a, 02, 01, 09, 00, 17, 01, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 9
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
-- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(2)
-- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 3 operands: lhs = Expression(0, Add), rhs = Counter(4)
-- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(4)
-- expression 5 operands: lhs = Expression(6, Add), rhs = Counter(3)
-- expression 6 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(3)
-- expression 8 operands: lhs = Counter(1), rhs = Counter(2)
+Number of expressions: 6
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(5, Add)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
+- expression 4 operands: lhs = Expression(5, Add), rhs = Counter(3)
+- expression 5 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 13, 1) to (start + 1, 27)
-- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 24)
-    = (((c0 + c1) + c2) + c3)
-- Code(Expression(3, Sub)) at (prev + 1, 12) to (start + 0, 26)
-    = ((((c0 + c1) + c2) + c3) - c4)
-- Code(Counter(1)) at (prev + 0, 27) to (start + 2, 10)
-- Code(Expression(4, Sub)) at (prev + 2, 19) to (start + 0, 32)
-    = (((c0 + c2) + c3) - c4)
-- Code(Counter(2)) at (prev + 0, 33) to (start + 2, 10)
-- Code(Counter(3)) at (prev + 2, 9) to (start + 0, 10)
-- Code(Expression(7, Add)) at (prev + 1, 9) to (start + 0, 23)
-    = ((c1 + c2) + c3)
-- Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2)
-Highest counter ID seen: c4
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 24)
+- Code(Expression(0, Sub)) at (prev + 1, 12) to (start + 0, 26)
+    = (c1 - c0)
+- Code(Counter(2)) at (prev + 0, 27) to (start + 2, 10)
+- Code(Expression(1, Sub)) at (prev + 2, 19) to (start + 0, 32)
+    = (c1 - (c0 + c2))
+- Code(Counter(3)) at (prev + 0, 33) to (start + 2, 10)
+- Code(Expression(3, Sub)) at (prev + 2, 9) to (start + 0, 10)
+    = (c1 - ((c0 + c2) + c3))
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 23)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 2, 5) to (start + 1, 2)
+Highest counter ID seen: c3
 
 Function name: panic_unwind::might_panic
 Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 01, 14, 05, 02, 09, 01, 19, 02, 02, 0c, 03, 02]
diff --git a/tests/coverage/panic_unwind.coverage b/tests/coverage/panic_unwind.coverage
index eaf96cb0289..a80ab6d16b0 100644
--- a/tests/coverage/panic_unwind.coverage
+++ b/tests/coverage/panic_unwind.coverage
@@ -12,16 +12,16 @@
    LL|       |
    LL|      1|fn main() -> Result<(), u8> {
    LL|      1|    let mut countdown = 10;
-   LL|     11|    while countdown > 0 {
-   LL|     11|        if countdown == 1 {
+   LL|     10|    while countdown > 0 {
+   LL|      9|        if countdown == 1 {
    LL|      1|            might_panic(true);
-   LL|     10|        } else if countdown < 5 {
+   LL|      8|        } else if countdown < 5 {
    LL|      3|            might_panic(false);
-   LL|      6|        }
-   LL|     10|        countdown -= 1;
+   LL|      5|        }
+   LL|      9|        countdown -= 1;
    LL|       |    }
-   LL|      0|    Ok(())
-   LL|      0|}
+   LL|      1|    Ok(())
+   LL|      1|}
    LL|       |
    LL|       |// Notes:
    LL|       |//   1. Compare this program and its coverage results to those of the similar tests `abort.rs` and
diff --git a/tests/coverage/simple_loop.cov-map b/tests/coverage/simple_loop.cov-map
index d1e684efbbc..8e428b267d5 100644
--- a/tests/coverage/simple_loop.cov-map
+++ b/tests/coverage/simple_loop.cov-map
@@ -1,19 +1,19 @@
 Function name: simple_loop::main
-Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 04, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 05, 00, 06, 07, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 09, 02, 0a, 03, 0a, 01, 06, 01, 00, 02]
+Raw bytes (43): 0x[01, 01, 02, 01, 05, 09, 01, 07, 01, 04, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 05, 00, 06, 09, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 06, 02, 0a, 03, 0a, 01, 06, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(2), rhs = Counter(0)
 Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 4, 1) to (start + 9, 16)
 - Code(Counter(1)) at (prev + 10, 5) to (start + 5, 6)
 - Code(Expression(0, Sub)) at (prev + 5, 5) to (start + 0, 6)
     = (c0 - c1)
-- Code(Expression(1, Add)) at (prev + 5, 13) to (start + 2, 14)
-    = (c0 + c2)
+- Code(Counter(2)) at (prev + 5, 13) to (start + 2, 14)
 - Code(Counter(0)) at (prev + 4, 13) to (start + 0, 18)
-- Code(Counter(2)) at (prev + 2, 10) to (start + 3, 10)
+- Code(Expression(1, Sub)) at (prev + 2, 10) to (start + 3, 10)
+    = (c2 - c0)
 - Code(Counter(0)) at (prev + 6, 1) to (start + 0, 2)
 Highest counter ID seen: c2
 
diff --git a/tests/coverage/simple_match.cov-map b/tests/coverage/simple_match.cov-map
index 8f973742959..15f114daa7f 100644
--- a/tests/coverage/simple_match.cov-map
+++ b/tests/coverage/simple_match.cov-map
@@ -1,31 +1,27 @@
 Function name: simple_match::main
-Raw bytes (72): 0x[01, 01, 09, 01, 05, 23, 0d, 01, 09, 1f, 11, 23, 0d, 01, 09, 1f, 11, 23, 0d, 01, 09, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 1f, 05, 09, 00, 0d, 1a, 05, 0d, 00, 16, 09, 02, 0d, 00, 0e, 1a, 02, 11, 02, 12, 09, 04, 0d, 07, 0e, 0d, 0a, 0d, 00, 0f, 11, 03, 01, 00, 02]
+Raw bytes (64): 0x[01, 01, 05, 01, 05, 09, 01, 09, 01, 09, 13, 01, 0d, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 09, 05, 09, 00, 0d, 0a, 05, 0d, 00, 16, 0d, 02, 0d, 00, 0e, 0a, 02, 11, 02, 12, 0d, 04, 0d, 07, 0e, 0e, 0a, 0d, 00, 0f, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 9
+Number of expressions: 5
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Expression(8, Add), rhs = Counter(3)
-- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 3 operands: lhs = Expression(7, Add), rhs = Counter(4)
-- expression 4 operands: lhs = Expression(8, Add), rhs = Counter(3)
-- expression 5 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(4)
-- expression 7 operands: lhs = Expression(8, Add), rhs = Counter(3)
-- expression 8 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(2), rhs = Counter(0)
+- expression 2 operands: lhs = Counter(2), rhs = Counter(0)
+- expression 3 operands: lhs = Counter(2), rhs = Expression(4, Add)
+- expression 4 operands: lhs = Counter(0), rhs = Counter(3)
 Number of file 0 mappings: 10
 - Code(Counter(0)) at (prev + 4, 1) to (start + 7, 15)
 - Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6)
 - Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
-- Code(Expression(7, Add)) at (prev + 5, 9) to (start + 0, 13)
-    = ((c0 + c2) + c3)
-- Code(Expression(6, Sub)) at (prev + 5, 13) to (start + 0, 22)
-    = (((c0 + c2) + c3) - c4)
-- Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14)
-- Code(Expression(6, Sub)) at (prev + 2, 17) to (start + 2, 18)
-    = (((c0 + c2) + c3) - c4)
-- Code(Counter(2)) at (prev + 4, 13) to (start + 7, 14)
-- Code(Counter(3)) at (prev + 10, 13) to (start + 0, 15)
-- Code(Counter(4)) at (prev + 3, 1) to (start + 0, 2)
-Highest counter ID seen: c4
+- Code(Counter(2)) at (prev + 5, 9) to (start + 0, 13)
+- Code(Expression(2, Sub)) at (prev + 5, 13) to (start + 0, 22)
+    = (c2 - c0)
+- Code(Counter(3)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Expression(2, Sub)) at (prev + 2, 17) to (start + 2, 18)
+    = (c2 - c0)
+- Code(Counter(3)) at (prev + 4, 13) to (start + 7, 14)
+- Code(Expression(3, Sub)) at (prev + 10, 13) to (start + 0, 15)
+    = (c2 - (c0 + c3))
+- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
+Highest counter ID seen: c3
 
diff --git a/tests/coverage/try_error_result.cov-map b/tests/coverage/try_error_result.cov-map
index f90b73592bd..03012f744c1 100644
--- a/tests/coverage/try_error_result.cov-map
+++ b/tests/coverage/try_error_result.cov-map
@@ -55,158 +55,148 @@ Number of file 0 mappings: 4
 Highest counter ID seen: c1
 
 Function name: try_error_result::test1
-Raw bytes (69): 0x[01, 01, 05, 07, 09, 01, 00, 03, 0d, 03, 13, 0d, 11, 0b, 01, 0d, 01, 02, 17, 03, 07, 09, 00, 0e, 0a, 02, 09, 04, 1a, 11, 06, 0d, 00, 29, 15, 00, 29, 00, 2a, 00, 01, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0e, 04, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 0d, 03, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (63): 0x[01, 01, 02, 09, 0d, 05, 09, 0b, 01, 0d, 01, 02, 17, 05, 07, 09, 00, 0e, 09, 02, 09, 04, 1a, 0d, 06, 0d, 00, 29, 11, 00, 29, 00, 2a, 00, 01, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 02, 04, 0d, 00, 2a, 00, 00, 2a, 00, 2b, 06, 03, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(0), rhs = Zero
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 3 operands: lhs = Expression(0, Add), rhs = Expression(4, Add)
-- expression 4 operands: lhs = Counter(3), rhs = Counter(4)
+Number of expressions: 2
+- expression 0 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 11
 - Code(Counter(0)) at (prev + 13, 1) to (start + 2, 23)
-- Code(Expression(0, Add)) at (prev + 7, 9) to (start + 0, 14)
-    = ((c0 + Zero) + c2)
-- Code(Expression(2, Sub)) at (prev + 2, 9) to (start + 4, 26)
-    = (((c0 + Zero) + c2) - c3)
-- Code(Counter(4)) at (prev + 6, 13) to (start + 0, 41)
-- Code(Counter(5)) at (prev + 0, 41) to (start + 0, 42)
+- Code(Counter(1)) at (prev + 7, 9) to (start + 0, 14)
+- Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26)
+- Code(Counter(3)) at (prev + 6, 13) to (start + 0, 41)
+- Code(Counter(4)) at (prev + 0, 41) to (start + 0, 42)
 - Code(Zero) at (prev + 1, 13) to (start + 0, 42)
 - Code(Zero) at (prev + 0, 42) to (start + 0, 43)
-- Code(Expression(3, Sub)) at (prev + 4, 13) to (start + 0, 42)
-    = (((c0 + Zero) + c2) - (c3 + c4))
+- Code(Expression(0, Sub)) at (prev + 4, 13) to (start + 0, 42)
+    = (c2 - c3)
 - Code(Zero) at (prev + 0, 42) to (start + 0, 43)
-- Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11)
+- Code(Expression(1, Sub)) at (prev + 3, 5) to (start + 0, 11)
+    = (c1 - c2)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
-Highest counter ID seen: c5
+Highest counter ID seen: c4
 
 Function name: try_error_result::test2
-Raw bytes (355): 0x[01, 01, 3b, 07, 09, 01, 05, 03, 0d, 11, 15, 11, 4b, 15, 19, 11, 43, 47, 21, 4b, 1d, 15, 19, 11, 4b, 15, 19, 11, 47, 4b, 1d, 15, 19, 11, 43, 47, 21, 4b, 1d, 15, 19, 45, 5f, 25, 29, 45, 25, 45, 5f, 25, 29, 03, 8b, 01, 8f, 01, 31, 93, 01, 2d, 0d, 11, 03, 93, 01, 0d, 11, 03, 8f, 01, 93, 01, 2d, 0d, 11, 03, 8b, 01, 8f, 01, 31, 93, 01, 2d, 0d, 11, 49, a7, 01, 35, 39, 49, 35, 49, a7, 01, 35, 39, 4d, bb, 01, 3d, 41, 4d, 3d, 4d, bb, 01, 3d, 41, c3, 01, 41, c7, 01, 3d, cb, 01, 39, cf, 01, 35, d3, 01, 31, d7, 01, 2d, db, 01, 29, df, 01, 25, e3, 01, 21, e7, 01, 1d, eb, 01, 19, 0d, 15, 28, 01, 3d, 01, 03, 17, 03, 08, 09, 00, 0e, 0a, 02, 09, 04, 1a, 11, 06, 0d, 00, 2f, 15, 00, 2f, 00, 30, 0e, 00, 31, 03, 35, 19, 04, 11, 00, 12, 2a, 02, 11, 04, 12, 3e, 05, 11, 00, 14, 2a, 00, 17, 00, 41, 1d, 00, 41, 00, 42, 32, 00, 43, 00, 5f, 21, 00, 5f, 00, 60, 3e, 01, 0d, 00, 20, 5a, 01, 11, 00, 14, 45, 00, 17, 00, 41, 25, 00, 41, 00, 42, 56, 00, 43, 00, 60, 29, 00, 60, 00, 61, 5a, 01, 0d, 00, 20, 86, 01, 04, 11, 00, 14, 72, 00, 17, 00, 42, 2d, 00, 42, 00, 43, 7a, 00, 44, 00, 61, 31, 00, 61, 00, 62, 86, 01, 01, 0d, 00, 20, a2, 01, 01, 11, 00, 14, 49, 00, 17, 01, 36, 35, 01, 36, 00, 37, 9e, 01, 01, 12, 00, 2f, 39, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 3d, 02, 11, 00, 12, b2, 01, 01, 12, 00, 2f, 41, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, bf, 01, 01, 01, 00, 02]
+Raw bytes (336): 0x[01, 01, 36, 0d, 11, 0d, 3f, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 0d, 3f, 11, 15, 0d, 3b, 3f, 19, 11, 15, 0d, 37, 3b, 1d, 3f, 19, 11, 15, 41, 53, 21, 25, 41, 21, 41, 53, 21, 25, 09, 73, 77, 2d, 0d, 29, 09, 0d, 09, 77, 0d, 29, 09, 73, 77, 2d, 0d, 29, 45, 8b, 01, 31, 35, 45, 31, 45, 8b, 01, 31, 35, 49, 9f, 01, 39, 3d, 49, 39, 49, 9f, 01, 39, 3d, 05, 09, ab, 01, 09, af, 01, 3d, b3, 01, 39, b7, 01, 35, bb, 01, 31, bf, 01, 2d, c3, 01, 29, c7, 01, 25, cb, 01, 21, cf, 01, 1d, d3, 01, 19, d7, 01, 15, 05, 11, 28, 01, 3d, 01, 03, 17, 05, 08, 09, 00, 0e, 09, 02, 09, 04, 1a, 0d, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 02, 00, 31, 03, 35, 15, 04, 11, 00, 12, 1e, 02, 11, 04, 12, 32, 05, 11, 00, 14, 1e, 00, 17, 00, 41, 19, 00, 41, 00, 42, 26, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 32, 01, 0d, 00, 20, 4e, 01, 11, 00, 14, 41, 00, 17, 00, 41, 21, 00, 41, 00, 42, 4a, 00, 43, 00, 60, 25, 00, 60, 00, 61, 4e, 01, 0d, 00, 20, 6e, 04, 11, 00, 14, 62, 00, 17, 00, 42, 29, 00, 42, 00, 43, 66, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 6e, 01, 0d, 00, 20, 86, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, 82, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, 86, 01, 01, 0d, 00, 20, 9a, 01, 01, 11, 00, 14, 49, 00, 17, 01, 36, 39, 02, 11, 00, 12, 96, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, 9a, 01, 02, 0d, 00, 20, a2, 01, 03, 05, 00, 0b, a6, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 59
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 4 operands: lhs = Counter(4), rhs = Expression(18, Add)
-- expression 5 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 6 operands: lhs = Counter(4), rhs = Expression(16, Add)
-- expression 7 operands: lhs = Expression(17, Add), rhs = Counter(8)
-- expression 8 operands: lhs = Expression(18, Add), rhs = Counter(7)
-- expression 9 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 10 operands: lhs = Counter(4), rhs = Expression(18, Add)
-- expression 11 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 12 operands: lhs = Counter(4), rhs = Expression(17, Add)
-- expression 13 operands: lhs = Expression(18, Add), rhs = Counter(7)
-- expression 14 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 15 operands: lhs = Counter(4), rhs = Expression(16, Add)
-- expression 16 operands: lhs = Expression(17, Add), rhs = Counter(8)
-- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(7)
-- expression 18 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 19 operands: lhs = Counter(17), rhs = Expression(23, Add)
-- expression 20 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 21 operands: lhs = Counter(17), rhs = Counter(9)
-- expression 22 operands: lhs = Counter(17), rhs = Expression(23, Add)
-- expression 23 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 24 operands: lhs = Expression(0, Add), rhs = Expression(34, Add)
-- expression 25 operands: lhs = Expression(35, Add), rhs = Counter(12)
-- expression 26 operands: lhs = Expression(36, Add), rhs = Counter(11)
-- expression 27 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 28 operands: lhs = Expression(0, Add), rhs = Expression(36, Add)
-- expression 29 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 30 operands: lhs = Expression(0, Add), rhs = Expression(35, Add)
-- expression 31 operands: lhs = Expression(36, Add), rhs = Counter(11)
-- expression 32 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 33 operands: lhs = Expression(0, Add), rhs = Expression(34, Add)
-- expression 34 operands: lhs = Expression(35, Add), rhs = Counter(12)
-- expression 35 operands: lhs = Expression(36, Add), rhs = Counter(11)
-- expression 36 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 37 operands: lhs = Counter(18), rhs = Expression(41, Add)
-- expression 38 operands: lhs = Counter(13), rhs = Counter(14)
-- expression 39 operands: lhs = Counter(18), rhs = Counter(13)
-- expression 40 operands: lhs = Counter(18), rhs = Expression(41, Add)
-- expression 41 operands: lhs = Counter(13), rhs = Counter(14)
-- expression 42 operands: lhs = Counter(19), rhs = Expression(46, Add)
-- expression 43 operands: lhs = Counter(15), rhs = Counter(16)
-- expression 44 operands: lhs = Counter(19), rhs = Counter(15)
-- expression 45 operands: lhs = Counter(19), rhs = Expression(46, Add)
-- expression 46 operands: lhs = Counter(15), rhs = Counter(16)
-- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(16)
-- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(15)
-- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(14)
-- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(13)
-- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(12)
-- expression 52 operands: lhs = Expression(53, Add), rhs = Counter(11)
-- expression 53 operands: lhs = Expression(54, Add), rhs = Counter(10)
-- expression 54 operands: lhs = Expression(55, Add), rhs = Counter(9)
-- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(8)
-- expression 56 operands: lhs = Expression(57, Add), rhs = Counter(7)
-- expression 57 operands: lhs = Expression(58, Add), rhs = Counter(6)
-- expression 58 operands: lhs = Counter(3), rhs = Counter(5)
+Number of expressions: 54
+- expression 0 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 1 operands: lhs = Counter(3), rhs = Expression(15, Add)
+- expression 2 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 3 operands: lhs = Counter(3), rhs = Expression(13, Add)
+- expression 4 operands: lhs = Expression(14, Add), rhs = Counter(7)
+- expression 5 operands: lhs = Expression(15, Add), rhs = Counter(6)
+- expression 6 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 7 operands: lhs = Counter(3), rhs = Expression(15, Add)
+- expression 8 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 9 operands: lhs = Counter(3), rhs = Expression(14, Add)
+- expression 10 operands: lhs = Expression(15, Add), rhs = Counter(6)
+- expression 11 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 12 operands: lhs = Counter(3), rhs = Expression(13, Add)
+- expression 13 operands: lhs = Expression(14, Add), rhs = Counter(7)
+- expression 14 operands: lhs = Expression(15, Add), rhs = Counter(6)
+- expression 15 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 16 operands: lhs = Counter(16), rhs = Expression(20, Add)
+- expression 17 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 18 operands: lhs = Counter(16), rhs = Counter(8)
+- expression 19 operands: lhs = Counter(16), rhs = Expression(20, Add)
+- expression 20 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 21 operands: lhs = Counter(2), rhs = Expression(28, Add)
+- expression 22 operands: lhs = Expression(29, Add), rhs = Counter(11)
+- expression 23 operands: lhs = Counter(3), rhs = Counter(10)
+- expression 24 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 25 operands: lhs = Counter(2), rhs = Expression(29, Add)
+- expression 26 operands: lhs = Counter(3), rhs = Counter(10)
+- expression 27 operands: lhs = Counter(2), rhs = Expression(28, Add)
+- expression 28 operands: lhs = Expression(29, Add), rhs = Counter(11)
+- expression 29 operands: lhs = Counter(3), rhs = Counter(10)
+- expression 30 operands: lhs = Counter(17), rhs = Expression(34, Add)
+- expression 31 operands: lhs = Counter(12), rhs = Counter(13)
+- expression 32 operands: lhs = Counter(17), rhs = Counter(12)
+- expression 33 operands: lhs = Counter(17), rhs = Expression(34, Add)
+- expression 34 operands: lhs = Counter(12), rhs = Counter(13)
+- expression 35 operands: lhs = Counter(18), rhs = Expression(39, Add)
+- expression 36 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 37 operands: lhs = Counter(18), rhs = Counter(14)
+- expression 38 operands: lhs = Counter(18), rhs = Expression(39, Add)
+- expression 39 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 40 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(2)
+- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(15)
+- expression 43 operands: lhs = Expression(44, Add), rhs = Counter(14)
+- expression 44 operands: lhs = Expression(45, Add), rhs = Counter(13)
+- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(12)
+- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(11)
+- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(10)
+- expression 48 operands: lhs = Expression(49, Add), rhs = Counter(9)
+- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(8)
+- expression 50 operands: lhs = Expression(51, Add), rhs = Counter(7)
+- expression 51 operands: lhs = Expression(52, Add), rhs = Counter(6)
+- expression 52 operands: lhs = Expression(53, Add), rhs = Counter(5)
+- expression 53 operands: lhs = Counter(1), rhs = Counter(4)
 Number of file 0 mappings: 40
 - Code(Counter(0)) at (prev + 61, 1) to (start + 3, 23)
-- Code(Expression(0, Add)) at (prev + 8, 9) to (start + 0, 14)
-    = ((c0 + c1) + c2)
-- Code(Expression(2, Sub)) at (prev + 2, 9) to (start + 4, 26)
-    = (((c0 + c1) + c2) - c3)
-- Code(Counter(4)) at (prev + 6, 13) to (start + 0, 47)
-- Code(Counter(5)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(3, Sub)) at (prev + 0, 49) to (start + 3, 53)
-    = (c4 - c5)
-- Code(Counter(6)) at (prev + 4, 17) to (start + 0, 18)
-- Code(Expression(10, Sub)) at (prev + 2, 17) to (start + 4, 18)
-    = (c4 - (c5 + c6))
-- Code(Expression(15, Sub)) at (prev + 5, 17) to (start + 0, 20)
-    = (c4 - (((c5 + c6) + c7) + c8))
-- Code(Expression(10, Sub)) at (prev + 0, 23) to (start + 0, 65)
-    = (c4 - (c5 + c6))
-- Code(Counter(7)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(12, Sub)) at (prev + 0, 67) to (start + 0, 95)
-    = (c4 - ((c5 + c6) + c7))
-- Code(Counter(8)) at (prev + 0, 95) to (start + 0, 96)
-- Code(Expression(15, Sub)) at (prev + 1, 13) to (start + 0, 32)
-    = (c4 - (((c5 + c6) + c7) + c8))
-- Code(Expression(22, Sub)) at (prev + 1, 17) to (start + 0, 20)
-    = (c17 - (c9 + c10))
-- Code(Counter(17)) at (prev + 0, 23) to (start + 0, 65)
-- Code(Counter(9)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(21, Sub)) at (prev + 0, 67) to (start + 0, 96)
-    = (c17 - c9)
-- Code(Counter(10)) at (prev + 0, 96) to (start + 0, 97)
-- Code(Expression(22, Sub)) at (prev + 1, 13) to (start + 0, 32)
-    = (c17 - (c9 + c10))
-- Code(Expression(33, Sub)) at (prev + 4, 17) to (start + 0, 20)
-    = (((c0 + c1) + c2) - (((c3 + c4) + c11) + c12))
-- Code(Expression(28, Sub)) at (prev + 0, 23) to (start + 0, 66)
-    = (((c0 + c1) + c2) - (c3 + c4))
-- Code(Counter(11)) at (prev + 0, 66) to (start + 0, 67)
-- Code(Expression(30, Sub)) at (prev + 0, 68) to (start + 0, 97)
-    = (((c0 + c1) + c2) - ((c3 + c4) + c11))
-- Code(Counter(12)) at (prev + 0, 97) to (start + 0, 98)
+- Code(Counter(1)) at (prev + 8, 9) to (start + 0, 14)
+- Code(Counter(2)) at (prev + 2, 9) to (start + 4, 26)
+- Code(Counter(3)) at (prev + 6, 13) to (start + 0, 47)
+- Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48)
+- Code(Expression(0, Sub)) at (prev + 0, 49) to (start + 3, 53)
+    = (c3 - c4)
+- Code(Counter(5)) at (prev + 4, 17) to (start + 0, 18)
+- Code(Expression(7, Sub)) at (prev + 2, 17) to (start + 4, 18)
+    = (c3 - (c4 + c5))
+- Code(Expression(12, Sub)) at (prev + 5, 17) to (start + 0, 20)
+    = (c3 - (((c4 + c5) + c6) + c7))
+- Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 65)
+    = (c3 - (c4 + c5))
+- Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66)
+- Code(Expression(9, Sub)) at (prev + 0, 67) to (start + 0, 95)
+    = (c3 - ((c4 + c5) + c6))
+- Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96)
+- Code(Expression(12, Sub)) at (prev + 1, 13) to (start + 0, 32)
+    = (c3 - (((c4 + c5) + c6) + c7))
+- Code(Expression(19, Sub)) at (prev + 1, 17) to (start + 0, 20)
+    = (c16 - (c8 + c9))
+- Code(Counter(16)) at (prev + 0, 23) to (start + 0, 65)
+- Code(Counter(8)) at (prev + 0, 65) to (start + 0, 66)
+- Code(Expression(18, Sub)) at (prev + 0, 67) to (start + 0, 96)
+    = (c16 - c8)
+- Code(Counter(9)) at (prev + 0, 96) to (start + 0, 97)
+- Code(Expression(19, Sub)) at (prev + 1, 13) to (start + 0, 32)
+    = (c16 - (c8 + c9))
+- Code(Expression(27, Sub)) at (prev + 4, 17) to (start + 0, 20)
+    = (c2 - ((c3 + c10) + c11))
+- Code(Expression(24, Sub)) at (prev + 0, 23) to (start + 0, 66)
+    = (c2 - c3)
+- Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67)
+- Code(Expression(25, Sub)) at (prev + 0, 68) to (start + 0, 97)
+    = (c2 - (c3 + c10))
+- Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98)
+- Code(Expression(27, Sub)) at (prev + 1, 13) to (start + 0, 32)
+    = (c2 - ((c3 + c10) + c11))
+- Code(Expression(33, Sub)) at (prev + 1, 17) to (start + 0, 20)
+    = (c17 - (c12 + c13))
+- Code(Counter(17)) at (prev + 0, 23) to (start + 1, 54)
+- Code(Counter(12)) at (prev + 1, 54) to (start + 0, 55)
+- Code(Expression(32, Sub)) at (prev + 1, 18) to (start + 0, 47)
+    = (c17 - c12)
+- Code(Counter(13)) at (prev + 0, 47) to (start + 0, 48)
 - Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 32)
-    = (((c0 + c1) + c2) - (((c3 + c4) + c11) + c12))
-- Code(Expression(40, Sub)) at (prev + 1, 17) to (start + 0, 20)
-    = (c18 - (c13 + c14))
+    = (c17 - (c12 + c13))
+- Code(Expression(38, Sub)) at (prev + 1, 17) to (start + 0, 20)
+    = (c18 - (c14 + c15))
 - Code(Counter(18)) at (prev + 0, 23) to (start + 1, 54)
-- Code(Counter(13)) at (prev + 1, 54) to (start + 0, 55)
-- Code(Expression(39, Sub)) at (prev + 1, 18) to (start + 0, 47)
-    = (c18 - c13)
-- Code(Counter(14)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(40, Sub)) at (prev + 1, 13) to (start + 0, 32)
-    = (c18 - (c13 + c14))
-- Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20)
-    = (c19 - (c15 + c16))
-- Code(Counter(19)) at (prev + 0, 23) to (start + 1, 54)
-- Code(Counter(15)) at (prev + 2, 17) to (start + 0, 18)
-- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 47)
-    = (c19 - c15)
-- Code(Counter(16)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 32)
-    = (c19 - (c15 + c16))
-- Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11)
-- Code(Expression(47, Add)) at (prev + 1, 1) to (start + 0, 2)
-    = ((((((((((((c3 + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) + c16)
-Highest counter ID seen: c19
+- Code(Counter(14)) at (prev + 2, 17) to (start + 0, 18)
+- Code(Expression(37, Sub)) at (prev + 1, 18) to (start + 0, 47)
+    = (c18 - c14)
+- Code(Counter(15)) at (prev + 1, 17) to (start + 0, 18)
+- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 32)
+    = (c18 - (c14 + c15))
+- Code(Expression(40, Sub)) at (prev + 3, 5) to (start + 0, 11)
+    = (c1 - c2)
+- Code(Expression(41, Sub)) at (prev + 1, 1) to (start + 0, 2)
+    = (((((((((((((c1 + c4) + c5) + c6) + c7) + c8) + c9) + c10) + c11) + c12) + c13) + c14) + c15) - c2)
+Highest counter ID seen: c18
 
diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map
index 0a4e367bb9e..7b9dc0b9bc8 100644
--- a/tests/coverage/unicode.cov-map
+++ b/tests/coverage/unicode.cov-map
@@ -1,16 +1,17 @@
 Function name: unicode::main
-Raw bytes (53): 0x[01, 01, 02, 01, 05, 01, 0d, 09, 01, 0e, 01, 00, 0b, 05, 01, 09, 00, 0c, 03, 00, 10, 00, 1b, 05, 00, 1c, 00, 28, 01, 02, 08, 00, 25, 09, 00, 29, 00, 46, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 01, 02]
+Raw bytes (53): 0x[01, 01, 02, 05, 01, 01, 0d, 09, 01, 0e, 01, 00, 0b, 02, 01, 09, 00, 0c, 05, 00, 10, 00, 1b, 02, 00, 1c, 00, 28, 01, 02, 08, 00, 25, 09, 00, 29, 00, 46, 0d, 00, 47, 02, 06, 06, 02, 05, 00, 06, 01, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
-- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(3)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 14, 1) to (start + 0, 11)
-- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12)
-- Code(Expression(0, Add)) at (prev + 0, 16) to (start + 0, 27)
-    = (c0 + c1)
-- Code(Counter(1)) at (prev + 0, 28) to (start + 0, 40)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 12)
+    = (c1 - c0)
+- Code(Counter(1)) at (prev + 0, 16) to (start + 0, 27)
+- Code(Expression(0, Sub)) at (prev + 0, 28) to (start + 0, 40)
+    = (c1 - c0)
 - Code(Counter(0)) at (prev + 2, 8) to (start + 0, 37)
 - Code(Counter(2)) at (prev + 0, 41) to (start + 0, 70)
 - Code(Counter(3)) at (prev + 0, 71) to (start + 2, 6)
diff --git a/tests/coverage/unused.cov-map b/tests/coverage/unused.cov-map
index 4eae63f380c..c18d331ec2e 100644
--- a/tests/coverage/unused.cov-map
+++ b/tests/coverage/unused.cov-map
@@ -1,44 +1,42 @@
 Function name: unused::foo::<f32>
-Raw bytes (42): 0x[01, 01, 04, 07, 09, 01, 05, 03, 0d, 05, 09, 06, 01, 03, 01, 01, 12, 03, 02, 0b, 00, 11, 0a, 01, 09, 00, 0f, 09, 00, 13, 00, 19, 0f, 01, 09, 00, 0f, 0d, 02, 01, 00, 02]
+Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 4
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
+Number of expressions: 3
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18)
-- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 17)
-    = ((c0 + c1) + c2)
-- Code(Expression(2, Sub)) at (prev + 1, 9) to (start + 0, 15)
-    = (((c0 + c1) + c2) - c3)
-- Code(Counter(2)) at (prev + 0, 19) to (start + 0, 25)
-- Code(Expression(3, Add)) at (prev + 1, 9) to (start + 0, 15)
-    = (c1 + c2)
-- Code(Counter(3)) at (prev + 2, 1) to (start + 0, 2)
-Highest counter ID seen: c3
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
+    = (c1 - c0)
+- Code(Expression(1, Sub)) at (prev + 0, 19) to (start + 0, 25)
+    = (c1 - (c0 + c2))
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
+Highest counter ID seen: c1
 
 Function name: unused::foo::<u32>
-Raw bytes (42): 0x[01, 01, 04, 07, 09, 01, 05, 03, 0d, 05, 09, 06, 01, 03, 01, 01, 12, 03, 02, 0b, 00, 11, 0a, 01, 09, 00, 0f, 09, 00, 13, 00, 19, 0f, 01, 09, 00, 0f, 0d, 02, 01, 00, 02]
+Raw bytes (40): 0x[01, 01, 03, 05, 01, 05, 0b, 01, 09, 06, 01, 03, 01, 01, 12, 05, 02, 0b, 00, 11, 02, 01, 09, 00, 0f, 06, 00, 13, 00, 19, 02, 01, 09, 00, 0f, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 4
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(2)
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
+Number of expressions: 3
+- expression 0 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
+- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 3, 1) to (start + 1, 18)
-- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 17)
-    = ((c0 + c1) + c2)
-- Code(Expression(2, Sub)) at (prev + 1, 9) to (start + 0, 15)
-    = (((c0 + c1) + c2) - c3)
-- Code(Counter(2)) at (prev + 0, 19) to (start + 0, 25)
-- Code(Expression(3, Add)) at (prev + 1, 9) to (start + 0, 15)
-    = (c1 + c2)
-- Code(Counter(3)) at (prev + 2, 1) to (start + 0, 2)
-Highest counter ID seen: c3
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 17)
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
+    = (c1 - c0)
+- Code(Expression(1, Sub)) at (prev + 0, 19) to (start + 0, 25)
+    = (c1 - (c0 + c2))
+- Code(Expression(0, Sub)) at (prev + 1, 9) to (start + 0, 15)
+    = (c1 - c0)
+- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
+Highest counter ID seen: c1
 
 Function name: unused::main
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 04, 02]
diff --git a/tests/coverage/while.cov-map b/tests/coverage/while.cov-map
index 29493a651dc..d42aa8a7b84 100644
--- a/tests/coverage/while.cov-map
+++ b/tests/coverage/while.cov-map
@@ -1,14 +1,12 @@
 Function name: while::main
-Raw bytes (26): 0x[01, 01, 01, 01, 00, 04, 01, 01, 01, 01, 10, 03, 02, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 01, 01, 01, 10, 05, 02, 0b, 00, 14, 00, 00, 15, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 1
-- expression 0 operands: lhs = Counter(0), rhs = Zero
+Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 1, 1) to (start + 1, 16)
-- Code(Expression(0, Add)) at (prev + 2, 11) to (start + 0, 20)
-    = (c0 + Zero)
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 20)
 - Code(Zero) at (prev + 0, 21) to (start + 2, 6)
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
-Highest counter ID seen: c0
+Highest counter ID seen: c1
 
diff --git a/tests/coverage/while_early_ret.cov-map b/tests/coverage/while_early_ret.cov-map
index 554056fa801..69b51bf9ca3 100644
--- a/tests/coverage/while_early_ret.cov-map
+++ b/tests/coverage/while_early_ret.cov-map
@@ -1,26 +1,28 @@
 Function name: while_early_ret::main
-Raw bytes (59): 0x[01, 01, 05, 01, 05, 03, 09, 01, 09, 01, 13, 09, 0d, 09, 01, 05, 01, 01, 1b, 03, 03, 09, 02, 0a, 06, 05, 0d, 02, 0e, 0a, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 0e, 04, 15, 00, 1b, 05, 03, 0a, 03, 0a, 09, 06, 05, 00, 0b, 01, 01, 01, 00, 02]
+Raw bytes (63): 0x[01, 01, 07, 0f, 05, 01, 09, 0f, 13, 01, 09, 05, 0d, 05, 01, 05, 09, 09, 01, 05, 01, 01, 1b, 05, 03, 09, 02, 0a, 09, 05, 0d, 02, 0e, 02, 06, 15, 02, 16, 0d, 04, 15, 00, 1b, 0a, 04, 15, 00, 1b, 16, 03, 0a, 03, 0a, 1a, 06, 05, 00, 0b, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
-- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(2)
-- expression 2 operands: lhs = Counter(0), rhs = Counter(2)
-- expression 3 operands: lhs = Counter(0), rhs = Expression(4, Add)
-- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
+Number of expressions: 7
+- expression 0 operands: lhs = Expression(3, Add), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 2 operands: lhs = Expression(3, Add), rhs = Expression(4, Add)
+- expression 3 operands: lhs = Counter(0), rhs = Counter(2)
+- expression 4 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 5 operands: lhs = Counter(1), rhs = Counter(0)
+- expression 6 operands: lhs = Counter(1), rhs = Counter(2)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 5, 1) to (start + 1, 27)
-- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 2, 10)
-    = (c0 + c1)
-- Code(Expression(1, Sub)) at (prev + 5, 13) to (start + 2, 14)
-    = ((c0 + c1) - c2)
-- Code(Expression(2, Sub)) at (prev + 6, 21) to (start + 2, 22)
-    = (c0 - c2)
+- Code(Counter(1)) at (prev + 3, 9) to (start + 2, 10)
+- Code(Counter(2)) at (prev + 5, 13) to (start + 2, 14)
+- Code(Expression(0, Sub)) at (prev + 6, 21) to (start + 2, 22)
+    = ((c0 + c2) - c1)
 - Code(Counter(3)) at (prev + 4, 21) to (start + 0, 27)
-- Code(Expression(3, Sub)) at (prev + 4, 21) to (start + 0, 27)
-    = (c0 - (c2 + c3))
-- Code(Counter(1)) at (prev + 3, 10) to (start + 3, 10)
-- Code(Counter(2)) at (prev + 6, 5) to (start + 0, 11)
+- Code(Expression(2, Sub)) at (prev + 4, 21) to (start + 0, 27)
+    = ((c0 + c2) - (c1 + c3))
+- Code(Expression(5, Sub)) at (prev + 3, 10) to (start + 3, 10)
+    = (c1 - c0)
+- Code(Expression(6, Sub)) at (prev + 6, 5) to (start + 0, 11)
+    = (c1 - c2)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c3
 
diff --git a/tests/coverage/yield.cov-map b/tests/coverage/yield.cov-map
index 868fec4b107..d296f9bd778 100644
--- a/tests/coverage/yield.cov-map
+++ b/tests/coverage/yield.cov-map
@@ -1,36 +1,36 @@
 Function name: yield::main
-Raw bytes (94): 0x[01, 01, 05, 05, 00, 0d, 15, 0d, 11, 19, 1d, 25, 29, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 0d, 01, 27, 00, 29, 03, 01, 0e, 00, 34, 0d, 02, 0b, 00, 2e, 06, 01, 22, 00, 27, 11, 00, 2c, 00, 2e, 0a, 01, 0e, 00, 34, 11, 03, 09, 00, 16, 11, 08, 0b, 00, 2e, 21, 01, 27, 00, 29, 0f, 01, 0e, 00, 34, 21, 02, 0b, 00, 2e, 2d, 01, 27, 00, 29, 13, 01, 0e, 00, 34, 2d, 02, 01, 00, 02]
+Raw bytes (94): 0x[01, 01, 05, 01, 05, 05, 09, 09, 11, 11, 15, 11, 15, 10, 01, 07, 01, 01, 16, 01, 07, 0b, 00, 2e, 05, 01, 27, 00, 29, 02, 01, 0e, 00, 34, 05, 02, 0b, 00, 2e, 0d, 01, 22, 00, 27, 09, 00, 2c, 00, 2e, 06, 01, 0e, 00, 34, 09, 03, 09, 00, 16, 09, 08, 0b, 00, 2e, 11, 01, 27, 00, 29, 0a, 01, 0e, 00, 34, 11, 02, 0b, 00, 2e, 12, 01, 27, 00, 29, 15, 01, 0e, 00, 34, 12, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
-- expression 0 operands: lhs = Counter(1), rhs = Zero
-- expression 1 operands: lhs = Counter(3), rhs = Counter(5)
-- expression 2 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 3 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 4 operands: lhs = Counter(9), rhs = Counter(10)
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 2 operands: lhs = Counter(2), rhs = Counter(4)
+- expression 3 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 4 operands: lhs = Counter(4), rhs = Counter(5)
 Number of file 0 mappings: 16
 - Code(Counter(0)) at (prev + 7, 1) to (start + 1, 22)
 - Code(Counter(0)) at (prev + 7, 11) to (start + 0, 46)
-- Code(Counter(3)) at (prev + 1, 39) to (start + 0, 41)
-- Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 52)
-    = (c1 + Zero)
-- Code(Counter(3)) at (prev + 2, 11) to (start + 0, 46)
-- Code(Expression(1, Sub)) at (prev + 1, 34) to (start + 0, 39)
-    = (c3 - c5)
-- Code(Counter(4)) at (prev + 0, 44) to (start + 0, 46)
+- Code(Counter(1)) at (prev + 1, 39) to (start + 0, 41)
+- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 52)
+    = (c0 - c1)
+- Code(Counter(1)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Counter(3)) at (prev + 1, 34) to (start + 0, 39)
+- Code(Counter(2)) at (prev + 0, 44) to (start + 0, 46)
+- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 52)
+    = (c1 - c2)
+- Code(Counter(2)) at (prev + 3, 9) to (start + 0, 22)
+- Code(Counter(2)) at (prev + 8, 11) to (start + 0, 46)
+- Code(Counter(4)) at (prev + 1, 39) to (start + 0, 41)
 - Code(Expression(2, Sub)) at (prev + 1, 14) to (start + 0, 52)
-    = (c3 - c4)
-- Code(Counter(4)) at (prev + 3, 9) to (start + 0, 22)
-- Code(Counter(4)) at (prev + 8, 11) to (start + 0, 46)
-- Code(Counter(8)) at (prev + 1, 39) to (start + 0, 41)
-- Code(Expression(3, Add)) at (prev + 1, 14) to (start + 0, 52)
-    = (c6 + c7)
-- Code(Counter(8)) at (prev + 2, 11) to (start + 0, 46)
-- Code(Counter(11)) at (prev + 1, 39) to (start + 0, 41)
-- Code(Expression(4, Add)) at (prev + 1, 14) to (start + 0, 52)
-    = (c9 + c10)
-- Code(Counter(11)) at (prev + 2, 1) to (start + 0, 2)
-Highest counter ID seen: c11
+    = (c2 - c4)
+- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Expression(4, Sub)) at (prev + 1, 39) to (start + 0, 41)
+    = (c4 - c5)
+- Code(Counter(5)) at (prev + 1, 14) to (start + 0, 52)
+- Code(Expression(4, Sub)) at (prev + 2, 1) to (start + 0, 2)
+    = (c4 - c5)
+Highest counter ID seen: c5
 
 Function name: yield::main::{closure#0}
 Raw bytes (14): 0x[01, 01, 00, 02, 01, 09, 08, 01, 10, 05, 02, 10, 01, 06]
diff --git a/tests/incremental/overlapping-impls-in-new-solver-issue-135514.rs b/tests/incremental/overlapping-impls-in-new-solver-issue-135514.rs
new file mode 100644
index 00000000000..8fcc913fa37
--- /dev/null
+++ b/tests/incremental/overlapping-impls-in-new-solver-issue-135514.rs
@@ -0,0 +1,40 @@
+// Regression test for #135514 where the new solver didn't properly record deps for incremental
+// compilation, similarly to `track-deps-in-new-solver.rs`.
+//
+// In this specially crafted example, @steffahn was able to trigger unsoundness with an overlapping
+// impl that was accepted during the incremental rebuild.
+
+//@ revisions: cpass1 cfail2
+//@ compile-flags: -Znext-solver
+
+pub trait Trait {}
+
+pub struct S0<T>(T);
+
+pub struct S<T>(T);
+impl<T> Trait for S<T> where S0<T>: Trait {}
+
+pub struct W;
+
+pub trait Other {
+    type Choose<L, R>;
+}
+
+// first impl
+impl<T: Trait> Other for T {
+    type Choose<L, R> = L;
+}
+
+// second impl
+impl<T> Other for S<T> {
+    //[cfail2]~^ ERROR conflicting implementations of trait
+    type Choose<L, R> = R;
+}
+
+#[cfg(cpass1)]
+impl Trait for W {}
+
+#[cfg(cfail2)]
+impl Trait for S<W> {}
+
+fn main() {}
diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
index b480d1ac13a..fa09cf0b83f 100644
--- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
@@ -8,11 +8,11 @@
       let mut _3: !;
   
 +     coverage body span: $DIR/instrument_coverage.rs:10:11: 16:2 (#0)
-+     coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Add, rhs: Counter(1) };
++     coverage ExpressionId(0) => Expression { lhs: Counter(1), op: Subtract, rhs: Counter(0) };
 +     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:10:1: 10:11 (#0);
-+     coverage Code(Expression(0)) => $DIR/instrument_coverage.rs:12:12: 12:17 (#0);
++     coverage Code(Counter(1)) => $DIR/instrument_coverage.rs:12:12: 12:17 (#0);
 +     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:13:13: 13:18 (#0);
-+     coverage Code(Counter(1)) => $DIR/instrument_coverage.rs:14:10: 14:10 (#0);
++     coverage Code(Expression(0)) => $DIR/instrument_coverage.rs:14:10: 14:10 (#0);
 +     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:16:2: 16:2 (#0);
 + 
       bb0: {
@@ -21,7 +21,7 @@
       }
   
       bb1: {
-+         Coverage::ExpressionUsed(0);
++         Coverage::CounterIncrement(1);
           falseUnwind -> [real: bb2, unwind: bb6];
       }
   
@@ -41,7 +41,7 @@
       }
   
       bb5: {
-+         Coverage::CounterIncrement(1);
++         Coverage::ExpressionUsed(0);
           _1 = const ();
           StorageDead(_2);
           goto -> bb1;
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
index 5ea9902b262..5a830254f61 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
@@ -16,25 +16,23 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
-                  let _6: *mut [bool; 0];
+                  let mut _6: std::num::NonZero<usize>;
                   scope 6 {
-                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                          let mut _8: bool;
-                          let _9: ();
-                          let mut _10: *mut ();
-                          let mut _11: *const [bool; 0];
-                          scope 11 (inlined core::ub_checks::check_language_ub) {
-                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                      scope 8 (inlined std::ptr::Alignment::as_nonzero) {
+                      }
+                      scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) {
+                          let _7: *const [bool; 0];
+                          scope 10 {
+                          }
+                          scope 11 (inlined NonZero::<usize>::get) {
+                          }
+                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                              scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
                       }
                   }
-                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
-                      let mut _7: usize;
-                      scope 8 (inlined align_of::<[bool; 0]>) {
-                      }
-                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
-                      }
+                  scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) {
                   }
               }
           }
@@ -44,40 +42,13 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
-          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
+          _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
           StorageLive(_7);
-          _7 = const 1_usize;
-          _6 = const {0x1 as *mut [bool; 0]};
-          StorageLive(_11);
-          StorageLive(_8);
-          _8 = UbChecks();
-          switchInt(move _8) -> [0: bb4, otherwise: bb2];
-      }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2: {
-          StorageLive(_10);
-          _10 = const {0x1 as *mut ()};
-          _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
-      }
-  
-      bb3: {
-          StorageDead(_10);
-          goto -> bb4;
-      }
-  
-      bb4: {
-          StorageDead(_8);
-          _11 = const {0x1 as *const [bool; 0]};
+          _7 = const {0x1 as *const [bool; 0]};
           _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
-          StorageDead(_11);
           StorageDead(_7);
           StorageDead(_6);
           _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
@@ -85,13 +56,17 @@
           _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
           StorageDead(_4);
           _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
-          StorageDead(_9);
           StorageDead(_3);
           _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind unreachable];
       }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
   }
   
   ALLOC2 (size: 8, align: 4) { .. }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
index cc5a41a7f63..c11368a347c 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -16,25 +16,23 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
-                  let _6: *mut [bool; 0];
+                  let mut _6: std::num::NonZero<usize>;
                   scope 6 {
-                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                          let mut _8: bool;
-                          let _9: ();
-                          let mut _10: *mut ();
-                          let mut _11: *const [bool; 0];
-                          scope 11 (inlined core::ub_checks::check_language_ub) {
-                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                      scope 8 (inlined std::ptr::Alignment::as_nonzero) {
+                      }
+                      scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) {
+                          let _7: *const [bool; 0];
+                          scope 10 {
+                          }
+                          scope 11 (inlined NonZero::<usize>::get) {
+                          }
+                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                              scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
                       }
                   }
-                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
-                      let mut _7: usize;
-                      scope 8 (inlined align_of::<[bool; 0]>) {
-                      }
-                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
-                      }
+                  scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) {
                   }
               }
           }
@@ -44,44 +42,13 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
-          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
+          _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
           StorageLive(_7);
-          _7 = const 1_usize;
-          _6 = const {0x1 as *mut [bool; 0]};
-          StorageLive(_11);
-          StorageLive(_8);
-          _8 = UbChecks();
-          switchInt(move _8) -> [0: bb5, otherwise: bb3];
-      }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2 (cleanup): {
-          resume;
-      }
-  
-      bb3: {
-          StorageLive(_10);
-          _10 = const {0x1 as *mut ()};
-          _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
-      }
-  
-      bb4: {
-          StorageDead(_10);
-          goto -> bb5;
-      }
-  
-      bb5: {
-          StorageDead(_8);
-          _11 = const {0x1 as *const [bool; 0]};
+          _7 = const {0x1 as *const [bool; 0]};
           _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
-          StorageDead(_11);
           StorageDead(_7);
           StorageDead(_6);
           _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
@@ -89,13 +56,21 @@
           _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
           StorageDead(_4);
           _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
-          StorageDead(_9);
           StorageDead(_3);
           _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind: bb2];
       }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
   }
   
   ALLOC2 (size: 8, align: 4) { .. }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
index 3d398fbea79..037ed02ce65 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
@@ -16,25 +16,23 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
-                  let _6: *mut [bool; 0];
+                  let mut _6: std::num::NonZero<usize>;
                   scope 6 {
-                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                          let mut _8: bool;
-                          let _9: ();
-                          let mut _10: *mut ();
-                          let mut _11: *const [bool; 0];
-                          scope 11 (inlined core::ub_checks::check_language_ub) {
-                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                      scope 8 (inlined std::ptr::Alignment::as_nonzero) {
+                      }
+                      scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) {
+                          let _7: *const [bool; 0];
+                          scope 10 {
+                          }
+                          scope 11 (inlined NonZero::<usize>::get) {
+                          }
+                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                              scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
                       }
                   }
-                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
-                      let mut _7: usize;
-                      scope 8 (inlined align_of::<[bool; 0]>) {
-                      }
-                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
-                      }
+                  scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) {
                   }
               }
           }
@@ -44,40 +42,13 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
-          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
+          _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
           StorageLive(_7);
-          _7 = const 1_usize;
-          _6 = const {0x1 as *mut [bool; 0]};
-          StorageLive(_11);
-          StorageLive(_8);
-          _8 = UbChecks();
-          switchInt(move _8) -> [0: bb4, otherwise: bb2];
-      }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2: {
-          StorageLive(_10);
-          _10 = const {0x1 as *mut ()};
-          _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
-      }
-  
-      bb3: {
-          StorageDead(_10);
-          goto -> bb4;
-      }
-  
-      bb4: {
-          StorageDead(_8);
-          _11 = const {0x1 as *const [bool; 0]};
+          _7 = const {0x1 as *const [bool; 0]};
           _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
-          StorageDead(_11);
           StorageDead(_7);
           StorageDead(_6);
           _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
@@ -85,13 +56,17 @@
           _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
           StorageDead(_4);
           _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
-          StorageDead(_9);
           StorageDead(_3);
           _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind unreachable];
       }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
   }
   
   ALLOC2 (size: 16, align: 8) { .. }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
index dc99c3f7a8c..86351c78759 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -16,25 +16,23 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
-                  let _6: *mut [bool; 0];
+                  let mut _6: std::num::NonZero<usize>;
                   scope 6 {
-                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                          let mut _8: bool;
-                          let _9: ();
-                          let mut _10: *mut ();
-                          let mut _11: *const [bool; 0];
-                          scope 11 (inlined core::ub_checks::check_language_ub) {
-                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                      scope 8 (inlined std::ptr::Alignment::as_nonzero) {
+                      }
+                      scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) {
+                          let _7: *const [bool; 0];
+                          scope 10 {
+                          }
+                          scope 11 (inlined NonZero::<usize>::get) {
+                          }
+                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                              scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
                       }
                   }
-                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
-                      let mut _7: usize;
-                      scope 8 (inlined align_of::<[bool; 0]>) {
-                      }
-                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
-                      }
+                  scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) {
                   }
               }
           }
@@ -44,44 +42,13 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
-          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
+          _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
           StorageLive(_7);
-          _7 = const 1_usize;
-          _6 = const {0x1 as *mut [bool; 0]};
-          StorageLive(_11);
-          StorageLive(_8);
-          _8 = UbChecks();
-          switchInt(move _8) -> [0: bb5, otherwise: bb3];
-      }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2 (cleanup): {
-          resume;
-      }
-  
-      bb3: {
-          StorageLive(_10);
-          _10 = const {0x1 as *mut ()};
-          _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
-      }
-  
-      bb4: {
-          StorageDead(_10);
-          goto -> bb5;
-      }
-  
-      bb5: {
-          StorageDead(_8);
-          _11 = const {0x1 as *const [bool; 0]};
+          _7 = const {0x1 as *const [bool; 0]};
           _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
-          StorageDead(_11);
           StorageDead(_7);
           StorageDead(_6);
           _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
@@ -89,13 +56,21 @@
           _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
           StorageDead(_4);
           _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
-          StorageDead(_9);
           StorageDead(_3);
           _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind: bb2];
       }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
   }
   
   ALLOC2 (size: 16, align: 8) { .. }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
index 6a3ec543069..20a3897a934 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
@@ -16,25 +16,23 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
-                  let _6: *mut [bool; 0];
+                  let mut _6: std::num::NonZero<usize>;
                   scope 6 {
-                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                          let mut _8: bool;
-                          let _9: ();
-                          let mut _10: *mut ();
-                          let mut _11: *const [bool; 0];
-                          scope 11 (inlined core::ub_checks::check_language_ub) {
-                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                      scope 8 (inlined std::ptr::Alignment::as_nonzero) {
+                      }
+                      scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) {
+                          let _7: *const [bool; 0];
+                          scope 10 {
+                          }
+                          scope 11 (inlined NonZero::<usize>::get) {
+                          }
+                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                              scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
                       }
                   }
-                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
-                      let mut _7: usize;
-                      scope 8 (inlined align_of::<[bool; 0]>) {
-                      }
-                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
-                      }
+                  scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) {
                   }
               }
           }
@@ -44,46 +42,16 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
-          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
+-         _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero<usize> (Transmute);
++         _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
           StorageLive(_7);
--         _7 = AlignOf([bool; 0]);
--         _6 = copy _7 as *mut [bool; 0] (Transmute);
-+         _7 = const 1_usize;
-+         _6 = const {0x1 as *mut [bool; 0]};
-          StorageLive(_11);
-          StorageLive(_8);
-          _8 = UbChecks();
-          switchInt(move _8) -> [0: bb4, otherwise: bb2];
-      }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2: {
-          StorageLive(_10);
--         _10 = copy _7 as *mut () (Transmute);
--         _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
-+         _10 = const {0x1 as *mut ()};
-+         _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
-      }
-  
-      bb3: {
-          StorageDead(_10);
-          goto -> bb4;
-      }
-  
-      bb4: {
-          StorageDead(_8);
--         _11 = copy _7 as *const [bool; 0] (Transmute);
--         _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
-+         _11 = const {0x1 as *const [bool; 0]};
+-         _7 = copy _6 as *const [bool; 0] (Transmute);
+-         _5 = NonNull::<[bool; 0]> { pointer: copy _7 };
++         _7 = const {0x1 as *const [bool; 0]};
 +         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
-          StorageDead(_11);
           StorageDead(_7);
           StorageDead(_6);
 -         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
@@ -94,7 +62,6 @@
           StorageDead(_4);
 -         _2 = Box::<[bool]>(copy _3, const std::alloc::Global);
 +         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
-          StorageDead(_9);
           StorageDead(_3);
 -         _1 = A { foo: move _2 };
 +         _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
@@ -102,6 +69,11 @@
           _0 = const ();
           drop(_1) -> [return: bb1, unwind unreachable];
       }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
   }
 + 
 + ALLOC2 (size: 8, align: 4) { .. }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
index 9471ad47cd9..2e396301fd0 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
@@ -16,25 +16,23 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
-                  let _6: *mut [bool; 0];
+                  let mut _6: std::num::NonZero<usize>;
                   scope 6 {
-                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                          let mut _8: bool;
-                          let _9: ();
-                          let mut _10: *mut ();
-                          let mut _11: *const [bool; 0];
-                          scope 11 (inlined core::ub_checks::check_language_ub) {
-                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                      scope 8 (inlined std::ptr::Alignment::as_nonzero) {
+                      }
+                      scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) {
+                          let _7: *const [bool; 0];
+                          scope 10 {
+                          }
+                          scope 11 (inlined NonZero::<usize>::get) {
+                          }
+                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                              scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
                       }
                   }
-                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
-                      let mut _7: usize;
-                      scope 8 (inlined align_of::<[bool; 0]>) {
-                      }
-                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
-                      }
+                  scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) {
                   }
               }
           }
@@ -44,50 +42,16 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
-          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
+-         _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero<usize> (Transmute);
++         _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
           StorageLive(_7);
--         _7 = AlignOf([bool; 0]);
--         _6 = copy _7 as *mut [bool; 0] (Transmute);
-+         _7 = const 1_usize;
-+         _6 = const {0x1 as *mut [bool; 0]};
-          StorageLive(_11);
-          StorageLive(_8);
-          _8 = UbChecks();
-          switchInt(move _8) -> [0: bb5, otherwise: bb3];
-      }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2 (cleanup): {
-          resume;
-      }
-  
-      bb3: {
-          StorageLive(_10);
--         _10 = copy _7 as *mut () (Transmute);
--         _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
-+         _10 = const {0x1 as *mut ()};
-+         _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
-      }
-  
-      bb4: {
-          StorageDead(_10);
-          goto -> bb5;
-      }
-  
-      bb5: {
-          StorageDead(_8);
--         _11 = copy _7 as *const [bool; 0] (Transmute);
--         _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
-+         _11 = const {0x1 as *const [bool; 0]};
+-         _7 = copy _6 as *const [bool; 0] (Transmute);
+-         _5 = NonNull::<[bool; 0]> { pointer: copy _7 };
++         _7 = const {0x1 as *const [bool; 0]};
 +         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
-          StorageDead(_11);
           StorageDead(_7);
           StorageDead(_6);
 -         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
@@ -98,7 +62,6 @@
           StorageDead(_4);
 -         _2 = Box::<[bool]>(copy _3, const std::alloc::Global);
 +         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
-          StorageDead(_9);
           StorageDead(_3);
 -         _1 = A { foo: move _2 };
 +         _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
@@ -106,6 +69,15 @@
           _0 = const ();
           drop(_1) -> [return: bb1, unwind: bb2];
       }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
   }
 + 
 + ALLOC2 (size: 8, align: 4) { .. }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
index 187927b8eca..319691174cf 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
@@ -16,25 +16,23 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
-                  let _6: *mut [bool; 0];
+                  let mut _6: std::num::NonZero<usize>;
                   scope 6 {
-                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                          let mut _8: bool;
-                          let _9: ();
-                          let mut _10: *mut ();
-                          let mut _11: *const [bool; 0];
-                          scope 11 (inlined core::ub_checks::check_language_ub) {
-                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                      scope 8 (inlined std::ptr::Alignment::as_nonzero) {
+                      }
+                      scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) {
+                          let _7: *const [bool; 0];
+                          scope 10 {
+                          }
+                          scope 11 (inlined NonZero::<usize>::get) {
+                          }
+                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                              scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
                       }
                   }
-                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
-                      let mut _7: usize;
-                      scope 8 (inlined align_of::<[bool; 0]>) {
-                      }
-                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
-                      }
+                  scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) {
                   }
               }
           }
@@ -44,46 +42,16 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
-          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
+-         _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero<usize> (Transmute);
++         _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
           StorageLive(_7);
--         _7 = AlignOf([bool; 0]);
--         _6 = copy _7 as *mut [bool; 0] (Transmute);
-+         _7 = const 1_usize;
-+         _6 = const {0x1 as *mut [bool; 0]};
-          StorageLive(_11);
-          StorageLive(_8);
-          _8 = UbChecks();
-          switchInt(move _8) -> [0: bb4, otherwise: bb2];
-      }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2: {
-          StorageLive(_10);
--         _10 = copy _7 as *mut () (Transmute);
--         _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
-+         _10 = const {0x1 as *mut ()};
-+         _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb3, unwind unreachable];
-      }
-  
-      bb3: {
-          StorageDead(_10);
-          goto -> bb4;
-      }
-  
-      bb4: {
-          StorageDead(_8);
--         _11 = copy _7 as *const [bool; 0] (Transmute);
--         _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
-+         _11 = const {0x1 as *const [bool; 0]};
+-         _7 = copy _6 as *const [bool; 0] (Transmute);
+-         _5 = NonNull::<[bool; 0]> { pointer: copy _7 };
++         _7 = const {0x1 as *const [bool; 0]};
 +         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
-          StorageDead(_11);
           StorageDead(_7);
           StorageDead(_6);
 -         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
@@ -94,7 +62,6 @@
           StorageDead(_4);
 -         _2 = Box::<[bool]>(copy _3, const std::alloc::Global);
 +         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
-          StorageDead(_9);
           StorageDead(_3);
 -         _1 = A { foo: move _2 };
 +         _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
@@ -102,6 +69,11 @@
           _0 = const ();
           drop(_1) -> [return: bb1, unwind unreachable];
       }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
   }
 + 
 + ALLOC2 (size: 16, align: 8) { .. }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
index 031c021ba5a..5dafc89d53f 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
@@ -16,25 +16,23 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
-                  let _6: *mut [bool; 0];
+                  let mut _6: std::num::NonZero<usize>;
                   scope 6 {
-                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                          let mut _8: bool;
-                          let _9: ();
-                          let mut _10: *mut ();
-                          let mut _11: *const [bool; 0];
-                          scope 11 (inlined core::ub_checks::check_language_ub) {
-                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
+                      scope 8 (inlined std::ptr::Alignment::as_nonzero) {
+                      }
+                      scope 9 (inlined NonNull::<[bool; 0]>::without_provenance) {
+                          let _7: *const [bool; 0];
+                          scope 10 {
+                          }
+                          scope 11 (inlined NonZero::<usize>::get) {
+                          }
+                          scope 12 (inlined without_provenance::<[bool; 0]>) {
+                              scope 13 (inlined without_provenance_mut::<[bool; 0]>) {
                               }
                           }
                       }
                   }
-                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
-                      let mut _7: usize;
-                      scope 8 (inlined align_of::<[bool; 0]>) {
-                      }
-                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
-                      }
+                  scope 7 (inlined std::ptr::Alignment::of::<[bool; 0]>) {
                   }
               }
           }
@@ -44,50 +42,16 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
-          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
+-         _6 = const std::ptr::Alignment::of::<[bool; 0]>::{constant#0} as std::num::NonZero<usize> (Transmute);
++         _6 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
           StorageLive(_7);
--         _7 = AlignOf([bool; 0]);
--         _6 = copy _7 as *mut [bool; 0] (Transmute);
-+         _7 = const 1_usize;
-+         _6 = const {0x1 as *mut [bool; 0]};
-          StorageLive(_11);
-          StorageLive(_8);
-          _8 = UbChecks();
-          switchInt(move _8) -> [0: bb5, otherwise: bb3];
-      }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2 (cleanup): {
-          resume;
-      }
-  
-      bb3: {
-          StorageLive(_10);
--         _10 = copy _7 as *mut () (Transmute);
--         _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
-+         _10 = const {0x1 as *mut ()};
-+         _9 = NonNull::<T>::new_unchecked::precondition_check(const {0x1 as *mut ()}) -> [return: bb4, unwind unreachable];
-      }
-  
-      bb4: {
-          StorageDead(_10);
-          goto -> bb5;
-      }
-  
-      bb5: {
-          StorageDead(_8);
--         _11 = copy _7 as *const [bool; 0] (Transmute);
--         _5 = NonNull::<[bool; 0]> { pointer: copy _11 };
-+         _11 = const {0x1 as *const [bool; 0]};
+-         _7 = copy _6 as *const [bool; 0] (Transmute);
+-         _5 = NonNull::<[bool; 0]> { pointer: copy _7 };
++         _7 = const {0x1 as *const [bool; 0]};
 +         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
-          StorageDead(_11);
           StorageDead(_7);
           StorageDead(_6);
 -         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
@@ -98,7 +62,6 @@
           StorageDead(_4);
 -         _2 = Box::<[bool]>(copy _3, const std::alloc::Global);
 +         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC1, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
-          StorageDead(_9);
           StorageDead(_3);
 -         _1 = A { foo: move _2 };
 +         _1 = const A {{ foo: Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: ALLOC2, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) }};
@@ -106,6 +69,15 @@
           _0 = const ();
           drop(_1) -> [return: bb1, unwind: bb2];
       }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
   }
 + 
 + ALLOC2 (size: 16, align: 8) { .. }
diff --git a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff
index 1e378d30a3e..8e7964297d0 100644
--- a/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff
+++ b/tests/mir-opt/gvn_ptr_eq_with_constant.main.GVN.diff
@@ -6,17 +6,33 @@
       let _1: bool;
       let mut _2: *mut u8;
       scope 1 (inlined dangling_mut::<u8>) {
-          let mut _3: usize;
-          scope 2 (inlined align_of::<u8>) {
+          scope 2 (inlined NonNull::<u8>::dangling) {
+              let mut _3: std::num::NonZero<usize>;
+              scope 3 {
+                  scope 5 (inlined std::ptr::Alignment::as_nonzero) {
+                  }
+                  scope 6 (inlined NonNull::<u8>::without_provenance) {
+                      scope 7 {
+                      }
+                      scope 8 (inlined NonZero::<usize>::get) {
+                      }
+                      scope 9 (inlined without_provenance::<u8>) {
+                          scope 10 (inlined without_provenance_mut::<u8>) {
+                          }
+                      }
+                  }
+              }
+              scope 4 (inlined std::ptr::Alignment::of::<u8>) {
+              }
           }
-          scope 3 (inlined without_provenance_mut::<u8>) {
+          scope 11 (inlined NonNull::<u8>::as_ptr) {
           }
       }
-      scope 4 (inlined Foo::<u8>::cmp_ptr) {
+      scope 12 (inlined Foo::<u8>::cmp_ptr) {
           let mut _4: *const u8;
           let mut _5: *mut u8;
           let mut _6: *const u8;
-          scope 5 (inlined std::ptr::eq::<u8>) {
+          scope 13 (inlined std::ptr::eq::<u8>) {
           }
       }
   
@@ -24,9 +40,9 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
--         _3 = AlignOf(u8);
+-         _3 = const std::ptr::Alignment::of::<u8>::{constant#0} as std::num::NonZero<usize> (Transmute);
 -         _2 = copy _3 as *mut u8 (Transmute);
-+         _3 = const 1_usize;
++         _3 = const NonZero::<usize>(core::num::niche_types::NonZeroUsizeInner(1_usize));
 +         _2 = const {0x1 as *mut u8};
           StorageDead(_3);
           StorageLive(_4);
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index a2ef53e0e13..496ec78fd8d 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -19,30 +19,30 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
             debug i => _22;
             debug x => _23;
         }
-        scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 19 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
             let mut _14: &mut std::slice::Iter<'_, T>;
             let mut _15: std::option::Option<&T>;
             let mut _19: (usize, bool);
             let mut _20: (usize, &T);
-            scope 19 {
+            scope 20 {
                 let _18: usize;
-                scope 24 {
+                scope 25 {
                 }
             }
-            scope 20 {
-                scope 21 {
-                    scope 27 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
+            scope 21 {
+                scope 22 {
+                    scope 28 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
                     }
                 }
             }
-            scope 22 {
-                scope 23 {
+            scope 23 {
+                scope 24 {
                 }
             }
-            scope 25 (inlined <Option<&T> as Try>::branch) {
+            scope 26 (inlined <Option<&T> as Try>::branch) {
                 let mut _16: isize;
                 let _17: &T;
-                scope 26 {
+                scope 27 {
                 }
             }
         }
@@ -60,10 +60,12 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
+                        scope 13 (inlined without_provenance_mut::<T>) {
+                        }
                     }
-                    scope 13 (inlined NonNull::<T>::as_ptr) {
+                    scope 14 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
@@ -79,11 +81,11 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
             }
         }
     }
-    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
-        scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+    scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+        scope 17 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index c1b846e662b..c4547cb888f 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -35,10 +35,12 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
+                        scope 13 (inlined without_provenance_mut::<T>) {
+                        }
                     }
-                    scope 13 (inlined NonNull::<T>::as_ptr) {
+                    scope 14 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
@@ -54,11 +56,11 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
             }
         }
     }
-    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
-        scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+    scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+        scope 17 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 8cebf2c6bac..7d011ea3347 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -32,10 +32,12 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
+                        scope 13 (inlined without_provenance_mut::<T>) {
+                        }
                     }
-                    scope 13 (inlined NonNull::<T>::as_ptr) {
+                    scope 14 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
@@ -51,7 +53,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
             }
         }
     }
-    scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 16 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index e7e39240fed..75e6542a3a4 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -32,10 +32,12 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
+                        scope 13 (inlined without_provenance_mut::<T>) {
+                        }
                     }
-                    scope 13 (inlined NonNull::<T>::as_ptr) {
+                    scope 14 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
@@ -51,7 +53,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
             }
         }
     }
-    scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 16 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index 58f95d0a432..41bc91ab028 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _17;
         }
-        scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 19 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             let mut _14: &mut std::slice::Iter<'_, T>;
         }
     }
@@ -35,10 +35,12 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
+                        scope 13 (inlined without_provenance_mut::<T>) {
+                        }
                     }
-                    scope 13 (inlined NonNull::<T>::as_ptr) {
+                    scope 14 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
@@ -54,11 +56,11 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
             }
         }
     }
-    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
-        scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+    scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+        scope 17 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index e7ddacf3144..6ed8ef9715b 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _17;
         }
-        scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 19 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             let mut _14: &mut std::slice::Iter<'_, T>;
         }
     }
@@ -35,10 +35,12 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
+                        scope 13 (inlined without_provenance_mut::<T>) {
+                        }
                     }
-                    scope 13 (inlined NonNull::<T>::as_ptr) {
+                    scope 14 (inlined NonNull::<T>::as_ptr) {
                     }
-                    scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                    scope 15 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
                     }
                 }
                 scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
@@ -54,11 +56,11 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
             }
         }
     }
-    scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
-        scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+    scope 16 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+        scope 17 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
         }
     }
-    scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
     }
 
     bb0: {
diff --git a/tests/run-make/extern-fn-reachable/Makefile b/tests/run-make/extern-fn-reachable/Makefile
deleted file mode 100644
index 3297251bfd1..00000000000
--- a/tests/run-make/extern-fn-reachable/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# ignore-windows-msvc
-
-NM=nm -D
-
-ifeq ($(UNAME),Darwin)
-NM=nm -gU
-endif
-
-ifdef IS_WINDOWS
-NM=nm -g
-endif
-
-# This overrides the LD_LIBRARY_PATH for RUN
-TARGET_RPATH_DIR:=$(TARGET_RPATH_DIR):$(TMPDIR)
-
-all:
-	$(RUSTC) dylib.rs -o $(TMPDIR)/libdylib.so -C prefer-dynamic
-
-	[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun1)" -eq "1" ]
-	[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun2)" -eq "1" ]
-	[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun3)" -eq "1" ]
-	[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun4)" -eq "1" ]
-	[ "$$($(NM) $(TMPDIR)/libdylib.so | grep -v __imp_ | grep -c fun5)" -eq "1" ]
diff --git a/tests/run-make/extern-fn-reachable/dylib.rs b/tests/run-make/extern-fn-reachable/dylib.rs
index fe0c7023b27..42b8270b214 100644
--- a/tests/run-make/extern-fn-reachable/dylib.rs
+++ b/tests/run-make/extern-fn-reachable/dylib.rs
@@ -1,19 +1,34 @@
 #![crate_type = "dylib"]
 #![allow(dead_code)]
 
+// `pub` extern fn here is a Rust nameres visibility concept, and should not affect symbol
+// visibility in the dylib.
 #[no_mangle]
 pub extern "C" fn fun1() {}
+
+// (Lack of) `pub` for the extern fn here is a Rust nameres visibility concept, and should not
+// affect symbol visibility in the dylib.
 #[no_mangle]
 extern "C" fn fun2() {}
 
+// Modules are a Rust nameres concept, and should not affect symbol visibility in the dylib if the
+// extern fn is nested inside a module.
 mod foo {
     #[no_mangle]
     pub extern "C" fn fun3() {}
 }
+
+// Similarly, the Rust visibility of the containing module is a Rust nameres concept, and should not
+// affect symbol visibility in the dylib.
 pub mod bar {
     #[no_mangle]
     pub extern "C" fn fun4() {}
 }
 
+// Non-extern `#[no_mangle]` fn should induce a symbol visible in the dylib.
 #[no_mangle]
 pub fn fun5() {}
+
+// The Rust visibility of the fn should not affect is symbol visibility in the dylib.
+#[no_mangle]
+fn fun6() {}
diff --git a/tests/run-make/extern-fn-reachable/rmake.rs b/tests/run-make/extern-fn-reachable/rmake.rs
new file mode 100644
index 00000000000..2fc992b14eb
--- /dev/null
+++ b/tests/run-make/extern-fn-reachable/rmake.rs
@@ -0,0 +1,46 @@
+//! Smoke test to check that that symbols of `extern "C"` functions and `#[no_mangle]` rust
+//! functions:
+//!
+//! 1. Are externally visible in the dylib produced.
+//! 2. That the symbol visibility is orthogonal to the Rust nameres visibility of the functions
+//!    involved.
+
+//@ ignore-cross-compile
+
+use std::collections::BTreeSet;
+
+use run_make_support::object::{self, Object};
+use run_make_support::{dynamic_lib_name, is_darwin, path, rfs, rustc};
+
+fn main() {
+    let dylib = dynamic_lib_name("dylib");
+    rustc().input("dylib.rs").output(&dylib).arg("-Cprefer-dynamic").run();
+
+    let expected_symbols = if is_darwin() {
+        // Mach-O states that all exported symbols should have an underscore as prefix. At the
+        // same time dlsym will implicitly add it, so outside of compilers, linkers and people
+        // writing assembly, nobody needs to be aware of this.
+        BTreeSet::from(["_fun1", "_fun2", "_fun3", "_fun4", "_fun5", "_fun6"])
+    } else {
+        BTreeSet::from(["fun1", "fun2", "fun3", "fun4", "fun5", "fun6"])
+    };
+
+    let mut found_symbols = BTreeSet::new();
+
+    let blob = rfs::read(path(dylib));
+    let file = object::File::parse(&*blob).unwrap();
+    for export in file.exports().unwrap() {
+        let sym_name = export.name();
+        let sym_name = std::str::from_utf8(sym_name).unwrap();
+        found_symbols.insert(sym_name);
+    }
+
+    println!("expected_symbols = {:?}", expected_symbols);
+    println!("found_symbols = {:?}", found_symbols);
+    if !found_symbols.is_superset(&expected_symbols) {
+        for diff in expected_symbols.difference(&found_symbols) {
+            eprintln!("missing symbol: {}", diff);
+        }
+        panic!("missing expected symbols");
+    }
+}
diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml
index ad1b5e801ca..8d26b826479 100644
--- a/tests/rustdoc-gui/links-color.goml
+++ b/tests/rustdoc-gui/links-color.goml
@@ -5,6 +5,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // This is needed so that the text color is computed.
 show-text: true
 
+// First we check the links of the different items.
 define-function: (
     "check-colors",
     [theme, mod, macro, struct, enum, trait, fn, type, union, keyword,
@@ -36,6 +37,11 @@ define-function: (
             },
             ALL,
         )
+        move-cursor-to: ".desc a[href='long_code_block_link/index.html']"
+        assert-css: (
+            ".desc a[href='long_code_block_link/index.html']",
+            {"text-decoration": "underline solid " + |mod|},
+        )
     },
 )
 
diff --git a/tests/ui/consts/const-block-const-bound.rs b/tests/ui/consts/const-block-const-bound.rs
index 596aac09b31..b4b89a93e75 100644
--- a/tests/ui/consts/const-block-const-bound.rs
+++ b/tests/ui/consts/const-block-const-bound.rs
@@ -1,5 +1,3 @@
-//@ known-bug: #103507
-
 #![allow(unused)]
 #![feature(const_trait_impl, negative_impls, const_destruct)]
 
@@ -16,6 +14,6 @@ impl Drop for UnconstDrop {
 fn main() {
     const {
         f(UnconstDrop);
-        //FIXME ~^ ERROR can't drop
+        //~^ ERROR trait bound `UnconstDrop: const Destruct` is not satisfied
     }
 }
diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr
index 0931eff2175..14c62fb4d25 100644
--- a/tests/ui/consts/const-block-const-bound.stderr
+++ b/tests/ui/consts/const-block-const-bound.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `UnconstDrop: const Destruct` is not satisfied
-  --> $DIR/const-block-const-bound.rs:18:11
+  --> $DIR/const-block-const-bound.rs:16:11
    |
 LL |         f(UnconstDrop);
    |         - ^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |         f(UnconstDrop);
    |         required by a bound introduced by this call
    |
 note: required by a bound in `f`
-  --> $DIR/const-block-const-bound.rs:8:15
+  --> $DIR/const-block-const-bound.rs:6:15
    |
 LL | const fn f<T: ~const Destruct>(x: T) {}
    |               ^^^^^^ required by this bound in `f`
diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs
index 2e30eebb07b..e1c6861c510 100644
--- a/tests/ui/consts/issue-94675.rs
+++ b/tests/ui/consts/issue-94675.rs
@@ -1,5 +1,3 @@
-//@ known-bug: #103507
-
 #![feature(const_trait_impl, const_vec_string_slice)]
 
 struct Foo<'a> {
@@ -9,9 +7,7 @@ struct Foo<'a> {
 impl<'a> Foo<'a> {
     const fn spam(&mut self, baz: &mut Vec<u32>) {
         self.bar[0] = baz.len();
-        //FIXME ~^ ERROR: cannot call
-        //FIXME ~| ERROR: cannot call
-        //FIXME ~| ERROR: the trait bound
+        //~^ ERROR: cannot call
     }
 }
 
diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr
index 8cad13724f2..63a86b45633 100644
--- a/tests/ui/consts/issue-94675.stderr
+++ b/tests/ui/consts/issue-94675.stderr
@@ -1,5 +1,5 @@
 error[E0015]: cannot call non-const operator in constant functions
-  --> $DIR/issue-94675.rs:11:17
+  --> $DIR/issue-94675.rs:9:17
    |
 LL |         self.bar[0] = baz.len();
    |                 ^^^
diff --git a/tests/ui/error-codes/E0253.rs b/tests/ui/error-codes/E0253.rs
index 284b16da8f2..8284f791c64 100644
--- a/tests/ui/error-codes/E0253.rs
+++ b/tests/ui/error-codes/E0253.rs
@@ -1,10 +1,10 @@
 mod foo {
     pub trait MyTrait {
-        fn do_something();
+        type SomeType;
     }
 }
 
-use foo::MyTrait::do_something;
+use foo::MyTrait::SomeType;
     //~^ ERROR E0253
 
 fn main() {}
diff --git a/tests/ui/error-codes/E0253.stderr b/tests/ui/error-codes/E0253.stderr
index 4ee36b70fe5..954dbc81693 100644
--- a/tests/ui/error-codes/E0253.stderr
+++ b/tests/ui/error-codes/E0253.stderr
@@ -1,8 +1,8 @@
-error[E0253]: `do_something` is not directly importable
+error[E0253]: `SomeType` is not directly importable
   --> $DIR/E0253.rs:7:5
    |
-LL | use foo::MyTrait::do_something;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
+LL | use foo::MyTrait::SomeType;
+   |     ^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs
new file mode 100644
index 00000000000..aec13fb0202
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs
@@ -0,0 +1,63 @@
+//@ edition:2018
+use std::collections::HashMap;
+
+use A::{DEFAULT, new};
+//~^ ERROR `use` associated items of traits is unstable [E0658]
+//~| ERROR `use` associated items of traits is unstable [E0658]
+use Default::default;
+//~^ ERROR `use` associated items of traits is unstable [E0658]
+
+struct S {
+    a: HashMap<i32, i32>,
+}
+
+impl S {
+    fn new() -> S {
+        S { a: default() }
+    }
+}
+
+trait A: Sized {
+    const DEFAULT: Option<Self> = None;
+    fn new() -> Self;
+    fn do_something(&self);
+}
+
+mod b {
+    use super::A::{self, DEFAULT, new};
+    //~^ ERROR `use` associated items of traits is unstable [E0658]
+    //~| ERROR `use` associated items of traits is unstable [E0658]
+
+    struct B();
+
+    impl A for B {
+        const DEFAULT: Option<Self> = Some(B());
+        fn new() -> Self {
+            B()
+        }
+
+        fn do_something(&self) {}
+    }
+
+    fn f() {
+        let b: B = new();
+        b.do_something();
+        let c: B = DEFAULT.unwrap();
+    }
+}
+
+impl A for S {
+    fn new() -> Self {
+        S::new()
+    }
+
+    fn do_something(&self) {}
+}
+
+fn f() {
+    let s: S = new();
+    s.do_something();
+    let t: Option<S> = DEFAULT;
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr
new file mode 100644
index 00000000000..d342f5bd551
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr
@@ -0,0 +1,53 @@
+error[E0658]: `use` associated items of traits is unstable
+  --> $DIR/feature-gate-import-trait-associated-functions.rs:4:9
+   |
+LL | use A::{DEFAULT, new};
+   |         ^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `use` associated items of traits is unstable
+  --> $DIR/feature-gate-import-trait-associated-functions.rs:4:18
+   |
+LL | use A::{DEFAULT, new};
+   |                  ^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `use` associated items of traits is unstable
+  --> $DIR/feature-gate-import-trait-associated-functions.rs:7:5
+   |
+LL | use Default::default;
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `use` associated items of traits is unstable
+  --> $DIR/feature-gate-import-trait-associated-functions.rs:27:26
+   |
+LL |     use super::A::{self, DEFAULT, new};
+   |                          ^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: `use` associated items of traits is unstable
+  --> $DIR/feature-gate-import-trait-associated-functions.rs:27:35
+   |
+LL |     use super::A::{self, DEFAULT, new};
+   |                                   ^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.rs b/tests/ui/impl-trait/normalize-tait-in-const.rs
index 1fd543b72e7..a735ef76673 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.rs
+++ b/tests/ui/impl-trait/normalize-tait-in-const.rs
@@ -1,4 +1,5 @@
-//@ known-bug: #103507
+//! This is a regression test for <https://github.com/rust-lang/rust/issues/103507>.
+//@ known-bug: #110395
 
 #![feature(type_alias_impl_trait)]
 #![feature(const_trait_impl, const_destruct)]
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr
index f4e8a872cec..c6cd1b139c5 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.stderr
+++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr
@@ -1,5 +1,5 @@
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/normalize-tait-in-const.rs:26:35
+  --> $DIR/normalize-tait-in-const.rs:27:35
    |
 LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
    |                                   ^^^^^^ can't be applied to `Fn`
@@ -8,7 +8,7 @@ note: `Fn` can't be used with `~const` because it isn't annotated with `#[const_
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
 
 error: `~const` can only be applied to `#[const_trait]` traits
-  --> $DIR/normalize-tait-in-const.rs:26:35
+  --> $DIR/normalize-tait-in-const.rs:27:35
    |
 LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
    |                                   ^^^^^^ can't be applied to `Fn`
@@ -18,7 +18,7 @@ note: `Fn` can't be used with `~const` because it isn't annotated with `#[const_
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0015]: cannot call non-const closure in constant functions
-  --> $DIR/normalize-tait-in-const.rs:27:5
+  --> $DIR/normalize-tait-in-const.rs:28:5
    |
 LL |     fun(filter_positive());
    |     ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/imports/import-trait-method.rs b/tests/ui/imports/import-trait-method.rs
index 97dd68f1e76..a24b3a13644 100644
--- a/tests/ui/imports/import-trait-method.rs
+++ b/tests/ui/imports/import-trait-method.rs
@@ -2,6 +2,6 @@ trait Foo {
     fn foo();
 }
 
-use Foo::foo; //~ ERROR not directly importable
+use Foo::foo; //~ ERROR `use` associated items of traits is unstable [E0658]
 
-fn main() { foo(); }
+fn main() { foo(); } //~ ERROR type annotations needed
diff --git a/tests/ui/imports/import-trait-method.stderr b/tests/ui/imports/import-trait-method.stderr
index 9786eb52d35..8fe774111b9 100644
--- a/tests/ui/imports/import-trait-method.stderr
+++ b/tests/ui/imports/import-trait-method.stderr
@@ -1,9 +1,22 @@
-error[E0253]: `foo` is not directly importable
+error[E0658]: `use` associated items of traits is unstable
   --> $DIR/import-trait-method.rs:5:5
    |
 LL | use Foo::foo;
-   |     ^^^^^^^^ cannot be imported directly
+   |     ^^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0283]: type annotations needed
+  --> $DIR/import-trait-method.rs:7:13
+   |
+LL | fn main() { foo(); }
+   |             ^^^^^ cannot infer type
+   |
+   = note: cannot satisfy `_: Foo`
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0253`.
+Some errors have detailed explanations: E0283, E0658.
+For more information about an error, try `rustc --explain E0283`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs
index 364b4d35812..d7c17299d06 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs
@@ -2,9 +2,23 @@
 
 #![feature(target_feature_11)]
 
+#[target_feature(enable = "avx")]
+fn foo_avx() {}
+
 #[target_feature(enable = "sse2")]
 fn foo() {}
 
+#[target_feature(enable = "sse2")]
+fn bar() {
+    let foo: fn() = foo; // this is OK, as we have the necessary target features.
+    let foo: fn() = foo_avx; //~ ERROR mismatched types
+}
+
 fn main() {
+    if std::is_x86_feature_detected!("sse2") {
+        unsafe {
+            bar();
+        }
+    }
     let foo: fn() = foo; //~ ERROR mismatched types
 }
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr
index a2bda229d10..1228404120a 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr
@@ -1,5 +1,20 @@
 error[E0308]: mismatched types
-  --> $DIR/fn-ptr.rs:9:21
+  --> $DIR/fn-ptr.rs:14:21
+   |
+LL | #[target_feature(enable = "avx")]
+   | --------------------------------- `#[target_feature]` added here
+...
+LL |     let foo: fn() = foo_avx;
+   |              ----   ^^^^^^^ cannot coerce functions with `#[target_feature]` to safe function pointers
+   |              |
+   |              expected due to this
+   |
+   = note: expected fn pointer `fn()`
+                 found fn item `#[target_features] fn() {foo_avx}`
+   = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
+
+error[E0308]: mismatched types
+  --> $DIR/fn-ptr.rs:23:21
    |
 LL | #[target_feature(enable = "sse2")]
    | ---------------------------------- `#[target_feature]` added here
@@ -13,6 +28,6 @@ LL |     let foo: fn() = foo;
                  found fn item `#[target_features] fn() {foo}`
    = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/return-fn-ptr.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/return-fn-ptr.rs
new file mode 100644
index 00000000000..b49493d6609
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/return-fn-ptr.rs
@@ -0,0 +1,22 @@
+//@ only-x86_64
+//@ run-pass
+
+#![feature(target_feature_11)]
+
+#[target_feature(enable = "sse2")]
+fn foo() -> bool {
+    true
+}
+
+#[target_feature(enable = "sse2")]
+fn bar() -> fn() -> bool {
+    foo
+}
+
+fn main() {
+    if !std::is_x86_feature_detected!("sse2") {
+        return;
+    }
+    let f = unsafe { bar() };
+    assert!(f());
+}
diff --git a/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr b/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr
new file mode 100644
index 00000000000..593a90d728f
--- /dev/null
+++ b/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr
@@ -0,0 +1,39 @@
+error[E0425]: cannot find function `cmp` in this scope
+  --> $DIR/fn-to-method.rs:12:13
+   |
+LL |     let x = cmp(&1, &2);
+   |             ^^^ not found in this scope
+   |
+help: consider importing one of these associated functions
+   |
+LL + use std::cmp::Ord::cmp;
+   |
+LL + use std::iter::Iterator::cmp;
+   |
+
+error[E0425]: cannot find function `len` in this scope
+  --> $DIR/fn-to-method.rs:16:13
+   |
+LL |     let y = len([1, 2, 3]);
+   |             ^^^ not found in this scope
+   |
+help: consider importing this associated function
+   |
+LL + use std::iter::ExactSizeIterator::len;
+   |
+
+error[E0425]: cannot find function `bar` in this scope
+  --> $DIR/fn-to-method.rs:20:13
+   |
+LL |     let z = bar(Foo);
+   |             ^^^ not found in this scope
+   |
+help: use the `.` operator to call the method `bar` on `Foo`
+   |
+LL -     let z = bar(Foo);
+LL +     let z = Foo.bar();
+   |
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/suggestions/fn-to-method.stderr b/tests/ui/suggestions/fn-to-method.normal.stderr
index 36c17e60d35..502be79481a 100644
--- a/tests/ui/suggestions/fn-to-method.stderr
+++ b/tests/ui/suggestions/fn-to-method.normal.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find function `cmp` in this scope
-  --> $DIR/fn-to-method.rs:8:13
+  --> $DIR/fn-to-method.rs:12:13
    |
 LL |     let x = cmp(&1, &2);
    |             ^^^ not found in this scope
@@ -10,7 +10,7 @@ LL |     let x = (&1).cmp(&2);
    |             ~  ~~~~~~~~~
 
 error[E0425]: cannot find function `len` in this scope
-  --> $DIR/fn-to-method.rs:12:13
+  --> $DIR/fn-to-method.rs:16:13
    |
 LL |     let y = len([1, 2, 3]);
    |             ^^^ not found in this scope
@@ -22,7 +22,7 @@ LL +     let y = [1, 2, 3].len();
    |
 
 error[E0425]: cannot find function `bar` in this scope
-  --> $DIR/fn-to-method.rs:16:13
+  --> $DIR/fn-to-method.rs:20:13
    |
 LL |     let z = bar(Foo);
    |             ^^^ not found in this scope
diff --git a/tests/ui/suggestions/fn-to-method.rs b/tests/ui/suggestions/fn-to-method.rs
index 9a35c3efc41..619ac444649 100644
--- a/tests/ui/suggestions/fn-to-method.rs
+++ b/tests/ui/suggestions/fn-to-method.rs
@@ -1,4 +1,8 @@
+//@ revisions: normal import_trait_associated_functions
+#![cfg_attr(import_trait_associated_functions, feature(import_trait_associated_functions))]
 struct Foo;
+//[import_trait_associated_functions]~^ HELP consider importing one of these associated functions
+//[import_trait_associated_functions]~| HELP consider importing this associated function
 
 impl Foo {
     fn bar(self) {}
@@ -7,11 +11,11 @@ impl Foo {
 fn main() {
     let x = cmp(&1, &2);
     //~^ ERROR cannot find function `cmp` in this scope
-    //~| HELP use the `.` operator to call the method `Ord::cmp` on `&{integer}`
+    //[normal]~| HELP use the `.` operator to call the method `Ord::cmp` on `&{integer}`
 
     let y = len([1, 2, 3]);
     //~^ ERROR cannot find function `len` in this scope
-    //~| HELP use the `.` operator to call the method `len` on `&[{integer}]`
+    //[normal]~| HELP use the `.` operator to call the method `len` on `&[{integer}]`
 
     let z = bar(Foo);
     //~^ ERROR cannot find function `bar` in this scope
diff --git a/tests/ui/use/import_trait_associated_functions-2015.rs b/tests/ui/use/import_trait_associated_functions-2015.rs
new file mode 100644
index 00000000000..3177aeefb09
--- /dev/null
+++ b/tests/ui/use/import_trait_associated_functions-2015.rs
@@ -0,0 +1,61 @@
+//@ edition:2015
+//@ check-pass
+#![feature(import_trait_associated_functions)]
+
+use std::collections::HashMap;
+
+use A::{DEFAULT, new};
+use std::default::Default::default;
+
+struct S {
+    a: HashMap<i32, i32>,
+}
+
+impl S {
+    fn new() -> S {
+        S { a: default() }
+    }
+}
+
+trait A: Sized {
+    const DEFAULT: Option<Self> = None;
+    fn new() -> Self;
+    fn do_something(&self);
+}
+
+mod b {
+    use super::A::{self, DEFAULT, new};
+
+    struct B();
+
+    impl A for B {
+        const DEFAULT: Option<Self> = Some(B());
+        fn new() -> Self {
+            B()
+        }
+
+        fn do_something(&self) {}
+    }
+
+    fn f() {
+        let b: B = new();
+        b.do_something();
+        let c: B = DEFAULT.unwrap();
+    }
+}
+
+impl A for S {
+    fn new() -> Self {
+        S::new()
+    }
+
+    fn do_something(&self) {}
+}
+
+fn f() {
+    let s: S = new();
+    s.do_something();
+    let t: Option<S> = DEFAULT;
+}
+
+fn main() {}
diff --git a/tests/ui/use/import_trait_associated_functions.rs b/tests/ui/use/import_trait_associated_functions.rs
new file mode 100644
index 00000000000..4dc473404db
--- /dev/null
+++ b/tests/ui/use/import_trait_associated_functions.rs
@@ -0,0 +1,61 @@
+//@ edition:2018
+//@ check-pass
+#![feature(import_trait_associated_functions)]
+
+use std::collections::HashMap;
+
+use A::{DEFAULT, new};
+use Default::default;
+
+struct S {
+    a: HashMap<i32, i32>,
+}
+
+impl S {
+    fn new() -> S {
+        S { a: default() }
+    }
+}
+
+trait A: Sized {
+    const DEFAULT: Option<Self> = None;
+    fn new() -> Self;
+    fn do_something(&self);
+}
+
+mod b {
+    use super::A::{self, DEFAULT, new};
+
+    struct B();
+
+    impl A for B {
+        const DEFAULT: Option<Self> = Some(B());
+        fn new() -> Self {
+            B()
+        }
+
+        fn do_something(&self) {}
+    }
+
+    fn f() {
+        let b: B = new();
+        b.do_something();
+        let c: B = DEFAULT.unwrap();
+    }
+}
+
+impl A for S {
+    fn new() -> Self {
+        S::new()
+    }
+
+    fn do_something(&self) {}
+}
+
+fn f() {
+    let s: S = new();
+    s.do_something();
+    let t: Option<S> = DEFAULT;
+}
+
+fn main() {}
diff --git a/tests/ui/use/use-from-trait-xc.rs b/tests/ui/use/use-from-trait-xc.rs
index b7b9c834b32..b030892aa26 100644
--- a/tests/ui/use/use-from-trait-xc.rs
+++ b/tests/ui/use/use-from-trait-xc.rs
@@ -3,13 +3,13 @@
 extern crate use_from_trait_xc;
 
 use use_from_trait_xc::Trait::foo;
-//~^ ERROR `foo` is not directly importable
+//~^ ERROR `use` associated items of traits is unstable [E0658]
 
 use use_from_trait_xc::Trait::Assoc;
 //~^ ERROR `Assoc` is not directly importable
 
 use use_from_trait_xc::Trait::CONST;
-//~^ ERROR `CONST` is not directly importable
+//~^ ERROR `use` associated items of traits is unstable [E0658]
 
 use use_from_trait_xc::Foo::new; //~ ERROR struct `Foo` is private
 //~^ ERROR unresolved import `use_from_trait_xc::Foo`
diff --git a/tests/ui/use/use-from-trait-xc.stderr b/tests/ui/use/use-from-trait-xc.stderr
index 4c4c2f6225f..0f8440aa530 100644
--- a/tests/ui/use/use-from-trait-xc.stderr
+++ b/tests/ui/use/use-from-trait-xc.stderr
@@ -1,8 +1,12 @@
-error[E0253]: `foo` is not directly importable
+error[E0658]: `use` associated items of traits is unstable
   --> $DIR/use-from-trait-xc.rs:5:5
    |
 LL | use use_from_trait_xc::Trait::foo;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0253]: `Assoc` is not directly importable
   --> $DIR/use-from-trait-xc.rs:8:5
@@ -10,11 +14,15 @@ error[E0253]: `Assoc` is not directly importable
 LL | use use_from_trait_xc::Trait::Assoc;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
 
-error[E0253]: `CONST` is not directly importable
+error[E0658]: `use` associated items of traits is unstable
   --> $DIR/use-from-trait-xc.rs:11:5
    |
 LL | use use_from_trait_xc::Trait::CONST;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0432]: unresolved import `use_from_trait_xc::Foo`
   --> $DIR/use-from-trait-xc.rs:14:24
@@ -66,5 +74,5 @@ LL | struct Foo;
 
 error: aborting due to 9 previous errors
 
-Some errors have detailed explanations: E0253, E0432, E0603.
+Some errors have detailed explanations: E0253, E0432, E0603, E0658.
 For more information about an error, try `rustc --explain E0253`.
diff --git a/tests/ui/use/use-from-trait.rs b/tests/ui/use/use-from-trait.rs
index eab4bb6e3b5..89b7aaa4ba3 100644
--- a/tests/ui/use/use-from-trait.rs
+++ b/tests/ui/use/use-from-trait.rs
@@ -1,6 +1,6 @@
-use Trait::foo; //~ ERROR `foo` is not directly importable
+use Trait::foo; //~ ERROR `use` associated items of traits is unstable [E0658]
 use Trait::Assoc; //~ ERROR `Assoc` is not directly importable
-use Trait::C; //~ ERROR `C` is not directly importable
+use Trait::C; //~ ERROR `use` associated items of traits is unstable [E0658]
 
 use Foo::new; //~ ERROR unresolved import `Foo` [E0432]
 
diff --git a/tests/ui/use/use-from-trait.stderr b/tests/ui/use/use-from-trait.stderr
index a5b0e356b34..2dd78a35452 100644
--- a/tests/ui/use/use-from-trait.stderr
+++ b/tests/ui/use/use-from-trait.stderr
@@ -1,8 +1,12 @@
-error[E0253]: `foo` is not directly importable
+error[E0658]: `use` associated items of traits is unstable
   --> $DIR/use-from-trait.rs:1:5
    |
 LL | use Trait::foo;
-   |     ^^^^^^^^^^ cannot be imported directly
+   |     ^^^^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0253]: `Assoc` is not directly importable
   --> $DIR/use-from-trait.rs:2:5
@@ -10,11 +14,15 @@ error[E0253]: `Assoc` is not directly importable
 LL | use Trait::Assoc;
    |     ^^^^^^^^^^^^ cannot be imported directly
 
-error[E0253]: `C` is not directly importable
+error[E0658]: `use` associated items of traits is unstable
   --> $DIR/use-from-trait.rs:3:5
    |
 LL | use Trait::C;
-   |     ^^^^^^^^ cannot be imported directly
+   |     ^^^^^^^^
+   |
+   = note: see issue #134691 <https://github.com/rust-lang/rust/issues/134691> for more information
+   = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0432]: unresolved import `Foo`
   --> $DIR/use-from-trait.rs:5:5
@@ -30,5 +38,5 @@ LL | use Foo::C2;
 
 error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0253, E0432.
+Some errors have detailed explanations: E0253, E0432, E0658.
 For more information about an error, try `rustc --explain E0253`.