about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--RELEASES.md117
-rw-r--r--compiler/rustc_abi/src/layout.rs76
-rw-r--r--compiler/rustc_abi/src/lib.rs69
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs56
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs5
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs1
-rw-r--r--compiler/rustc_borrowck/src/lib.rs2
-rw-r--r--compiler/rustc_borrowck/src/places_conflict.rs2
-rw-r--r--compiler/rustc_borrowck/src/prefixes.rs3
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/value_and_place.rs10
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs2
-rwxr-xr-xcompiler/rustc_codegen_gcc/test.sh2
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs93
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs45
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs25
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs25
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs32
-rw-r--r--compiler/rustc_const_eval/src/util/compare_types.rs14
-rw-r--r--compiler/rustc_const_eval/src/util/mod.rs2
-rw-r--r--compiler/rustc_fluent_macro/src/fluent.rs58
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs60
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs74
-rw-r--r--compiler/rustc_infer/messages.ftl4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/test_type_match.rs24
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs10
-rw-r--r--compiler/rustc_llvm/Cargo.toml4
-rw-r--r--compiler/rustc_log/src/lib.rs4
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs10
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs15
-rw-r--r--compiler/rustc_middle/src/mir/statement.rs3
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs14
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs9
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs9
-rw-r--r--compiler/rustc_middle/src/ty/_match.rs12
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs9
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs25
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs1
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs9
-rw-r--r--compiler/rustc_mir_transform/src/add_subtyping_projections.rs66
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs37
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs81
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs57
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs34
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs1
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs24
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs10
-rw-r--r--compiler/rustc_monomorphize/messages.ftl2
-rw-r--r--compiler/rustc_parse/messages.ftl30
-rw-r--r--compiler/rustc_query_system/messages.ftl2
-rw-r--r--compiler/rustc_resolve/messages.ftl12
-rw-r--r--compiler/rustc_resolve/src/late.rs38
-rw-r--r--compiler/rustc_session/messages.ftl2
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs91
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs52
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs9
-rw-r--r--config.example.toml17
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/rc.rs4
-rw-r--r--library/alloc/src/sync.rs4
-rw-r--r--library/core/src/fmt/mod.rs6
-rw-r--r--library/core/src/hint.rs2
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/primitive_docs.rs10
-rw-r--r--library/core/src/ptr/mod.rs24
-rw-r--r--library/core/src/result.rs1
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/net/udp.rs21
-rw-r--r--library/std/src/process.rs4
-rw-r--r--library/std/src/sync/rwlock.rs4
-rw-r--r--library/std/src/sys/personality/gcc.rs2
-rw-r--r--library/std/src/sys/uefi/mod.rs1
-rw-r--r--library/std/src/sys/uefi/stdio.rs162
-rw-r--r--library/std/src/sys/unix/fs.rs1
m---------library/stdarch0
-rw-r--r--src/bootstrap/CHANGELOG.md71
-rw-r--r--src/bootstrap/README.md14
-rw-r--r--src/bootstrap/bin/main.rs41
-rw-r--r--src/bootstrap/bootstrap_test.py2
-rw-r--r--src/bootstrap/compile.rs17
-rw-r--r--src/bootstrap/config.rs20
-rw-r--r--src/bootstrap/config/tests.rs12
-rw-r--r--src/bootstrap/install.rs6
-rw-r--r--src/bootstrap/lib.rs23
-rw-r--r--src/bootstrap/setup.rs5
-rw-r--r--src/doc/rustc/src/platform-support.md47
-rw-r--r--src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md2
-rw-r--r--src/doc/rustc/src/platform-support/nto-qnx.md2
-rw-r--r--src/doc/rustc/src/platform-support/openharmony.md2
-rw-r--r--src/doc/rustc/src/platform-support/unknown-uefi.md8
-rw-r--r--src/tools/build_helper/src/ci.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs1
-rw-r--r--src/tools/opt-dist/src/tests.rs2
-rw-r--r--tests/assembly/stack-protector/stack-protector-heuristics-effect.rs3
-rw-r--r--tests/codegen/issue-97217.rs22
-rw-r--r--tests/codegen/unwind-landingpad-cold.rs16
-rw-r--r--tests/codegen/unwind-landingpad-inline.rs39
-rw-r--r--tests/coverage-map/status-quo/async.cov-map90
-rw-r--r--tests/coverage-map/status-quo/async2.cov-map28
-rw-r--r--tests/coverage-map/status-quo/closure.cov-map185
-rw-r--r--tests/coverage-map/status-quo/closure_bug.cov-map125
-rw-r--r--tests/coverage-map/status-quo/closure_macro.cov-map22
-rw-r--r--tests/coverage-map/status-quo/closure_macro_async.cov-map22
-rw-r--r--tests/coverage-map/status-quo/conditions.cov-map338
-rw-r--r--tests/coverage-map/status-quo/continue.cov-map74
-rw-r--r--tests/coverage-map/status-quo/dead_code.cov-map8
-rw-r--r--tests/coverage-map/status-quo/generator.cov-map39
-rw-r--r--tests/coverage-map/status-quo/inline-dead.cov-map12
-rw-r--r--tests/coverage-map/status-quo/inline.cov-map26
-rw-r--r--tests/coverage-map/status-quo/issue-93054.cov-map8
-rw-r--r--tests/coverage-map/status-quo/lazy_boolean.cov-map372
-rw-r--r--tests/coverage-map/status-quo/loops_branches.cov-map218
-rw-r--r--tests/coverage-map/status-quo/no_cov_crate.cov-map4
-rw-r--r--tests/coverage-map/status-quo/partial_eq.cov-map12
-rw-r--r--tests/coverage-map/status-quo/simple_loop.cov-map23
-rw-r--r--tests/coverage-map/status-quo/simple_match.cov-map31
-rw-r--r--tests/coverage-map/status-quo/test_harness.cov-map4
-rw-r--r--tests/coverage-map/status-quo/try_error_result.cov-map166
-rw-r--r--tests/coverage-map/status-quo/unused.cov-map16
-rw-r--r--tests/coverage-map/status-quo/yield.cov-map62
-rw-r--r--tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff48
-rw-r--r--tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff48
-rw-r--r--tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff2
-rw-r--r--tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff9
-rw-r--r--tests/ui/async-await/issue-108572.fixed16
-rw-r--r--tests/ui/async-await/issue-108572.rs7
-rw-r--r--tests/ui/async-await/issue-108572.stderr9
-rw-r--r--tests/ui/async-await/pin-needed-to-poll.stderr8
-rw-r--r--tests/ui/const-generics/occurs-check/unused-substs-1.stderr2
-rw-r--r--tests/ui/generic-const-items/unsatisfied-bounds.stderr2
-rw-r--r--tests/ui/impl-trait/issues/issue-62742.stderr5
-rw-r--r--tests/ui/indexing/index-help.stderr3
-rw-r--r--tests/ui/indexing/indexing-requires-a-uint.stderr3
-rw-r--r--tests/ui/integral-indexing.stderr24
-rw-r--r--tests/ui/issues/issue-34334.stderr3
-rw-r--r--tests/ui/issues/issue-45801.stderr1
-rw-r--r--tests/ui/issues/issue-66923-show-error-for-correct-call.stderr6
-rw-r--r--tests/ui/iterators/invalid-iterator-chain.stderr6
-rw-r--r--tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr1
-rw-r--r--tests/ui/on-unimplemented/impl-substs.stderr3
-rw-r--r--tests/ui/on-unimplemented/on-impl.stderr3
-rw-r--r--tests/ui/on-unimplemented/slice-index.stderr3
-rw-r--r--tests/ui/or-patterns/missing-bindings.stderr84
-rw-r--r--tests/ui/resolve/resolve-inconsistent-names.stderr42
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.rs28
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.stderr26
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs9
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr20
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr32
-rw-r--r--tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed3
-rw-r--r--tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr10
-rw-r--r--tests/ui/span/issue-39698.stderr34
-rw-r--r--tests/ui/str/str-idx.stderr9
-rw-r--r--tests/ui/str/str-mut-idx.stderr9
-rw-r--r--tests/ui/suggestions/issue-101623.stderr3
-rw-r--r--tests/ui/suggestions/suggest-dereferencing-index.stderr3
-rw-r--r--tests/ui/traits/coercion-generic-bad.stderr1
-rw-r--r--tests/ui/traits/non_lifetime_binders/on-rpit.rs16
-rw-r--r--tests/ui/traits/non_lifetime_binders/on-rpit.stderr11
-rw-r--r--tests/ui/try-block/try-block-bad-type.stderr1
-rw-r--r--tests/ui/try-trait/bad-interconversion.stderr9
-rw-r--r--tests/ui/type/type-check/point-at-inference-issue-116155.rs17
-rw-r--r--tests/ui/type/type-check/point-at-inference-issue-116155.stderr18
-rw-r--r--triagebot.toml5
194 files changed, 2775 insertions, 1963 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 7f91d12a419..f0a3553da2b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2009,9 +2009,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
 
 [[package]]
 name = "jemalloc-sys"
-version = "0.5.3+5.3.0-patched"
+version = "0.5.4+5.3.0-patched"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9bd5d616ea7ed58b571b2e209a65759664d7fb021a0819d7a790afc67e47ca1"
+checksum = "ac6c1946e1cea1788cbfde01c993b52a10e2da07f4bac608228d1bed20bfebf2"
 dependencies = [
  "cc",
  "libc",
diff --git a/RELEASES.md b/RELEASES.md
index d390f2b7f5e..e261294a032 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,120 @@
+Version 1.73.0 (2023-10-05)
+==========================
+
+<a id="1.73.0-Language"></a>
+
+Language
+--------
+
+- [Uplift `clippy::fn_null_check` lint as `useless_ptr_null_checks`.](https://github.com/rust-lang/rust/pull/111717/)
+- [Make `noop_method_call` warn by default.](https://github.com/rust-lang/rust/pull/111916/)
+- [Support interpolated block for `try` and `async` in macros.](https://github.com/rust-lang/rust/pull/112953/)
+- [Make `unconditional_recursion` lint detect recursive drops.](https://github.com/rust-lang/rust/pull/113902/)
+- [Future compatibility warning for some impls being incorrectly considered not overlapping.](https://github.com/rust-lang/rust/pull/114023/)
+- [The `invalid_reference_casting` lint is now **deny-by-default** (instead of allow-by-default)](https://github.com/rust-lang/rust/pull/112431)
+
+<a id="1.73.0-Compiler"></a>
+
+Compiler
+--------
+
+- [Write version information in a `.comment` section like GCC/Clang.](https://github.com/rust-lang/rust/pull/97550/)
+- [Add documentation on v0 symbol mangling.](https://github.com/rust-lang/rust/pull/97571/)
+- [Stabilize `extern "thiscall"` and `"thiscall-unwind"` ABIs.](https://github.com/rust-lang/rust/pull/114562/)
+- [Only check outlives goals on impl compared to trait.](https://github.com/rust-lang/rust/pull/109356/)
+- [Infer type in irrefutable slice patterns with fixed length as array.](https://github.com/rust-lang/rust/pull/113199/)
+- [Discard default auto trait impls if explicit ones exist.](https://github.com/rust-lang/rust/pull/113312/)
+- Add several new tier 3 targets:
+    - [`aarch64-unknown-teeos`](https://github.com/rust-lang/rust/pull/113480/)
+    - [`csky-unknown-linux-gnuabiv2`](https://github.com/rust-lang/rust/pull/113658/)
+    - [`riscv64-linux-android`](https://github.com/rust-lang/rust/pull/112858/)
+    - [`riscv64gc-unknown-hermit`](https://github.com/rust-lang/rust/pull/114004/)
+    - [`x86_64-unikraft-linux-musl`](https://github.com/rust-lang/rust/pull/113411/)
+    - [`x86_64-unknown-linux-ohos`](https://github.com/rust-lang/rust/pull/113061/)
+- [Add `wasm32-wasi-preview1-threads` as a tier 2 target.](https://github.com/rust-lang/rust/pull/112922/)
+
+Refer to Rust's [platform support page][platform-support-doc]
+for more information on Rust's tiered platform support.
+
+<a id="1.73.0-Libraries"></a>
+
+Libraries
+---------
+
+- [Add `Read`, `Write` and `Seek` impls for `Arc<File>`.](https://github.com/rust-lang/rust/pull/94748/)
+- [Merge functionality of `io::Sink` into `io::Empty`.](https://github.com/rust-lang/rust/pull/98154/)
+- [Implement `RefUnwindSafe` for `Backtrace`](https://github.com/rust-lang/rust/pull/100455/)
+- [Make `ExitStatus` implement `Default`](https://github.com/rust-lang/rust/pull/106425/)
+- [`impl SliceIndex<str> for (Bound<usize>, Bound<usize>)`](https://github.com/rust-lang/rust/pull/111081/)
+- [Change default panic handler message format.](https://github.com/rust-lang/rust/pull/112849/)
+- [Cleaner `assert_eq!` & `assert_ne!` panic messages.](https://github.com/rust-lang/rust/pull/111071/)
+- [Correct the (deprecated) Android `stat` struct definitions.](https://github.com/rust-lang/rust/pull/113130/)
+
+<a id="1.73.0-Stabilized-APIs"></a>
+
+Stabilized APIs
+---------------
+
+- [Unsigned `{integer}::div_ceil`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.div_ceil)
+- [Unsigned `{integer}::next_multiple_of`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.next_multiple_of)
+- [Unsigned `{integer}::checked_next_multiple_of`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.checked_next_multiple_of)
+- [`std::ffi::FromBytesUntilNulError`](https://doc.rust-lang.org/stable/std/ffi/struct.FromBytesUntilNulError.html)
+- [`std::os::unix::fs::chown`](https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chown.html)
+- [`std::os::unix::fs::fchown`](https://doc.rust-lang.org/stable/std/os/unix/fs/fn.fchown.html)
+- [`std::os::unix::fs::lchown`](https://doc.rust-lang.org/stable/std/os/unix/fs/fn.lchown.html)
+- [`LocalKey::<Cell<T>>::get`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.get)
+- [`LocalKey::<Cell<T>>::set`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.set)
+- [`LocalKey::<Cell<T>>::take`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.take)
+- [`LocalKey::<Cell<T>>::replace`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.replace)
+- [`LocalKey::<RefCell<T>>::with_borrow`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.with_borrow)
+- [`LocalKey::<RefCell<T>>::with_borrow_mut`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.with_borrow_mut)
+- [`LocalKey::<RefCell<T>>::set`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.set-1)
+- [`LocalKey::<RefCell<T>>::take`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.take-1)
+- [`LocalKey::<RefCell<T>>::replace`](https://doc.rust-lang.org/stable/std/thread/struct.LocalKey.html#method.replace-1)
+
+These APIs are now stable in const contexts:
+
+- [`rc::Weak::new`](https://doc.rust-lang.org/stable/alloc/rc/struct.Weak.html#method.new)
+- [`sync::Weak::new`](https://doc.rust-lang.org/stable/alloc/sync/struct.Weak.html#method.new)
+- [`NonNull::as_ref`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.as_ref)
+
+<a id="1.73.0-Cargo"></a>
+
+Cargo
+-----
+
+- [Encode URL params correctly for `SourceId` in `Cargo.lock`.](https://github.com/rust-lang/cargo/pull/12280/)
+- [Bail out an error when using `cargo::` in custom build script.](https://github.com/rust-lang/cargo/pull/12332/)
+
+<a id="1.73.0-Misc"></a>
+
+Misc
+----
+
+<a id="1.73.0-Compatibility-Notes"></a>
+
+Compatibility Notes
+-------------------
+
+- [Update the minimum external LLVM to 15.](https://github.com/rust-lang/rust/pull/114148/)
+- [Check for non-defining uses of return position `impl Trait`.](https://github.com/rust-lang/rust/pull/112842/)
+
+<a id="1.73.0-Internal-Changes"></a>
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- [Remove LLVM pointee types, supporting only opaque pointers.](https://github.com/rust-lang/rust/pull/105545/)
+- [Port PGO/LTO/BOLT optimized build pipeline to Rust.](https://github.com/rust-lang/rust/pull/112235/)
+- [Replace in-tree `rustc_apfloat` with the new version of the crate.](https://github.com/rust-lang/rust/pull/113843/)
+- [Update to LLVM 17.](https://github.com/rust-lang/rust/pull/114048/)
+- [Add `internal_features` lint for internal unstable features.](https://github.com/rust-lang/rust/pull/108955/)
+- [Mention style for new syntax in tracking issue template.](https://github.com/rust-lang/rust/pull/113586/)
+
 Version 1.72.1 (2023-09-19)
 ===========================
 
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 0706dc18f0e..e096ad7e6df 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -53,32 +53,32 @@ pub trait LayoutCalculator {
         kind: StructKind,
     ) -> Option<LayoutS> {
         let layout = univariant(self, dl, fields, repr, kind, NicheBias::Start);
-        // Enums prefer niches close to the beginning or the end of the variants so that other (smaller)
-        // data-carrying variants can be packed into the space after/before the niche.
+        // Enums prefer niches close to the beginning or the end of the variants so that other
+        // (smaller) data-carrying variants can be packed into the space after/before the niche.
         // If the default field ordering does not give us a niche at the front then we do a second
-        // run and bias niches to the right and then check which one is closer to one of the struct's
-        // edges.
+        // run and bias niches to the right and then check which one is closer to one of the
+        // struct's edges.
         if let Some(layout) = &layout {
             // Don't try to calculate an end-biased layout for unsizable structs,
             // otherwise we could end up with different layouts for
-            // Foo<Type> and Foo<dyn Trait> which would break unsizing
+            // Foo<Type> and Foo<dyn Trait> which would break unsizing.
             if !matches!(kind, StructKind::MaybeUnsized) {
                 if let Some(niche) = layout.largest_niche {
                     let head_space = niche.offset.bytes();
-                    let niche_length = niche.value.size(dl).bytes();
-                    let tail_space = layout.size.bytes() - head_space - niche_length;
+                    let niche_len = niche.value.size(dl).bytes();
+                    let tail_space = layout.size.bytes() - head_space - niche_len;
 
-                    // This may end up doing redundant work if the niche is already in the last field
-                    // (e.g. a trailing bool) and there is tail padding. But it's non-trivial to get
-                    // the unpadded size so we try anyway.
+                    // This may end up doing redundant work if the niche is already in the last
+                    // field (e.g. a trailing bool) and there is tail padding. But it's non-trivial
+                    // to get the unpadded size so we try anyway.
                     if fields.len() > 1 && head_space != 0 && tail_space > 0 {
                         let alt_layout = univariant(self, dl, fields, repr, kind, NicheBias::End)
                             .expect("alt layout should always work");
-                        let niche = alt_layout
+                        let alt_niche = alt_layout
                             .largest_niche
                             .expect("alt layout should have a niche like the regular one");
-                        let alt_head_space = niche.offset.bytes();
-                        let alt_niche_len = niche.value.size(dl).bytes();
+                        let alt_head_space = alt_niche.offset.bytes();
+                        let alt_niche_len = alt_niche.value.size(dl).bytes();
                         let alt_tail_space =
                             alt_layout.size.bytes() - alt_head_space - alt_niche_len;
 
@@ -93,7 +93,7 @@ pub trait LayoutCalculator {
                             alt_layout: {}\n",
                             layout.size.bytes(),
                             head_space,
-                            niche_length,
+                            niche_len,
                             tail_space,
                             alt_head_space,
                             alt_niche_len,
@@ -684,7 +684,8 @@ pub trait LayoutCalculator {
                 // Also do not overwrite any already existing "clever" ABIs.
                 if variant.fields.count() > 0 && matches!(variant.abi, Abi::Aggregate { .. }) {
                     variant.abi = abi;
-                    // Also need to bump up the size and alignment, so that the entire value fits in here.
+                    // Also need to bump up the size and alignment, so that the entire value fits
+                    // in here.
                     variant.size = cmp::max(variant.size, size);
                     variant.align.abi = cmp::max(variant.align.abi, align.abi);
                 }
@@ -868,15 +869,15 @@ fn univariant(
 
         // If `-Z randomize-layout` was enabled for the type definition we can shuffle
         // the field ordering to try and catch some code making assumptions about layouts
-        // we don't guarantee
+        // we don't guarantee.
         if repr.can_randomize_type_layout() && cfg!(feature = "randomize") {
             #[cfg(feature = "randomize")]
             {
-                // `ReprOptions.layout_seed` is a deterministic seed that we can use to
-                // randomize field ordering with
+                // `ReprOptions.layout_seed` is a deterministic seed we can use to randomize field
+                // ordering.
                 let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed.as_u64());
 
-                // Shuffle the ordering of the fields
+                // Shuffle the ordering of the fields.
                 optimizing.shuffle(&mut rng);
             }
             // Otherwise we just leave things alone and actually optimize the type's fields
@@ -892,27 +893,26 @@ fn univariant(
                 .max()
                 .unwrap_or(0);
 
-            // Calculates a sort key to group fields by their alignment or possibly some size-derived
-            // pseudo-alignment.
+            // Calculates a sort key to group fields by their alignment or possibly some
+            // size-derived pseudo-alignment.
             let alignment_group_key = |layout: Layout<'_>| {
                 if let Some(pack) = pack {
-                    // return the packed alignment in bytes
+                    // Return the packed alignment in bytes.
                     layout.align().abi.min(pack).bytes()
                 } else {
-                    // returns log2(effective-align).
-                    // This is ok since `pack` applies to all fields equally.
-                    // The calculation assumes that size is an integer multiple of align, except for ZSTs.
-                    //
+                    // Returns `log2(effective-align)`. This is ok since `pack` applies to all
+                    // fields equally. The calculation assumes that size is an integer multiple of
+                    // align, except for ZSTs.
                     let align = layout.align().abi.bytes();
                     let size = layout.size().bytes();
                     let niche_size = layout.largest_niche().map(|n| n.available(dl)).unwrap_or(0);
-                    // group [u8; 4] with align-4 or [u8; 6] with align-2 fields
+                    // Group [u8; 4] with align-4 or [u8; 6] with align-2 fields.
                     let size_as_align = align.max(size).trailing_zeros();
                     let size_as_align = if largest_niche_size > 0 {
                         match niche_bias {
-                            // Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the array
-                            // to the front in the first case (for aligned loads) but keep the bool in front
-                            // in the second case for its niches.
+                            // Given `A(u8, [u8; 16])` and `B(bool, [u8; 16])` we want to bump the
+                            // array to the front in the first case (for aligned loads) but keep
+                            // the bool in front in the second case for its niches.
                             NicheBias::Start => max_field_align.trailing_zeros().min(size_as_align),
                             // When moving niches towards the end of the struct then for
                             // A((u8, u8, u8, bool), (u8, bool, u8)) we want to keep the first tuple
@@ -931,14 +931,14 @@ fn univariant(
 
             match kind {
                 StructKind::AlwaysSized | StructKind::MaybeUnsized => {
-                    // Currently `LayoutS` only exposes a single niche so sorting is usually sufficient
-                    // to get one niche into the preferred position. If it ever supported multiple niches
-                    // then a more advanced pick-and-pack approach could provide better results.
-                    // But even for the single-niche cache it's not optimal. E.g. for
-                    // A(u32, (bool, u8), u16) it would be possible to move the bool to the front
-                    // but it would require packing the tuple together with the u16 to build a 4-byte
-                    // group so that the u32 can be placed after it without padding. This kind
-                    // of packing can't be achieved by sorting.
+                    // Currently `LayoutS` only exposes a single niche so sorting is usually
+                    // sufficient to get one niche into the preferred position. If it ever
+                    // supported multiple niches then a more advanced pick-and-pack approach could
+                    // provide better results. But even for the single-niche cache it's not
+                    // optimal. E.g. for A(u32, (bool, u8), u16) it would be possible to move the
+                    // bool to the front but it would require packing the tuple together with the
+                    // u16 to build a 4-byte group so that the u32 can be placed after it without
+                    // padding. This kind of packing can't be achieved by sorting.
                     optimizing.sort_by_key(|&x| {
                         let f = fields[x];
                         let field_size = f.size().bytes();
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index b30ff058a30..31566c221cc 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -53,10 +53,11 @@ bitflags! {
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))]
 pub enum IntegerType {
-    /// Pointer sized integer type, i.e. isize and usize. The field shows signedness, that
-    /// is, `Pointer(true)` is isize.
+    /// Pointer-sized integer type, i.e. `isize` and `usize`. The field shows signedness, e.g.
+    /// `Pointer(true)` means `isize`.
     Pointer(bool),
-    /// Fix sized integer type, e.g. i8, u32, i128 The bool field shows signedness, `Fixed(I8, false)` means `u8`
+    /// Fixed-sized integer type, e.g. `i8`, `u32`, `i128`. The bool field shows signedness, e.g.
+    /// `Fixed(I8, false)` means `u8`.
     Fixed(Integer, bool),
 }
 
@@ -69,7 +70,7 @@ impl IntegerType {
     }
 }
 
-/// Represents the repr options provided by the user,
+/// Represents the repr options provided by the user.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
 #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))]
 pub struct ReprOptions {
@@ -139,7 +140,7 @@ impl ReprOptions {
     }
 
     /// Returns `true` if this type is valid for reordering and `-Z randomize-layout`
-    /// was enabled for its declaration crate
+    /// was enabled for its declaration crate.
     pub fn can_randomize_type_layout(&self) -> bool {
         !self.inhibit_struct_field_reordering_opt()
             && self.flags.contains(ReprFlags::RANDOMIZE_LAYOUT)
@@ -217,7 +218,8 @@ pub enum TargetDataLayoutErrors<'a> {
 }
 
 impl TargetDataLayout {
-    /// Parse data layout from an [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
+    /// Parse data layout from an
+    /// [llvm data layout string](https://llvm.org/docs/LangRef.html#data-layout)
     ///
     /// This function doesn't fill `c_enum_min_size` and it will always be `I32` since it can not be
     /// determined from llvm string.
@@ -242,10 +244,11 @@ impl TargetDataLayout {
         };
 
         // Parse a size string.
-        let size = |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
+        let parse_size =
+            |s: &'a str, cause: &'a str| parse_bits(s, "size", cause).map(Size::from_bits);
 
         // Parse an alignment string.
-        let align = |s: &[&'a str], cause: &'a str| {
+        let parse_align = |s: &[&'a str], cause: &'a str| {
             if s.is_empty() {
                 return Err(TargetDataLayoutErrors::MissingAlignment { cause });
             }
@@ -269,22 +272,22 @@ impl TargetDataLayout {
                 [p] if p.starts_with('P') => {
                     dl.instruction_address_space = parse_address_space(&p[1..], "P")?
                 }
-                ["a", ref a @ ..] => dl.aggregate_align = align(a, "a")?,
-                ["f32", ref a @ ..] => dl.f32_align = align(a, "f32")?,
-                ["f64", ref a @ ..] => dl.f64_align = align(a, "f64")?,
+                ["a", ref a @ ..] => dl.aggregate_align = parse_align(a, "a")?,
+                ["f32", ref a @ ..] => dl.f32_align = parse_align(a, "f32")?,
+                ["f64", ref a @ ..] => dl.f64_align = parse_align(a, "f64")?,
                 // FIXME(erikdesjardins): we should be parsing nonzero address spaces
                 // this will require replacing TargetDataLayout::{pointer_size,pointer_align}
                 // with e.g. `fn pointer_size_in(AddressSpace)`
                 [p @ "p", s, ref a @ ..] | [p @ "p0", s, ref a @ ..] => {
-                    dl.pointer_size = size(s, p)?;
-                    dl.pointer_align = align(a, p)?;
+                    dl.pointer_size = parse_size(s, p)?;
+                    dl.pointer_align = parse_align(a, p)?;
                 }
                 [s, ref a @ ..] if s.starts_with('i') => {
                     let Ok(bits) = s[1..].parse::<u64>() else {
-                        size(&s[1..], "i")?; // For the user error.
+                        parse_size(&s[1..], "i")?; // For the user error.
                         continue;
                     };
-                    let a = align(a, s)?;
+                    let a = parse_align(a, s)?;
                     match bits {
                         1 => dl.i1_align = a,
                         8 => dl.i8_align = a,
@@ -301,8 +304,8 @@ impl TargetDataLayout {
                     }
                 }
                 [s, ref a @ ..] if s.starts_with('v') => {
-                    let v_size = size(&s[1..], "v")?;
-                    let a = align(a, s)?;
+                    let v_size = parse_size(&s[1..], "v")?;
+                    let a = parse_align(a, s)?;
                     if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) {
                         v.1 = a;
                         continue;
@@ -747,7 +750,6 @@ impl Align {
 /// A pair of alignments, ABI-mandated and preferred.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 #[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
-
 pub struct AbiAndPrefAlign {
     pub abi: Align,
     pub pref: Align,
@@ -773,7 +775,6 @@ impl AbiAndPrefAlign {
 /// Integers, also used for enum discriminants.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))]
-
 pub enum Integer {
     I8,
     I16,
@@ -937,8 +938,7 @@ impl Primitive {
 }
 
 /// Inclusive wrap-around range of valid values, that is, if
-/// start > end, it represents `start..=MAX`,
-/// followed by `0..=end`.
+/// start > end, it represents `start..=MAX`, followed by `0..=end`.
 ///
 /// That is, for an i8 primitive, a range of `254..=2` means following
 /// sequence:
@@ -970,21 +970,21 @@ impl WrappingRange {
 
     /// Returns `self` with replaced `start`
     #[inline(always)]
-    pub fn with_start(mut self, start: u128) -> Self {
+    fn with_start(mut self, start: u128) -> Self {
         self.start = start;
         self
     }
 
     /// Returns `self` with replaced `end`
     #[inline(always)]
-    pub fn with_end(mut self, end: u128) -> Self {
+    fn with_end(mut self, end: u128) -> Self {
         self.end = end;
         self
     }
 
     /// Returns `true` if `size` completely fills the range.
     #[inline]
-    pub fn is_full_for(&self, size: Size) -> bool {
+    fn is_full_for(&self, size: Size) -> bool {
         let max_value = size.unsigned_int_max();
         debug_assert!(self.start <= max_value && self.end <= max_value);
         self.start == (self.end.wrapping_add(1) & max_value)
@@ -1066,7 +1066,8 @@ impl Scalar {
     }
 
     #[inline]
-    /// Allows the caller to mutate the valid range. This operation will panic if attempted on a union.
+    /// Allows the caller to mutate the valid range. This operation will panic if attempted on a
+    /// union.
     pub fn valid_range_mut(&mut self) -> &mut WrappingRange {
         match self {
             Scalar::Initialized { valid_range, .. } => valid_range,
@@ -1074,7 +1075,8 @@ impl Scalar {
         }
     }
 
-    /// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole layout
+    /// Returns `true` if all possible numbers are valid, i.e `valid_range` covers the whole
+    /// layout.
     #[inline]
     pub fn is_always_valid<C: HasDataLayout>(&self, cx: &C) -> bool {
         match *self {
@@ -1252,7 +1254,6 @@ impl AddressSpace {
 /// in terms of categories of C types there are ABI rules for.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 #[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
-
 pub enum Abi {
     Uninhabited,
     Scalar(Scalar),
@@ -1457,17 +1458,19 @@ impl Niche {
             return None;
         }
 
-        // Extend the range of valid values being reserved by moving either `v.start` or `v.end` bound.
-        // Given an eventual `Option<T>`, we try to maximize the chance for `None` to occupy the niche of zero.
-        // This is accomplished by preferring enums with 2 variants(`count==1`) and always taking the shortest path to niche zero.
-        // Having `None` in niche zero can enable some special optimizations.
+        // Extend the range of valid values being reserved by moving either `v.start` or `v.end`
+        // bound. Given an eventual `Option<T>`, we try to maximize the chance for `None` to occupy
+        // the niche of zero. This is accomplished by preferring enums with 2 variants(`count==1`)
+        // and always taking the shortest path to niche zero. Having `None` in niche zero can
+        // enable some special optimizations.
         //
         // Bound selection criteria:
         // 1. Select closest to zero given wrapping semantics.
         // 2. Avoid moving past zero if possible.
         //
-        // In practice this means that enums with `count > 1` are unlikely to claim niche zero, since they have to fit perfectly.
-        // If niche zero is already reserved, the selection of bounds are of little interest.
+        // In practice this means that enums with `count > 1` are unlikely to claim niche zero,
+        // since they have to fit perfectly. If niche zero is already reserved, the selection of
+        // bounds are of little interest.
         let move_start = |v: WrappingRange| {
             let start = v.start.wrapping_sub(count) & max_value;
             Some((start, Scalar::Initialized { value, valid_range: v.with_start(start) }))
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 7bc685a5450..743fad8e865 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -52,7 +52,8 @@ struct AstValidator<'a> {
     /// Are we inside a trait impl?
     in_trait_impl: bool,
 
-    in_const_trait_impl: bool,
+    /// Are we inside a const trait defn or impl?
+    in_const_trait_or_impl: bool,
 
     has_proc_macro_decls: bool,
 
@@ -78,11 +79,19 @@ impl<'a> AstValidator<'a> {
         f: impl FnOnce(&mut Self),
     ) {
         let old = mem::replace(&mut self.in_trait_impl, is_in);
-        let old_const =
-            mem::replace(&mut self.in_const_trait_impl, matches!(constness, Some(Const::Yes(_))));
+        let old_const = mem::replace(
+            &mut self.in_const_trait_or_impl,
+            matches!(constness, Some(Const::Yes(_))),
+        );
         f(self);
         self.in_trait_impl = old;
-        self.in_const_trait_impl = old_const;
+        self.in_const_trait_or_impl = old_const;
+    }
+
+    fn with_in_trait(&mut self, is_const: bool, f: impl FnOnce(&mut Self)) {
+        let old = mem::replace(&mut self.in_const_trait_or_impl, is_const);
+        f(self);
+        self.in_const_trait_or_impl = old;
     }
 
     fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
@@ -933,23 +942,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
             }
             ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => {
-                if *is_auto == IsAuto::Yes {
-                    // Auto traits cannot have generics, super traits nor contain items.
-                    self.deny_generic_params(generics, item.ident.span);
-                    self.deny_super_traits(bounds, item.ident.span);
-                    self.deny_where_clause(&generics.where_clause, item.ident.span);
-                    self.deny_items(items, item.ident.span);
-                }
+                let is_const_trait = attr::contains_name(&item.attrs, sym::const_trait);
+                self.with_in_trait(is_const_trait, |this| {
+                    if *is_auto == IsAuto::Yes {
+                        // Auto traits cannot have generics, super traits nor contain items.
+                        this.deny_generic_params(generics, item.ident.span);
+                        this.deny_super_traits(bounds, item.ident.span);
+                        this.deny_where_clause(&generics.where_clause, item.ident.span);
+                        this.deny_items(items, item.ident.span);
+                    }
 
-                // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound
-                // context for the supertraits.
-                self.visit_vis(&item.vis);
-                self.visit_ident(item.ident);
-                self.visit_generics(generics);
-                self.with_tilde_const_allowed(|this| {
-                    walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
+                    // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound
+                    // context for the supertraits.
+                    this.visit_vis(&item.vis);
+                    this.visit_ident(item.ident);
+                    this.visit_generics(generics);
+                    this.with_tilde_const_allowed(|this| {
+                        walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
+                    });
+                    walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait);
                 });
-                walk_list!(self, visit_assoc_item, items, AssocCtxt::Trait);
                 walk_list!(self, visit_attribute, &item.attrs);
                 return; // Avoid visiting again
             }
@@ -1278,7 +1290,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
         let tilde_const_allowed =
             matches!(fk.header(), Some(FnHeader { constness: ast::Const::Yes(_), .. }))
-                || matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
+                || matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)) if self.in_const_trait_or_impl);
 
         let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
 
@@ -1363,7 +1375,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 walk_list!(self, visit_ty, ty);
             }
             AssocItemKind::Fn(box Fn { sig, generics, body, .. })
-                if self.in_const_trait_impl
+                if self.in_const_trait_or_impl
                     || ctxt == AssocCtxt::Trait
                     || matches!(sig.header.constness, Const::Yes(_)) =>
             {
@@ -1510,7 +1522,7 @@ pub fn check_crate(
         features,
         extern_mod: None,
         in_trait_impl: false,
-        in_const_trait_impl: false,
+        in_const_trait_or_impl: false,
         has_proc_macro_decls: false,
         outer_impl_trait: None,
         disallow_tilde_const: None,
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 48d09f2c2b2..d676906ff5e 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2828,6 +2828,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         }
                         ProjectionElem::ConstantIndex { .. }
                         | ProjectionElem::Subslice { .. }
+                        | ProjectionElem::Subtype(_)
                         | ProjectionElem::Index(_) => kind,
                     },
                     place_ty.projection_ty(tcx, elem),
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index f70263e9dcf..c3cf7db32b1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -242,6 +242,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 ProjectionElem::Downcast(..) if opt.including_downcast => return None,
                 ProjectionElem::Downcast(..) => (),
                 ProjectionElem::OpaqueCast(..) => (),
+                ProjectionElem::Subtype(..) => (),
                 ProjectionElem::Field(field, _ty) => {
                     // FIXME(project-rfc_2229#36): print capture precisely here.
                     if let Some(field) = self.is_upvar_field_projection(PlaceRef {
@@ -322,7 +323,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx)
                 }
                 ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx),
-                ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(*ty),
+                ProjectionElem::Subtype(ty) | ProjectionElem::OpaqueCast(ty) => {
+                    PlaceTy::from_ty(*ty)
+                }
                 ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
             },
         };
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index a0edeec59d0..8ca57383e82 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -159,6 +159,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     [
                         ..,
                         ProjectionElem::Index(_)
+                        | ProjectionElem::Subtype(_)
                         | ProjectionElem::ConstantIndex { .. }
                         | ProjectionElem::OpaqueCast { .. }
                         | ProjectionElem::Subslice { .. }
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 8115c61e89d..990f098efc5 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1803,6 +1803,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         for (place_base, elem) in place.iter_projections().rev() {
             match elem {
                 ProjectionElem::Index(_/*operand*/) |
+                ProjectionElem::Subtype(_) |
                 ProjectionElem::OpaqueCast(_) |
                 ProjectionElem::ConstantIndex { .. } |
                 // assigning to P[i] requires P to be valid.
@@ -2191,6 +2192,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     | ProjectionElem::Index(..)
                     | ProjectionElem::ConstantIndex { .. }
                     | ProjectionElem::Subslice { .. }
+                    | ProjectionElem::Subtype(..)
                     | ProjectionElem::OpaqueCast { .. }
                     | ProjectionElem::Downcast(..) => {
                         let upvar_field_projection = self.is_upvar_field_projection(place);
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index c02f6f3b687..539d0837659 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -249,6 +249,7 @@ fn place_components_conflict<'tcx>(
                 | (ProjectionElem::ConstantIndex { .. }, _, _)
                 | (ProjectionElem::Subslice { .. }, _, _)
                 | (ProjectionElem::OpaqueCast { .. }, _, _)
+                | (ProjectionElem::Subtype(_), _, _)
                 | (ProjectionElem::Downcast { .. }, _, _) => {
                     // Recursive case. This can still be disjoint on a
                     // further iteration if this a shallow access and
@@ -508,6 +509,7 @@ fn place_projection_conflict<'tcx>(
             | ProjectionElem::Field(..)
             | ProjectionElem::Index(..)
             | ProjectionElem::ConstantIndex { .. }
+            | ProjectionElem::Subtype(_)
             | ProjectionElem::OpaqueCast { .. }
             | ProjectionElem::Subslice { .. }
             | ProjectionElem::Downcast(..),
diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs
index 6f281349863..e9c9709bd1f 100644
--- a/compiler/rustc_borrowck/src/prefixes.rs
+++ b/compiler/rustc_borrowck/src/prefixes.rs
@@ -89,6 +89,9 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
                             cursor = cursor_base;
                             continue 'cursor;
                         }
+                        ProjectionElem::Subtype(..) => {
+                            panic!("Subtype projection is not allowed before borrow check")
+                        }
                         ProjectionElem::Deref => {
                             // (handled below)
                         }
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 9b952f3fe36..e7b1a489f5d 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -716,6 +716,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                 }
                 PlaceTy::from_ty(fty)
             }
+            ProjectionElem::Subtype(_) => {
+                bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
+            }
             ProjectionElem::OpaqueCast(ty) => {
                 let ty = self.sanitize_type(place, ty);
                 let ty = self.cx.normalize(ty, location);
@@ -2563,6 +2566,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 | ProjectionElem::Subslice { .. } => {
                     // other field access
                 }
+                ProjectionElem::Subtype(_) => {
+                    bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
+                }
             }
         }
     }
diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
index e6bbac647e5..f09b9ef12de 100644
--- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
@@ -31,7 +31,7 @@ index d95b5b7f17f..00b6f0e3635 100644
 EOF
 
 cat > config.toml <<EOF
-changelog-seen = 2
+change-id = 115898
 
 [llvm]
 ninja = false
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 6d55fdc3074..0a451dad9d2 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -876,6 +876,7 @@ pub(crate) fn codegen_place<'tcx>(
                 cplace = cplace.place_deref(fx);
             }
             PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"),
+            PlaceElem::Subtype(ty) => cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty)),
             PlaceElem::Field(field, _ty) => {
                 cplace = cplace.place_field(fx, field);
             }
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index d4273c0b593..45893a4f3ac 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -674,6 +674,16 @@ impl<'tcx> CPlace<'tcx> {
         }
     }
 
+    /// Used for `ProjectionElem::Subtype`, `ty` has to be monomorphized before
+    /// passed on.
+    pub(crate) fn place_transmute_type(
+        self,
+        fx: &mut FunctionCx<'_, '_, 'tcx>,
+        ty: Ty<'tcx>,
+    ) -> CPlace<'tcx> {
+        CPlace { inner: self.inner, layout: fx.layout_of(ty) }
+    }
+
     pub(crate) fn place_field(
         self,
         fx: &mut FunctionCx<'_, '_, 'tcx>,
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 308cb04cac3..ecc293aee23 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -1420,7 +1420,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
         self.cx
     }
 
-    fn do_not_inline(&mut self, _llret: RValue<'gcc>) {
+    fn apply_attrs_to_cleanup_callsite(&mut self, _llret: RValue<'gcc>) {
         // FIXME(bjorn3): implement
     }
 
diff --git a/compiler/rustc_codegen_gcc/test.sh b/compiler/rustc_codegen_gcc/test.sh
index 592997b8ab9..b462e5d156b 100755
--- a/compiler/rustc_codegen_gcc/test.sh
+++ b/compiler/rustc_codegen_gcc/test.sh
@@ -214,7 +214,7 @@ function setup_rustc() {
     rm config.toml || true
 
     cat > config.toml <<EOF
-changelog-seen = 2
+change-id = 115898
 
 [rust]
 codegen-backends = []
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index ac6d8f84142..4f9b86ec20a 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -3,6 +3,7 @@ use crate::attributes;
 use crate::common::Funclet;
 use crate::context::CodegenCx;
 use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True};
+use crate::llvm_util;
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
@@ -1225,9 +1226,16 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
     }
 
-    fn do_not_inline(&mut self, llret: &'ll Value) {
-        let noinline = llvm::AttributeKind::NoInline.create_attr(self.llcx);
-        attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[noinline]);
+    fn apply_attrs_to_cleanup_callsite(&mut self, llret: &'ll Value) {
+        if llvm_util::get_version() < (17, 0, 2) {
+            // Work around https://github.com/llvm/llvm-project/issues/66984.
+            let noinline = llvm::AttributeKind::NoInline.create_attr(self.llcx);
+            attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[noinline]);
+        } else {
+            // Cleanup is always the cold path.
+            let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx);
+            attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]);
+        }
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
index e83110dcad4..55f43aa5341 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
@@ -11,7 +11,7 @@ pub struct Expression {
     lhs: Operand,
     op: Op,
     rhs: Operand,
-    region: Option<CodeRegion>,
+    code_regions: Vec<CodeRegion>,
 }
 
 /// Collects all of the coverage regions associated with (a) injected counters, (b) counter
@@ -30,7 +30,7 @@ pub struct FunctionCoverage<'tcx> {
     instance: Instance<'tcx>,
     source_hash: u64,
     is_used: bool,
-    counters: IndexVec<CounterId, Option<CodeRegion>>,
+    counters: IndexVec<CounterId, Option<Vec<CodeRegion>>>,
     expressions: IndexVec<ExpressionId, Option<Expression>>,
     unreachable_regions: Vec<CodeRegion>,
 }
@@ -77,28 +77,40 @@ impl<'tcx> FunctionCoverage<'tcx> {
         }
     }
 
-    /// Adds a code region to be counted by an injected counter intrinsic.
-    pub fn add_counter(&mut self, id: CounterId, region: CodeRegion) {
-        if let Some(previous_region) = self.counters[id].replace(region.clone()) {
-            assert_eq!(previous_region, region, "add_counter: code region for id changed");
+    /// Adds code regions to be counted by an injected counter intrinsic.
+    #[instrument(level = "debug", skip(self))]
+    pub(crate) fn add_counter(&mut self, id: CounterId, code_regions: &[CodeRegion]) {
+        if code_regions.is_empty() {
+            return;
+        }
+
+        let slot = &mut self.counters[id];
+        match slot {
+            None => *slot = Some(code_regions.to_owned()),
+            // If this counter ID slot has already been filled, it should
+            // contain identical information.
+            Some(ref previous_regions) => assert_eq!(
+                previous_regions, code_regions,
+                "add_counter: code regions for id changed"
+            ),
         }
     }
 
+    /// Adds information about a coverage expression, along with zero or more
+    /// code regions mapped to that expression.
+    ///
     /// Both counters and "counter expressions" (or simply, "expressions") can be operands in other
     /// expressions. These are tracked as separate variants of `Operand`, so there is no ambiguity
     /// between operands that are counter IDs and operands that are expression IDs.
-    pub fn add_counter_expression(
+    #[instrument(level = "debug", skip(self))]
+    pub(crate) fn add_counter_expression(
         &mut self,
         expression_id: ExpressionId,
         lhs: Operand,
         op: Op,
         rhs: Operand,
-        region: Option<CodeRegion>,
+        code_regions: &[CodeRegion],
     ) {
-        debug!(
-            "add_counter_expression({:?}, lhs={:?}, op={:?}, rhs={:?} at {:?}",
-            expression_id, lhs, op, rhs, region
-        );
         debug_assert!(
             expression_id.as_usize() < self.expressions.len(),
             "expression_id {} is out of range for expressions.len() = {}
@@ -107,23 +119,25 @@ impl<'tcx> FunctionCoverage<'tcx> {
             self.expressions.len(),
             self,
         );
-        if let Some(previous_expression) = self.expressions[expression_id].replace(Expression {
-            lhs,
-            op,
-            rhs,
-            region: region.clone(),
-        }) {
-            assert_eq!(
-                previous_expression,
-                Expression { lhs, op, rhs, region },
+
+        let expression = Expression { lhs, op, rhs, code_regions: code_regions.to_owned() };
+        let slot = &mut self.expressions[expression_id];
+        match slot {
+            None => *slot = Some(expression),
+            // If this expression ID slot has already been filled, it should
+            // contain identical information.
+            Some(ref previous_expression) => assert_eq!(
+                previous_expression, &expression,
                 "add_counter_expression: expression for id changed"
-            );
+            ),
         }
     }
 
-    /// Add a region that will be marked as "unreachable", with a constant "zero counter".
-    pub fn add_unreachable_region(&mut self, region: CodeRegion) {
-        self.unreachable_regions.push(region)
+    /// Adds regions that will be marked as "unreachable", with a constant "zero counter".
+    #[instrument(level = "debug", skip(self))]
+    pub(crate) fn add_unreachable_regions(&mut self, code_regions: &[CodeRegion]) {
+        assert!(!code_regions.is_empty(), "unreachable regions always have code regions");
+        self.unreachable_regions.extend_from_slice(code_regions);
     }
 
     /// Perform some simplifications to make the final coverage mappings
@@ -212,11 +226,16 @@ impl<'tcx> FunctionCoverage<'tcx> {
     }
 
     fn counter_regions(&self) -> impl Iterator<Item = (Counter, &CodeRegion)> {
-        self.counters.iter_enumerated().filter_map(|(index, entry)| {
-            // Option::map() will return None to filter out missing counters. This may happen
-            // if, for example, a MIR-instrumented counter is removed during an optimization.
-            entry.as_ref().map(|region| (Counter::counter_value_reference(index), region))
-        })
+        self.counters
+            .iter_enumerated()
+            // Filter out counter IDs that we never saw during MIR traversal.
+            // This can happen if a counter was optimized out by MIR transforms
+            // (and replaced with `CoverageKind::Unreachable` instead).
+            .filter_map(|(id, maybe_code_regions)| Some((id, maybe_code_regions.as_ref()?)))
+            .flat_map(|(id, code_regions)| {
+                let counter = Counter::counter_value_reference(id);
+                code_regions.iter().map(move |region| (counter, region))
+            })
     }
 
     /// Convert this function's coverage expression data into a form that can be
@@ -254,13 +273,17 @@ impl<'tcx> FunctionCoverage<'tcx> {
 
     fn expression_regions(&self) -> Vec<(Counter, &CodeRegion)> {
         // Find all of the expression IDs that weren't optimized out AND have
-        // an attached code region, and return the corresponding mapping as a
-        // counter/region pair.
+        // one or more attached code regions, and return the corresponding
+        // mappings as counter/region pairs.
         self.expressions
             .iter_enumerated()
-            .filter_map(|(id, expression)| {
-                let code_region = expression.as_ref()?.region.as_ref()?;
-                Some((Counter::expression(id), code_region))
+            .filter_map(|(id, maybe_expression)| {
+                let code_regions = &maybe_expression.as_ref()?.code_regions;
+                Some((id, code_regions))
+            })
+            .flat_map(|(id, code_regions)| {
+                let counter = Counter::expression(id);
+                code_regions.iter().map(move |code_region| (counter, code_region))
             })
             .collect::<Vec<_>>()
     }
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index c70cb670e96..dd2ce9b525b 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -89,9 +89,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     /// `function_coverage_map` (keyed by function `Instance`) during codegen.
     /// But in this case, since the unused function was _not_ previously
     /// codegenned, collect the coverage `CodeRegion`s from the MIR and add
-    /// them. The first `CodeRegion` is used to add a single counter, with the
-    /// same counter ID used in the injected `instrprof.increment` intrinsic
-    /// call. Since the function is never called, all other `CodeRegion`s can be
+    /// them. Since the function is never called, all of its `CodeRegion`s can be
     /// added as `unreachable_region`s.
     fn define_unused_fn(&self, def_id: DefId) {
         let instance = declare_unused_fn(self, def_id);
@@ -110,25 +108,15 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
             .entry(instance)
             .or_insert_with(|| FunctionCoverage::new(bx.tcx(), instance));
 
-        let Coverage { kind, code_region } = coverage.clone();
-        match kind {
+        let Coverage { kind, code_regions } = coverage;
+        match *kind {
             CoverageKind::Counter { function_source_hash, id } => {
                 debug!(
                     "ensuring function source hash is set for instance={:?}; function_source_hash={}",
                     instance, function_source_hash,
                 );
                 func_coverage.set_function_source_hash(function_source_hash);
-
-                if let Some(code_region) = code_region {
-                    // Note: Some counters do not have code regions, but may still be referenced
-                    // from expressions. In that case, don't add the counter to the coverage map,
-                    // but do inject the counter intrinsic.
-                    debug!(
-                        "adding counter to coverage_map: instance={:?}, id={:?}, region={:?}",
-                        instance, id, code_region,
-                    );
-                    func_coverage.add_counter(id, code_region);
-                }
+                func_coverage.add_counter(id, code_regions);
                 // We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,
                 // as that needs an exclusive borrow.
                 drop(coverage_map);
@@ -146,20 +134,10 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
                 bx.instrprof_increment(fn_name, hash, num_counters, index);
             }
             CoverageKind::Expression { id, lhs, op, rhs } => {
-                debug!(
-                    "adding counter expression to coverage_map: instance={:?}, id={:?}, {:?} {:?} {:?}; region: {:?}",
-                    instance, id, lhs, op, rhs, code_region,
-                );
-                func_coverage.add_counter_expression(id, lhs, op, rhs, code_region);
+                func_coverage.add_counter_expression(id, lhs, op, rhs, code_regions);
             }
             CoverageKind::Unreachable => {
-                let code_region =
-                    code_region.expect("unreachable regions always have code regions");
-                debug!(
-                    "adding unreachable code to coverage_map: instance={:?}, at {:?}",
-                    instance, code_region,
-                );
-                func_coverage.add_unreachable_region(code_region);
+                func_coverage.add_unreachable_regions(code_regions);
             }
         }
     }
@@ -227,14 +205,9 @@ fn add_unused_function_coverage<'tcx>(
     let tcx = cx.tcx;
 
     let mut function_coverage = FunctionCoverage::unused(tcx, instance);
-    for (index, &code_region) in tcx.covered_code_regions(def_id).iter().enumerate() {
-        if index == 0 {
-            // Insert at least one real counter so the LLVM CoverageMappingReader will find expected
-            // definitions.
-            function_coverage.add_counter(UNUSED_FUNCTION_COUNTER_ID, code_region.clone());
-        } else {
-            function_coverage.add_unreachable_region(code_region.clone());
-        }
+    for &code_region in tcx.covered_code_regions(def_id) {
+        let code_region = std::slice::from_ref(code_region);
+        function_coverage.add_unreachable_regions(code_region);
     }
 
     if let Some(coverage_context) = cx.coverage_context() {
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index bd0707edfd9..a0cb97d51a0 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -213,7 +213,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
                 self.funclet(fx),
             );
             if fx.mir[self.bb].is_cleanup {
-                bx.do_not_inline(invokeret);
+                bx.apply_attrs_to_cleanup_callsite(invokeret);
             }
 
             if let Some((ret_dest, target)) = destination {
@@ -228,11 +228,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
         } else {
             let llret = bx.call(fn_ty, fn_attrs, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx));
             if fx.mir[self.bb].is_cleanup {
-                // Cleanup is always the cold path. Don't inline
-                // drop glue. Also, when there is a deeply-nested
-                // struct, there are "symmetry" issues that cause
-                // exponential inlining - see issue #41696.
-                bx.do_not_inline(llret);
+                bx.apply_attrs_to_cleanup_callsite(llret);
             }
 
             if let Some((ret_dest, target)) = destination {
@@ -1627,7 +1623,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let fn_ty = bx.fn_decl_backend_type(&fn_abi);
 
         let llret = bx.call(fn_ty, None, Some(&fn_abi), fn_ptr, &[], funclet.as_ref());
-        bx.do_not_inline(llret);
+        bx.apply_attrs_to_cleanup_callsite(llret);
 
         bx.unreachable();
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index f775711f870..eb590a45a63 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -466,6 +466,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 mir::ProjectionElem::OpaqueCast(ty) => {
                     bug!("encountered OpaqueCast({ty}) in codegen")
                 }
+                mir::ProjectionElem::Subtype(ty) => cg_base.project_type(bx, self.monomorphize(ty)),
                 mir::ProjectionElem::Index(index) => {
                     let index = &mir::Operand::Copy(mir::Place::from(index));
                     let index = self.codegen_operand(bx, index);
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 853c6934c2c..aa411f002a0 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -332,5 +332,5 @@ pub trait BuilderMethods<'a, 'tcx>:
     ) -> Self::Value;
     fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
 
-    fn do_not_inline(&mut self, llret: Self::Value);
+    fn apply_attrs_to_cleanup_callsite(&mut self, llret: Self::Value);
 }
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 94a5cc67d31..af7dfbef2ff 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -13,7 +13,7 @@ use rustc_middle::ty::layout::{
     self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
     TyAndLayout,
 };
-use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, Variance};
 use rustc_mir_dataflow::storage::always_storage_live_locals;
 use rustc_session::Limit;
 use rustc_span::Span;
@@ -384,7 +384,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
     // all normal lifetimes are erased, higher-ranked types with their
     // late-bound lifetimes are still around and can lead to type
     // differences.
-    if util::is_subtype(tcx, param_env, src.ty, dest.ty) {
+    if util::relate_types(tcx, param_env, Variance::Covariant, src.ty, dest.ty) {
         // Make sure the layout is equal, too -- just to be safe. Miri really
         // needs layout equality. For performance reason we skip this check when
         // the types are equal. Equal types *can* have different layouts when
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index a32ea204f98..99dba977a43 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -670,19 +670,24 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         trace!("eval_place_to_op: got {:?}", op);
         // Sanity-check the type we ended up with.
-        debug_assert!(
-            mir_assign_valid_types(
+        if cfg!(debug_assertions) {
+            let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions(
+                mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
+            )?;
+            if !mir_assign_valid_types(
                 *self.tcx,
                 self.param_env,
-                self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions(
-                    mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty
-                )?)?,
+                self.layout_of(normalized_place_ty)?,
                 op.layout,
-            ),
-            "eval_place of a MIR place with type {:?} produced an interpreter operand with type {}",
-            mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
-            op.layout.ty,
-        );
+            ) {
+                span_bug!(
+                    self.cur_span(),
+                    "eval_place of a MIR place with type {} produced an interpreter operand with type {}",
+                    normalized_place_ty,
+                    op.layout.ty,
+                )
+            }
+        }
         Ok(op)
     }
 
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 503004cbbe1..79448f07cae 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -573,19 +573,24 @@ where
 
         trace!("{:?}", self.dump_place(&place));
         // Sanity-check the type we ended up with.
-        debug_assert!(
-            mir_assign_valid_types(
+        if cfg!(debug_assertions) {
+            let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions(
+                mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
+            )?;
+            if !mir_assign_valid_types(
                 *self.tcx,
                 self.param_env,
-                self.layout_of(self.subst_from_current_frame_and_normalize_erasing_regions(
-                    mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty
-                )?)?,
+                self.layout_of(normalized_place_ty)?,
                 place.layout,
-            ),
-            "eval_place of a MIR place with type {:?} produced an interpreter place with type {}",
-            mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
-            place.layout.ty,
-        );
+            ) {
+                span_bug!(
+                    self.cur_span(),
+                    "eval_place of a MIR place with type {} produced an interpreter place with type {}",
+                    normalized_place_ty,
+                    place.layout.ty,
+                )
+            }
+        }
         Ok(place)
     }
 
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index f462c13816e..70df3d8fd78 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -319,6 +319,8 @@ where
             OpaqueCast(ty) => {
                 span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck")
             }
+            // We don't want anything happening here, this is here as a dummy.
+            Subtype(_) => base.transmute(base.layout(), self)?,
             Field(field, _) => self.project_field(base, field.index())?,
             Downcast(_, variant) => self.project_downcast(base, variant)?,
             Deref => self.deref_pointer(&base.to_op(self)?)?.into(),
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 9d00ade477a..d380849fefe 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -664,6 +664,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             | ProjectionElem::Downcast(..)
             | ProjectionElem::OpaqueCast(..)
             | ProjectionElem::Subslice { .. }
+            | ProjectionElem::Subtype(..)
             | ProjectionElem::Field(..)
             | ProjectionElem::Index(_) => {}
         }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 34e9b76c484..de3186a53c1 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -306,6 +306,7 @@ where
             ProjectionElem::Index(index) if in_local(index) => return true,
 
             ProjectionElem::Deref
+            | ProjectionElem::Subtype(_)
             | ProjectionElem::Field(_, _)
             | ProjectionElem::OpaqueCast(_)
             | ProjectionElem::ConstantIndex { .. }
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 4a9977add78..8ede3bdd2b6 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -357,7 +357,9 @@ impl<'tcx> Validator<'_, 'tcx> {
                         return Err(Unpromotable);
                     }
 
-                    ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {}
+                    ProjectionElem::ConstantIndex { .. }
+                    | ProjectionElem::Subtype(_)
+                    | ProjectionElem::Subslice { .. } => {}
 
                     ProjectionElem::Index(local) => {
                         let mut promotable = false;
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 18b22882e7d..4711f7b47cc 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -7,7 +7,7 @@ use rustc_infer::traits::Reveal;
 use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
-use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance};
 use rustc_mir_dataflow::impls::MaybeStorageLive;
 use rustc_mir_dataflow::storage::always_storage_live_locals;
 use rustc_mir_dataflow::{Analysis, ResultsCursor};
@@ -16,6 +16,8 @@ use rustc_target::spec::abi::Abi;
 
 use crate::util::is_within_packed;
 
+use crate::util::relate_types;
+
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 enum EdgeKind {
     Unwind,
@@ -602,7 +604,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             return true;
         }
 
-        crate::util::is_subtype(self.tcx, self.param_env, src, dest)
+        // After borrowck subtyping should be fully explicit via
+        // `Subtype` projections.
+        let variance = if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
+            Variance::Invariant
+        } else {
+            Variance::Covariant
+        };
+
+        crate::util::relate_types(self.tcx, self.param_env, variance, src, dest)
     }
 }
 
@@ -753,6 +763,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     }
                 }
             }
+            ProjectionElem::Subtype(ty) => {
+                if !relate_types(
+                    self.tcx,
+                    self.param_env,
+                    Variance::Covariant,
+                    ty,
+                    place_ref.ty(&self.body.local_decls, self.tcx).ty,
+                ) {
+                    self.fail(
+                        location,
+                        format!(
+                            "Failed subtyping {ty:#?} and {:#?}",
+                            place_ref.ty(&self.body.local_decls, self.tcx).ty
+                        ),
+                    )
+                }
+            }
             _ => {}
         }
         self.super_projection_elem(place_ref, elem, context, location);
@@ -1088,6 +1115,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 // LHS and RHS of the assignment must have the same type.
                 let left_ty = dest.ty(&self.body.local_decls, self.tcx).ty;
                 let right_ty = rvalue.ty(&self.body.local_decls, self.tcx);
+
                 if !self.mir_assign_valid_types(right_ty, left_ty) {
                     self.fail(
                         location,
diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs
index 83376c8e992..265ca0c7884 100644
--- a/compiler/rustc_const_eval/src/util/compare_types.rs
+++ b/compiler/rustc_const_eval/src/util/compare_types.rs
@@ -5,7 +5,7 @@
 
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_middle::traits::{DefiningAnchor, ObligationCause};
-use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Variance};
 use rustc_trait_selection::traits::ObligationCtxt;
 
 /// Returns whether the two types are equal up to subtyping.
@@ -24,16 +24,22 @@ pub fn is_equal_up_to_subtyping<'tcx>(
     }
 
     // Check for subtyping in either direction.
-    is_subtype(tcx, param_env, src, dest) || is_subtype(tcx, param_env, dest, src)
+    relate_types(tcx, param_env, Variance::Covariant, src, dest)
+        || relate_types(tcx, param_env, Variance::Covariant, dest, src)
 }
 
 /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
 ///
+/// When validating assignments, the variance should be `Covariant`. When checking
+/// during `MirPhase` >= `MirPhase::Runtime(RuntimePhase::Initial)` variance should be `Invariant`
+/// because we want to check for type equality.
+///
 /// This mostly ignores opaque types as it can be used in constraining contexts
 /// while still computing the final underlying type.
-pub fn is_subtype<'tcx>(
+pub fn relate_types<'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ParamEnv<'tcx>,
+    variance: Variance,
     src: Ty<'tcx>,
     dest: Ty<'tcx>,
 ) -> bool {
@@ -48,7 +54,7 @@ pub fn is_subtype<'tcx>(
     let cause = ObligationCause::dummy();
     let src = ocx.normalize(&cause, param_env, src);
     let dest = ocx.normalize(&cause, param_env, dest);
-    match ocx.sub(&cause, param_env, src, dest) {
+    match ocx.relate(&cause, param_env, variance, src, dest) {
         Ok(()) => {}
         Err(_) => return false,
     };
diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs
index 0aef7fa469e..040b3071e6f 100644
--- a/compiler/rustc_const_eval/src/util/mod.rs
+++ b/compiler/rustc_const_eval/src/util/mod.rs
@@ -7,7 +7,7 @@ mod type_name;
 
 pub use self::alignment::{is_disaligned, is_within_packed};
 pub use self::check_validity_requirement::check_validity_requirement;
-pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype};
+pub use self::compare_types::{is_equal_up_to_subtyping, relate_types};
 pub use self::type_name::type_name;
 
 /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the
diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs
index 56e23ac2775..7479e4ef2b3 100644
--- a/compiler/rustc_fluent_macro/src/fluent.rs
+++ b/compiler/rustc_fluent_macro/src/fluent.rs
@@ -40,26 +40,35 @@ fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf {
     }
 }
 
-/// Tokens to be returned when the macro cannot proceed.
-fn failed(crate_name: &Ident) -> proc_macro::TokenStream {
+/// Final tokens.
+fn finish(body: TokenStream, resource: TokenStream) -> proc_macro::TokenStream {
     quote! {
-        pub static DEFAULT_LOCALE_RESOURCE: &'static str = "";
+        /// Raw content of Fluent resource for this crate, generated by `fluent_messages` macro,
+        /// imported by `rustc_driver` to include all crates' resources in one bundle.
+        pub static DEFAULT_LOCALE_RESOURCE: &'static str = #resource;
 
         #[allow(non_upper_case_globals)]
         #[doc(hidden)]
+        /// Auto-generated constants for type-checked references to Fluent messages.
         pub(crate) mod fluent_generated {
-            pub mod #crate_name {
-            }
+            #body
 
+            /// Constants expected to exist by the diagnostic derive macros to use as default Fluent
+            /// identifiers for different subdiagnostic kinds.
             pub mod _subdiag {
+                /// Default for `#[help]`
                 pub const help: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help"));
+                /// Default for `#[note]`
                 pub const note: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note"));
+                /// Default for `#[warn]`
                 pub const warn: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn"));
+                /// Default for `#[label]`
                 pub const label: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label"));
+                /// Default for `#[suggestion]`
                 pub const suggestion: crate::SubdiagnosticMessage =
                     crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion"));
             }
@@ -68,6 +77,11 @@ fn failed(crate_name: &Ident) -> proc_macro::TokenStream {
     .into()
 }
 
+/// Tokens to be returned when the macro cannot proceed.
+fn failed(crate_name: &Ident) -> proc_macro::TokenStream {
+    finish(quote! { pub mod #crate_name {} }, quote! { "" })
+}
+
 /// See [rustc_fluent_macro::fluent_messages].
 pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
     let crate_name = std::env::var("CARGO_PKG_NAME")
@@ -311,39 +325,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
         }
     }
 
-    quote! {
-        /// Raw content of Fluent resource for this crate, generated by `fluent_messages` macro,
-        /// imported by `rustc_driver` to include all crates' resources in one bundle.
-        pub static DEFAULT_LOCALE_RESOURCE: &'static str = include_str!(#relative_ftl_path);
-
-        #[allow(non_upper_case_globals)]
-        #[doc(hidden)]
-        /// Auto-generated constants for type-checked references to Fluent messages.
-        pub(crate) mod fluent_generated {
-            #constants
-
-            /// Constants expected to exist by the diagnostic derive macros to use as default Fluent
-            /// identifiers for different subdiagnostic kinds.
-            pub mod _subdiag {
-                /// Default for `#[help]`
-                pub const help: crate::SubdiagnosticMessage =
-                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help"));
-                /// Default for `#[note]`
-                pub const note: crate::SubdiagnosticMessage =
-                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note"));
-                /// Default for `#[warn]`
-                pub const warn: crate::SubdiagnosticMessage =
-                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn"));
-                /// Default for `#[label]`
-                pub const label: crate::SubdiagnosticMessage =
-                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label"));
-                /// Default for `#[suggestion]`
-                pub const suggestion: crate::SubdiagnosticMessage =
-                    crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion"));
-            }
-        }
-    }
-    .into()
+    finish(constants, quote! { include_str!(#relative_ftl_path) })
 }
 
 fn variable_references<'a>(msg: &Message<&'a str>) -> Vec<&'a str> {
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 1c926533a27..ee475e3de7e 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -96,8 +96,6 @@ hir_analysis_enum_discriminant_overflowed = enum discriminant overflowed
     .label = overflowed on value after {$discr}
     .note = explicitly set `{$item_name} = {$wrapped_discr}` if that is desired outcome
 
-hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
-
 hir_analysis_field_already_declared =
     field `{$field_name}` is already declared
     .label = field already declared
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index d081b0e35c6..b5a3437c992 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -16,6 +16,7 @@ use rustc_infer::traits::util;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::util::ExplicitSelf;
+use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::{
     self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
 };
@@ -2279,16 +2280,16 @@ pub(super) fn check_type_bounds<'tcx>(
                 //
                 // impl<T> X for T where T: X { type Y = <T as X>::Y; }
             }
-            _ => predicates.push(ty::Clause::from_projection_clause(
-                tcx,
+            _ => predicates.push(
                 ty::Binder::bind_with_vars(
                     ty::ProjectionPredicate {
                         projection_ty: tcx.mk_alias_ty(trait_ty.def_id, rebased_args),
                         term: normalize_impl_ty.into(),
                     },
                     bound_vars,
-                ),
-            )),
+                )
+                .to_predicate(tcx),
+            ),
         };
         ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing)
     };
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index c4fdffb0261..de6ca0d61dc 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1130,11 +1130,11 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt
     let wf_obligations =
         bounds.instantiate_identity_iter_copied().flat_map(|(bound, bound_span)| {
             let normalized_bound = wfcx.normalize(span, None, bound);
-            traits::wf::predicate_obligations(
+            traits::wf::clause_obligations(
                 wfcx.infcx,
                 wfcx.param_env,
                 wfcx.body_def_id,
-                normalized_bound.as_predicate(),
+                normalized_bound,
                 bound_span,
             )
         });
@@ -1234,7 +1234,7 @@ fn check_impl<'tcx>(
                     wfcx.infcx,
                     wfcx.param_env,
                     wfcx.body_def_id,
-                    &trait_pred,
+                    trait_pred,
                     ast_trait_ref.path.span,
                     item,
                 );
@@ -1443,13 +1443,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
     debug!(?predicates.predicates);
     assert_eq!(predicates.predicates.len(), predicates.spans.len());
     let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| {
-        traits::wf::predicate_obligations(
-            infcx,
-            wfcx.param_env,
-            wfcx.body_def_id,
-            p.as_predicate(),
-            sp,
-        )
+        traits::wf::clause_obligations(infcx, wfcx.param_env, wfcx.body_def_id, p, sp)
     });
     let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect();
     wfcx.register_obligations(obligations);
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 3760195a5e8..dbd38e1b1fe 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -376,9 +376,9 @@ fn check_predicates<'tcx>(
     let always_applicable_traits = impl1_predicates
         .iter()
         .copied()
-        .filter(|(clause, _span)| {
+        .filter(|&(clause, _span)| {
             matches!(
-                trait_predicate_kind(tcx, clause.as_predicate()),
+                trait_specialization_kind(tcx, clause),
                 Some(TraitSpecializationKind::AlwaysApplicable)
             )
         })
@@ -402,7 +402,7 @@ fn check_predicates<'tcx>(
             .iter()
             .any(|pred2| trait_predicates_eq(tcx, clause.as_predicate(), *pred2, span))
         {
-            check_specialization_on(tcx, clause.as_predicate(), span)
+            check_specialization_on(tcx, clause, span)
         }
     }
 }
@@ -441,19 +441,16 @@ fn trait_predicates_eq<'tcx>(
 }
 
 #[instrument(level = "debug", skip(tcx))]
-fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>, span: Span) {
-    match predicate.kind().skip_binder() {
+fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, clause: ty::Clause<'tcx>, span: Span) {
+    match clause.kind().skip_binder() {
         // Global predicates are either always true or always false, so we
         // are fine to specialize on.
-        _ if predicate.is_global() => (),
+        _ if clause.is_global() => (),
         // We allow specializing on explicitly marked traits with no associated
         // items.
-        ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
-            trait_ref,
-            polarity: _,
-        })) => {
+        ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
             if !matches!(
-                trait_predicate_kind(tcx, predicate),
+                trait_specialization_kind(tcx, clause),
                 Some(TraitSpecializationKind::Marker)
             ) {
                 tcx.sess
@@ -467,10 +464,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
                     .emit();
             }
         }
-        ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
-            projection_ty,
-            term,
-        })) => {
+        ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
             tcx.sess
                 .struct_span_err(
                     span,
@@ -478,7 +472,7 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
                 )
                 .emit();
         }
-        ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) => {
+        ty::ClauseKind::ConstArgHasType(..) => {
             // FIXME(min_specialization), FIXME(const_generics):
             // It probably isn't right to allow _every_ `ConstArgHasType` but I am somewhat unsure
             // about the actual rules that would be sound. Can't just always error here because otherwise
@@ -490,33 +484,25 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
         }
         _ => {
             tcx.sess
-                .struct_span_err(span, format!("cannot specialize on predicate `{predicate}`"))
+                .struct_span_err(span, format!("cannot specialize on predicate `{clause}`"))
                 .emit();
         }
     }
 }
 
-fn trait_predicate_kind<'tcx>(
+fn trait_specialization_kind<'tcx>(
     tcx: TyCtxt<'tcx>,
-    predicate: ty::Predicate<'tcx>,
+    clause: ty::Clause<'tcx>,
 ) -> Option<TraitSpecializationKind> {
-    match predicate.kind().skip_binder() {
-        ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
-            trait_ref,
-            polarity: _,
-        })) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind),
-        ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_))
-        | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_))
-        | ty::PredicateKind::Clause(ty::ClauseKind::Projection(_))
-        | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
-        | ty::PredicateKind::AliasRelate(..)
-        | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_))
-        | ty::PredicateKind::Subtype(_)
-        | ty::PredicateKind::Coerce(_)
-        | ty::PredicateKind::ObjectSafe(_)
-        | ty::PredicateKind::ClosureKind(..)
-        | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
-        | ty::PredicateKind::ConstEquate(..)
-        | ty::PredicateKind::Ambiguous => None,
+    match clause.kind().skip_binder() {
+        ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
+            Some(tcx.trait_def(trait_ref.def_id).specialization_kind)
+        }
+        ty::ClauseKind::RegionOutlives(_)
+        | ty::ClauseKind::TypeOutlives(_)
+        | ty::ClauseKind::Projection(_)
+        | ty::ClauseKind::ConstArgHasType(..)
+        | ty::ClauseKind::WellFormed(_)
+        | ty::ClauseKind::ConstEvaluatable(..) => None,
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index d97691369c9..5c3f2b85966 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -14,7 +14,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable};
+use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable, TypeVisitableExt};
 use rustc_span::symbol::sym;
 use rustc_span::{BytePos, Span, DUMMY_SP};
 use rustc_trait_selection::infer::InferCtxtExt as _;
@@ -504,12 +504,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // incompatible fix at the original mismatch site.
                     if matches!(source, TypeMismatchSource::Ty(_))
                         && let Some(ideal_method) = ideal_method
+                        && let ideal_arg_ty = self.resolve_vars_if_possible(ideal_method.sig.inputs()[idx + 1])
+                        // HACK(compiler-errors): We don't actually consider the implications
+                        // of our inference guesses in `emit_type_mismatch_suggestions`, so
+                        // only suggest things when we know our type error is precisely due to
+                        // a type mismatch, and not via some projection or something. See #116155.
+                        && !ideal_arg_ty.has_non_region_infer()
                     {
                         self.emit_type_mismatch_suggestions(
                             err,
                             arg_expr,
                             arg_ty,
-                            self.resolve_vars_if_possible(ideal_method.sig.inputs()[idx + 1]),
+                            ideal_arg_ty,
                             None,
                             None,
                         );
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 07c48ec6392..a4bbb16026a 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -2494,10 +2494,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Try alternative arbitrary self types that could fulfill this call.
             // FIXME: probe for all types that *could* be arbitrary self-types, not
             // just this list.
-            for (rcvr_ty, post) in &[
-                (rcvr_ty, ""),
-                (Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "),
-                (Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty), "&"),
+            for (rcvr_ty, post, pin_call) in &[
+                (rcvr_ty, "", None),
+                (
+                    Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty),
+                    "&mut ",
+                    Some("as_mut"),
+                ),
+                (
+                    Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rcvr_ty),
+                    "&",
+                    Some("as_ref"),
+                ),
             ] {
                 match self.lookup_probe_for_diagnostic(
                     item_name,
@@ -2531,6 +2539,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     Err(_) => (),
                 }
 
+                let pred = ty::TraitRef::new(
+                    self.tcx,
+                    self.tcx.lang_items().unpin_trait().unwrap(),
+                    [*rcvr_ty],
+                );
+                let unpin = self.predicate_must_hold_considering_regions(&Obligation::new(
+                    self.tcx,
+                    ObligationCause::misc(rcvr.span, self.body_id),
+                    self.param_env,
+                    pred,
+                ));
                 for (rcvr_ty, pre) in &[
                     (Ty::new_lang_item(self.tcx, *rcvr_ty, LangItem::OwnedBox), "Box::new"),
                     (Ty::new_lang_item(self.tcx, *rcvr_ty, LangItem::Pin), "Pin::new"),
@@ -2554,7 +2573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // Explicitly ignore the `Pin::as_ref()` method as `Pin` does not
                         // implement the `AsRef` trait.
                         let skip = skippable.contains(&did)
-                            || (("Pin::new" == *pre) && (sym::as_ref == item_name.name))
+                            || (("Pin::new" == *pre) && ((sym::as_ref == item_name.name) || !unpin))
                             || inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() != inputs_len);
                         // Make sure the method is defined for the *actual* receiver: we don't
                         // want to treat `Box<Self>` as a receiver if it only works because of
@@ -2566,7 +2585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             );
                             err.multipart_suggestion(
                                 "consider wrapping the receiver expression with the \
-                                    appropriate type",
+                                 appropriate type",
                                 vec![
                                     (rcvr.span.shrink_to_lo(), format!("{pre}({post}")),
                                     (rcvr.span.shrink_to_hi(), ")".to_string()),
@@ -2578,6 +2597,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     }
                 }
+                // We special case the situation where `Pin::new` wouldn't work, and instead
+                // suggest using the `pin!()` macro instead.
+                if let Some(new_rcvr_t) = Ty::new_lang_item(self.tcx, *rcvr_ty, LangItem::Pin)
+                    // We didn't find an alternative receiver for the method.
+                    && !alt_rcvr_sugg
+                    // `T: !Unpin`
+                    && !unpin
+                    // The method isn't `as_ref`, as it would provide a wrong suggestion for `Pin`.
+                    && sym::as_ref != item_name.name
+                    // Either `Pin::as_ref` or `Pin::as_mut`.
+                    && let Some(pin_call) = pin_call
+                    // Search for `item_name` as a method accessible on `Pin<T>`.
+                    && let Ok(pick) = self.lookup_probe_for_diagnostic(
+                        item_name,
+                        new_rcvr_t,
+                        rcvr,
+                        ProbeScope::AllTraits,
+                        return_type,
+                    )
+                    // We skip some common traits that we don't want to consider because autoderefs
+                    // would take care of them.
+                    && !skippable.contains(&Some(pick.item.container_id(self.tcx)))
+                    // We don't want to go through derefs.
+                    && pick.autoderefs == 0
+                    // Check that the method of the same name that was found on the new `Pin<T>`
+                    // receiver has the same number of arguments that appear in the user's code.
+                    && inputs_len.is_some_and(|inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().skip_binder().inputs().len() == inputs_len)
+                {
+                    let indent = self.tcx.sess
+                        .source_map()
+                        .indentation_before(rcvr.span)
+                        .unwrap_or_else(|| " ".to_string());
+                    err.multipart_suggestion(
+                        "consider pinning the expression",
+                        vec![
+                            (rcvr.span.shrink_to_lo(), format!("let mut pinned = std::pin::pin!(")),
+                            (rcvr.span.shrink_to_hi(), format!(");\n{indent}pinned.{pin_call}()")),
+                        ],
+                        Applicability::MaybeIncorrect,
+                    );
+                    // We don't care about the other suggestions.
+                    alt_rcvr_sugg = true;
+                }
             }
         }
         if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl
index 46558997f72..b36fb6a4dba 100644
--- a/compiler/rustc_infer/messages.ftl
+++ b/compiler/rustc_infer/messages.ftl
@@ -66,7 +66,6 @@ infer_await_both_futures = consider `await`ing on both `Future`s
 infer_await_future = consider `await`ing on the `Future`
 infer_await_note = calling an async function returns a future
 
-infer_borrowed_too_long = a value of type `{$ty}` is borrowed for too long
 infer_but_calling_introduces = {$has_param_name ->
     [true] `{$param_name}`
     *[false] `fn` parameter
@@ -181,8 +180,6 @@ infer_more_targeted = {$has_param_name ->
 } but calling `{$ident}` introduces an implicit `'static` lifetime requirement
 
 infer_msl_introduces_static = introduces a `'static` lifetime requirement
-infer_msl_trait_note = this has an implicit `'static` lifetime requirement
-infer_msl_trait_sugg = consider relaxing the implicit `'static` requirement
 infer_msl_unmet_req = because this has an unmet lifetime requirement
 infer_need_type_info_in_generator =
     type inside {$generator_kind ->
@@ -233,7 +230,6 @@ infer_prlf_known_limitation = this is a known limitation that will be removed in
 infer_prlf_must_outlive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here
 infer_prlf_must_outlive_without_sup = ...must outlive the lifetime defined here
 infer_reborrow = ...so that reference does not outlive borrowed content
-infer_reborrow_upvar = ...so that closure can access `{$name}`
 infer_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references
 
 infer_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at
diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
index fefa8959545..2d6b88226ad 100644
--- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
+++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
@@ -44,7 +44,7 @@ pub fn extract_verify_if_eq<'tcx>(
     test_ty: Ty<'tcx>,
 ) -> Option<ty::Region<'tcx>> {
     assert!(!verify_if_eq_b.has_escaping_bound_vars());
-    let mut m = Match::new(tcx, param_env);
+    let mut m = MatchAgainstHigherRankedOutlives::new(tcx, param_env);
     let verify_if_eq = verify_if_eq_b.skip_binder();
     m.relate(verify_if_eq.ty, test_ty).ok()?;
 
@@ -87,24 +87,32 @@ pub(super) fn can_match_erased_ty<'tcx>(
         // pointless micro-optimization
         true
     } else {
-        Match::new(tcx, param_env).relate(outlives_ty, erased_ty).is_ok()
+        MatchAgainstHigherRankedOutlives::new(tcx, param_env).relate(outlives_ty, erased_ty).is_ok()
     }
 }
 
-struct Match<'tcx> {
+struct MatchAgainstHigherRankedOutlives<'tcx> {
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     pattern_depth: ty::DebruijnIndex,
     map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,
 }
 
-impl<'tcx> Match<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Match<'tcx> {
-        Match { tcx, param_env, pattern_depth: ty::INNERMOST, map: FxHashMap::default() }
+impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
+    fn new(
+        tcx: TyCtxt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+    ) -> MatchAgainstHigherRankedOutlives<'tcx> {
+        MatchAgainstHigherRankedOutlives {
+            tcx,
+            param_env,
+            pattern_depth: ty::INNERMOST,
+            map: FxHashMap::default(),
+        }
     }
 }
 
-impl<'tcx> Match<'tcx> {
+impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
     /// Creates the "Error" variant that signals "no match".
     fn no_match<T>(&self) -> RelateResult<'tcx, T> {
         Err(TypeError::Mismatch)
@@ -134,7 +142,7 @@ impl<'tcx> Match<'tcx> {
     }
 }
 
-impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
+impl<'tcx> TypeRelation<'tcx> for MatchAgainstHigherRankedOutlives<'tcx> {
     fn tag(&self) -> &'static str {
         "Match"
     }
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index 79b0b32bef2..c24846ca939 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -37,8 +37,6 @@ declare_lint! {
     ///     type Assoc: Duh;
     /// }
     ///
-    /// struct Struct;
-    ///
     /// impl<F: Duh> Trait for F {
     ///     type Assoc = F;
     /// }
@@ -53,12 +51,12 @@ declare_lint! {
     /// {{produces}}
     ///
     /// In this example, `test` declares that the associated type `Assoc` for
-    /// `impl Trait` is `impl Sized`, which does not satisfy the `Send` bound
+    /// `impl Trait` is `impl Sized`, which does not satisfy the bound `Duh`
     /// on the associated type.
     ///
     /// Although the hidden type, `i32` does satisfy this bound, we do not
     /// consider the return type to be well-formed with this lint. It can be
-    /// fixed by changing `Tait = impl Sized` into `Tait = impl Sized + Send`.
+    /// fixed by changing `Tait = impl Sized` into `Tait = impl Sized + Duh`.
     pub OPAQUE_HIDDEN_INFERRED_BOUND,
     Warn,
     "detects the use of nested `impl Trait` types in associated type bounds that are not general enough"
@@ -79,9 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
         for (pred, pred_span) in
             cx.tcx.explicit_item_bounds(def_id).instantiate_identity_iter_copied()
         {
-            // Liberate bound regions in the predicate since we
-            // don't actually care about lifetimes in this check.
-            let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind());
+            let predicate = infcx.instantiate_binder_with_placeholders(pred.kind());
             let ty::ClauseKind::Projection(proj) = predicate else {
                 continue;
             };
diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml
index 34556df3c6d..3880f25a9ba 100644
--- a/compiler/rustc_llvm/Cargo.toml
+++ b/compiler/rustc_llvm/Cargo.toml
@@ -3,10 +3,6 @@ name = "rustc_llvm"
 version = "0.0.0"
 edition = "2021"
 
-[features]
-static-libstdcpp = []
-emscripten = []
-
 [dependencies]
 libc = "0.2.73"
 
diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs
index e7b80c64184..3e43bcb3b8f 100644
--- a/compiler/rustc_log/src/lib.rs
+++ b/compiler/rustc_log/src/lib.rs
@@ -23,10 +23,10 @@
 //! }
 //! ```
 //!
-//! Now `LOG=debug cargo run` will run your minimal main.rs and show
+//! Now `LOG=debug cargo +nightly run` will run your minimal main.rs and show
 //! rustc's debug logging. In a workflow like this, one might also add
 //! `std::env::set_var("LOG", "debug")` to the top of main so that `cargo
-//! run` by itself is sufficient to get logs.
+//! +nightly run` by itself is sufficient to get logs.
 //!
 //! The reason rustc_log is a tiny separate crate, as opposed to exposing the
 //! same things in rustc_driver only, is to enable the above workflow. If you
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 9ef67392291..a6d6f6f5df4 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -18,11 +18,6 @@ rustc_index::newtype_index! {
 
 impl CounterId {
     pub const START: Self = Self::from_u32(0);
-
-    #[inline(always)]
-    pub fn next_id(self) -> Self {
-        Self::from_u32(self.as_u32() + 1)
-    }
 }
 
 rustc_index::newtype_index! {
@@ -38,11 +33,6 @@ rustc_index::newtype_index! {
 
 impl ExpressionId {
     pub const START: Self = Self::from_u32(0);
-
-    #[inline(always)]
-    pub fn next_id(self) -> Self {
-        Self::from_u32(self.as_u32() + 1)
-    }
 }
 
 /// Operand of a coverage-counter expression.
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 76567c3f6b0..c5e3ee575e1 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -16,7 +16,7 @@ use rustc_middle::mir::interpret::{
     Pointer, Provenance,
 };
 use rustc_middle::mir::visit::Visitor;
-use rustc_middle::mir::*;
+use rustc_middle::mir::{self, *};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_target::abi::Size;
 
@@ -685,10 +685,13 @@ impl Debug for Statement<'_> {
             AscribeUserType(box (ref place, ref c_ty), ref variance) => {
                 write!(fmt, "AscribeUserType({place:?}, {variance:?}, {c_ty:?})")
             }
-            Coverage(box self::Coverage { ref kind, code_region: Some(ref rgn) }) => {
-                write!(fmt, "Coverage::{kind:?} for {rgn:?}")
+            Coverage(box mir::Coverage { ref kind, ref code_regions }) => {
+                if code_regions.is_empty() {
+                    write!(fmt, "Coverage::{kind:?}")
+                } else {
+                    write!(fmt, "Coverage::{kind:?} for {code_regions:?}")
+                }
             }
-            Coverage(box ref coverage) => write!(fmt, "Coverage::{:?}", coverage.kind),
             Intrinsic(box ref intrinsic) => write!(fmt, "{intrinsic}"),
             ConstEvalCounter => write!(fmt, "ConstEvalCounter"),
             Nop => write!(fmt, "nop"),
@@ -1103,6 +1106,7 @@ fn pre_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
     for &elem in projection.iter().rev() {
         match elem {
             ProjectionElem::OpaqueCast(_)
+            | ProjectionElem::Subtype(_)
             | ProjectionElem::Downcast(_, _)
             | ProjectionElem::Field(_, _) => {
                 write!(fmt, "(").unwrap();
@@ -1125,6 +1129,9 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
             ProjectionElem::OpaqueCast(ty) => {
                 write!(fmt, " as {ty})")?;
             }
+            ProjectionElem::Subtype(ty) => {
+                write!(fmt, " as subtype {ty})")?;
+            }
             ProjectionElem::Downcast(Some(name), _index) => {
                 write!(fmt, " as {name})")?;
             }
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index 5ac108bc829..5864acaed7b 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -57,6 +57,7 @@ impl<V, T> ProjectionElem<V, T> {
             Self::Field(_, _)
             | Self::Index(_)
             | Self::OpaqueCast(_)
+            | Self::Subtype(_)
             | Self::ConstantIndex { .. }
             | Self::Subslice { .. }
             | Self::Downcast(_, _) => false,
@@ -70,6 +71,7 @@ impl<V, T> ProjectionElem<V, T> {
             Self::Deref | Self::Index(_) => false,
             Self::Field(_, _)
             | Self::OpaqueCast(_)
+            | Self::Subtype(_)
             | Self::ConstantIndex { .. }
             | Self::Subslice { .. }
             | Self::Downcast(_, _) => true,
@@ -95,6 +97,7 @@ impl<V, T> ProjectionElem<V, T> {
             | Self::Field(_, _) => true,
             Self::ConstantIndex { from_end: true, .. }
             | Self::Index(_)
+            | Self::Subtype(_)
             | Self::OpaqueCast(_)
             | Self::Subslice { .. } => false,
         }
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 55f895f73b4..bc28735a45d 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -514,7 +514,7 @@ pub enum FakeReadCause {
 #[derive(TypeFoldable, TypeVisitable)]
 pub struct Coverage {
     pub kind: CoverageKind,
-    pub code_region: Option<CodeRegion>,
+    pub code_regions: Vec<CodeRegion>,
 }
 
 #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
@@ -1075,6 +1075,18 @@ pub enum ProjectionElem<V, T> {
     /// Like an explicit cast from an opaque type to a concrete type, but without
     /// requiring an intermediate variable.
     OpaqueCast(T),
+
+    /// A `Subtype(T)` projection is applied to any `StatementKind::Assign` where
+    /// type of lvalue doesn't match the type of rvalue, the primary goal is making subtyping
+    /// explicit during optimizations and codegen.
+    ///
+    /// This projection doesn't impact the runtime behavior of the program except for potentially changing
+    /// some type metadata of the interpreter or codegen backend.
+    ///
+    /// This goal is achieved with mir_transform pass `Subtyper`, which runs right after
+    /// borrowchecker, as we only care about subtyping that can affect trait selection and
+    /// `TypeId`.
+    Subtype(T),
 }
 
 /// Alias for projections as they appear in places, where the base is a place
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 01c04f63890..44ae75e2de7 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -69,7 +69,7 @@ impl<'tcx> PlaceTy<'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         elem: &ProjectionElem<V, T>,
         mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>,
-        mut handle_opaque_cast: impl FnMut(&Self, T) -> Ty<'tcx>,
+        mut handle_opaque_cast_and_subtype: impl FnMut(&Self, T) -> Ty<'tcx>,
     ) -> PlaceTy<'tcx>
     where
         V: ::std::fmt::Debug,
@@ -110,7 +110,12 @@ impl<'tcx> PlaceTy<'tcx> {
                 PlaceTy { ty: self.ty, variant_index: Some(index) }
             }
             ProjectionElem::Field(f, fty) => PlaceTy::from_ty(handle_field(&self, f, fty)),
-            ProjectionElem::OpaqueCast(ty) => PlaceTy::from_ty(handle_opaque_cast(&self, ty)),
+            ProjectionElem::OpaqueCast(ty) => {
+                PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
+            }
+            ProjectionElem::Subtype(ty) => {
+                PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty))
+            }
         };
         debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
         answer
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 51ec6da1ac8..60f78bef0af 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -1109,6 +1109,11 @@ macro_rules! visit_place_fns {
                     self.visit_ty(&mut new_ty, TyContext::Location(location));
                     if ty != new_ty { Some(PlaceElem::OpaqueCast(new_ty)) } else { None }
                 }
+                PlaceElem::Subtype(ty) => {
+                    let mut new_ty = ty;
+                    self.visit_ty(&mut new_ty, TyContext::Location(location));
+                    if ty != new_ty { Some(PlaceElem::Subtype(new_ty)) } else { None }
+                }
                 PlaceElem::Deref
                 | PlaceElem::ConstantIndex { .. }
                 | PlaceElem::Subslice { .. }
@@ -1175,7 +1180,9 @@ macro_rules! visit_place_fns {
             location: Location,
         ) {
             match elem {
-                ProjectionElem::OpaqueCast(ty) | ProjectionElem::Field(_, ty) => {
+                ProjectionElem::OpaqueCast(ty)
+                | ProjectionElem::Subtype(ty)
+                | ProjectionElem::Field(_, ty) => {
                     self.visit_ty(ty, TyContext::Location(location));
                 }
                 ProjectionElem::Index(local) => {
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index 09517200b0d..85181720d17 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
@@ -18,20 +18,20 @@ use crate::ty::{self, InferConst, Ty, TyCtxt};
 /// Like subtyping, matching is really a binary relation, so the only
 /// important thing about the result is Ok/Err. Also, matching never
 /// affects any type variables or unification state.
-pub struct Match<'tcx> {
+pub struct MatchAgainstFreshVars<'tcx> {
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
 }
 
-impl<'tcx> Match<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Match<'tcx> {
-        Match { tcx, param_env }
+impl<'tcx> MatchAgainstFreshVars<'tcx> {
+    pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> MatchAgainstFreshVars<'tcx> {
+        MatchAgainstFreshVars { tcx, param_env }
     }
 }
 
-impl<'tcx> TypeRelation<'tcx> for Match<'tcx> {
+impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
     fn tag(&self) -> &'static str {
-        "Match"
+        "MatchAgainstFreshVars"
     }
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 0b0a708e42b..0a425be52ff 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -617,12 +617,17 @@ impl<'tcx> Instance<'tcx> {
         v: EarlyBinder<T>,
     ) -> Result<T, NormalizationError<'tcx>>
     where
-        T: TypeFoldable<TyCtxt<'tcx>> + Clone,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         if let Some(args) = self.args_for_mir_body() {
             tcx.try_instantiate_and_normalize_erasing_regions(args, param_env, v)
         } else {
-            tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
+            // We're using `instantiate_identity` as e.g.
+            // `FnPtrShim` is separately generated for every
+            // instantiation of the `FnDef`, so the MIR body
+            // is already instantiated. Any generic parameters it
+            // contains are generic parameters from the caller.
+            tcx.try_normalize_erasing_regions(param_env, v.instantiate_identity())
         }
     }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index aa1e7f216a0..78396358969 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -578,11 +578,6 @@ impl rustc_errors::IntoDiagnosticArg for Clause<'_> {
 pub struct Clause<'tcx>(Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>);
 
 impl<'tcx> Clause<'tcx> {
-    pub fn from_projection_clause(tcx: TyCtxt<'tcx>, pred: PolyProjectionPredicate<'tcx>) -> Self {
-        let pred: Predicate<'tcx> = pred.to_predicate(tcx);
-        pred.expect_clause()
-    }
-
     pub fn as_predicate(self) -> Predicate<'tcx> {
         Predicate(self.0)
     }
@@ -1296,12 +1291,25 @@ impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef
     }
 }
 
+impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> {
+    fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
+        PredicateKind::Clause(ClauseKind::Trait(self)).to_predicate(tcx)
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
     fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
         self.map_bound(|p| PredicateKind::Clause(ClauseKind::Trait(p))).to_predicate(tcx)
     }
 }
 
+impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitPredicate<'tcx> {
+    fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
+        let p: Predicate<'tcx> = self.to_predicate(tcx);
+        p.expect_clause()
+    }
+}
+
 impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyTraitPredicate<'tcx> {
     fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
         let p: Predicate<'tcx> = self.to_predicate(tcx);
@@ -1340,9 +1348,10 @@ impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for ProjectionPredicate<'tcx> {
     }
 }
 
-impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> {
-    fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
-        PredicateKind::Clause(ClauseKind::Trait(self)).to_predicate(tcx)
+impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyProjectionPredicate<'tcx> {
+    fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
+        let p: Predicate<'tcx> = self.to_predicate(tcx);
+        p.expect_clause()
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 1e57392e0e7..e5f418bbb4b 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -725,7 +725,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
                 self.rebind(tr).with_self_ty(tcx, self_ty).to_predicate(tcx)
             }
             ExistentialPredicate::Projection(p) => {
-                ty::Clause::from_projection_clause(tcx, self.rebind(p.with_self_ty(tcx, self_ty)))
+                self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
             }
             ExistentialPredicate::AutoTrait(did) => {
                 let generics = tcx.generics_of(did);
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 2e7ef265a93..4aff406b376 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -102,7 +102,7 @@ fn convert_to_hir_projections_and_truncate_for_capture(
                 continue;
             }
             // These do not affect anything, they just make sure we know the right type.
-            ProjectionElem::OpaqueCast(_) => continue,
+            ProjectionElem::OpaqueCast(_) | ProjectionElem::Subtype(..) => continue,
             ProjectionElem::Index(..)
             | ProjectionElem::ConstantIndex { .. }
             | ProjectionElem::Subslice { .. } => {
@@ -709,6 +709,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     ProjectionElem::Field(..)
                     | ProjectionElem::Downcast(..)
                     | ProjectionElem::OpaqueCast(..)
+                    | ProjectionElem::Subtype(..)
                     | ProjectionElem::ConstantIndex { .. }
                     | ProjectionElem::Subslice { .. } => (),
                 }
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
index 7806e8f45d3..2a7f23ef6d2 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs
@@ -57,6 +57,7 @@ impl<'tcx> Lift for PlaceElem<'tcx> {
                 ProjectionElem::ConstantIndex { offset, min_length, from_end }
             }
             ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u),
+            ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty.lift()),
         }
     }
 }
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 9ced3a7f3cd..7a5b3585d59 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -227,10 +227,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                     }
                     _ => bug!("Unexpected type {place_ty:#?}"),
                 },
-                // `OpaqueCast` only transmutes the type, so no moves there and
-                // `Downcast` only changes information about a `Place` without moving
+                // `OpaqueCast`:Only transmutes the type, so no moves there.
+                // `Downcast`  :Only changes information about a `Place` without moving.
+                // `Subtype`   :Only transmutes the type, so moves.
                 // So it's safe to skip these.
-                ProjectionElem::OpaqueCast(_) | ProjectionElem::Downcast(_, _) => (),
+                ProjectionElem::OpaqueCast(_)
+                | ProjectionElem::Subtype(_)
+                | ProjectionElem::Downcast(_, _) => (),
             }
             if union_path.is_none() {
                 // inlined from add_move_path because of a borrowck conflict with the iterator
diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
new file mode 100644
index 00000000000..1cc049d5a22
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
@@ -0,0 +1,66 @@
+use crate::MirPass;
+use rustc_index::IndexVec;
+use rustc_middle::mir::patch::MirPatch;
+use rustc_middle::mir::visit::MutVisitor;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
+
+pub struct Subtyper;
+
+pub struct SubTypeChecker<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    patcher: MirPatch<'tcx>,
+    local_decls: &'a IndexVec<Local, LocalDecl<'tcx>>,
+}
+
+impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn visit_assign(
+        &mut self,
+        place: &mut Place<'tcx>,
+        rvalue: &mut Rvalue<'tcx>,
+        location: Location,
+    ) {
+        let mut place_ty = place.ty(self.local_decls, self.tcx).ty;
+        let mut rval_ty = rvalue.ty(self.local_decls, self.tcx);
+        // Not erasing this causes `Free Regions` errors in validator,
+        // when rval is `ReStatic`.
+        rval_ty = self.tcx.erase_regions_ty(rval_ty);
+        place_ty = self.tcx.erase_regions(place_ty);
+        if place_ty != rval_ty {
+            let temp = self
+                .patcher
+                .new_temp(rval_ty, self.local_decls[place.as_ref().local].source_info.span);
+            let new_place = Place::from(temp);
+            self.patcher.add_assign(location, new_place, rvalue.clone());
+            let subtyped = new_place.project_deeper(&[ProjectionElem::Subtype(place_ty)], self.tcx);
+            *rvalue = Rvalue::Use(Operand::Move(subtyped));
+        }
+    }
+}
+
+// Aim here is to do this kind of transformation:
+//
+// let place: place_ty = rval;
+// // gets transformed to
+// let temp: rval_ty = rval;
+// let place: place_ty = temp as place_ty;
+//
+pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+    let patch = MirPatch::new(body);
+    let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls };
+
+    for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
+        checker.visit_basic_block_data(bb, data);
+    }
+    checker.patcher.apply(body);
+}
+
+impl<'tcx> MirPass<'tcx> for Subtyper {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        subtype_finder(tcx, body);
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index d56d4ad4f1e..78845af0162 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -1,10 +1,8 @@
 use super::Error;
 
 use super::graph;
-use super::spans;
 
 use graph::{BasicCoverageBlock, BcbBranch, CoverageGraph, TraverseCoverageGraphWithLoops};
-use spans::CoverageSpan;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::WithNumNodes;
@@ -93,14 +91,14 @@ impl CoverageCounters {
     }
 
     /// Makes [`BcbCounter`] `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
-    /// indirectly associated with `CoverageSpans`, and accumulates additional `Expression`s
+    /// indirectly associated with coverage spans, and accumulates additional `Expression`s
     /// representing intermediate values.
     pub fn make_bcb_counters(
         &mut self,
         basic_coverage_blocks: &CoverageGraph,
-        coverage_spans: &[CoverageSpan],
+        bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool,
     ) -> Result<(), Error> {
-        MakeBcbCounters::new(self, basic_coverage_blocks).make_bcb_counters(coverage_spans)
+        MakeBcbCounters::new(self, basic_coverage_blocks).make_bcb_counters(bcb_has_coverage_spans)
     }
 
     fn make_counter(&mut self) -> BcbCounter {
@@ -113,14 +111,10 @@ impl CoverageCounters {
         BcbCounter::Expression { id, lhs, op, rhs }
     }
 
-    pub fn make_identity_counter(&mut self, counter_operand: Operand) -> BcbCounter {
-        self.make_expression(counter_operand, Op::Add, Operand::Zero)
-    }
-
     /// Counter IDs start from one and go up.
     fn next_counter(&mut self) -> CounterId {
         let next = self.next_counter_id;
-        self.next_counter_id = next.next_id();
+        self.next_counter_id = self.next_counter_id + 1;
         next
     }
 
@@ -128,7 +122,7 @@ impl CoverageCounters {
     /// (Counter IDs and Expression IDs are distinguished by the `Operand` enum.)
     fn next_expression(&mut self) -> ExpressionId {
         let next = self.next_expression_id;
-        self.next_expression_id = next.next_id();
+        self.next_expression_id = self.next_expression_id + 1;
         next
     }
 
@@ -208,7 +202,7 @@ impl CoverageCounters {
 }
 
 /// Traverse the `CoverageGraph` and add either a `Counter` or `Expression` to every BCB, to be
-/// injected with `CoverageSpan`s. `Expressions` have no runtime overhead, so if a viable expression
+/// injected with coverage spans. `Expressions` have no runtime overhead, so if a viable expression
 /// (adding or subtracting two other counters or expressions) can compute the same result as an
 /// embedded counter, an `Expression` should be used.
 struct MakeBcbCounters<'a> {
@@ -234,17 +228,14 @@ impl<'a> MakeBcbCounters<'a> {
     /// Returns any non-code-span expressions created to represent intermediate values (such as to
     /// add two counters so the result can be subtracted from another counter), or an Error with
     /// message for subsequent debugging.
-    fn make_bcb_counters(&mut self, coverage_spans: &[CoverageSpan]) -> Result<(), Error> {
+    fn make_bcb_counters(
+        &mut self,
+        bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool,
+    ) -> Result<(), Error> {
         debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
-        let num_bcbs = self.basic_coverage_blocks.num_nodes();
-
-        let mut bcbs_with_coverage = BitSet::new_empty(num_bcbs);
-        for covspan in coverage_spans {
-            bcbs_with_coverage.insert(covspan.bcb);
-        }
 
         // Walk the `CoverageGraph`. For each `BasicCoverageBlock` node with an associated
-        // `CoverageSpan`, add a counter. If the `BasicCoverageBlock` branches, add a counter or
+        // coverage span, add a counter. If the `BasicCoverageBlock` branches, add a counter or
         // expression to each branch `BasicCoverageBlock` (if the branch BCB has only one incoming
         // edge) or edge from the branching BCB to the branch BCB (if the branch BCB has multiple
         // incoming edges).
@@ -255,8 +246,8 @@ impl<'a> MakeBcbCounters<'a> {
         // the current BCB is in one or more nested loops or not.
         let mut traversal = TraverseCoverageGraphWithLoops::new(&self.basic_coverage_blocks);
         while let Some(bcb) = traversal.next(self.basic_coverage_blocks) {
-            if bcbs_with_coverage.contains(bcb) {
-                debug!("{:?} has at least one `CoverageSpan`. Get or make its counter", bcb);
+            if bcb_has_coverage_spans(bcb) {
+                debug!("{:?} has at least one coverage span. Get or make its counter", bcb);
                 let branching_counter_operand = self.get_or_make_counter_operand(bcb)?;
 
                 if self.bcb_needs_branch_counters(bcb) {
@@ -264,7 +255,7 @@ impl<'a> MakeBcbCounters<'a> {
                 }
             } else {
                 debug!(
-                    "{:?} does not have any `CoverageSpan`s. A counter will only be added if \
+                    "{:?} does not have any coverage spans. A counter will only be added if \
                     and when a covered BCB has an expression dependency.",
                     bcb,
                 );
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index ff2254d6941..812633348e3 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -288,9 +288,9 @@ rustc_index::newtype_index! {
 ///     not relevant to coverage analysis. `FalseUnwind`, for example, can be treated the same as
 ///     a `Goto`, and merged with its successor into the same BCB.
 ///
-/// Each BCB with at least one computed `CoverageSpan` will have no more than one `Counter`.
+/// Each BCB with at least one computed coverage span will have no more than one `Counter`.
 /// In some cases, a BCB's execution count can be computed by `Expression`. Additional
-/// disjoint `CoverageSpan`s in a BCB can also be counted by `Expression` (by adding `ZERO`
+/// disjoint coverage spans in a BCB can also be counted by `Expression` (by adding `ZERO`
 /// to the BCB's primary counter or expression).
 ///
 /// The BCB CFG is critical to simplifying the coverage analysis by ensuring graph path-based
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index c75d33eeb31..abf13519e9e 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -9,13 +9,11 @@ mod tests;
 
 use self::counters::{BcbCounter, CoverageCounters};
 use self::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph};
-use self::spans::{CoverageSpan, CoverageSpans};
+use self::spans::CoverageSpans;
 
 use crate::MirPass;
 
-use rustc_data_structures::graph::WithNumNodes;
 use rustc_data_structures::sync::Lrc;
-use rustc_index::IndexVec;
 use rustc_middle::hir;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::coverage::*;
@@ -154,7 +152,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         let body_span = self.body_span;
 
         ////////////////////////////////////////////////////
-        // Compute `CoverageSpan`s from the `CoverageGraph`.
+        // Compute coverage spans from the `CoverageGraph`.
         let coverage_spans = CoverageSpans::generate_coverage_spans(
             &self.mir_body,
             fn_sig_span,
@@ -164,32 +162,33 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
 
         ////////////////////////////////////////////////////
         // Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
-        // every `CoverageSpan` has a `Counter` or `Expression` assigned to its `BasicCoverageBlock`
+        // every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock`
         // and all `Expression` dependencies (operands) are also generated, for any other
-        // `BasicCoverageBlock`s not already associated with a `CoverageSpan`.
+        // `BasicCoverageBlock`s not already associated with a coverage span.
         //
         // Intermediate expressions (used to compute other `Expression` values), which have no
         // direct association with any `BasicCoverageBlock`, are accumulated inside `coverage_counters`.
+        let bcb_has_coverage_spans = |bcb| coverage_spans.bcb_has_coverage_spans(bcb);
         let result = self
             .coverage_counters
-            .make_bcb_counters(&mut self.basic_coverage_blocks, &coverage_spans);
+            .make_bcb_counters(&mut self.basic_coverage_blocks, bcb_has_coverage_spans);
 
         if let Ok(()) = result {
             ////////////////////////////////////////////////////
-            // Remove the counter or edge counter from of each `CoverageSpan`s associated
+            // Remove the counter or edge counter from of each coverage cpan's associated
             // `BasicCoverageBlock`, and inject a `Coverage` statement into the MIR.
             //
-            // `Coverage` statements injected from `CoverageSpan`s will include the code regions
+            // `Coverage` statements injected from coverage spans will include the code regions
             // (source code start and end positions) to be counted by the associated counter.
             //
-            // These `CoverageSpan`-associated counters are removed from their associated
+            // These coverage-span-associated counters are removed from their associated
             // `BasicCoverageBlock`s so that the only remaining counters in the `CoverageGraph`
             // are indirect counters (to be injected next, without associated code regions).
-            self.inject_coverage_span_counters(coverage_spans);
+            self.inject_coverage_span_counters(&coverage_spans);
 
             ////////////////////////////////////////////////////
             // For any remaining `BasicCoverageBlock` counters (that were not associated with
-            // any `CoverageSpan`), inject `Coverage` statements (_without_ code region `Span`s)
+            // any coverage span), inject `Coverage` statements (_without_ code region spans)
             // to ensure `BasicCoverageBlock` counters that other `Expression`s may depend on
             // are in fact counted, even though they don't directly contribute to counting
             // their own independent code region's coverage.
@@ -214,47 +213,40 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
         }
     }
 
-    /// Inject a counter for each `CoverageSpan`. There can be multiple `CoverageSpan`s for a given
-    /// BCB, but only one actual counter needs to be incremented per BCB. `bb_counters` maps each
-    /// `bcb` to its `Counter`, when injected. Subsequent `CoverageSpan`s for a BCB that already has
-    /// a `Counter` will inject an `Expression` instead, and compute its value by adding `ZERO` to
-    /// the BCB `Counter` value.
-    fn inject_coverage_span_counters(&mut self, coverage_spans: Vec<CoverageSpan>) {
+    /// Injects a single [`StatementKind::Coverage`] for each BCB that has one
+    /// or more coverage spans.
+    fn inject_coverage_span_counters(&mut self, coverage_spans: &CoverageSpans) {
         let tcx = self.tcx;
         let source_map = tcx.sess.source_map();
         let body_span = self.body_span;
         let file_name = Symbol::intern(&self.source_file.name.prefer_remapped().to_string_lossy());
 
-        let mut bcb_counters = IndexVec::from_elem_n(None, self.basic_coverage_blocks.num_nodes());
-        for covspan in coverage_spans {
-            let bcb = covspan.bcb;
-            let span = covspan.span;
-            let counter_kind = if let Some(&counter_operand) = bcb_counters[bcb].as_ref() {
-                self.coverage_counters.make_identity_counter(counter_operand)
-            } else if let Some(counter_kind) = self.coverage_counters.take_bcb_counter(bcb) {
-                bcb_counters[bcb] = Some(counter_kind.as_operand());
-                counter_kind
-            } else {
+        for (bcb, spans) in coverage_spans.bcbs_with_coverage_spans() {
+            let counter_kind = self.coverage_counters.take_bcb_counter(bcb).unwrap_or_else(|| {
                 bug!("Every BasicCoverageBlock should have a Counter or Expression");
-            };
+            });
 
-            let code_region = make_code_region(source_map, file_name, span, body_span);
+            // Convert the coverage spans into a vector of code regions to be
+            // associated with this BCB's coverage statement.
+            let code_regions = spans
+                .iter()
+                .map(|&span| make_code_region(source_map, file_name, span, body_span))
+                .collect::<Vec<_>>();
 
             inject_statement(
                 self.mir_body,
                 self.make_mir_coverage_kind(&counter_kind),
                 self.bcb_leader_bb(bcb),
-                Some(code_region),
+                code_regions,
             );
         }
     }
 
-    /// `inject_coverage_span_counters()` looped through the `CoverageSpan`s and injected the
-    /// counter from the `CoverageSpan`s `BasicCoverageBlock`, removing it from the BCB in the
-    /// process (via `take_counter()`).
+    /// At this point, any BCB with coverage counters has already had its counter injected
+    /// into MIR, and had its counter removed from `coverage_counters` (via `take_counter()`).
     ///
     /// Any other counter associated with a `BasicCoverageBlock`, or its incoming edge, but not
-    /// associated with a `CoverageSpan`, should only exist if the counter is an `Expression`
+    /// associated with a coverage span, should only exist if the counter is an `Expression`
     /// dependency (one of the expression operands). Collect them, and inject the additional
     /// counters into the MIR, without a reportable coverage span.
     fn inject_indirect_counters(&mut self) {
@@ -303,7 +295,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
                         self.mir_body,
                         self.make_mir_coverage_kind(&counter_kind),
                         inject_to_bb,
-                        None,
+                        Vec::new(),
                     );
                 }
                 BcbCounter::Expression { .. } => inject_intermediate_expression(
@@ -368,20 +360,14 @@ fn inject_statement(
     mir_body: &mut mir::Body<'_>,
     counter_kind: CoverageKind,
     bb: BasicBlock,
-    some_code_region: Option<CodeRegion>,
+    code_regions: Vec<CodeRegion>,
 ) {
-    debug!(
-        "  injecting statement {:?} for {:?} at code region: {:?}",
-        counter_kind, bb, some_code_region
-    );
+    debug!("  injecting statement {counter_kind:?} for {bb:?} at code regions: {code_regions:?}");
     let data = &mut mir_body[bb];
     let source_info = data.terminator().source_info;
     let statement = Statement {
         source_info,
-        kind: StatementKind::Coverage(Box::new(Coverage {
-            kind: counter_kind,
-            code_region: some_code_region,
-        })),
+        kind: StatementKind::Coverage(Box::new(Coverage { kind: counter_kind, code_regions })),
     };
     data.statements.insert(0, statement);
 }
@@ -395,7 +381,10 @@ fn inject_intermediate_expression(mir_body: &mut mir::Body<'_>, expression: Cove
     let source_info = data.terminator().source_info;
     let statement = Statement {
         source_info,
-        kind: StatementKind::Coverage(Box::new(Coverage { kind: expression, code_region: None })),
+        kind: StatementKind::Coverage(Box::new(Coverage {
+            kind: expression,
+            code_regions: Vec::new(),
+        })),
     };
     data.statements.push(statement);
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index 56365c5d474..2c0164e765c 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -93,8 +93,8 @@ fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) ->
 fn covered_code_regions(tcx: TyCtxt<'_>, def_id: DefId) -> Vec<&CodeRegion> {
     let body = mir_body(tcx, def_id);
     all_coverage_in_mir_body(body)
-        // Not all coverage statements have an attached code region.
-        .filter_map(|coverage| coverage.code_region.as_ref())
+        // Coverage statements have a list of code regions (possibly empty).
+        .flat_map(|coverage| coverage.code_regions.as_slice())
         .collect()
 }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 767f8e9f4fa..dd87694f97c 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -1,6 +1,7 @@
 use super::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB};
 
 use rustc_data_structures::graph::WithNumNodes;
+use rustc_index::IndexVec;
 use rustc_middle::mir::{
     self, AggregateKind, BasicBlock, FakeReadCause, Rvalue, Statement, StatementKind, Terminator,
     TerminatorKind,
@@ -10,6 +11,48 @@ use rustc_span::{BytePos, ExpnKind, MacroKind, Span, Symbol};
 
 use std::cell::OnceCell;
 
+pub(super) struct CoverageSpans {
+    /// Map from BCBs to their list of coverage spans.
+    bcb_to_spans: IndexVec<BasicCoverageBlock, Vec<Span>>,
+}
+
+impl CoverageSpans {
+    pub(super) fn generate_coverage_spans(
+        mir_body: &mir::Body<'_>,
+        fn_sig_span: Span,
+        body_span: Span,
+        basic_coverage_blocks: &CoverageGraph,
+    ) -> Self {
+        let coverage_spans = CoverageSpansGenerator::generate_coverage_spans(
+            mir_body,
+            fn_sig_span,
+            body_span,
+            basic_coverage_blocks,
+        );
+
+        // Group the coverage spans by BCB, with the BCBs in sorted order.
+        let mut bcb_to_spans = IndexVec::from_elem_n(Vec::new(), basic_coverage_blocks.num_nodes());
+        for CoverageSpan { bcb, span, .. } in coverage_spans {
+            bcb_to_spans[bcb].push(span);
+        }
+
+        Self { bcb_to_spans }
+    }
+
+    pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool {
+        !self.bcb_to_spans[bcb].is_empty()
+    }
+
+    pub(super) fn bcbs_with_coverage_spans(
+        &self,
+    ) -> impl Iterator<Item = (BasicCoverageBlock, &[Span])> {
+        self.bcb_to_spans.iter_enumerated().filter_map(|(bcb, spans)| {
+            // Only yield BCBs that have at least one coverage span.
+            (!spans.is_empty()).then_some((bcb, spans.as_slice()))
+        })
+    }
+}
+
 #[derive(Debug, Copy, Clone)]
 pub(super) enum CoverageStatement {
     Statement(BasicBlock, Span, usize),
@@ -35,7 +78,7 @@ impl CoverageStatement {
 /// or is subsumed by the `Span` associated with this `CoverageSpan`, and it's `BasicBlock`
 /// `dominates()` the `BasicBlock`s in this `CoverageSpan`.
 #[derive(Debug, Clone)]
-pub(super) struct CoverageSpan {
+struct CoverageSpan {
     pub span: Span,
     pub expn_span: Span,
     pub current_macro_or_none: OnceCell<Option<Symbol>>,
@@ -162,7 +205,7 @@ impl CoverageSpan {
 ///  * Merge spans that represent continuous (both in source code and control flow), non-branching
 ///    execution
 ///  * Carve out (leave uncovered) any span that will be counted by another MIR (notably, closures)
-pub struct CoverageSpans<'a, 'tcx> {
+struct CoverageSpansGenerator<'a, 'tcx> {
     /// The MIR, used to look up `BasicBlockData`.
     mir_body: &'a mir::Body<'tcx>,
 
@@ -218,7 +261,7 @@ pub struct CoverageSpans<'a, 'tcx> {
     refined_spans: Vec<CoverageSpan>,
 }
 
-impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
+impl<'a, 'tcx> CoverageSpansGenerator<'a, 'tcx> {
     /// Generate a minimal set of `CoverageSpan`s, each representing a contiguous code region to be
     /// counted.
     ///
@@ -246,7 +289,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
         body_span: Span,
         basic_coverage_blocks: &'a CoverageGraph,
     ) -> Vec<CoverageSpan> {
-        let mut coverage_spans = CoverageSpans {
+        let mut coverage_spans = Self {
             mir_body,
             fn_sig_span,
             body_span,
@@ -734,7 +777,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
 
 /// If the MIR `Statement` has a span contributive to computing coverage spans,
 /// return it; otherwise return `None`.
-pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span> {
+fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span> {
     match statement.kind {
         // These statements have spans that are often outside the scope of the executed source code
         // for their parent `BasicBlock`.
@@ -781,7 +824,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span>
 
 /// If the MIR `Terminator` has a span contributive to computing coverage spans,
 /// return it; otherwise return `None`.
-pub(super) fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> {
+fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> {
     match terminator.kind {
         // These terminators have spans that don't positively contribute to computing a reasonable
         // span of actually executed source code. (For example, SwitchInt terminators extracted from
@@ -828,7 +871,7 @@ pub(super) fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Sp
 /// [^1]Expansions result from Rust syntax including macros, syntactic sugar,
 /// etc.).
 #[inline]
-pub(super) fn function_source_span(span: Span, body_span: Span) -> Span {
+fn function_source_span(span: Span, body_span: Span) -> Span {
     let original_span = original_sp(span, body_span).with_ctxt(body_span.ctxt());
     if body_span.contains(original_span) { original_span } else { body_span }
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index 4a066ed3abd..7476d3ce927 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -25,8 +25,7 @@
 //! to: `rustc_span::create_default_session_globals_then(|| { test_here(); })`.
 
 use super::counters;
-use super::graph;
-use super::spans;
+use super::graph::{self, BasicCoverageBlock};
 
 use coverage_test_macros::let_bcb;
 
@@ -644,39 +643,18 @@ fn test_traverse_coverage_with_loops() {
     );
 }
 
-fn synthesize_body_span_from_terminators(mir_body: &Body<'_>) -> Span {
-    let mut some_span: Option<Span> = None;
-    for (_, data) in mir_body.basic_blocks.iter_enumerated() {
-        let term_span = data.terminator().source_info.span;
-        if let Some(span) = some_span.as_mut() {
-            *span = span.to(term_span);
-        } else {
-            some_span = Some(term_span)
-        }
-    }
-    some_span.expect("body must have at least one BasicBlock")
-}
-
 #[test]
 fn test_make_bcb_counters() {
     rustc_span::create_default_session_globals_then(|| {
         let mir_body = goto_switchint();
-        let body_span = synthesize_body_span_from_terminators(&mir_body);
         let mut basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
-        let mut coverage_spans = Vec::new();
-        for (bcb, data) in basic_coverage_blocks.iter_enumerated() {
-            if let Some(span) = spans::filtered_terminator_span(data.terminator(&mir_body)) {
-                coverage_spans.push(spans::CoverageSpan::for_terminator(
-                    spans::function_source_span(span, body_span),
-                    span,
-                    bcb,
-                    data.last_bb(),
-                ));
-            }
-        }
+        // Historically this test would use `spans` internals to set up fake
+        // coverage spans for BCBs 1 and 2. Now we skip that step and just tell
+        // BCB counter construction that those BCBs have spans.
+        let bcb_has_coverage_spans = |bcb: BasicCoverageBlock| (1..=2).contains(&bcb.as_usize());
         let mut coverage_counters = counters::CoverageCounters::new(&basic_coverage_blocks);
         coverage_counters
-            .make_bcb_counters(&mut basic_coverage_blocks, &coverage_spans)
+            .make_bcb_counters(&mut basic_coverage_blocks, bcb_has_coverage_spans)
             .expect("should be Ok");
         assert_eq!(coverage_counters.intermediate_expressions.len(), 0);
 
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 449bade3322..56bdc5a171a 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -306,6 +306,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 }
                 ProjectionElem::Downcast(name, index) => ProjectionElem::Downcast(name, index),
                 ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
+                ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty),
             };
             value = self.insert(Value::Projection(value, proj));
         }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index ebd61f8ad95..b53e0852c09 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -218,7 +218,13 @@ impl<'tcx> Inliner<'tcx> {
         // Normally, this shouldn't be required, but trait normalization failure can create a
         // validation ICE.
         let output_type = callee_body.return_ty();
-        if !util::is_subtype(self.tcx, self.param_env, output_type, destination_ty) {
+        if !util::relate_types(
+            self.tcx,
+            self.param_env,
+            ty::Variance::Covariant,
+            output_type,
+            destination_ty,
+        ) {
             trace!(?output_type, ?destination_ty);
             return Err("failed to normalize return type");
         }
@@ -248,7 +254,13 @@ impl<'tcx> Inliner<'tcx> {
                 self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
             {
                 let input_type = callee_body.local_decls[input].ty;
-                if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) {
+                if !util::relate_types(
+                    self.tcx,
+                    self.param_env,
+                    ty::Variance::Covariant,
+                    input_type,
+                    arg_ty,
+                ) {
                     trace!(?arg_ty, ?input_type);
                     return Err("failed to normalize tuple argument type");
                 }
@@ -257,7 +269,13 @@ impl<'tcx> Inliner<'tcx> {
             for (arg, input) in args.iter().zip(callee_body.args_iter()) {
                 let input_type = callee_body.local_decls[input].ty;
                 let arg_ty = arg.ty(&caller_body.local_decls, self.tcx);
-                if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) {
+                if !util::relate_types(
+                    self.tcx,
+                    self.param_env,
+                    ty::Variance::Covariant,
+                    input_type,
+                    arg_ty,
+                ) {
                     trace!(?arg_ty, ?input_type);
                     return Err("failed to normalize argument type");
                 }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 754f2ee8376..22381844d6d 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -54,6 +54,7 @@ mod check_packed_ref;
 pub mod check_unsafety;
 mod remove_place_mention;
 // This pass is public to allow external drivers to perform MIR cleanup
+mod add_subtyping_projections;
 pub mod cleanup_post_borrowck;
 mod const_debuginfo;
 mod const_goto;
@@ -466,6 +467,7 @@ pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
 /// After this series of passes, no lifetime analysis based on borrowing can be done.
 fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let passes: &[&dyn MirPass<'tcx>] = &[
+        &add_subtyping_projections::Subtyper,
         &cleanup_post_borrowck::CleanupPostBorrowck,
         &remove_noop_landing_pads::RemoveNoopLandingPads,
         &simplify::SimplifyCfg::EarlyOpt,
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index 2795cf15702..73dae044355 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -441,21 +441,23 @@ fn save_unreachable_coverage(
         let dead_block = &basic_blocks[dead_block];
         for statement in &dead_block.statements {
             let StatementKind::Coverage(coverage) = &statement.kind else { continue };
-            let Some(code_region) = &coverage.code_region else { continue };
+            if coverage.code_regions.is_empty() {
+                continue;
+            };
             let instance = statement.source_info.scope.inlined_instance(source_scopes);
             if live.contains(&instance) {
-                retained_coverage.push((statement.source_info, code_region.clone()));
+                retained_coverage.push((statement.source_info, coverage.code_regions.clone()));
             }
         }
     }
 
     let start_block = &mut basic_blocks[START_BLOCK];
     start_block.statements.extend(retained_coverage.into_iter().map(
-        |(source_info, code_region)| Statement {
+        |(source_info, code_regions)| Statement {
             source_info,
             kind: StatementKind::Coverage(Box::new(Coverage {
                 kind: CoverageKind::Unreachable,
-                code_region: Some(code_region),
+                code_regions,
             })),
         },
     ));
diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl
index 2b7d9bd3413..cf23d79afaf 100644
--- a/compiler/rustc_monomorphize/messages.ftl
+++ b/compiler/rustc_monomorphize/messages.ftl
@@ -7,8 +7,6 @@ monomorphize_couldnt_dump_mono_stats =
 monomorphize_encountered_error_while_instantiating =
     the above error was encountered while instantiating `{$formatted_item}`
 
-monomorphize_fatal_error = {$error_message}
-
 monomorphize_large_assignments =
     moving {$size} bytes
     .label = value moved from here
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 05b6c406206..88a305e8214 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -59,7 +59,6 @@ parse_bare_cr = {$double_quotes ->
 
 parse_bare_cr_in_raw_string = bare CR not allowed in raw string
 
-parse_binary_float_literal_not_supported = binary float literal is not supported
 parse_bounds_not_allowed_on_trait_aliases = bounds are not allowed on trait aliases
 
 parse_box_not_pat = expected pattern, found {$descr}
@@ -284,7 +283,6 @@ parse_generics_in_path = unexpected generic arguments in path
 
 parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
 parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
-parse_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported
 parse_if_expression_missing_condition = missing condition for `if` expression
     .condition_label = expected condition here
     .block_label = if this block is the condition of the `if` expression, then it must be followed by another block
@@ -356,8 +354,6 @@ parse_inner_doc_comment_not_permitted = expected outer doc comment
     .label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item}
     .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style
 
-parse_int_literal_too_large = integer literal is too large
-
 parse_invalid_block_macro_segment = cannot use a `block` macro fragment here
     .label = the `block` fragment is within this context
     .suggestion = wrap this in another block
@@ -382,18 +378,8 @@ parse_invalid_dyn_keyword = invalid `dyn` keyword
     .suggestion = remove this keyword
 
 parse_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else`
-parse_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal
-    .label = invalid suffix `{$suffix}`
-    .help = valid suffixes are `f32` and `f64`
-
-parse_invalid_float_literal_width = invalid width `{$width}` for float literal
-    .help = valid widths are 32 and 64
-
 parse_invalid_identifier_with_leading_number = identifiers cannot start with a number
 
-parse_invalid_int_literal_width = invalid width `{$width}` for integer literal
-    .help = valid widths are 8, 16, 32, 64 and 128
-
 parse_invalid_interpolated_expression = invalid interpolated expression
 
 parse_invalid_literal_suffix = suffixes on {$kind} literals are invalid
@@ -412,14 +398,6 @@ parse_invalid_logical_operator = `{$incorrect}` is not a logical operator
 
 parse_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}`
 
-parse_invalid_num_literal_base_prefix = invalid base prefix for number literal
-    .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase
-    .suggestion = try making the prefix lowercase
-
-parse_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal
-    .label = invalid suffix `{$suffix}`
-    .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
-
 parse_invalid_unicode_escape = invalid unicode character escape
     .label = invalid escape
     .help = unicode escape must {$surrogate ->
@@ -603,13 +581,6 @@ parse_no_brace_unicode_escape = incorrect unicode escape sequence
 
 parse_no_digits_literal = no valid digits found for number
 
-parse_non_item_in_item_list = non-item in item list
-    .suggestion_use_const_not_let = consider using `const` instead of `let` for associated const
-    .label_list_start = item list starts here
-    .label_non_item = non-item starts here
-    .label_list_end = item list ends here
-    .suggestion_remove_semicolon = consider removing this semicolon
-
 parse_non_string_abi_literal = non-string ABI literal
     .suggestion = specify the ABI with a string literal
 
@@ -626,7 +597,6 @@ parse_note_mut_pattern_usage = `mut` may be followed by `variable` and `variable
 
 parse_note_pattern_alternatives_use_single_vert = alternatives in or-patterns are separated with `|`, not `||`
 
-parse_octal_float_literal_not_supported = octal float literal is not supported
 parse_or_pattern_not_allowed_in_fn_parameters = top-level or-patterns are not allowed in function parameters
 parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allowed in `let` bindings
 parse_out_of_range_hex_escape = out of range hex escape
diff --git a/compiler/rustc_query_system/messages.ftl b/compiler/rustc_query_system/messages.ftl
index d5fed8fe179..d7ab7557511 100644
--- a/compiler/rustc_query_system/messages.ftl
+++ b/compiler/rustc_query_system/messages.ftl
@@ -15,8 +15,6 @@ query_system_cycle_stack_single = ...which immediately requires {$stack_bottom}
 
 query_system_cycle_usage = cycle used when {$usage}
 
-query_system_cycle_which_requires = ...which requires {$desc}...
-
 query_system_increment_compilation = internal compiler error: encountered incremental compilation error with {$dep_node}
     .help = This is a known issue with the compiler. Run {$run_cmd} to allow your project to compile
 
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 9a970f5db39..272483d4a98 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -130,9 +130,6 @@ resolve_generic_params_from_outer_item_ty_param = type parameter from outer item
 resolve_glob_import_doesnt_reexport =
     glob import doesn't reexport anything because no candidate is public enough
 
-resolve_help_try_using_local_generic_param =
-    try using a local generic parameter instead
-
 resolve_ident_bound_more_than_once_in_parameter_list =
     identifier `{$identifier}` is bound more than once in this parameter list
     .label = used as parameter more than once
@@ -249,9 +246,6 @@ resolve_self_in_generic_param_default =
     generic parameters cannot use `Self` in their defaults
     .label = `Self` in generic parameter default
 
-resolve_self_type_implicitly_declared_by_impl =
-    `Self` type implicitly declared here, by this `impl`
-
 resolve_tool_module_imported =
     cannot use a tool module through an import
     .note = the tool module imported here
@@ -267,12 +261,6 @@ resolve_trait_impl_mismatch =
     .label = does not match trait
     .label_trait_item = item in trait
 
-resolve_try_adding_local_generic_param_on_method =
-    try adding a local generic parameter in this method instead
-
-resolve_try_using_local_generic_parameter =
-    try using a local generic parameter instead
-
 resolve_try_using_similarly_named_label =
     try using similarly named label
 
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 15ec727e4c9..ece8b7f6ec9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -41,9 +41,6 @@ type Res = def::Res<NodeId>;
 
 type IdentMap<T> = FxHashMap<Ident, T>;
 
-/// Map from the name in a pattern to its binding mode.
-type BindingMap = IdentMap<BindingInfo>;
-
 use diagnostics::{
     ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime, MissingLifetimeKind,
 };
@@ -3164,8 +3161,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     /// this is done hygienically. This could arise for a macro
     /// that expands into an or-pattern where one 'x' was from the
     /// user and one 'x' came from the macro.
-    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
-        let mut binding_map = FxHashMap::default();
+    fn binding_mode_map(&mut self, pat: &Pat) -> FxIndexMap<Ident, BindingInfo> {
+        let mut binding_map = FxIndexMap::default();
 
         pat.walk(&mut |pat| {
             match pat.kind {
@@ -3200,22 +3197,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
     /// Checks that all of the arms in an or-pattern have exactly the
     /// same set of bindings, with the same binding modes for each.
-    fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) -> Vec<BindingMap> {
-        let mut missing_vars = FxHashMap::default();
-        let mut inconsistent_vars = FxHashMap::default();
+    fn check_consistent_bindings(
+        &mut self,
+        pats: &[P<Pat>],
+    ) -> Vec<FxIndexMap<Ident, BindingInfo>> {
+        // pats is consistent.
+        let mut missing_vars = FxIndexMap::default();
+        let mut inconsistent_vars = FxIndexMap::default();
 
         // 1) Compute the binding maps of all arms.
         let maps = pats.iter().map(|pat| self.binding_mode_map(pat)).collect::<Vec<_>>();
 
         // 2) Record any missing bindings or binding mode inconsistencies.
-        for (map_outer, pat_outer) in pats.iter().enumerate().map(|(idx, pat)| (&maps[idx], pat)) {
+        for (map_outer, pat_outer) in maps.iter().zip(pats.iter()) {
             // Check against all arms except for the same pattern which is always self-consistent.
-            let inners = pats
+            let inners = maps
                 .iter()
-                .enumerate()
+                .zip(pats.iter())
                 .filter(|(_, pat)| pat.id != pat_outer.id)
-                .flat_map(|(idx, _)| maps[idx].iter())
-                .map(|(key, binding)| (key.name, map_outer.get(&key), binding));
+                .flat_map(|(map, _)| map)
+                .map(|(key, binding)| (key.name, map_outer.get(key), binding));
+
+            let inners = inners.collect::<Vec<_>>();
 
             for (name, info, &binding_inner) in inners {
                 match info {
@@ -3244,10 +3247,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         }
 
         // 3) Report all missing variables we found.
-        let mut missing_vars = missing_vars.into_iter().collect::<Vec<_>>();
-        missing_vars.sort_by_key(|&(sym, ref _err)| sym);
-
-        for (name, mut v) in missing_vars.into_iter() {
+        for (name, mut v) in missing_vars {
             if inconsistent_vars.contains_key(&name) {
                 v.could_be_path = false;
             }
@@ -3258,10 +3258,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         }
 
         // 4) Report all inconsistencies in binding modes we found.
-        let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
-        inconsistent_vars.sort();
         for (name, v) in inconsistent_vars {
-            self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
+            self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(name, v.1));
         }
 
         // 5) Finally bubble up all the binding maps.
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index e06b6380944..b356b503aa5 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -25,8 +25,6 @@ session_feature_diagnostic_for_issue =
 session_feature_diagnostic_help =
     add `#![feature({$feature})]` to the crate attributes to enable
 
-session_feature_gate_error = {$explain}
-
 session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions
 
 session_file_write_fail = failed to write `{$path}` due to error `{$err}`
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
index 8d80fcd5fe5..624837a22d6 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
@@ -3,7 +3,7 @@ use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions};
 // This target if is for the Android v7a ABI in thumb mode with
 // NEON unconditionally enabled and, therefore, with 32 FPU registers
 // enabled as well. See section A2.6.2 on page A2-56 in
-// https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
+// https://web.archive.org/web/20210307234416/https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
 
 // See https://developer.android.com/ndk/guides/abis.html#v7a
 // for target ABI requirements.
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
index 28c81340ad8..b500c50de98 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
@@ -4,7 +4,7 @@ use crate::spec::{Target, TargetOptions};
 // (for consistency with Android and Debian-based distributions)
 // and with NEON unconditionally enabled and, therefore, with 32 FPU
 // registers enabled as well. See section A2.6.2 on page A2-56 in
-// https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
+// https://web.archive.org/web/20210307234416/https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
 
 pub fn target() -> Target {
     Target {
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
index 2c375ab22d7..dce0cbcef02 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
@@ -4,7 +4,7 @@ use crate::spec::{Target, TargetOptions};
 // (for consistency with Android and Debian-based distributions)
 // and with NEON unconditionally enabled and, therefore, with 32 FPU
 // registers enabled as well. See section A2.6.2 on page A2-56 in
-// https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
+// https://web.archive.org/web/20210307234416/https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
 
 pub fn target() -> Target {
     Target {
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 0f9d36342ad..339a3e73846 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -346,14 +346,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
             ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output])
         });
 
-        let pred = ty::Clause::from_projection_clause(
-            tcx,
-            tupled_inputs_and_output.map_bound(|(inputs, output)| ty::ProjectionPredicate {
+        let pred = tupled_inputs_and_output
+            .map_bound(|(inputs, output)| ty::ProjectionPredicate {
                 projection_ty: tcx
                     .mk_alias_ty(goal.predicate.def_id(), [goal.predicate.self_ty(), inputs]),
                 term: output.into(),
-            }),
-        );
+            })
+            .to_predicate(tcx);
 
         // A built-in `Fn` impl only holds if the output is sized.
         // (FIXME: technically we only need to check this if the type is a fn ptr...)
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index 820973dc090..015e38b2ac0 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -23,6 +23,7 @@ use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::TypeFoldable;
+use rustc_middle::ty::Variance;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::config::TraitSolver;
 
@@ -156,6 +157,20 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
             .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
     }
 
+    pub fn relate<T: ToTrace<'tcx>>(
+        &self,
+        cause: &ObligationCause<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        variance: Variance,
+        expected: T,
+        actual: T,
+    ) -> Result<(), TypeError<'tcx>> {
+        self.infcx
+            .at(cause, param_env)
+            .relate(DefineOpaqueTypes::Yes, expected, variance, actual)
+            .map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
+    }
+
     /// Checks whether `expected` is a supertype of `actual`: `expected :> actual`.
     pub fn sup<T: ToTrace<'tcx>>(
         &self,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 2a586f810d6..9a728b1060f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-filelength :(
+
 mod ambiguity;
 pub mod on_unimplemented;
 pub mod suggestions;
@@ -67,6 +69,7 @@ pub enum CandidateSimilarity {
 pub struct ImplCandidate<'tcx> {
     pub trait_ref: ty::TraitRef<'tcx>,
     pub similarity: CandidateSimilarity,
+    impl_def_id: DefId,
 }
 
 enum GetSafeTransmuteErrorAndReason {
@@ -1331,6 +1334,7 @@ trait InferCtxtPrivExt<'tcx> {
         body_def_id: LocalDefId,
         err: &mut Diagnostic,
         other: bool,
+        param_env: ty::ParamEnv<'tcx>,
     ) -> bool;
 
     fn report_similar_impl_candidates_for_root_obligation(
@@ -1918,8 +1922,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
                 let imp = self.tcx.impl_trait_ref(def_id).unwrap().skip_binder();
 
-                self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false)
-                    .map(|similarity| ImplCandidate { trait_ref: imp, similarity })
+                self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false).map(
+                    |similarity| ImplCandidate { trait_ref: imp, similarity, impl_def_id: def_id },
+                )
             })
             .collect();
         if candidates.iter().any(|c| matches!(c.similarity, CandidateSimilarity::Exact { .. })) {
@@ -1938,7 +1943,82 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         body_def_id: LocalDefId,
         err: &mut Diagnostic,
         other: bool,
+        param_env: ty::ParamEnv<'tcx>,
     ) -> bool {
+        // If we have a single implementation, try to unify it with the trait ref
+        // that failed. This should uncover a better hint for what *is* implemented.
+        if let [single] = &impl_candidates {
+            if self.probe(|_| {
+                let ocx = ObligationCtxt::new(self);
+                let obligation_trait_ref = self.instantiate_binder_with_placeholders(trait_ref);
+                let impl_args = self.fresh_args_for_item(DUMMY_SP, single.impl_def_id);
+                let impl_trait_ref = ocx.normalize(
+                    &ObligationCause::dummy(),
+                    param_env,
+                    ty::EarlyBinder::bind(single.trait_ref).instantiate(self.tcx, impl_args),
+                );
+
+                ocx.register_obligations(
+                    self.tcx
+                        .predicates_of(single.impl_def_id)
+                        .instantiate(self.tcx, impl_args)
+                        .into_iter()
+                        .map(|(clause, _)| {
+                            Obligation::new(self.tcx, ObligationCause::dummy(), param_env, clause)
+                        }),
+                );
+                if !ocx.select_where_possible().is_empty() {
+                    return false;
+                }
+
+                let mut terrs = vec![];
+                for (obligation_arg, impl_arg) in
+                    std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args)
+                {
+                    if let Err(terr) =
+                        ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg)
+                    {
+                        terrs.push(terr);
+                    }
+                    if !ocx.select_where_possible().is_empty() {
+                        return false;
+                    }
+                }
+
+                // Literally nothing unified, just give up.
+                if terrs.len() == impl_trait_ref.args.len() {
+                    return false;
+                }
+
+                let cand =
+                    self.resolve_vars_if_possible(impl_trait_ref).fold_with(&mut BottomUpFolder {
+                        tcx: self.tcx,
+                        ty_op: |ty| ty,
+                        lt_op: |lt| lt,
+                        ct_op: |ct| ct.normalize(self.tcx, ty::ParamEnv::empty()),
+                    });
+                err.highlighted_help(vec![
+                    (format!("the trait `{}` ", cand.print_only_trait_path()), Style::NoStyle),
+                    ("is".to_string(), Style::Highlight),
+                    (" implemented for `".to_string(), Style::NoStyle),
+                    (cand.self_ty().to_string(), Style::Highlight),
+                    ("`".to_string(), Style::NoStyle),
+                ]);
+
+                if let [TypeError::Sorts(exp_found)] = &terrs[..] {
+                    let exp_found = self.resolve_vars_if_possible(*exp_found);
+                    err.help(format!(
+                        "for that trait implementation, expected `{}`, found `{}`",
+                        exp_found.expected, exp_found.found
+                    ));
+                }
+
+                true
+            }) {
+                return true;
+            }
+        }
+
         let other = if other { "other " } else { "" };
         let report = |candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| {
             if candidates.is_empty() {
@@ -2062,9 +2142,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             })
             .collect();
         impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref));
+        let mut impl_candidates: Vec<_> =
+            impl_candidates.into_iter().map(|cand| cand.trait_ref).collect();
         impl_candidates.dedup();
 
-        report(impl_candidates.into_iter().map(|cand| cand.trait_ref).collect(), err)
+        report(impl_candidates, err)
     }
 
     fn report_similar_impl_candidates_for_root_obligation(
@@ -2108,6 +2190,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 body_def_id,
                 err,
                 true,
+                obligation.param_env,
             );
         }
     }
@@ -2316,6 +2399,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             obligation.cause.body_id,
                             &mut err,
                             false,
+                            obligation.param_env,
                         );
                     }
                 }
@@ -3051,6 +3135,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 body_def_id,
                 err,
                 true,
+                obligation.param_env,
             ) {
                 self.report_similar_impl_candidates_for_root_obligation(
                     &obligation,
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 154cc7a7141..73c2ff3c536 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1644,7 +1644,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
     let env_predicates = data
         .projection_bounds()
         .filter(|bound| bound.item_def_id() == obligation.predicate.def_id)
-        .map(|p| ty::Clause::from_projection_clause(tcx, p.with_self_ty(tcx, object_ty)));
+        .map(|p| p.with_self_ty(tcx, object_ty).to_predicate(tcx));
 
     assemble_candidates_from_predicates(
         selcx,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index bc9ba85fc9f..9b8853b42ab 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -39,6 +39,7 @@ use rustc_middle::dep_graph::dep_kinds;
 use rustc_middle::dep_graph::DepNodeIndex;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::traits::DefiningAnchor;
+use rustc_middle::ty::_match::MatchAgainstFreshVars;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::relate::TypeRelation;
@@ -2642,7 +2643,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         current: ty::PolyTraitPredicate<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> bool {
-        let mut matcher = ty::_match::Match::new(self.tcx(), param_env);
+        let mut matcher = MatchAgainstFreshVars::new(self.tcx(), param_env);
         matcher.relate(previous, current).is_ok()
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index b04008d9ee5..060df772613 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -105,13 +105,13 @@ pub fn unnormalized_obligations<'tcx>(
 
 /// Returns the obligations that make this trait reference
 /// well-formed. For example, if there is a trait `Set` defined like
-/// `trait Set<K:Eq>`, then the trait reference `Foo: Set<Bar>` is WF
+/// `trait Set<K: Eq>`, then the trait bound `Foo: Set<Bar>` is WF
 /// if `Bar: Eq`.
 pub fn trait_obligations<'tcx>(
     infcx: &InferCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     body_id: LocalDefId,
-    trait_pred: &ty::TraitPredicate<'tcx>,
+    trait_pred: ty::TraitPredicate<'tcx>,
     span: Span,
     item: &'tcx hir::Item<'tcx>,
 ) -> Vec<traits::PredicateObligation<'tcx>> {
@@ -129,12 +129,17 @@ pub fn trait_obligations<'tcx>(
     wf.normalize(infcx)
 }
 
+/// Returns the requirements for `clause` to be well-formed.
+///
+/// For example, if there is a trait `Set` defined like
+/// `trait Set<K: Eq>`, then the trait bound `Foo: Set<Bar>` is WF
+/// if `Bar: Eq`.
 #[instrument(skip(infcx), ret)]
-pub fn predicate_obligations<'tcx>(
+pub fn clause_obligations<'tcx>(
     infcx: &InferCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     body_id: LocalDefId,
-    predicate: ty::Predicate<'tcx>,
+    clause: ty::Clause<'tcx>,
     span: Span,
 ) -> Vec<traits::PredicateObligation<'tcx>> {
     let mut wf = WfPredicates {
@@ -148,45 +153,32 @@ pub fn predicate_obligations<'tcx>(
     };
 
     // It's ok to skip the binder here because wf code is prepared for it
-    match predicate.kind().skip_binder() {
-        ty::PredicateKind::Clause(ty::ClauseKind::Trait(t)) => {
-            wf.compute_trait_pred(&t, Elaborate::None);
+    match clause.kind().skip_binder() {
+        ty::ClauseKind::Trait(t) => {
+            wf.compute_trait_pred(t, Elaborate::None);
         }
-        ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) => {}
-        ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
-            ty,
-            _reg,
-        ))) => {
+        ty::ClauseKind::RegionOutlives(..) => {}
+        ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
             wf.compute(ty.into());
         }
-        ty::PredicateKind::Clause(ty::ClauseKind::Projection(t)) => {
+        ty::ClauseKind::Projection(t) => {
             wf.compute_projection(t.projection_ty);
             wf.compute(match t.term.unpack() {
                 ty::TermKind::Ty(ty) => ty.into(),
                 ty::TermKind::Const(c) => c.into(),
             })
         }
-        ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
+        ty::ClauseKind::ConstArgHasType(ct, ty) => {
             wf.compute(ct.into());
             wf.compute(ty.into());
         }
-        ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
+        ty::ClauseKind::WellFormed(arg) => {
             wf.compute(arg);
         }
 
-        ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
+        ty::ClauseKind::ConstEvaluatable(ct) => {
             wf.compute(ct.into());
         }
-
-        ty::PredicateKind::ObjectSafe(_)
-        | ty::PredicateKind::ClosureKind(..)
-        | ty::PredicateKind::Subtype(..)
-        | ty::PredicateKind::Coerce(..)
-        | ty::PredicateKind::ConstEquate(..)
-        | ty::PredicateKind::Ambiguous
-        | ty::PredicateKind::AliasRelate(..) => {
-            bug!("We should only wf check where clauses, unexpected predicate: {predicate:?}")
-        }
     }
 
     wf.normalize(infcx)
@@ -233,7 +225,7 @@ enum Elaborate {
 
 fn extend_cause_with_original_assoc_item_obligation<'tcx>(
     tcx: TyCtxt<'tcx>,
-    trait_ref: &ty::TraitRef<'tcx>,
+    trait_ref: ty::TraitRef<'tcx>,
     item: Option<&hir::Item<'tcx>>,
     cause: &mut traits::ObligationCause<'tcx>,
     pred: ty::Predicate<'tcx>,
@@ -336,9 +328,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
     }
 
     /// Pushes the obligations required for `trait_ref` to be WF into `self.out`.
-    fn compute_trait_pred(&mut self, trait_pred: &ty::TraitPredicate<'tcx>, elaborate: Elaborate) {
+    fn compute_trait_pred(&mut self, trait_pred: ty::TraitPredicate<'tcx>, elaborate: Elaborate) {
         let tcx = self.tcx();
-        let trait_ref = &trait_pred.trait_ref;
+        let trait_ref = trait_pred.trait_ref;
 
         // Negative trait predicates don't require supertraits to hold, just
         // that their args are WF.
@@ -411,7 +403,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
 
     // Compute the obligations that are required for `trait_ref` to be WF,
     // given that it is a *negative* trait predicate.
-    fn compute_negative_trait_pred(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
+    fn compute_negative_trait_pred(&mut self, trait_ref: ty::TraitRef<'tcx>) {
         for arg in trait_ref.args {
             self.compute(arg);
         }
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 4234e69e854..c22c67bd907 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -3,9 +3,8 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_index::bit_set::BitSet;
 use rustc_middle::query::Providers;
-use rustc_middle::ty::{
-    self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
-};
+use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitor};
+use rustc_middle::ty::{ToPredicate, TypeSuperVisitable, TypeVisitable};
 use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
 use rustc_span::DUMMY_SP;
 use rustc_trait_selection::traits;
@@ -214,10 +213,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
             // strategy, then just reinterpret the associated type like an opaque :^)
             let default_ty = self.tcx.type_of(shifted_alias_ty.def_id).instantiate(self.tcx, shifted_alias_ty.args);
 
-            self.predicates.push(ty::Clause::from_projection_clause(self.tcx, ty::Binder::bind_with_vars(
+            self.predicates.push(ty::Binder::bind_with_vars(
                 ty::ProjectionPredicate { projection_ty: shifted_alias_ty, term: default_ty.into() },
                 self.bound_vars,
-            )));
+            ).to_predicate(self.tcx));
 
             // We walk the *un-shifted* alias ty, because we're tracking the de bruijn
             // binder depth, and if we were to walk `shifted_alias_ty` instead, we'd
diff --git a/config.example.toml b/config.example.toml
index f3c2366d674..4f44121410e 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -19,11 +19,18 @@
 # Note that this has no default value (x.py uses the defaults in `config.example.toml`).
 #profile = <none>
 
-# Keeps track of the last version of `x.py` used.
-# If `changelog-seen` does not match the version that is currently running,
-# `x.py` will prompt you to update it and to read the changelog.
-# See `src/bootstrap/CHANGELOG.md` for more information.
-changelog-seen = 2
+# Keeps track of major changes made to this configuration.
+#
+# This value also represents ID of the PR that caused major changes. Meaning,
+# you can visit github.com/rust-lang/rust/pull/{change-id} to check for more details.
+#
+# A 'major change' includes any of the following
+#  - A new option
+#  - A change in the default values
+#
+# If `change-id` does not match the version that is currently running,
+# `x.py` will prompt you to update it and check the related PR for more details.
+change-id = 115898
 
 # =============================================================================
 # Tweaking how LLVM is compiled
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index f435f503fc1..cd3648214a4 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -140,6 +140,7 @@
 #![feature(maybe_uninit_uninit_array_transpose)]
 #![feature(pattern)]
 #![feature(pointer_byte_offsets)]
+#![feature(ptr_addr_eq)]
 #![feature(ptr_internals)]
 #![feature(ptr_metadata)]
 #![feature(ptr_sub_ptr)]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 8dbaca223aa..124f16cfc62 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1649,7 +1649,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
     /// assert!(!Rc::ptr_eq(&five, &other_five));
     /// ```
     pub fn ptr_eq(this: &Self, other: &Self) -> bool {
-        this.ptr.as_ptr() as *const () == other.ptr.as_ptr() as *const ()
+        ptr::addr_eq(this.ptr.as_ptr(), other.ptr.as_ptr())
     }
 }
 
@@ -3146,7 +3146,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
     #[must_use]
     #[stable(feature = "weak_ptr_eq", since = "1.39.0")]
     pub fn ptr_eq(&self, other: &Self) -> bool {
-        ptr::eq(self.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ())
+        ptr::addr_eq(self.ptr.as_ptr(), other.ptr.as_ptr())
     }
 }
 
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 61f4bfc54b0..415825cc878 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -1778,7 +1778,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
     #[must_use]
     #[stable(feature = "ptr_eq", since = "1.17.0")]
     pub fn ptr_eq(this: &Self, other: &Self) -> bool {
-        this.ptr.as_ptr() as *const () == other.ptr.as_ptr() as *const ()
+        ptr::addr_eq(this.ptr.as_ptr(), other.ptr.as_ptr())
     }
 }
 
@@ -2900,7 +2900,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
     #[must_use]
     #[stable(feature = "weak_ptr_eq", since = "1.39.0")]
     pub fn ptr_eq(&self, other: &Self) -> bool {
-        ptr::eq(self.ptr.as_ptr() as *const (), other.ptr.as_ptr() as *const ())
+        ptr::addr_eq(self.ptr.as_ptr(), other.ptr.as_ptr())
     }
 }
 
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index fc91d1afc43..f7d3cda2fe9 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -791,8 +791,10 @@ pub trait Octal {
 /// assert_eq!(format!("l as binary is: {l:b}"), "l as binary is: 1101011");
 ///
 /// assert_eq!(
-///     format!("l as binary is: {l:#032b}"),
-///     "l as binary is: 0b000000000000000000000001101011"
+///     // Note that the `0b` prefix added by `#` is included in the total width, so we
+///     // need to add two to correctly display all 32 bits.
+///     format!("l as binary is: {l:#034b}"),
+///     "l as binary is: 0b00000000000000000000000001101011"
 /// );
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 4bf3da07354..ff177c70d39 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -277,7 +277,7 @@ pub fn spin_loop() {
 /// - Treats the call to `contains` and its result as volatile: the body of `benchmark` cannot
 ///   optimize this away
 ///
-/// This makes our benchmark much more realistic to how the function would be used in situ, where
+/// This makes our benchmark much more realistic to how the function would actually be used, where
 /// arguments are usually not known at compile time and the result is used in some way.
 #[inline]
 #[stable(feature = "bench_black_box", since = "1.66.0")]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index be734a9ba52..ab8d9f33b08 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -418,6 +418,7 @@ pub mod primitive;
 // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is
 // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet.
 #[allow(clashing_extern_declarations)]
+#[cfg_attr(bootstrap, allow(deprecated_in_future))]
 #[unstable(feature = "stdsimd", issue = "48556")]
 mod core_arch;
 
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index fd5fe5a04f4..380a21b376b 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1142,10 +1142,9 @@ impl<T: Copy> Copy for (T,) {
 ///     surprising results upon inspecting the bit patterns,
 ///     as the same calculations might produce NaNs with different bit patterns.
 ///
-/// When the number resulting from a primitive operation (addition,
-/// subtraction, multiplication, or division) on this type is not exactly
-/// representable as `f32`, it is rounded according to the roundTiesToEven
-/// direction defined in IEEE 754-2008. That means:
+/// When a primitive operation (addition, subtraction, multiplication, or
+/// division) is performed on this type, the result is rounded according to the
+/// roundTiesToEven direction defined in IEEE 754-2008. That means:
 ///
 /// - The result is the representable value closest to the true value, if there
 ///   is a unique closest representable value.
@@ -1154,6 +1153,9 @@ impl<T: Copy> Copy for (T,) {
 /// - If the true value's magnitude is ≥ `f32::MAX` + 2<sup>(`f32::MAX_EXP` −
 ///   `f32::MANTISSA_DIGITS` − 1)</sup>, the result is ∞ or −∞ (preserving the
 ///   true value's sign).
+/// - If the result of a sum exactly equals zero, the outcome is +0.0 unless
+///   both arguments were negative, then it is -0.0. Subtraction `a - b` is
+///   regarded as a sum `a + (-b)`.
 ///
 /// For more information on floating point numbers, see [Wikipedia][wikipedia].
 ///
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index d1286a1dea7..5cd2a303310 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1864,10 +1864,34 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz
 /// ```
 #[stable(feature = "ptr_eq", since = "1.17.0")]
 #[inline(always)]
+#[must_use = "pointer comparison produces a value"]
 pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
     a == b
 }
 
+/// Compares the *addresses* of the two pointers for equality,
+/// ignoring any metadata in fat pointers.
+///
+/// If the arguments are thin pointers of the same type,
+/// then this is the same as [`eq`].
+///
+/// # Examples
+///
+/// ```
+/// #![feature(ptr_addr_eq)]
+///
+/// let whole: &[i32; 3] = &[1, 2, 3];
+/// let first: &i32 = &whole[0];
+/// assert!(std::ptr::addr_eq(whole, first));
+/// assert!(!std::ptr::eq::<dyn std::fmt::Debug>(whole, first));
+/// ```
+#[unstable(feature = "ptr_addr_eq", issue = "116324")]
+#[inline(always)]
+#[must_use = "pointer comparison produces a value"]
+pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool {
+    (p as *const ()) == (q as *const ())
+}
+
 /// Hash a raw pointer.
 ///
 /// This can be used to hash a `&T` reference (which coerces to `*const T` implicitly)
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 6981abc9be1..50127b27f8b 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1422,6 +1422,7 @@ impl<T, E> Result<T, E> {
     /// assert_eq!(Err("foo").unwrap_or_else(count), 3);
     /// ```
     #[inline]
+    #[track_caller]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
         match self {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index f1f0f8b1653..6f78778f01a 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -259,7 +259,7 @@
     all(target_vendor = "fortanix", target_env = "sgx"),
     feature(slice_index_methods, coerce_unsized, sgx_platform)
 )]
-#![cfg_attr(windows, feature(round_char_boundary))]
+#![cfg_attr(any(windows, target_os = "uefi"), feature(round_char_boundary))]
 #![cfg_attr(target_os = "xous", feature(slice_ptr_len))]
 //
 // Language features:
diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs
index 227e418b709..60347a11da9 100644
--- a/library/std/src/net/udp.rs
+++ b/library/std/src/net/udp.rs
@@ -99,6 +99,16 @@ impl UdpSocket {
     ///
     /// let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
     /// ```
+    ///
+    /// Note that `bind` declares the scope of your network connection.
+    /// You can only receive datagrams from and send datagrams to
+    /// participants in that view of the network.
+    /// For instance, binding to a loopback address as in the example
+    /// above will prevent you from sending datagrams to another device
+    /// in your local network.
+    ///
+    /// In order to limit your view of the network the least, `bind` to
+    /// [`Ipv4Addr::UNSPECIFIED`] or [`Ipv6Addr::UNSPECIFIED`].
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
         super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
@@ -157,7 +167,9 @@ impl UdpSocket {
     }
 
     /// Sends data on the socket to the given address. On success, returns the
-    /// number of bytes written.
+    /// number of bytes written. Note that the operating system may refuse
+    /// buffers larger than 65507. However, partial writes are not possible
+    /// until buffer sizes above `i32::MAX`.
     ///
     /// Address type can be any implementor of [`ToSocketAddrs`] trait. See its
     /// documentation for concrete examples.
@@ -652,12 +664,19 @@ impl UdpSocket {
     /// function of a UDP socket is not a useful thing to do: The OS will be
     /// unable to determine whether something is listening on the remote
     /// address without the application sending data.
+    ///
+    /// If your first `connect` is to a loopback address, subsequent
+    /// `connect`s to non-loopback addresses might fail, depending
+    /// on the platform.
     #[stable(feature = "net2_mutators", since = "1.9.0")]
     pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
         super::each_addr(addr, |addr| self.0.connect(addr))
     }
 
     /// Sends data on the socket to the remote address to which it is connected.
+    /// On success, returns the number of bytes written. Note that the operating
+    /// system may refuse buffers larger than 65507. However, partial writes are
+    /// not possible until buffer sizes above `i32::MAX`.
     ///
     /// [`UdpSocket::connect`] will connect this socket to a remote address. This
     /// method will fail if the socket is not connected.
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 6cf3bd619b2..e4ab1c17d96 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -607,7 +607,7 @@ impl Command {
     ///
     /// Note that the argument is not passed through a shell, but given
     /// literally to the program. This means that shell syntax like quotes,
-    /// escaped characters, word splitting, glob patterns, substitution, etc.
+    /// escaped characters, word splitting, glob patterns, variable substitution, etc.
     /// have no effect.
     ///
     /// # Examples
@@ -637,7 +637,7 @@ impl Command {
     ///
     /// Note that the arguments are not passed through a shell, but given
     /// literally to the program. This means that shell syntax like quotes,
-    /// escaped characters, word splitting, glob patterns, substitution, etc.
+    /// escaped characters, word splitting, glob patterns, variable substitution, etc.
     /// have no effect.
     ///
     /// # Examples
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 26aaa2414c9..ac7c800ff6f 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -380,7 +380,7 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// If the lock is poisoned, it will remain poisoned until this function is called. This allows
     /// recovering from a poisoned state and marking that it has recovered. For example, if the
-    /// value is overwritten by a known-good value, then the mutex can be marked as un-poisoned. Or
+    /// value is overwritten by a known-good value, then the lock can be marked as un-poisoned. Or
     /// possibly, the value could be inspected to determine if it is in a consistent state, and if
     /// so the poison is removed.
     ///
@@ -397,7 +397,7 @@ impl<T: ?Sized> RwLock<T> {
     ///
     /// let _ = thread::spawn(move || {
     ///     let _lock = c_lock.write().unwrap();
-    ///     panic!(); // the mutex gets poisoned
+    ///     panic!(); // the lock gets poisoned
     /// }).join();
     ///
     /// assert_eq!(lock.is_poisoned(), true);
diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index e477a0cd7ab..559d2c7db47 100644
--- a/library/std/src/sys/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
@@ -95,7 +95,7 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
 cfg_if::cfg_if! {
     if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "tvos"), not(target_os = "watchos"), not(target_os = "netbsd")))] {
         // ARM EHABI personality routine.
-        // https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
+        // https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
         //
         // iOS uses the default routine instead since it uses SjLj unwinding.
         #[lang = "eh_personality"]
diff --git a/library/std/src/sys/uefi/mod.rs b/library/std/src/sys/uefi/mod.rs
index 9a10395af8e..097396ae993 100644
--- a/library/std/src/sys/uefi/mod.rs
+++ b/library/std/src/sys/uefi/mod.rs
@@ -36,7 +36,6 @@ pub mod path;
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
 pub mod process;
-#[path = "../unsupported/stdio.rs"]
 pub mod stdio;
 #[path = "../unsupported/thread.rs"]
 pub mod thread;
diff --git a/library/std/src/sys/uefi/stdio.rs b/library/std/src/sys/uefi/stdio.rs
new file mode 100644
index 00000000000..a533d8a0575
--- /dev/null
+++ b/library/std/src/sys/uefi/stdio.rs
@@ -0,0 +1,162 @@
+use crate::io;
+use crate::iter::Iterator;
+use crate::mem::MaybeUninit;
+use crate::os::uefi;
+use crate::ptr::NonNull;
+
+const MAX_BUFFER_SIZE: usize = 8192;
+
+pub struct Stdin;
+pub struct Stdout;
+pub struct Stderr;
+
+impl Stdin {
+    pub const fn new() -> Stdin {
+        Stdin
+    }
+}
+
+impl io::Read for Stdin {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        let st: NonNull<r_efi::efi::SystemTable> = uefi::env::system_table().cast();
+        let stdin = unsafe { (*st.as_ptr()).con_in };
+
+        // Try reading any pending data
+        let inp = match read_key_stroke(stdin) {
+            Ok(x) => x,
+            Err(e) if e == r_efi::efi::Status::NOT_READY => {
+                // Wait for keypress for new data
+                wait_stdin(stdin)?;
+                read_key_stroke(stdin).map_err(|x| io::Error::from_raw_os_error(x.as_usize()))?
+            }
+            Err(e) => {
+                return Err(io::Error::from_raw_os_error(e.as_usize()));
+            }
+        };
+
+        // Check if the key is printiable character
+        if inp.scan_code != 0x00 {
+            return Err(io::const_io_error!(io::ErrorKind::Interrupted, "Special Key Press"));
+        }
+
+        // SAFETY: Iterator will have only 1 character since we are reading only 1 Key
+        // SAFETY: This character will always be UCS-2 and thus no surrogates.
+        let ch: char = char::decode_utf16([inp.unicode_char]).next().unwrap().unwrap();
+        if ch.len_utf8() > buf.len() {
+            return Ok(0);
+        }
+
+        ch.encode_utf8(buf);
+
+        Ok(ch.len_utf8())
+    }
+}
+
+impl Stdout {
+    pub const fn new() -> Stdout {
+        Stdout
+    }
+}
+
+impl io::Write for Stdout {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        let st: NonNull<r_efi::efi::SystemTable> = uefi::env::system_table().cast();
+        let stdout = unsafe { (*st.as_ptr()).con_out };
+
+        write(stdout, buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl Stderr {
+    pub const fn new() -> Stderr {
+        Stderr
+    }
+}
+
+impl io::Write for Stderr {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        let st: NonNull<r_efi::efi::SystemTable> = uefi::env::system_table().cast();
+        let stderr = unsafe { (*st.as_ptr()).std_err };
+
+        write(stderr, buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+// UCS-2 character should occupy 3 bytes at most in UTF-8
+pub const STDIN_BUF_SIZE: usize = 3;
+
+pub fn is_ebadf(_err: &io::Error) -> bool {
+    true
+}
+
+pub fn panic_output() -> Option<impl io::Write> {
+    uefi::env::try_system_table().map(|_| Stderr::new())
+}
+
+fn write(
+    protocol: *mut r_efi::protocols::simple_text_output::Protocol,
+    buf: &[u8],
+) -> io::Result<usize> {
+    let mut utf16 = [0; MAX_BUFFER_SIZE / 2];
+
+    // Get valid UTF-8 buffer
+    let utf8 = match crate::str::from_utf8(buf) {
+        Ok(x) => x,
+        Err(e) => unsafe { crate::str::from_utf8_unchecked(&buf[..e.valid_up_to()]) },
+    };
+    // Clip UTF-8 buffer to max UTF-16 buffer we support
+    let utf8 = &utf8[..utf8.floor_char_boundary(utf16.len() - 1)];
+
+    for (i, ch) in utf8.encode_utf16().enumerate() {
+        utf16[i] = ch;
+    }
+
+    unsafe { simple_text_output(protocol, &mut utf16) }?;
+
+    Ok(utf8.len())
+}
+
+unsafe fn simple_text_output(
+    protocol: *mut r_efi::protocols::simple_text_output::Protocol,
+    buf: &mut [u16],
+) -> io::Result<()> {
+    let res = unsafe { ((*protocol).output_string)(protocol, buf.as_mut_ptr()) };
+    if res.is_error() { Err(io::Error::from_raw_os_error(res.as_usize())) } else { Ok(()) }
+}
+
+fn wait_stdin(stdin: *mut r_efi::protocols::simple_text_input::Protocol) -> io::Result<()> {
+    let boot_services: NonNull<r_efi::efi::BootServices> =
+        uefi::env::boot_services().unwrap().cast();
+    let wait_for_event = unsafe { (*boot_services.as_ptr()).wait_for_event };
+    let wait_for_key_event = unsafe { (*stdin).wait_for_key };
+
+    let r = {
+        let mut x: usize = 0;
+        (wait_for_event)(1, [wait_for_key_event].as_mut_ptr(), &mut x)
+    };
+    if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
+}
+
+fn read_key_stroke(
+    stdin: *mut r_efi::protocols::simple_text_input::Protocol,
+) -> Result<r_efi::protocols::simple_text_input::InputKey, r_efi::efi::Status> {
+    let mut input_key: MaybeUninit<r_efi::protocols::simple_text_input::InputKey> =
+        MaybeUninit::uninit();
+
+    let r = unsafe { ((*stdin).read_key_stroke)(stdin, input_key.as_mut_ptr()) };
+
+    if r.is_error() {
+        Err(r)
+    } else {
+        let input_key = unsafe { input_key.assume_init() };
+        Ok(input_key)
+    }
+}
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 764e1f25790..5ed2bdd7fe3 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -1391,6 +1391,7 @@ impl FromInner<FileDesc> for File {
 }
 
 impl AsFd for File {
+    #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
         self.0.as_fd()
     }
diff --git a/library/stdarch b/library/stdarch
-Subproject 6100854c4b360f84da5ab25e7c75cb2080667dd
+Subproject 333e9e9977188d0748327e9b5be0f3f41206317
diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md
deleted file mode 100644
index 1aba0713850..00000000000
--- a/src/bootstrap/CHANGELOG.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# Changelog
-
-All notable changes to bootstrap will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
-
-
-## [Changes since the last major version]
-
-- Vendoring is no longer done automatically when building from git sources. To use vendoring, run `cargo vendor` manually, or use the pre-vendored `rustc-src` tarball.
-- `llvm-libunwind` now accepts `in-tree` (formerly true), `system` or `no` (formerly false) [#77703](https://github.com/rust-lang/rust/pull/77703)
-- The options `infodir`, `localstatedir`, and `gpg-password-file` are no longer allowed in config.toml. Previously, they were ignored without warning. Note that `infodir` and `localstatedir` are still accepted by `./configure`, with a warning. [#82451](https://github.com/rust-lang/rust/pull/82451)
-- Change the names for `dist` commands to match the component they generate. [#90684](https://github.com/rust-lang/rust/pull/90684)
-- The `build.fast-submodules` option has been removed. Fast submodule checkouts are enabled unconditionally. Automatic submodule handling can still be disabled with `build.submodules = false`.
-- Several unsupported `./configure` options have been removed: `optimize`, `parallel-compiler`. These can still be enabled with `--set`, although it isn't recommended.
-- `remote-test-server`'s `verbose` argument has been removed in favor of the `--verbose` flag
-- `remote-test-server`'s `remote` argument has been removed in favor of the `--bind` flag. Use `--bind 0.0.0.0:12345` to replicate the behavior of the `remote` argument.
-- `x.py fmt` now formats only files modified between the merge-base of HEAD and the last commit in the master branch of the rust-lang repository and the current working directory. To restore old behaviour, use `x.py fmt .`. The check mode is not affected by this change. [#105702](https://github.com/rust-lang/rust/pull/105702)
-- The `llvm.version-check` config option has been removed. Older versions were never supported. If you still need to support older versions (e.g. you are applying custom patches), patch `check_llvm_version` in bootstrap to change the minimum version. [#108619](https://github.com/rust-lang/rust/pull/108619)
-- The `rust.ignore-git` option has been renamed to `rust.omit-git-hash`. [#110059](https://github.com/rust-lang/rust/pull/110059)
-- `--exclude` no longer accepts a `Kind` as part of a Step; instead it uses the top-level Kind of the subcommand. If this matches how you were already using --exclude (e.g. `x test --exclude test::std`), simply remove the kind: `--exclude std`. If you were using a kind that did not match the top-level subcommand, please open an issue explaining why you wanted this feature.
-
-### Non-breaking changes
-
-- `x.py check` needs opt-in to check tests (--all-targets) [#77473](https://github.com/rust-lang/rust/pull/77473)
-- The default bootstrap profiles are now located at `bootstrap/defaults/config.$PROFILE.toml` (previously they were located at `bootstrap/defaults/config.toml.$PROFILE`) [#77558](https://github.com/rust-lang/rust/pull/77558)
-- If you have Rust already installed, `x.py` will now infer the host target
-  from the default rust toolchain. [#78513](https://github.com/rust-lang/rust/pull/78513)
-- Add options for enabling overflow checks, one for std (`overflow-checks-std`) and one for everything else (`overflow-checks`). Both default to false.
-- Add llvm option `enable-warnings` to have control on llvm compilation warnings. Default to false.
-- Add `rpath` option in `target` section to support set rpath option for each target independently. [#111242](https://github.com/rust-lang/rust/pull/111242)
-
-
-## [Version 2] - 2020-09-25
-
-- `host` now defaults to the value of `build` in all cases
-  + Previously `host` defaulted to an empty list when `target` was overridden, and to `build` otherwise
-
-### Non-breaking changes
-
-- Add `x.py setup` [#76631](https://github.com/rust-lang/rust/pull/76631)
-- Add a changelog for x.py [#76626](https://github.com/rust-lang/rust/pull/76626)
-- Optionally, download LLVM from CI on Linux and NixOS. This can be enabled with `download-ci-llvm = true` under `[llvm]`.
-  + [#76439](https://github.com/rust-lang/rust/pull/76349)
-  + [#76667](https://github.com/rust-lang/rust/pull/76667)
-  + [#76708](https://github.com/rust-lang/rust/pull/76708)
-- Distribute rustc sources as part of `rustc-dev` [#76856](https://github.com/rust-lang/rust/pull/76856)
-- Make the default stage for x.py configurable [#76625](https://github.com/rust-lang/rust/pull/76625). This can be enabled with `build-stage = N`, `doc-stage = N`, etc.
-- Add a dedicated debug-logging option [#76588](https://github.com/rust-lang/rust/pull/76588). Previously, `debug-logging` could only be set with `debug-assertions`, slowing down the compiler more than necessary.
-- Add sample defaults for x.py [#76628](https://github.com/rust-lang/rust/pull/76628)
-- Add `--keep-stage-std`, which behaves like `keep-stage` but allows the stage
-  0 compiler artifacts (i.e., stage1/bin/rustc) to be rebuilt if changed
-  [#77120](https://github.com/rust-lang/rust/pull/77120).
-- File locking is now used to avoid collisions between multiple running instances of `x.py` (e.g. when using `rust-analyzer` and `x.py` at the same time). Note that Solaris and possibly other non Unix and non Windows systems don't support it [#108607](https://github.com/rust-lang/rust/pull/108607). This might possibly lead to build data corruption.
-
-
-## [Version 1] - 2020-09-11
-
-This is the first changelog entry, and it does not attempt to be an exhaustive list of features in x.py.
-Instead, this documents the changes to bootstrap in the past 2 months.
-
-- Improve defaults in `x.py` [#73964](https://github.com/rust-lang/rust/pull/73964)
-  (see [blog post] for details)
-- Set `ninja = true` by default [#74922](https://github.com/rust-lang/rust/pull/74922)
-- Avoid trying to inversely cross-compile for build triple from host triples [#76415](https://github.com/rust-lang/rust/pull/76415)
-- Allow blessing expect-tests in tools [#75975](https://github.com/rust-lang/rust/pull/75975)
-- `x.py check` checks tests/examples/benches [#76258](https://github.com/rust-lang/rust/pull/76258)
-- Fix `rust.use-lld` when linker is not set [#76326](https://github.com/rust-lang/rust/pull/76326)
-- Build tests with LLD if `use-lld = true` was passed [#76378](https://github.com/rust-lang/rust/pull/76378)
-
-[blog post]: https://blog.rust-lang.org/inside-rust/2020/08/30/changes-to-x-py-defaults.html
diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md
index 548281ca506..e7998a40a65 100644
--- a/src/bootstrap/README.md
+++ b/src/bootstrap/README.md
@@ -181,11 +181,10 @@ Some general areas that you may be interested in modifying are:
   `Config` struct.
 * Adding a sanity check? Take a look at `bootstrap/sanity.rs`.
 
-If you make a major change, please remember to:
+If you make a major change on bootstrap configuration, please remember to:
 
-+ Update `VERSION` in `src/bootstrap/main.rs`.
-* Update `changelog-seen = N` in `config.example.toml`.
-* Add an entry in `src/bootstrap/CHANGELOG.md`.
++ Update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/lib.rs`.
+* Update `change-id = {pull-request-id}` in `config.example.toml`.
 
 A 'major change' includes
 
@@ -193,7 +192,7 @@ A 'major change' includes
 * A change in the default options.
 
 Changes that do not affect contributors to the compiler or users
-building rustc from source don't need an update to `VERSION`.
+building rustc from source don't need an update to `CONFIG_CHANGE_HISTORY`.
 
 If you have any questions, feel free to reach out on the `#t-infra/bootstrap` channel
 at [Rust Bootstrap Zulip server][rust-bootstrap-zulip]. When you encounter bugs,
@@ -201,3 +200,8 @@ please file issues on the [Rust issue tracker][rust-issue-tracker].
 
 [rust-bootstrap-zulip]: https://rust-lang.zulipchat.com/#narrow/stream/t-infra.2Fbootstrap
 [rust-issue-tracker]: https://github.com/rust-lang/rust/issues
+
+## Changelog
+
+Because we do not release bootstrap with versions, we also do not maintain CHANGELOG files. To
+review the changes made to bootstrap, simply run `git log --no-merges --oneline -- src/bootstrap`.
diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs
index c497cabbd69..d87fb6a9cef 100644
--- a/src/bootstrap/bin/main.rs
+++ b/src/bootstrap/bin/main.rs
@@ -13,7 +13,7 @@ use std::{env, fs};
 
 #[cfg(all(any(unix, windows), not(target_os = "solaris")))]
 use bootstrap::t;
-use bootstrap::{Build, Config, Subcommand, VERSION};
+use bootstrap::{find_recent_config_change_ids, Build, Config, Subcommand, CONFIG_CHANGE_HISTORY};
 
 fn main() {
     let args = env::args().skip(1).collect::<Vec<_>>();
@@ -42,7 +42,7 @@ fn main() {
             }
             err => {
                 drop(err);
-                println!("warning: build directory locked by process {pid}, waiting for lock");
+                println!("WARNING: build directory locked by process {pid}, waiting for lock");
                 let mut lock = t!(build_lock.write());
                 t!(lock.write(&process::id().to_string().as_ref()));
                 lock
@@ -51,7 +51,7 @@ fn main() {
     }
 
     #[cfg(any(not(any(unix, windows)), target_os = "solaris"))]
-    println!("warning: file locking not supported for target, not locking build directory");
+    println!("WARNING: file locking not supported for target, not locking build directory");
 
     // check_version warnings are not printed during setup
     let changelog_suggestion =
@@ -61,7 +61,7 @@ fn main() {
     // changelog warning, not the `x.py setup` message.
     let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. });
     if suggest_setup {
-        println!("warning: you have not made a `config.toml`");
+        println!("WARNING: you have not made a `config.toml`");
         println!(
             "help: consider running `./x.py setup` or copying `config.example.toml` by running \
             `cp config.example.toml config.toml`"
@@ -74,7 +74,7 @@ fn main() {
     Build::new(config).build();
 
     if suggest_setup {
-        println!("warning: you have not made a `config.toml`");
+        println!("WARNING: you have not made a `config.toml`");
         println!(
             "help: consider running `./x.py setup` or copying `config.example.toml` by running \
             `cp config.example.toml config.toml`"
@@ -91,7 +91,7 @@ fn main() {
         contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570")
     }) {
         println!(
-            "warning: You have the pre-push script installed to .git/hooks/pre-commit. \
+            "WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \
                   Consider moving it to .git/hooks/pre-push instead, which runs less often."
         );
     }
@@ -104,19 +104,34 @@ fn main() {
 fn check_version(config: &Config) -> Option<String> {
     let mut msg = String::new();
 
-    let suggestion = if let Some(seen) = config.changelog_seen {
-        if seen != VERSION {
-            msg.push_str("warning: there have been changes to x.py since you last updated.\n");
-            format!("update `config.toml` to use `changelog-seen = {VERSION}` instead")
+    if config.changelog_seen.is_some() {
+        msg.push_str("WARNING: The use of `changelog-seen` is deprecated. Please refer to `change-id` option in `config.example.toml` instead.\n");
+    }
+
+    let latest_config_id = CONFIG_CHANGE_HISTORY.last().unwrap();
+    let suggestion = if let Some(id) = config.change_id {
+        if &id != latest_config_id {
+            msg.push_str("WARNING: there have been changes to x.py since you last updated.\n");
+            let change_links: Vec<String> = find_recent_config_change_ids(id)
+                .iter()
+                .map(|id| format!("https://github.com/rust-lang/rust/pull/{id}"))
+                .collect();
+            if !change_links.is_empty() {
+                msg.push_str("To see more detail about these changes, visit the following PRs:\n");
+                for link in change_links {
+                    msg.push_str(&format!("  - {link}\n"));
+                }
+            }
+            msg.push_str("WARNING: there have been changes to x.py since you last updated.\n");
+            format!("update `config.toml` to use `change-id = {latest_config_id}` instead")
         } else {
             return None;
         }
     } else {
-        msg.push_str("warning: x.py has made several changes recently you may want to look at\n");
-        format!("add `changelog-seen = {VERSION}` at the top of `config.toml`")
+        msg.push_str("WARNING: The `change-id` is missing in the `config.toml`. This means that you will not be able to track the major changes made to the bootstrap configurations.\n");
+        format!("add `change-id = {latest_config_id}` at the top of `config.toml`")
     };
 
-    msg.push_str("help: consider looking at the changes in `src/bootstrap/CHANGELOG.md`\n");
     msg.push_str("note: to silence this warning, ");
     msg.push_str(&suggestion);
 
diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py
index dc06a4c9734..fefd6b18739 100644
--- a/src/bootstrap/bootstrap_test.py
+++ b/src/bootstrap/bootstrap_test.py
@@ -103,7 +103,7 @@ class GenerateAndParseConfig(unittest.TestCase):
     """Test that we can serialize and deserialize a config.toml file"""
     def test_no_args(self):
         build = serialize_and_parse([])
-        self.assertEqual(build.get_toml("changelog-seen"), '2')
+        self.assertEqual(build.get_toml("change-id"), '115898')
         self.assertEqual(build.get_toml("profile"), 'dist')
         self.assertIsNone(build.get_toml("llvm.download-ci-llvm"))
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 292ccc5780f..daf0798357b 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -158,6 +158,23 @@ impl Step for Std {
         target_deps.extend(copy_third_party_objects(builder, &compiler, target));
         target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
 
+        // The LLD wrappers and `rust-lld` are self-contained linking components that can be
+        // necessary to link the stdlib on some targets. We'll also need to copy these binaries to
+        // the `stage0-sysroot` to ensure the linker is found when bootstrapping on such a target.
+        if compiler.stage == 0 && compiler.host == builder.config.build {
+            // We want to copy the host `bin` folder within the `rustlib` folder in the sysroot.
+            let src_sysroot_bin = builder
+                .rustc_snapshot_sysroot()
+                .join("lib")
+                .join("rustlib")
+                .join(&compiler.host.triple)
+                .join("bin");
+            let target_sysroot_bin =
+                builder.sysroot_libdir(compiler, target).parent().unwrap().join("bin");
+            t!(fs::create_dir_all(&target_sysroot_bin));
+            builder.cp_r(&src_sysroot_bin, &target_sysroot_bin);
+        }
+
         let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build");
         std_cargo(builder, target, compiler.stage, &mut cargo);
         for krate in &*self.crates {
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 836328f94ef..1755c3166de 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -112,7 +112,8 @@ impl Display for DebuginfoLevel {
 /// `config.example.toml`.
 #[derive(Default, Clone)]
 pub struct Config {
-    pub changelog_seen: Option<usize>,
+    pub changelog_seen: Option<usize>, // FIXME: Deprecated field. Remove it at 2024.
+    pub change_id: Option<usize>,
     pub ccache: Option<String>,
     /// Call Build::ninja() instead of this.
     pub ninja_in_file: bool,
@@ -546,7 +547,8 @@ impl Target {
 #[derive(Deserialize, Default)]
 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
 struct TomlConfig {
-    changelog_seen: Option<usize>,
+    changelog_seen: Option<usize>, // FIXME: Deprecated field. Remove it at 2024.
+    change_id: Option<usize>,
     build: Option<Build>,
     install: Option<Install>,
     llvm: Option<Llvm>,
@@ -574,7 +576,17 @@ trait Merge {
 impl Merge for TomlConfig {
     fn merge(
         &mut self,
-        TomlConfig { build, install, llvm, rust, dist, target, profile: _, changelog_seen }: Self,
+        TomlConfig {
+            build,
+            install,
+            llvm,
+            rust,
+            dist,
+            target,
+            profile: _,
+            changelog_seen,
+            change_id,
+        }: Self,
         replace: ReplaceOpt,
     ) {
         fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) {
@@ -587,6 +599,7 @@ impl Merge for TomlConfig {
             }
         }
         self.changelog_seen.merge(changelog_seen, replace);
+        self.change_id.merge(change_id, replace);
         do_merge(&mut self.build, build, replace);
         do_merge(&mut self.install, install, replace);
         do_merge(&mut self.llvm, llvm, replace);
@@ -1242,6 +1255,7 @@ impl Config {
         toml.merge(override_toml, ReplaceOpt::Override);
 
         config.changelog_seen = toml.changelog_seen;
+        config.change_id = toml.change_id;
 
         let build = toml.build.unwrap_or_default();
         if let Some(file_build) = build.build {
diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs
index aac76cdcbcf..d091f33eee4 100644
--- a/src/bootstrap/config/tests.rs
+++ b/src/bootstrap/config/tests.rs
@@ -102,7 +102,7 @@ fn override_toml() {
         &[
             "check".to_owned(),
             "--config=/does/not/exist".to_owned(),
-            "--set=changelog-seen=1".to_owned(),
+            "--set=change-id=1".to_owned(),
             "--set=rust.lto=fat".to_owned(),
             "--set=rust.deny-warnings=false".to_owned(),
             "--set=build.gdb=\"bar\"".to_owned(),
@@ -112,7 +112,7 @@ fn override_toml() {
         |&_| {
             toml::from_str(
                 r#"
-changelog-seen = 0
+change-id = 0
 [rust]
 lto = "off"
 deny-warnings = true
@@ -129,7 +129,7 @@ build-config = {}
             .unwrap()
         },
     );
-    assert_eq!(config.changelog_seen, Some(1), "setting top-level value");
+    assert_eq!(config.change_id, Some(1), "setting top-level value");
     assert_eq!(
         config.rust_lto,
         crate::config::RustcLto::Fat,
@@ -156,10 +156,10 @@ fn override_toml_duplicate() {
         &[
             "check".to_owned(),
             "--config=/does/not/exist".to_owned(),
-            "--set=changelog-seen=1".to_owned(),
-            "--set=changelog-seen=2".to_owned(),
+            "--set=change-id=1".to_owned(),
+            "--set=change-id=2".to_owned(),
         ],
-        |&_| toml::from_str("changelog-seen = 0").unwrap(),
+        |&_| toml::from_str("change-id = 0").unwrap(),
     );
 }
 
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 85cd8abb995..885b3a78236 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -46,10 +46,10 @@ fn sanitize_sh(path: &Path) -> String {
 }
 
 fn is_dir_writable_for_user(dir: &PathBuf) -> bool {
-    let tmp_file = dir.join(".tmp");
-    match fs::File::create(&tmp_file) {
+    let tmp = dir.join(".tmp");
+    match fs::create_dir_all(&tmp) {
         Ok(_) => {
-            fs::remove_file(tmp_file).unwrap();
+            fs::remove_dir_all(tmp).unwrap();
             true
         }
         Err(e) => {
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 8b8d4b23795..5c78015e560 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -112,7 +112,15 @@ const LLVM_TOOLS: &[&str] = &[
 /// LLD file names for all flavors.
 const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
 
-pub const VERSION: usize = 2;
+/// Keeps track of major changes made to the bootstrap configuration.
+///
+/// These values also represent the IDs of the PRs that caused major changes.
+/// You can visit `https://github.com/rust-lang/rust/pull/{any-id-from-the-list}` to
+/// check for more details regarding each change.
+///
+/// If you make any major changes (such as adding new values or changing default values), please
+/// ensure that the associated PR ID is added to the end of this list.
+pub const CONFIG_CHANGE_HISTORY: &[usize] = &[115898];
 
 /// Extra --check-cfg to add when building
 /// (Mode restriction, config name, config values (if any))
@@ -1844,3 +1852,16 @@ fn envify(s: &str) -> String {
         .flat_map(|c| c.to_uppercase())
         .collect()
 }
+
+pub fn find_recent_config_change_ids(current_id: usize) -> Vec<usize> {
+    let index = CONFIG_CHANGE_HISTORY
+        .iter()
+        .position(|&id| id == current_id)
+        .expect(&format!("Value `{}` was not found in `CONFIG_CHANGE_HISTORY`.", current_id));
+
+    CONFIG_CHANGE_HISTORY
+        .iter()
+        .skip(index + 1) // Skip the current_id and IDs before it
+        .cloned()
+        .collect()
+}
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index ef0234957b5..14ec33147fb 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -1,6 +1,6 @@
 use crate::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::Config;
-use crate::{t, VERSION};
+use crate::{t, CONFIG_CHANGE_HISTORY};
 use sha2::Digest;
 use std::env::consts::EXE_SUFFIX;
 use std::fmt::Write as _;
@@ -208,10 +208,11 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
         crate::exit!(1);
     }
 
+    let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap();
     let settings = format!(
         "# Includes one of the default files in src/bootstrap/defaults\n\
     profile = \"{profile}\"\n\
-    changelog-seen = {VERSION}\n"
+    change-id = {latest_change_id}\n"
     );
 
     t!(fs::write(path, settings));
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index ff831a20504..ef4eb5a1965 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -33,9 +33,9 @@ All tier 1 targets with host tools support the full standard library.
 target | notes
 -------|-------
 `aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) [^missing-stack-probes]
-`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support]
-`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support]
-`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+)
+`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support] [^x86_32-floats-return-ABI]
+`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support] [^x86_32-floats-return-ABI]
+`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI]
 `x86_64-apple-darwin` | 64-bit macOS (10.12+, Sierra+)
 `x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 7+) [^windows-support]
 `x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+) [^windows-support]
@@ -47,7 +47,10 @@ target | notes
 
 [^windows-support]: Only Windows 10 currently undergoes automated testing. Earlier versions of Windows rely on testing and support from the community.
 
+[^x86_32-floats-return-ABI]: Due to limitations of the C ABI, floating-point support on `i686` targets is non-compliant: floating-point return values are passed via an x87 register, so NaN payload bits can be lost. See [issue #114479][x86-32-float-issue].
+
 [77071]: https://github.com/rust-lang/rust/issues/77071
+[x86-32-float-issue]: https://github.com/rust-lang/rust/issues/114479
 
 ## Tier 1
 
@@ -150,12 +153,12 @@ target | std | notes
 `armv7r-none-eabi` | * | Bare ARMv7-R
 `armv7r-none-eabihf` | * | Bare ARMv7-R, hardfloat
 `asmjs-unknown-emscripten` | ✓ | asm.js via Emscripten
-`i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE
-`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17)
-`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL
-[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android
-`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD
-`i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL
+`i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE [^x86_32-floats-x87]
+`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17) [^x86_32-floats-x87]
+`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL [^x86_32-floats-x87]
+[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android [^x86_32-floats-return-ABI]
+`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI]
+`i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL [^x86_32-floats-return-ABI]
 [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI
 [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64D ABI)
 [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64S ABI)
@@ -195,6 +198,8 @@ target | std | notes
 `x86_64-unknown-redox` | ✓ | Redox OS
 [`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | 64-bit UEFI
 
+[^x86_32-floats-x87]: Floating-point support on `i586` targets is non-compliant: the `x87` registers and instructions used for these targets do not provide IEEE-754-compliant behavior, in particular when it comes to rounding and NaN payload bits. See [issue #114479][x86-32-float-issue].
+
 [Fortanix ABI]: https://edp.fortanix.com/
 
 ## Tier 3
@@ -264,18 +269,18 @@ target | std | host | notes
 `bpfel-unknown-none` | * |  | BPF (little endian)
 `csky-unknown-linux-gnuabiv2` | ✓ |  | C-SKY abiv2 Linux(little endian)
 `hexagon-unknown-linux-musl` | ? |  |
-`i386-apple-ios` | ✓ |  | 32-bit x86 iOS
-[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * |  | 32-bit x86 QNX Neutrino 7.0 RTOS |
-`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+)
-`i686-pc-windows-msvc` | * |  | 32-bit Windows XP support
-[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
-`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku
-[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd
-[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2
-[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD
-`i686-uwp-windows-gnu` | ? |  |
-`i686-uwp-windows-msvc` | ? |  |
-`i686-wrs-vxworks` | ? |  |
+`i386-apple-ios` | ✓ |  | 32-bit x86 iOS [^x86_32-floats-return-ABI]
+[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * |  | 32-bit x86 QNX Neutrino 7.0 RTOS  [^x86_32-floats-return-ABI]
+`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+) [^x86_32-floats-return-ABI]
+`i686-pc-windows-msvc` | * |  | 32-bit Windows XP support [^x86_32-floats-return-ABI]
+[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | [^x86_32-floats-return-ABI]
+`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku [^x86_32-floats-return-ABI]
+[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd [^x86_32-floats-return-ABI]
+[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 [^x86_32-floats-return-ABI]
+[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD [^x86_32-floats-return-ABI]
+`i686-uwp-windows-gnu` | ? |  | [^x86_32-floats-return-ABI]
+`i686-uwp-windows-msvc` | ? |  | [^x86_32-floats-return-ABI]
+`i686-wrs-vxworks` | ? |  | [^x86_32-floats-return-ABI]
 [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? |  | Motorola 680x0 Linux
 `mips-unknown-linux-uclibc` | ✓ |  | MIPS Linux with uClibc
 [`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? |  | MIPS64 for OpenWrt Linux MUSL
diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
index f8cd92f9257..9233a36db3d 100644
--- a/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
+++ b/src/doc/rustc/src/platform-support/aarch64-unknown-teeos.md
@@ -58,7 +58,7 @@ To build a rust toolchain, create a `config.toml` with the following contents:
 
 ```toml
 profile = "compiler"
-changelog-seen = 2
+change-id = 115898
 
 [build]
 sanitizers = true
diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md
index b376c4a84ac..9f0662783a4 100644
--- a/src/doc/rustc/src/platform-support/nto-qnx.md
+++ b/src/doc/rustc/src/platform-support/nto-qnx.md
@@ -98,7 +98,7 @@ Example content:
 
 ```toml
 profile = "compiler"
-changelog-seen = 2
+change-id = 115898
 ```
 
 2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host (for both `aarch64` and `x86_64` targets)
diff --git a/src/doc/rustc/src/platform-support/openharmony.md b/src/doc/rustc/src/platform-support/openharmony.md
index 89539f3888c..05fd407ed71 100644
--- a/src/doc/rustc/src/platform-support/openharmony.md
+++ b/src/doc/rustc/src/platform-support/openharmony.md
@@ -101,7 +101,7 @@ To build a rust toolchain, create a `config.toml` with the following contents:
 
 ```toml
 profile = "compiler"
-changelog-seen = 2
+change-id = 115898
 
 [build]
 sanitizers = true
diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md
index 68cd7fae319..370939520dc 100644
--- a/src/doc/rustc/src/platform-support/unknown-uefi.md
+++ b/src/doc/rustc/src/platform-support/unknown-uefi.md
@@ -265,9 +265,12 @@ cargo build --target x86_64-unknown-uefi -Zbuild-std=std,panic_abort
 #### os_str
 - While the strings in UEFI should be valid UCS-2, in practice, many implementations just do not care and use UTF-16 strings.
 - Thus, the current implementation supports full UTF-16 strings.
+#### stdio
+- Uses `Simple Text Input Protocol` and `Simple Text Output Protocol`.
+- Note: UEFI uses CRLF for new line. This means Enter key is registered as CR instead of LF.
 
 ## Example: Hello World With std
-The following code features a valid UEFI application, including stdio and `alloc` (`OsString` and `Vec`):
+The following code features a valid UEFI application, including `stdio` and `alloc` (`OsString` and `Vec`):
 
 This example can be compiled as binary crate via `cargo` using the toolchain
 compiled from the above source (named custom):
@@ -286,6 +289,9 @@ use std::{
 };
 
 pub fn main() {
+  println!("Starting Rust Application...");
+
+  // Use System Table Directly
   let st = env::system_table().as_ptr() as *mut efi::SystemTable;
   let mut s: Vec<u16> = OsString::from("Hello World!\n").encode_wide().collect();
   s.push(0);
diff --git a/src/tools/build_helper/src/ci.rs b/src/tools/build_helper/src/ci.rs
index a8505ec9596..09489b0d9b7 100644
--- a/src/tools/build_helper/src/ci.rs
+++ b/src/tools/build_helper/src/ci.rs
@@ -82,15 +82,15 @@ pub mod gha {
 
     fn start_group(name: impl std::fmt::Display) {
         if is_in_gha() {
-            eprintln!("::group::{name}");
+            println!("::group::{name}");
         } else {
-            eprintln!("{name}")
+            println!("{name}")
         }
     }
 
     fn end_group() {
         if is_in_gha() {
-            eprintln!("::endgroup::");
+            println!("::endgroup::");
         }
     }
 
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 17233058c9c..55f9cb27ad4 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -272,6 +272,7 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B
             | ProjectionElem::Downcast(..)
             | ProjectionElem::Subslice { .. }
             | ProjectionElem::Deref
+            | ProjectionElem::Subtype(_)
             | ProjectionElem::Index(_) => {},
         }
     }
diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs
index 31aabca09f3..8000c9e7fdd 100644
--- a/src/tools/opt-dist/src/tests.rs
+++ b/src/tools/opt-dist/src/tests.rs
@@ -61,7 +61,7 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> {
 
     let config_content = format!(
         r#"profile = "user"
-changelog-seen = 2
+change-id = 115898
 
 [build]
 rustc = "{rustc}"
diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
index a7c9e4845c7..e46b902df07 100644
--- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
+++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
@@ -9,6 +9,7 @@
 // [basic] compile-flags: -Z stack-protector=basic
 // [none] compile-flags: -Z stack-protector=none
 // compile-flags: -C opt-level=2 -Z merge-functions=disabled
+// min-llvm-version: 17.0.2
 
 #![crate_type = "lib"]
 
@@ -371,7 +372,7 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
 
 
     // all: __stack_chk_fail
-    // strong: __stack_chk_fail
+    // strong-NOT: __stack_chk_fail
     // basic-NOT: __stack_chk_fail
     // none-NOT: __stack_chk_fail
     // missing-NOT: __stack_chk_fail
diff --git a/tests/codegen/issue-97217.rs b/tests/codegen/issue-97217.rs
new file mode 100644
index 00000000000..af7345442fc
--- /dev/null
+++ b/tests/codegen/issue-97217.rs
@@ -0,0 +1,22 @@
+// compile-flags: -C opt-level=3
+// ignore-debug: the debug assertions get in the way
+// min-llvm-version: 17.0.2
+#![crate_type = "lib"]
+
+// Regression test for issue 97217 (the following should result in no allocations)
+
+// CHECK-LABEL: @issue97217
+#[no_mangle]
+pub fn issue97217() -> i32 {
+    // drop_in_place should be inlined and never appear
+    // CHECK-NOT: drop_in_place
+
+    // __rust_alloc should be optimized out
+    // CHECK-NOT: __rust_alloc
+
+    let v1 = vec![5, 6, 7];
+    let v1_iter = v1.iter();
+    let total: i32 = v1_iter.sum();
+    println!("{}",total);
+    total
+}
diff --git a/tests/codegen/unwind-landingpad-cold.rs b/tests/codegen/unwind-landingpad-cold.rs
new file mode 100644
index 00000000000..3a902a7d712
--- /dev/null
+++ b/tests/codegen/unwind-landingpad-cold.rs
@@ -0,0 +1,16 @@
+// compile-flags: -Cno-prepopulate-passes
+// needs-unwind
+// min-llvm-version: 17.0.2
+#![crate_type = "lib"]
+
+// This test checks that drop calls in unwind landing pads
+// get the `cold` attribute.
+
+// CHECK-LABEL: @check_cold
+// CHECK: {{(call|invoke) void .+}}drop_in_place{{.+}} [[ATTRIBUTES:#[0-9]+]]
+// CHECK: attributes [[ATTRIBUTES]] = { cold }
+#[no_mangle]
+pub fn check_cold(f: fn(), x: Box<u32>) {
+    // this may unwind
+    f();
+}
diff --git a/tests/codegen/unwind-landingpad-inline.rs b/tests/codegen/unwind-landingpad-inline.rs
new file mode 100644
index 00000000000..0774cefdd2d
--- /dev/null
+++ b/tests/codegen/unwind-landingpad-inline.rs
@@ -0,0 +1,39 @@
+// min-llvm-version: 17.0.2
+// compile-flags: -Copt-level=3
+// ignore-debug: the debug assertions get in the way
+#![crate_type = "lib"]
+
+// This test checks that we can inline drop_in_place in
+// unwind landing pads.
+
+// Without inlining, the box pointers escape via the call to drop_in_place,
+// and LLVM will not optimize out the pointer comparison.
+// With inlining, everything should be optimized out.
+// See https://github.com/rust-lang/rust/issues/46515
+// CHECK-LABEL: @check_no_escape_in_landingpad
+// CHECK: start:
+// CHECK-NEXT: __rust_no_alloc_shim_is_unstable
+// CHECK-NEXT: __rust_no_alloc_shim_is_unstable
+// CHECK-NEXT: ret void
+#[no_mangle]
+pub fn check_no_escape_in_landingpad(f: fn()) {
+    let x = &*Box::new(0);
+    let y = &*Box::new(0);
+
+    if x as *const _ == y as *const _ {
+        f();
+    }
+}
+
+// Without inlining, the compiler can't tell that
+// dropping an empty string (in a landing pad) does nothing.
+// With inlining, the landing pad should be optimized out.
+// See https://github.com/rust-lang/rust/issues/87055
+// CHECK-LABEL: @check_eliminate_noop_drop
+// CHECK: call void %g()
+// CHECK-NEXT: ret void
+#[no_mangle]
+pub fn check_eliminate_noop_drop(g: fn()) {
+    let _var = String::new();
+    g();
+}
diff --git a/tests/coverage-map/status-quo/async.cov-map b/tests/coverage-map/status-quo/async.cov-map
index 5f28252ef80..598791537ad 100644
--- a/tests/coverage-map/status-quo/async.cov-map
+++ b/tests/coverage-map/status-quo/async.cov-map
@@ -38,42 +38,40 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 13, 20) to (start + 0, 25)
 
 Function name: async::e (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 01, 00, 14]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 01, 00, 14]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 15, 1) to (start + 0, 20)
+- Code(Zero) at (prev + 15, 1) to (start + 0, 20)
 
 Function name: async::e::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 0f, 14, 00, 19]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 0f, 14, 00, 19]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 15, 20) to (start + 0, 25)
+- Code(Zero) at (prev + 15, 20) to (start + 0, 25)
 
 Function name: async::executor::block_on::<core::pin::Pin<&mut async::i::{closure#0}>>
-Raw bytes (44): 0x[01, 01, 05, 0b, 05, 01, 05, 01, 05, 02, 00, 02, 00, 06, 01, 6e, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 0f, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 13, 02, 05, 00, 06]
+Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 6e, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
+Number of expressions: 3
 - expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero
-- expression 4 operands: lhs = Expression(0, Sub), rhs = Zero
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 110, 5) to (start + 10, 54)
 - Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35)
     = ((c0 + c1) - c1)
 - Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73)
     = (c0 + c1)
-- Code(Expression(3, Add)) at (prev + 1, 23) to (start + 0, 26)
-    = (((c0 + c1) - c1) + Zero)
+- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26)
+    = ((c0 + c1) - c1)
 - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15)
-- Code(Expression(4, Add)) at (prev + 2, 5) to (start + 0, 6)
-    = (((c0 + c1) - c1) + Zero)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
+    = ((c0 + c1) - c1)
 
 Function name: async::executor::block_on::VTABLE::{closure#0}
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 72, 11, 00, 33]
@@ -124,20 +122,20 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 17, 20) to (start + 0, 25)
 
 Function name: async::foo (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 01, 00, 1e]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 01, 00, 1e]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 1) to (start + 0, 30)
+- Code(Zero) at (prev + 19, 1) to (start + 0, 30)
 
 Function name: async::foo::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 13, 1e, 00, 2d]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 13, 1e, 00, 2d]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 19, 30) to (start + 0, 45)
+- Code(Zero) at (prev + 19, 30) to (start + 0, 45)
 
 Function name: async::g
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 15, 01, 00, 17]
@@ -148,14 +146,14 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 21, 1) to (start + 0, 23)
 
 Function name: async::g::{closure#0} (unused)
-Raw bytes (69): 0x[01, 01, 00, 0d, 00, 15, 17, 01, 0c, 00, 02, 09, 00, 0a, 01, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (69): 0x[01, 01, 00, 0d, 00, 15, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 13
 - Code(Zero) at (prev + 21, 23) to (start + 1, 12)
 - Code(Zero) at (prev + 2, 9) to (start + 0, 10)
-- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 17)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 17)
 - Code(Zero) at (prev + 0, 18) to (start + 0, 23)
 - Code(Zero) at (prev + 0, 27) to (start + 0, 28)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
@@ -176,14 +174,14 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 29, 1) to (start + 0, 22)
 
 Function name: async::h::{closure#0} (unused)
-Raw bytes (44): 0x[01, 01, 00, 08, 00, 1d, 16, 03, 0c, 00, 04, 09, 00, 0a, 01, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (44): 0x[01, 01, 00, 08, 00, 1d, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 8
 - Code(Zero) at (prev + 29, 22) to (start + 3, 12)
 - Code(Zero) at (prev + 4, 9) to (start + 0, 10)
-- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 19)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 19)
 - Code(Zero) at (prev + 0, 20) to (start + 0, 25)
 - Code(Zero) at (prev + 0, 26) to (start + 0, 27)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
@@ -199,58 +197,46 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 38, 1) to (start + 0, 19)
 
 Function name: async::i::{closure#0}
-Raw bytes (84): 0x[01, 01, 05, 01, 00, 0d, 00, 1d, 00, 19, 13, 1d, 21, 0e, 01, 26, 13, 04, 0c, 0d, 05, 09, 00, 0a, 03, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 07, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 0b, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 0f, 02, 01, 00, 02]
+Raw bytes (78): 0x[01, 01, 02, 19, 07, 1d, 21, 0e, 01, 26, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
-- expression 0 operands: lhs = Counter(0), rhs = Zero
-- expression 1 operands: lhs = Counter(3), rhs = Zero
-- expression 2 operands: lhs = Counter(7), rhs = Zero
-- expression 3 operands: lhs = Counter(6), rhs = Expression(4, Add)
-- expression 4 operands: lhs = Counter(7), rhs = Counter(8)
+Number of expressions: 2
+- expression 0 operands: lhs = Counter(6), rhs = Expression(1, Add)
+- expression 1 operands: lhs = Counter(7), rhs = Counter(8)
 Number of file 0 mappings: 14
 - Code(Counter(0)) at (prev + 38, 19) to (start + 4, 12)
 - Code(Counter(3)) at (prev + 5, 9) to (start + 0, 10)
-- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 18)
-    = (c0 + Zero)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18)
 - Code(Counter(1)) at (prev + 0, 19) to (start + 0, 24)
 - Code(Counter(2)) at (prev + 0, 28) to (start + 0, 33)
-- Code(Expression(1, Add)) at (prev + 0, 39) to (start + 0, 42)
-    = (c3 + Zero)
+- Code(Counter(3)) at (prev + 0, 39) to (start + 0, 42)
 - Code(Counter(5)) at (prev + 0, 43) to (start + 0, 48)
 - Code(Counter(7)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(4)) at (prev + 0, 14) to (start + 0, 17)
 - Code(Counter(9)) at (prev + 0, 18) to (start + 0, 23)
 - Code(Counter(10)) at (prev + 0, 27) to (start + 0, 32)
-- Code(Expression(2, Add)) at (prev + 0, 36) to (start + 0, 38)
-    = (c7 + Zero)
+- Code(Counter(7)) at (prev + 0, 36) to (start + 0, 38)
 - Code(Counter(8)) at (prev + 1, 14) to (start + 0, 16)
-- Code(Expression(3, Add)) at (prev + 2, 1) to (start + 0, 2)
+- Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2)
     = (c6 + (c7 + c8))
 
 Function name: async::j
-Raw bytes (59): 0x[01, 01, 05, 01, 00, 05, 00, 09, 00, 05, 13, 09, 0d, 09, 01, 31, 01, 13, 0c, 05, 14, 09, 00, 0a, 03, 00, 0e, 00, 1b, 07, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 0b, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 0f, 02, 01, 00, 02]
+Raw bytes (53): 0x[01, 01, 02, 05, 07, 09, 0d, 09, 01, 31, 01, 13, 0c, 05, 14, 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]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
-- expression 0 operands: lhs = Counter(0), rhs = Zero
-- expression 1 operands: lhs = Counter(1), rhs = Zero
-- expression 2 operands: lhs = Counter(2), rhs = Zero
-- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
-- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
+Number of expressions: 2
+- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add)
+- expression 1 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 49, 1) to (start + 19, 12)
 - Code(Counter(1)) at (prev + 20, 9) to (start + 0, 10)
-- Code(Expression(0, Add)) at (prev + 0, 14) to (start + 0, 27)
-    = (c0 + Zero)
-- Code(Expression(1, Add)) at (prev + 0, 31) to (start + 0, 39)
-    = (c1 + Zero)
+- 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(2, Add)) at (prev + 0, 30) to (start + 0, 32)
-    = (c2 + Zero)
+- Code(Counter(2)) at (prev + 0, 30) to (start + 0, 32)
 - Code(Counter(3)) at (prev + 1, 14) to (start + 0, 16)
-- Code(Expression(3, Add)) at (prev + 2, 1) to (start + 0, 2)
+- Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2)
     = (c1 + (c2 + c3))
 
 Function name: async::j::c
@@ -285,12 +271,12 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 67, 5) to (start + 0, 23)
 
 Function name: async::k (unused)
-Raw bytes (29): 0x[01, 01, 00, 05, 01, 4b, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (29): 0x[01, 01, 00, 05, 00, 4b, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 5
-- Code(Counter(0)) at (prev + 75, 1) to (start + 1, 12)
+- Code(Zero) at (prev + 75, 1) to (start + 1, 12)
 - Code(Zero) at (prev + 2, 14) to (start + 0, 16)
 - Code(Zero) at (prev + 1, 14) to (start + 0, 16)
 - Code(Zero) at (prev + 1, 14) to (start + 0, 16)
@@ -323,12 +309,12 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 91, 1) to (start + 0, 25)
 
 Function name: async::m::{closure#0} (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 19, 00, 22]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 5b, 19, 00, 22]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 91, 25) to (start + 0, 34)
+- Code(Zero) at (prev + 91, 25) to (start + 0, 34)
 
 Function name: async::main
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 5d, 01, 08, 02]
diff --git a/tests/coverage-map/status-quo/async2.cov-map b/tests/coverage-map/status-quo/async2.cov-map
index fe74dcd8840..cc7aed9aee3 100644
--- a/tests/coverage-map/status-quo/async2.cov-map
+++ b/tests/coverage-map/status-quo/async2.cov-map
@@ -38,48 +38,44 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 19, 36) to (start + 2, 2)
 
 Function name: async2::executor::block_on::<async2::async_func::{closure#0}>
-Raw bytes (44): 0x[01, 01, 05, 0b, 05, 01, 05, 01, 05, 02, 00, 02, 00, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 0f, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 13, 02, 05, 00, 06]
+Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
+Number of expressions: 3
 - expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero
-- expression 4 operands: lhs = Expression(0, Sub), rhs = Zero
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54)
 - Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35)
     = ((c0 + c1) - c1)
 - Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73)
     = (c0 + c1)
-- Code(Expression(3, Add)) at (prev + 1, 23) to (start + 0, 26)
-    = (((c0 + c1) - c1) + Zero)
+- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26)
+    = ((c0 + c1) - c1)
 - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15)
-- Code(Expression(4, Add)) at (prev + 2, 5) to (start + 0, 6)
-    = (((c0 + c1) - c1) + Zero)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
+    = ((c0 + c1) - c1)
 
 Function name: async2::executor::block_on::<async2::async_func_just_println::{closure#0}>
-Raw bytes (44): 0x[01, 01, 05, 0b, 05, 01, 05, 01, 05, 02, 00, 02, 00, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 0f, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 13, 02, 05, 00, 06]
+Raw bytes (40): 0x[01, 01, 03, 0b, 05, 01, 05, 01, 05, 06, 01, 27, 05, 0a, 36, 02, 0d, 20, 00, 23, 0b, 00, 27, 00, 49, 02, 01, 17, 00, 1a, 05, 01, 0e, 00, 0f, 02, 02, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
+Number of expressions: 3
 - expression 0 operands: lhs = Expression(2, Add), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero
-- expression 4 operands: lhs = Expression(0, Sub), rhs = Zero
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 39, 5) to (start + 10, 54)
 - Code(Expression(0, Sub)) at (prev + 13, 32) to (start + 0, 35)
     = ((c0 + c1) - c1)
 - Code(Expression(2, Add)) at (prev + 0, 39) to (start + 0, 73)
     = (c0 + c1)
-- Code(Expression(3, Add)) at (prev + 1, 23) to (start + 0, 26)
-    = (((c0 + c1) - c1) + Zero)
+- Code(Expression(0, Sub)) at (prev + 1, 23) to (start + 0, 26)
+    = ((c0 + c1) - c1)
 - Code(Counter(1)) at (prev + 1, 14) to (start + 0, 15)
-- Code(Expression(4, Add)) at (prev + 2, 5) to (start + 0, 6)
-    = (((c0 + c1) - c1) + Zero)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
+    = ((c0 + c1) - c1)
 
 Function name: async2::executor::block_on::VTABLE::{closure#0}
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 2b, 11, 00, 33]
diff --git a/tests/coverage-map/status-quo/closure.cov-map b/tests/coverage-map/status-quo/closure.cov-map
index 7dbf6ec834d..522c1e73afe 100644
--- a/tests/coverage-map/status-quo/closure.cov-map
+++ b/tests/coverage-map/status-quo/closure.cov-map
@@ -1,77 +1,36 @@
 Function name: closure::main
-Raw bytes (170): 0x[01, 01, 17, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 00, 01, 05, 05, 5a, 01, 05, 18, 01, 08, 01, 0f, 0d, 03, 16, 0e, 06, 0a, 07, 10, 05, 13, 0d, 0b, 1a, 0e, 06, 0a, 0f, 10, 05, 0c, 16, 13, 16, 05, 0d, 18, 17, 19, 09, 01, 1e, 1b, 04, 09, 00, 29, 1f, 01, 09, 00, 2d, 23, 01, 09, 00, 24, 27, 05, 09, 00, 24, 2b, 02, 09, 00, 21, 2f, 04, 09, 00, 21, 33, 04, 09, 00, 28, 37, 09, 09, 00, 32, 3b, 04, 09, 00, 33, 3f, 07, 09, 00, 4b, 43, 08, 09, 00, 48, 47, 0a, 09, 00, 47, 4b, 08, 09, 00, 44, 4f, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 5a, 04, 06, 00, 07, 57, 01, 05, 03, 02]
+Raw bytes (128): 0x[01, 01, 02, 01, 05, 05, 02, 18, 01, 08, 01, 0f, 0d, 01, 16, 0e, 06, 0a, 01, 10, 05, 13, 0d, 01, 1a, 0e, 06, 0a, 01, 10, 05, 0c, 16, 01, 16, 05, 0d, 18, 01, 19, 09, 01, 1e, 01, 04, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 02, 04, 06, 00, 07, 07, 01, 05, 03, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 23
-- expression 0 operands: lhs = Counter(0), rhs = Zero
-- expression 1 operands: lhs = Counter(0), rhs = Zero
-- expression 2 operands: lhs = Counter(0), rhs = Zero
-- expression 3 operands: lhs = Counter(0), rhs = Zero
-- expression 4 operands: lhs = Counter(0), rhs = Zero
-- expression 5 operands: lhs = Counter(0), rhs = Zero
-- expression 6 operands: lhs = Counter(0), rhs = Zero
-- expression 7 operands: lhs = Counter(0), rhs = Zero
-- expression 8 operands: lhs = Counter(0), rhs = Zero
-- expression 9 operands: lhs = Counter(0), rhs = Zero
-- expression 10 operands: lhs = Counter(0), rhs = Zero
-- expression 11 operands: lhs = Counter(0), rhs = Zero
-- expression 12 operands: lhs = Counter(0), rhs = Zero
-- expression 13 operands: lhs = Counter(0), rhs = Zero
-- expression 14 operands: lhs = Counter(0), rhs = Zero
-- expression 15 operands: lhs = Counter(0), rhs = Zero
-- expression 16 operands: lhs = Counter(0), rhs = Zero
-- expression 17 operands: lhs = Counter(0), rhs = Zero
-- expression 18 operands: lhs = Counter(0), rhs = Zero
-- expression 19 operands: lhs = Counter(0), rhs = Zero
-- expression 20 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 21 operands: lhs = Counter(1), rhs = Expression(22, Sub)
-- expression 22 operands: lhs = Counter(0), rhs = Counter(1)
+Number of expressions: 2
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 24
 - Code(Counter(0)) at (prev + 8, 1) to (start + 15, 13)
-- Code(Expression(0, Add)) at (prev + 22, 14) to (start + 6, 10)
-    = (c0 + Zero)
-- Code(Expression(1, Add)) at (prev + 16, 5) to (start + 19, 13)
-    = (c0 + Zero)
-- Code(Expression(2, Add)) at (prev + 26, 14) to (start + 6, 10)
-    = (c0 + Zero)
-- Code(Expression(3, Add)) at (prev + 16, 5) to (start + 12, 22)
-    = (c0 + Zero)
-- Code(Expression(4, Add)) at (prev + 22, 5) to (start + 13, 24)
-    = (c0 + Zero)
-- Code(Expression(5, Add)) at (prev + 25, 9) to (start + 1, 30)
-    = (c0 + Zero)
-- Code(Expression(6, Add)) at (prev + 4, 9) to (start + 0, 41)
-    = (c0 + Zero)
-- Code(Expression(7, Add)) at (prev + 1, 9) to (start + 0, 45)
-    = (c0 + Zero)
-- Code(Expression(8, Add)) at (prev + 1, 9) to (start + 0, 36)
-    = (c0 + Zero)
-- Code(Expression(9, Add)) at (prev + 5, 9) to (start + 0, 36)
-    = (c0 + Zero)
-- Code(Expression(10, Add)) at (prev + 2, 9) to (start + 0, 33)
-    = (c0 + Zero)
-- Code(Expression(11, Add)) at (prev + 4, 9) to (start + 0, 33)
-    = (c0 + Zero)
-- Code(Expression(12, Add)) at (prev + 4, 9) to (start + 0, 40)
-    = (c0 + Zero)
-- Code(Expression(13, Add)) at (prev + 9, 9) to (start + 0, 50)
-    = (c0 + Zero)
-- Code(Expression(14, Add)) at (prev + 4, 9) to (start + 0, 51)
-    = (c0 + Zero)
-- Code(Expression(15, Add)) at (prev + 7, 9) to (start + 0, 75)
-    = (c0 + Zero)
-- Code(Expression(16, Add)) at (prev + 8, 9) to (start + 0, 72)
-    = (c0 + Zero)
-- Code(Expression(17, Add)) at (prev + 10, 9) to (start + 0, 71)
-    = (c0 + Zero)
-- Code(Expression(18, Add)) at (prev + 8, 9) to (start + 0, 68)
-    = (c0 + Zero)
-- Code(Expression(19, Add)) at (prev + 10, 8) to (start + 0, 16)
-    = (c0 + Zero)
+- Code(Counter(0)) at (prev + 22, 14) to (start + 6, 10)
+- Code(Counter(0)) at (prev + 16, 5) to (start + 19, 13)
+- Code(Counter(0)) at (prev + 26, 14) to (start + 6, 10)
+- Code(Counter(0)) at (prev + 16, 5) to (start + 12, 22)
+- Code(Counter(0)) at (prev + 22, 5) to (start + 13, 24)
+- Code(Counter(0)) at (prev + 25, 9) to (start + 1, 30)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 41)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 45)
+- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 5, 9) to (start + 0, 36)
+- Code(Counter(0)) at (prev + 2, 9) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 9, 9) to (start + 0, 50)
+- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 51)
+- Code(Counter(0)) at (prev + 7, 9) to (start + 0, 75)
+- Code(Counter(0)) at (prev + 8, 9) to (start + 0, 72)
+- Code(Counter(0)) at (prev + 10, 9) to (start + 0, 71)
+- Code(Counter(0)) at (prev + 8, 9) to (start + 0, 68)
+- Code(Counter(0)) at (prev + 10, 8) to (start + 0, 16)
 - Code(Counter(1)) at (prev + 0, 17) to (start + 4, 6)
-- Code(Expression(22, Sub)) at (prev + 4, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 4, 6) to (start + 0, 7)
     = (c0 - c1)
-- Code(Expression(21, Add)) at (prev + 1, 5) to (start + 3, 2)
+- Code(Expression(1, Add)) at (prev + 1, 5) to (start + 3, 2)
     = (c1 + (c0 - c1))
 
 Function name: closure::main::{closure#0}
@@ -90,46 +49,45 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: closure::main::{closure#10} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 9a, 01, 07, 00, 21]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, 9a, 01, 07, 00, 21]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 154, 7) to (start + 0, 33)
+- Code(Zero) at (prev + 154, 7) to (start + 0, 33)
 
 Function name: closure::main::{closure#11} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 9e, 01, 07, 00, 21]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, 9e, 01, 07, 00, 21]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 158, 7) to (start + 0, 33)
+- Code(Zero) at (prev + 158, 7) to (start + 0, 33)
 
 Function name: closure::main::{closure#12} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 01, a6, 01, 01, 00, 17]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, a6, 01, 01, 00, 17]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 166, 1) to (start + 0, 23)
+- Code(Zero) at (prev + 166, 1) to (start + 0, 23)
 
 Function name: closure::main::{closure#13} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 01, ab, 01, 0d, 02, 0e]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, ab, 01, 0d, 02, 0e]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 171, 13) to (start + 2, 14)
+- Code(Zero) at (prev + 171, 13) to (start + 2, 14)
 
 Function name: closure::main::{closure#14}
-Raw bytes (38): 0x[01, 01, 04, 05, 0a, 01, 05, 01, 05, 03, 00, 05, 03, b2, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 0f, 01, 0d, 00, 0e]
+Raw bytes (36): 0x[01, 01, 03, 05, 0a, 01, 05, 01, 05, 05, 03, b2, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 03, 01, 0d, 00, 0e]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 4
+Number of expressions: 3
 - expression 0 operands: lhs = Counter(1), rhs = Expression(2, Sub)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 3 operands: lhs = Expression(0, Add), rhs = Zero
 Number of file 0 mappings: 5
 - Code(Expression(0, Add)) at (prev + 178, 13) to (start + 0, 21)
     = (c1 + (c0 - c1))
@@ -137,40 +95,36 @@ Number of file 0 mappings: 5
 - Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37)
 - Code(Expression(2, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
-- Code(Expression(3, Add)) at (prev + 1, 13) to (start + 0, 14)
-    = ((c1 + (c0 - c1)) + Zero)
+- Code(Expression(0, Add)) at (prev + 1, 13) to (start + 0, 14)
+    = (c1 + (c0 - c1))
 
 Function name: closure::main::{closure#15}
-Raw bytes (45): 0x[01, 01, 05, 05, 0e, 01, 05, 01, 00, 01, 05, 03, 00, 06, 01, ba, 01, 09, 00, 0a, 03, 01, 0d, 00, 15, 0b, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0e, 00, 2f, 00, 33, 13, 02, 09, 00, 0a]
+Raw bytes (41): 0x[01, 01, 03, 05, 0a, 01, 05, 01, 05, 06, 01, ba, 01, 09, 00, 0a, 03, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 03, 02, 09, 00, 0a]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
-- expression 0 operands: lhs = Counter(1), rhs = Expression(3, Sub)
+Number of expressions: 3
+- expression 0 operands: lhs = Counter(1), rhs = Expression(2, Sub)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Counter(0), rhs = Zero
-- expression 3 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 4 operands: lhs = Expression(0, Add), rhs = Zero
+- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 186, 9) to (start + 0, 10)
 - Code(Expression(0, Add)) at (prev + 1, 13) to (start + 0, 21)
     = (c1 + (c0 - c1))
-- Code(Expression(2, Add)) at (prev + 1, 17) to (start + 1, 27)
-    = (c0 + Zero)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27)
 - Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37)
-- Code(Expression(3, Sub)) at (prev + 0, 47) to (start + 0, 51)
+- Code(Expression(2, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
-- Code(Expression(4, Add)) at (prev + 2, 9) to (start + 0, 10)
-    = ((c1 + (c0 - c1)) + Zero)
+- Code(Expression(0, Add)) at (prev + 2, 9) to (start + 0, 10)
+    = (c1 + (c0 - c1))
 
 Function name: closure::main::{closure#16}
-Raw bytes (38): 0x[01, 01, 04, 05, 0a, 01, 05, 01, 05, 03, 00, 05, 03, c4, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 0f, 01, 0d, 00, 0e]
+Raw bytes (36): 0x[01, 01, 03, 05, 0a, 01, 05, 01, 05, 05, 03, c4, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 03, 01, 0d, 00, 0e]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 4
+Number of expressions: 3
 - expression 0 operands: lhs = Counter(1), rhs = Expression(2, Sub)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 2 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 3 operands: lhs = Expression(0, Add), rhs = Zero
 Number of file 0 mappings: 5
 - Code(Expression(0, Add)) at (prev + 196, 13) to (start + 0, 21)
     = (c1 + (c0 - c1))
@@ -178,30 +132,27 @@ Number of file 0 mappings: 5
 - Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37)
 - Code(Expression(2, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
-- Code(Expression(3, Add)) at (prev + 1, 13) to (start + 0, 14)
-    = ((c1 + (c0 - c1)) + Zero)
+- Code(Expression(0, Add)) at (prev + 1, 13) to (start + 0, 14)
+    = (c1 + (c0 - c1))
 
 Function name: closure::main::{closure#17}
-Raw bytes (45): 0x[01, 01, 05, 05, 0e, 01, 05, 01, 00, 01, 05, 03, 00, 06, 01, cc, 01, 09, 00, 0a, 03, 01, 0d, 00, 15, 0b, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0e, 00, 2f, 00, 33, 13, 02, 09, 00, 0a]
+Raw bytes (41): 0x[01, 01, 03, 05, 0a, 01, 05, 01, 05, 06, 01, cc, 01, 09, 00, 0a, 03, 01, 0d, 00, 15, 01, 01, 11, 01, 1b, 05, 01, 1e, 00, 25, 0a, 00, 2f, 00, 33, 03, 02, 09, 00, 0a]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
-- expression 0 operands: lhs = Counter(1), rhs = Expression(3, Sub)
+Number of expressions: 3
+- expression 0 operands: lhs = Counter(1), rhs = Expression(2, Sub)
 - expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Counter(0), rhs = Zero
-- expression 3 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 4 operands: lhs = Expression(0, Add), rhs = Zero
+- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 204, 9) to (start + 0, 10)
 - Code(Expression(0, Add)) at (prev + 1, 13) to (start + 0, 21)
     = (c1 + (c0 - c1))
-- Code(Expression(2, Add)) at (prev + 1, 17) to (start + 1, 27)
-    = (c0 + Zero)
+- Code(Counter(0)) at (prev + 1, 17) to (start + 1, 27)
 - Code(Counter(1)) at (prev + 1, 30) to (start + 0, 37)
-- Code(Expression(3, Sub)) at (prev + 0, 47) to (start + 0, 51)
+- Code(Expression(2, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
-- Code(Expression(4, Add)) at (prev + 2, 9) to (start + 0, 10)
-    = ((c1 + (c0 - c1)) + Zero)
+- Code(Expression(0, Add)) at (prev + 2, 9) to (start + 0, 10)
+    = (c1 + (c0 - c1))
 
 Function name: closure::main::{closure#18}
 Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 18, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 12, 00, 13, 07, 01, 11, 01, 0e]
@@ -264,23 +215,23 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: closure::main::{closure#3} (unused)
-Raw bytes (25): 0x[01, 01, 00, 04, 01, 80, 01, 05, 01, 14, 00, 01, 15, 02, 0a, 00, 02, 0a, 00, 0b, 00, 01, 09, 01, 06]
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 80, 01, 05, 01, 14, 00, 01, 15, 02, 0a, 00, 02, 0a, 00, 0b, 00, 01, 09, 01, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 128, 5) to (start + 1, 20)
+- Code(Zero) at (prev + 128, 5) to (start + 1, 20)
 - Code(Zero) at (prev + 1, 21) to (start + 2, 10)
 - Code(Zero) at (prev + 2, 10) to (start + 0, 11)
 - Code(Zero) at (prev + 1, 9) to (start + 1, 6)
 
 Function name: closure::main::{closure#4} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 88, 01, 35, 00, 43]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, 88, 01, 35, 00, 43]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 136, 53) to (start + 0, 67)
+- Code(Zero) at (prev + 136, 53) to (start + 0, 67)
 
 Function name: closure::main::{closure#5}
 Raw bytes (10): 0x[01, 01, 00, 01, 01, 8b, 01, 3d, 00, 4f]
@@ -299,26 +250,26 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 140, 65) to (start + 0, 87)
 
 Function name: closure::main::{closure#7} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 8d, 01, 3b, 00, 51]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, 8d, 01, 3b, 00, 51]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 141, 59) to (start + 0, 81)
+- Code(Zero) at (prev + 141, 59) to (start + 0, 81)
 
 Function name: closure::main::{closure#8} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 92, 01, 3b, 00, 55]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, 92, 01, 3b, 00, 55]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 146, 59) to (start + 0, 85)
+- Code(Zero) at (prev + 146, 59) to (start + 0, 85)
 
 Function name: closure::main::{closure#9} (unused)
-Raw bytes (10): 0x[01, 01, 00, 01, 01, 94, 01, 38, 02, 06]
+Raw bytes (10): 0x[01, 01, 00, 01, 00, 94, 01, 38, 02, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 148, 56) to (start + 2, 6)
+- Code(Zero) at (prev + 148, 56) to (start + 2, 6)
 
diff --git a/tests/coverage-map/status-quo/closure_bug.cov-map b/tests/coverage-map/status-quo/closure_bug.cov-map
index 4fe2e5ad243..90eeb1a6686 100644
--- a/tests/coverage-map/status-quo/closure_bug.cov-map
+++ b/tests/coverage-map/status-quo/closure_bug.cov-map
@@ -1,89 +1,74 @@
 Function name: closure_bug::main
-Raw bytes (241): 0x[01, 01, 34, 01, 00, 01, 05, 05, ce, 01, 01, 05, cb, 01, 00, 05, ce, 01, 01, 05, cb, 01, 09, 05, ce, 01, 01, 05, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, c3, 01, 00, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, bb, 01, 00, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, bb, 01, 11, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, 11, b6, 01, bb, 01, 11, 0d, be, 01, c3, 01, 0d, 09, c6, 01, cb, 01, 09, 05, ce, 01, 01, 05, 11, 01, 06, 01, 03, 0a, 03, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, ce, 01, 00, 17, 00, 18, cb, 01, 02, 09, 00, 0a, 13, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, c6, 01, 00, 17, 00, 18, c3, 01, 02, 09, 00, 0a, 3b, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, be, 01, 00, 17, 00, 18, bb, 01, 02, 09, 00, 0a, 7b, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, b6, 01, 00, 17, 00, 18, b3, 01, 01, 01, 00, 02]
+Raw bytes (201): 0x[01, 01, 26, 01, 05, 05, 02, 05, 02, 97, 01, 09, 05, 02, 09, 92, 01, 97, 01, 09, 05, 02, 09, 92, 01, 97, 01, 09, 05, 02, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 0d, 8a, 01, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 0d, 8a, 01, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 87, 01, 11, 0d, 8a, 01, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 11, 82, 01, 87, 01, 11, 0d, 8a, 01, 8f, 01, 0d, 09, 92, 01, 97, 01, 09, 05, 02, 11, 01, 06, 01, 03, 0a, 01, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, 02, 00, 17, 00, 18, 97, 01, 02, 09, 00, 0a, 97, 01, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, 92, 01, 00, 17, 00, 18, 8f, 01, 02, 09, 00, 0a, 8f, 01, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, 8a, 01, 00, 17, 00, 18, 87, 01, 02, 09, 00, 0a, 87, 01, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, 82, 01, 00, 17, 00, 18, 7f, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 52
-- expression 0 operands: lhs = Counter(0), rhs = Zero
-- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 2 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 3 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 4 operands: lhs = Expression(50, Add), rhs = Zero
-- expression 5 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 6 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 7 operands: lhs = Expression(50, Add), rhs = Counter(2)
-- expression 8 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 9 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 10 operands: lhs = Counter(2), rhs = Expression(49, Sub)
-- expression 11 operands: lhs = Expression(50, Add), rhs = Counter(2)
-- expression 12 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 13 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 14 operands: lhs = Expression(48, Add), rhs = Zero
-- expression 15 operands: lhs = Counter(2), rhs = Expression(49, Sub)
-- expression 16 operands: lhs = Expression(50, Add), rhs = Counter(2)
-- expression 17 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 18 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 19 operands: lhs = Expression(48, Add), rhs = Counter(3)
-- expression 20 operands: lhs = Counter(2), rhs = Expression(49, Sub)
-- expression 21 operands: lhs = Expression(50, Add), rhs = Counter(2)
-- expression 22 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 23 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 24 operands: lhs = Counter(3), rhs = Expression(47, Sub)
-- expression 25 operands: lhs = Expression(48, Add), rhs = Counter(3)
-- expression 26 operands: lhs = Counter(2), rhs = Expression(49, Sub)
-- expression 27 operands: lhs = Expression(50, Add), rhs = Counter(2)
-- expression 28 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 29 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 30 operands: lhs = Expression(46, Add), rhs = Zero
-- expression 31 operands: lhs = Counter(3), rhs = Expression(47, Sub)
-- expression 32 operands: lhs = Expression(48, Add), rhs = Counter(3)
-- expression 33 operands: lhs = Counter(2), rhs = Expression(49, Sub)
-- expression 34 operands: lhs = Expression(50, Add), rhs = Counter(2)
-- expression 35 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 36 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 37 operands: lhs = Expression(46, Add), rhs = Counter(4)
-- expression 38 operands: lhs = Counter(3), rhs = Expression(47, Sub)
-- expression 39 operands: lhs = Expression(48, Add), rhs = Counter(3)
-- expression 40 operands: lhs = Counter(2), rhs = Expression(49, Sub)
-- expression 41 operands: lhs = Expression(50, Add), rhs = Counter(2)
-- expression 42 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 43 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 44 operands: lhs = Counter(4), rhs = Expression(45, Sub)
-- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(4)
-- expression 46 operands: lhs = Counter(3), rhs = Expression(47, Sub)
-- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(3)
-- expression 48 operands: lhs = Counter(2), rhs = Expression(49, Sub)
-- expression 49 operands: lhs = Expression(50, Add), rhs = Counter(2)
-- expression 50 operands: lhs = Counter(1), rhs = Expression(51, Sub)
-- expression 51 operands: lhs = Counter(0), rhs = Counter(1)
+Number of expressions: 38
+- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 2 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 3 operands: lhs = Expression(37, Add), rhs = Counter(2)
+- expression 4 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 5 operands: lhs = Counter(2), rhs = Expression(36, Sub)
+- expression 6 operands: lhs = Expression(37, Add), rhs = Counter(2)
+- expression 7 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 8 operands: lhs = Counter(2), rhs = Expression(36, Sub)
+- expression 9 operands: lhs = Expression(37, Add), rhs = Counter(2)
+- expression 10 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 11 operands: lhs = Expression(35, Add), rhs = Counter(3)
+- expression 12 operands: lhs = Counter(2), rhs = Expression(36, Sub)
+- expression 13 operands: lhs = Expression(37, Add), rhs = Counter(2)
+- expression 14 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 15 operands: lhs = Counter(3), rhs = Expression(34, Sub)
+- expression 16 operands: lhs = Expression(35, Add), rhs = Counter(3)
+- expression 17 operands: lhs = Counter(2), rhs = Expression(36, Sub)
+- expression 18 operands: lhs = Expression(37, Add), rhs = Counter(2)
+- expression 19 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 20 operands: lhs = Counter(3), rhs = Expression(34, Sub)
+- expression 21 operands: lhs = Expression(35, Add), rhs = Counter(3)
+- expression 22 operands: lhs = Counter(2), rhs = Expression(36, Sub)
+- expression 23 operands: lhs = Expression(37, Add), rhs = Counter(2)
+- expression 24 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 25 operands: lhs = Expression(33, Add), rhs = Counter(4)
+- expression 26 operands: lhs = Counter(3), rhs = Expression(34, Sub)
+- expression 27 operands: lhs = Expression(35, Add), rhs = Counter(3)
+- expression 28 operands: lhs = Counter(2), rhs = Expression(36, Sub)
+- expression 29 operands: lhs = Expression(37, Add), rhs = Counter(2)
+- expression 30 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 31 operands: lhs = Counter(4), rhs = Expression(32, Sub)
+- expression 32 operands: lhs = Expression(33, Add), rhs = Counter(4)
+- expression 33 operands: lhs = Counter(3), rhs = Expression(34, Sub)
+- expression 34 operands: lhs = Expression(35, Add), rhs = Counter(3)
+- expression 35 operands: lhs = Counter(2), rhs = Expression(36, Sub)
+- expression 36 operands: lhs = Expression(37, Add), rhs = Counter(2)
+- expression 37 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 17
 - Code(Counter(0)) at (prev + 6, 1) to (start + 3, 10)
-- Code(Expression(0, Add)) at (prev + 9, 5) to (start + 1, 14)
-    = (c0 + Zero)
+- Code(Counter(0)) at (prev + 9, 5) to (start + 1, 14)
 - Code(Counter(1)) at (prev + 1, 15) to (start + 0, 23)
-- Code(Expression(51, Sub)) at (prev + 0, 23) to (start + 0, 24)
+- Code(Expression(0, Sub)) at (prev + 0, 23) to (start + 0, 24)
     = (c0 - c1)
-- Code(Expression(50, Add)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(37, Add)) at (prev + 2, 9) to (start + 0, 10)
+    = (c1 + (c0 - c1))
+- Code(Expression(37, Add)) at (prev + 6, 5) to (start + 1, 14)
     = (c1 + (c0 - c1))
-- Code(Expression(4, Add)) at (prev + 6, 5) to (start + 1, 14)
-    = ((c1 + (c0 - c1)) + Zero)
 - Code(Counter(2)) at (prev + 1, 15) to (start + 0, 23)
-- Code(Expression(49, Sub)) at (prev + 0, 23) to (start + 0, 24)
+- Code(Expression(36, Sub)) at (prev + 0, 23) to (start + 0, 24)
     = ((c1 + (c0 - c1)) - c2)
-- Code(Expression(48, Add)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(35, Add)) at (prev + 2, 9) to (start + 0, 10)
+    = (c2 + ((c1 + (c0 - c1)) - c2))
+- Code(Expression(35, Add)) at (prev + 6, 5) to (start + 1, 14)
     = (c2 + ((c1 + (c0 - c1)) - c2))
-- Code(Expression(14, Add)) at (prev + 6, 5) to (start + 1, 14)
-    = ((c2 + ((c1 + (c0 - c1)) - c2)) + Zero)
 - Code(Counter(3)) at (prev + 1, 15) to (start + 0, 23)
-- Code(Expression(47, Sub)) at (prev + 0, 23) to (start + 0, 24)
+- Code(Expression(34, Sub)) at (prev + 0, 23) to (start + 0, 24)
     = ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)
-- Code(Expression(46, Add)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(33, Add)) at (prev + 2, 9) to (start + 0, 10)
+    = (c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3))
+- Code(Expression(33, Add)) at (prev + 6, 5) to (start + 1, 14)
     = (c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3))
-- Code(Expression(30, Add)) at (prev + 6, 5) to (start + 1, 14)
-    = ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) + Zero)
 - Code(Counter(4)) at (prev + 1, 15) to (start + 0, 23)
-- Code(Expression(45, Sub)) at (prev + 0, 23) to (start + 0, 24)
+- Code(Expression(32, Sub)) at (prev + 0, 23) to (start + 0, 24)
     = ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)
-- Code(Expression(44, Add)) at (prev + 1, 1) to (start + 0, 2)
+- Code(Expression(31, Add)) at (prev + 1, 1) to (start + 0, 2)
     = (c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4))
 
 Function name: closure_bug::main::{closure#0}
diff --git a/tests/coverage-map/status-quo/closure_macro.cov-map b/tests/coverage-map/status-quo/closure_macro.cov-map
index ac017eb4468..b02c7e2e4c6 100644
--- a/tests/coverage-map/status-quo/closure_macro.cov-map
+++ b/tests/coverage-map/status-quo/closure_macro.cov-map
@@ -7,27 +7,23 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2)
 
 Function name: closure_macro::main
-Raw bytes (49): 0x[01, 01, 05, 01, 05, 02, 00, 05, 00, 02, 00, 05, 02, 07, 01, 21, 01, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 07, 00, 12, 00, 13, 0b, 00, 54, 00, 55, 0f, 02, 09, 02, 0b, 13, 03, 01, 00, 02]
+Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 21, 01, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
+Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Expression(0, Sub), rhs = Zero
-- expression 2 operands: lhs = Counter(1), rhs = Zero
-- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero
-- expression 4 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 33, 1) to (start + 1, 33)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19)
-- Code(Expression(1, Add)) at (prev + 0, 18) to (start + 0, 19)
-    = ((c0 - c1) + Zero)
-- Code(Expression(2, Add)) at (prev + 0, 84) to (start + 0, 85)
-    = (c1 + Zero)
-- Code(Expression(3, Add)) at (prev + 2, 9) to (start + 2, 11)
-    = ((c0 - c1) + Zero)
-- Code(Expression(4, Add)) at (prev + 3, 1) to (start + 0, 2)
+- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19)
+    = (c0 - c1)
+- Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
+    = (c0 - c1)
+- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2)
     = (c1 + (c0 - c1))
 
 Function name: closure_macro::main::{closure#0}
diff --git a/tests/coverage-map/status-quo/closure_macro_async.cov-map b/tests/coverage-map/status-quo/closure_macro_async.cov-map
index c9a142e5aeb..7f8666948d9 100644
--- a/tests/coverage-map/status-quo/closure_macro_async.cov-map
+++ b/tests/coverage-map/status-quo/closure_macro_async.cov-map
@@ -15,27 +15,23 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 33, 1) to (start + 0, 43)
 
 Function name: closure_macro_async::test::{closure#0}
-Raw bytes (49): 0x[01, 01, 05, 01, 05, 02, 00, 05, 00, 02, 00, 05, 02, 07, 01, 21, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 07, 00, 12, 00, 13, 0b, 00, 54, 00, 55, 0f, 02, 09, 02, 0b, 13, 03, 01, 00, 02]
+Raw bytes (43): 0x[01, 01, 02, 01, 05, 05, 02, 07, 01, 21, 2b, 01, 21, 02, 02, 09, 00, 0f, 05, 00, 12, 00, 13, 02, 00, 12, 00, 13, 05, 00, 54, 00, 55, 02, 02, 09, 02, 0b, 07, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
+Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Expression(0, Sub), rhs = Zero
-- expression 2 operands: lhs = Counter(1), rhs = Zero
-- expression 3 operands: lhs = Expression(0, Sub), rhs = Zero
-- expression 4 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 1 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 33, 43) to (start + 1, 33)
 - Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 15)
     = (c0 - c1)
 - Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19)
-- Code(Expression(1, Add)) at (prev + 0, 18) to (start + 0, 19)
-    = ((c0 - c1) + Zero)
-- Code(Expression(2, Add)) at (prev + 0, 84) to (start + 0, 85)
-    = (c1 + Zero)
-- Code(Expression(3, Add)) at (prev + 2, 9) to (start + 2, 11)
-    = ((c0 - c1) + Zero)
-- Code(Expression(4, Add)) at (prev + 3, 1) to (start + 0, 2)
+- Code(Expression(0, Sub)) at (prev + 0, 18) to (start + 0, 19)
+    = (c0 - c1)
+- Code(Counter(1)) at (prev + 0, 84) to (start + 0, 85)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 2, 11)
+    = (c0 - c1)
+- Code(Expression(1, Add)) at (prev + 3, 1) to (start + 0, 2)
     = (c1 + (c0 - c1))
 
 Function name: closure_macro_async::test::{closure#0}::{closure#0}
diff --git a/tests/coverage-map/status-quo/conditions.cov-map b/tests/coverage-map/status-quo/conditions.cov-map
index d82b8389b4d..7600d2d96bd 100644
--- a/tests/coverage-map/status-quo/conditions.cov-map
+++ b/tests/coverage-map/status-quo/conditions.cov-map
@@ -1,14 +1,14 @@
 Function name: conditions::main
-Raw bytes (793): 0x[01, 01, 90, 01, 09, 33, 37, 41, 3b, 3d, 35, 39, 05, 00, bf, 04, 09, 05, 00, 0d, 35, 26, 39, 0d, 35, 3b, 3d, 35, 39, 37, 41, 3b, 3d, 35, 39, ba, 04, 0d, bf, 04, 09, 05, 00, 03, 00, 45, 00, 87, 01, 49, 45, 00, 82, 01, 31, 87, 01, 49, 45, 00, 7e, 4d, 82, 01, 31, 87, 01, 49, 45, 00, 7a, 51, 7e, 4d, 82, 01, 31, 87, 01, 49, 45, 00, ab, 01, 55, 4d, 51, a7, 01, 59, ab, 01, 55, 4d, 51, 49, a3, 01, a7, 01, 59, ab, 01, 55, 4d, 51, 61, 00, e7, 01, 65, 61, 00, e2, 01, 2d, e7, 01, 65, 61, 00, de, 01, 69, e2, 01, 2d, e7, 01, 65, 61, 00, da, 01, 6d, de, 01, 69, e2, 01, 2d, e7, 01, 65, 61, 00, 8f, 02, 71, 69, 6d, 8b, 02, 75, 8f, 02, 71, 69, 6d, 83, 02, 00, 65, 87, 02, 8b, 02, 75, 8f, 02, 71, 69, 6d, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, 79, 00, db, 02, 7d, 79, 00, d6, 02, 29, db, 02, 7d, 79, 00, d2, 02, 81, 01, d6, 02, 29, db, 02, 7d, 79, 00, ce, 02, 85, 01, d2, 02, 81, 01, d6, 02, 29, db, 02, 7d, 79, 00, fb, 03, 89, 01, 81, 01, 85, 01, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, 11, 9b, 04, 9f, 04, 21, a3, 04, 1d, 15, 19, ef, 03, 00, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, ef, 03, 11, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, ea, 03, 25, ef, 03, 11, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, e6, 03, 15, ea, 03, 25, ef, 03, 11, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, e2, 03, 19, e6, 03, 15, ea, 03, 25, ef, 03, 11, 7d, f3, 03, f7, 03, 8d, 01, fb, 03, 89, 01, 81, 01, 85, 01, a3, 04, 1d, 15, 19, 9f, 04, 21, a3, 04, 1d, 15, 19, 97, 04, a7, 04, 11, 9b, 04, 9f, 04, 21, a3, 04, 1d, 15, 19, ab, 04, b6, 04, af, 04, b3, 04, 25, 29, 2d, 31, ba, 04, 0d, bf, 04, 09, 05, 00, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 06, 00, 07, 03, 03, 09, 00, 0a, bf, 04, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, ba, 04, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 26, 00, 1d, 00, 2a, 22, 00, 2e, 00, 3c, 37, 00, 3d, 02, 0a, 41, 02, 0a, 00, 0b, 33, 01, 09, 01, 12, b6, 04, 03, 09, 00, 0f, 4b, 03, 09, 01, 0c, 45, 01, 0d, 02, 06, 00, 02, 06, 00, 07, 87, 01, 02, 08, 00, 15, 49, 00, 16, 02, 06, 82, 01, 02, 0f, 00, 1c, 7e, 01, 0c, 00, 19, 7a, 00, 1d, 00, 2a, 76, 00, 2e, 00, 3c, a7, 01, 00, 3d, 02, 0a, 59, 02, 0a, 00, 0b, a3, 01, 01, 09, 00, 17, 31, 02, 09, 00, 0f, 9f, 01, 03, 08, 00, 0c, 5d, 01, 0d, 01, 10, 61, 01, 11, 02, 0a, 00, 02, 0a, 00, 0b, e7, 01, 02, 0c, 00, 19, 65, 00, 1a, 02, 0a, e2, 01, 03, 11, 00, 1e, de, 01, 01, 10, 00, 1d, da, 01, 00, 21, 00, 2e, d6, 01, 00, 32, 00, 40, 8b, 02, 00, 41, 02, 0e, 75, 02, 0e, 00, 0f, 87, 02, 01, 0d, 00, 1b, 2d, 02, 0d, 00, 13, 00, 02, 06, 00, 07, ff, 01, 02, 09, 01, 0c, 79, 01, 0d, 02, 06, 00, 02, 06, 00, 07, ef, 03, 02, 09, 00, 0a, db, 02, 00, 10, 00, 1d, 7d, 00, 1e, 02, 06, d6, 02, 02, 0f, 00, 1c, d2, 02, 01, 0c, 00, 19, ce, 02, 00, 1d, 00, 2a, ca, 02, 00, 2e, 00, 3c, f7, 03, 00, 3d, 02, 0a, 8d, 01, 02, 0a, 00, 0b, f3, 03, 01, 09, 00, 17, 29, 02, 0d, 02, 0f, 97, 04, 05, 09, 00, 0a, 83, 03, 00, 10, 00, 1d, 11, 00, 1e, 02, 06, ea, 03, 02, 0f, 00, 1c, e6, 03, 01, 0c, 00, 19, e2, 03, 00, 1d, 00, 2a, de, 03, 00, 2e, 00, 3c, 9f, 04, 00, 3d, 02, 0a, 21, 02, 0a, 00, 0b, 9b, 04, 01, 09, 00, 17, 25, 02, 09, 00, 0f, 93, 04, 02, 01, 00, 02]
+Raw bytes (784): 0x[01, 01, 8e, 01, 09, 33, 37, 41, 3b, 3d, 35, 39, 05, 00, b7, 04, 09, 05, 00, 0d, 35, 26, 39, 0d, 35, 3b, 3d, 35, 39, 37, 41, 3b, 3d, 35, 39, b2, 04, 0d, b7, 04, 09, 05, 00, 45, 00, 83, 01, 49, 45, 00, 7e, 31, 83, 01, 49, 45, 00, 7a, 4d, 7e, 31, 83, 01, 49, 45, 00, 76, 51, 7a, 4d, 7e, 31, 83, 01, 49, 45, 00, a7, 01, 55, 4d, 51, a3, 01, 59, a7, 01, 55, 4d, 51, 49, 9f, 01, a3, 01, 59, a7, 01, 55, 4d, 51, 61, 00, e3, 01, 65, 61, 00, de, 01, 2d, e3, 01, 65, 61, 00, da, 01, 69, de, 01, 2d, e3, 01, 65, 61, 00, d6, 01, 6d, da, 01, 69, de, 01, 2d, e3, 01, 65, 61, 00, 8b, 02, 71, 69, 6d, 87, 02, 75, 8b, 02, 71, 69, 6d, ff, 01, 00, 65, 83, 02, 87, 02, 75, 8b, 02, 71, 69, 6d, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 79, 00, d7, 02, 7d, 79, 00, d2, 02, 29, d7, 02, 7d, 79, 00, ce, 02, 81, 01, d2, 02, 29, d7, 02, 7d, 79, 00, ca, 02, 85, 01, ce, 02, 81, 01, d2, 02, 29, d7, 02, 7d, 79, 00, f3, 03, 89, 01, 81, 01, 85, 01, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 11, 93, 04, 97, 04, 21, 9b, 04, 1d, 15, 19, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, de, 03, 15, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, da, 03, 19, de, 03, 15, e2, 03, 25, e7, 03, 11, 7d, eb, 03, ef, 03, 8d, 01, f3, 03, 89, 01, 81, 01, 85, 01, 9b, 04, 1d, 15, 19, 97, 04, 21, 9b, 04, 1d, 15, 19, 8f, 04, 9f, 04, 11, 93, 04, 97, 04, 21, 9b, 04, 1d, 15, 19, a3, 04, ae, 04, a7, 04, ab, 04, 25, 29, 2d, 31, b2, 04, 0d, b7, 04, 09, 05, 00, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 06, 00, 07, 03, 03, 09, 00, 0a, b7, 04, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, b2, 04, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 26, 00, 1d, 00, 2a, 22, 00, 2e, 00, 3c, 37, 00, 3d, 02, 0a, 41, 02, 0a, 00, 0b, 33, 01, 09, 01, 12, ae, 04, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 45, 01, 0d, 02, 06, 00, 02, 06, 00, 07, 83, 01, 02, 08, 00, 15, 49, 00, 16, 02, 06, 7e, 02, 0f, 00, 1c, 7a, 01, 0c, 00, 19, 76, 00, 1d, 00, 2a, 72, 00, 2e, 00, 3c, a3, 01, 00, 3d, 02, 0a, 59, 02, 0a, 00, 0b, 9f, 01, 01, 09, 00, 17, 31, 02, 09, 00, 0f, 9b, 01, 03, 08, 00, 0c, 5d, 01, 0d, 01, 10, 61, 01, 11, 02, 0a, 00, 02, 0a, 00, 0b, e3, 01, 02, 0c, 00, 19, 65, 00, 1a, 02, 0a, de, 01, 03, 11, 00, 1e, da, 01, 01, 10, 00, 1d, d6, 01, 00, 21, 00, 2e, d2, 01, 00, 32, 00, 40, 87, 02, 00, 41, 02, 0e, 75, 02, 0e, 00, 0f, 83, 02, 01, 0d, 00, 1b, 2d, 02, 0d, 00, 13, 00, 02, 06, 00, 07, fb, 01, 02, 09, 01, 0c, 79, 01, 0d, 02, 06, 00, 02, 06, 00, 07, e7, 03, 02, 09, 00, 0a, d7, 02, 00, 10, 00, 1d, 7d, 00, 1e, 02, 06, d2, 02, 02, 0f, 00, 1c, ce, 02, 01, 0c, 00, 19, ca, 02, 00, 1d, 00, 2a, c6, 02, 00, 2e, 00, 3c, ef, 03, 00, 3d, 02, 0a, 8d, 01, 02, 0a, 00, 0b, eb, 03, 01, 09, 00, 17, 29, 02, 0d, 02, 0f, 8f, 04, 05, 09, 00, 0a, e7, 03, 00, 10, 00, 1d, 11, 00, 1e, 02, 06, e2, 03, 02, 0f, 00, 1c, de, 03, 01, 0c, 00, 19, da, 03, 00, 1d, 00, 2a, d6, 03, 00, 2e, 00, 3c, 97, 04, 00, 3d, 02, 0a, 21, 02, 0a, 00, 0b, 93, 04, 01, 09, 00, 17, 25, 02, 09, 00, 0f, 8b, 04, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 144
+Number of expressions: 142
 - expression 0 operands: lhs = Counter(2), rhs = Expression(12, Add)
 - expression 1 operands: lhs = Expression(13, Add), rhs = Counter(16)
 - expression 2 operands: lhs = Expression(14, Add), rhs = Counter(15)
 - expression 3 operands: lhs = Counter(13), rhs = Counter(14)
 - expression 4 operands: lhs = Counter(1), rhs = Zero
-- expression 5 operands: lhs = Expression(143, Add), rhs = Counter(2)
+- expression 5 operands: lhs = Expression(141, Add), rhs = Counter(2)
 - expression 6 operands: lhs = Counter(1), rhs = Zero
 - expression 7 operands: lhs = Counter(3), rhs = Counter(13)
 - expression 8 operands: lhs = Expression(9, Sub), rhs = Counter(14)
@@ -18,145 +18,143 @@ Number of expressions: 144
 - expression 12 operands: lhs = Expression(13, Add), rhs = Counter(16)
 - expression 13 operands: lhs = Expression(14, Add), rhs = Counter(15)
 - expression 14 operands: lhs = Counter(13), rhs = Counter(14)
-- expression 15 operands: lhs = Expression(142, Sub), rhs = Counter(3)
-- expression 16 operands: lhs = Expression(143, Add), rhs = Counter(2)
+- expression 15 operands: lhs = Expression(140, Sub), rhs = Counter(3)
+- expression 16 operands: lhs = Expression(141, Add), rhs = Counter(2)
 - expression 17 operands: lhs = Counter(1), rhs = Zero
-- expression 18 operands: lhs = Expression(0, Add), rhs = Zero
-- expression 19 operands: lhs = Counter(17), rhs = Zero
-- expression 20 operands: lhs = Expression(33, Add), rhs = Counter(18)
-- expression 21 operands: lhs = Counter(17), rhs = Zero
-- expression 22 operands: lhs = Expression(32, Sub), rhs = Counter(12)
-- expression 23 operands: lhs = Expression(33, Add), rhs = Counter(18)
-- expression 24 operands: lhs = Counter(17), rhs = Zero
-- expression 25 operands: lhs = Expression(31, Sub), rhs = Counter(19)
-- expression 26 operands: lhs = Expression(32, Sub), rhs = Counter(12)
-- expression 27 operands: lhs = Expression(33, Add), rhs = Counter(18)
-- expression 28 operands: lhs = Counter(17), rhs = Zero
-- expression 29 operands: lhs = Expression(30, Sub), rhs = Counter(20)
-- expression 30 operands: lhs = Expression(31, Sub), rhs = Counter(19)
-- expression 31 operands: lhs = Expression(32, Sub), rhs = Counter(12)
-- expression 32 operands: lhs = Expression(33, Add), rhs = Counter(18)
-- expression 33 operands: lhs = Counter(17), rhs = Zero
-- expression 34 operands: lhs = Expression(42, Add), rhs = Counter(21)
-- expression 35 operands: lhs = Counter(19), rhs = Counter(20)
-- expression 36 operands: lhs = Expression(41, Add), rhs = Counter(22)
-- expression 37 operands: lhs = Expression(42, Add), rhs = Counter(21)
-- expression 38 operands: lhs = Counter(19), rhs = Counter(20)
-- expression 39 operands: lhs = Counter(18), rhs = Expression(40, Add)
-- expression 40 operands: lhs = Expression(41, Add), rhs = Counter(22)
-- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(21)
-- expression 42 operands: lhs = Counter(19), rhs = Counter(20)
-- expression 43 operands: lhs = Counter(24), rhs = Zero
-- expression 44 operands: lhs = Expression(57, Add), rhs = Counter(25)
-- expression 45 operands: lhs = Counter(24), rhs = Zero
-- expression 46 operands: lhs = Expression(56, Sub), rhs = Counter(11)
-- expression 47 operands: lhs = Expression(57, Add), rhs = Counter(25)
-- expression 48 operands: lhs = Counter(24), rhs = Zero
-- expression 49 operands: lhs = Expression(55, Sub), rhs = Counter(26)
-- expression 50 operands: lhs = Expression(56, Sub), rhs = Counter(11)
-- expression 51 operands: lhs = Expression(57, Add), rhs = Counter(25)
-- expression 52 operands: lhs = Counter(24), rhs = Zero
-- expression 53 operands: lhs = Expression(54, Sub), rhs = Counter(27)
-- expression 54 operands: lhs = Expression(55, Sub), rhs = Counter(26)
-- expression 55 operands: lhs = Expression(56, Sub), rhs = Counter(11)
-- expression 56 operands: lhs = Expression(57, Add), rhs = Counter(25)
-- expression 57 operands: lhs = Counter(24), rhs = Zero
-- expression 58 operands: lhs = Expression(67, Add), rhs = Counter(28)
-- expression 59 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 60 operands: lhs = Expression(66, Add), rhs = Counter(29)
-- expression 61 operands: lhs = Expression(67, Add), rhs = Counter(28)
-- expression 62 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 63 operands: lhs = Expression(64, Add), rhs = Zero
-- expression 64 operands: lhs = Counter(25), rhs = Expression(65, Add)
-- expression 65 operands: lhs = Expression(66, Add), rhs = Counter(29)
-- expression 66 operands: lhs = Expression(67, Add), rhs = Counter(28)
-- expression 67 operands: lhs = Counter(26), rhs = Counter(27)
-- expression 68 operands: lhs = Counter(31), rhs = Expression(124, Add)
-- expression 69 operands: lhs = Expression(125, Add), rhs = Counter(35)
-- expression 70 operands: lhs = Expression(126, Add), rhs = Counter(34)
-- expression 71 operands: lhs = Counter(32), rhs = Counter(33)
-- expression 72 operands: lhs = Counter(30), rhs = Zero
-- expression 73 operands: lhs = Expression(86, Add), rhs = Counter(31)
-- expression 74 operands: lhs = Counter(30), rhs = Zero
-- expression 75 operands: lhs = Expression(85, Sub), rhs = Counter(10)
-- expression 76 operands: lhs = Expression(86, Add), rhs = Counter(31)
-- expression 77 operands: lhs = Counter(30), rhs = Zero
-- expression 78 operands: lhs = Expression(84, Sub), rhs = Counter(32)
-- expression 79 operands: lhs = Expression(85, Sub), rhs = Counter(10)
-- expression 80 operands: lhs = Expression(86, Add), rhs = Counter(31)
-- expression 81 operands: lhs = Counter(30), rhs = Zero
-- expression 82 operands: lhs = Expression(83, Sub), rhs = Counter(33)
-- expression 83 operands: lhs = Expression(84, Sub), rhs = Counter(32)
-- expression 84 operands: lhs = Expression(85, Sub), rhs = Counter(10)
-- expression 85 operands: lhs = Expression(86, Add), rhs = Counter(31)
-- expression 86 operands: lhs = Counter(30), rhs = Zero
-- expression 87 operands: lhs = Expression(126, Add), rhs = Counter(34)
-- expression 88 operands: lhs = Counter(32), rhs = Counter(33)
-- expression 89 operands: lhs = Expression(125, Add), rhs = Counter(35)
-- expression 90 operands: lhs = Expression(126, Add), rhs = Counter(34)
-- expression 91 operands: lhs = Counter(32), rhs = Counter(33)
-- expression 92 operands: lhs = Counter(4), rhs = Expression(134, Add)
-- expression 93 operands: lhs = Expression(135, Add), rhs = Counter(8)
-- expression 94 operands: lhs = Expression(136, Add), rhs = Counter(7)
-- expression 95 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 96 operands: lhs = Expression(123, Add), rhs = Zero
-- expression 97 operands: lhs = Counter(31), rhs = Expression(124, Add)
-- expression 98 operands: lhs = Expression(125, Add), rhs = Counter(35)
-- expression 99 operands: lhs = Expression(126, Add), rhs = Counter(34)
-- expression 100 operands: lhs = Counter(32), rhs = Counter(33)
-- expression 101 operands: lhs = Expression(123, Add), rhs = Counter(4)
-- expression 102 operands: lhs = Counter(31), rhs = Expression(124, Add)
-- expression 103 operands: lhs = Expression(125, Add), rhs = Counter(35)
-- expression 104 operands: lhs = Expression(126, Add), rhs = Counter(34)
-- expression 105 operands: lhs = Counter(32), rhs = Counter(33)
-- expression 106 operands: lhs = Expression(122, Sub), rhs = Counter(9)
-- expression 107 operands: lhs = Expression(123, Add), rhs = Counter(4)
-- expression 108 operands: lhs = Counter(31), rhs = Expression(124, Add)
-- expression 109 operands: lhs = Expression(125, Add), rhs = Counter(35)
-- expression 110 operands: lhs = Expression(126, Add), rhs = Counter(34)
-- expression 111 operands: lhs = Counter(32), rhs = Counter(33)
-- expression 112 operands: lhs = Expression(121, Sub), rhs = Counter(5)
-- expression 113 operands: lhs = Expression(122, Sub), rhs = Counter(9)
-- expression 114 operands: lhs = Expression(123, Add), rhs = Counter(4)
-- expression 115 operands: lhs = Counter(31), rhs = Expression(124, Add)
-- expression 116 operands: lhs = Expression(125, Add), rhs = Counter(35)
-- expression 117 operands: lhs = Expression(126, Add), rhs = Counter(34)
-- expression 118 operands: lhs = Counter(32), rhs = Counter(33)
-- expression 119 operands: lhs = Expression(120, Sub), rhs = Counter(6)
-- expression 120 operands: lhs = Expression(121, Sub), rhs = Counter(5)
-- expression 121 operands: lhs = Expression(122, Sub), rhs = Counter(9)
-- expression 122 operands: lhs = Expression(123, Add), rhs = Counter(4)
-- expression 123 operands: lhs = Counter(31), rhs = Expression(124, Add)
-- expression 124 operands: lhs = Expression(125, Add), rhs = Counter(35)
-- expression 125 operands: lhs = Expression(126, Add), rhs = Counter(34)
-- expression 126 operands: lhs = Counter(32), rhs = Counter(33)
-- expression 127 operands: lhs = Expression(136, Add), rhs = Counter(7)
-- expression 128 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 129 operands: lhs = Expression(135, Add), rhs = Counter(8)
-- expression 130 operands: lhs = Expression(136, Add), rhs = Counter(7)
-- expression 131 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 132 operands: lhs = Expression(133, Add), rhs = Expression(137, Add)
-- expression 133 operands: lhs = Counter(4), rhs = Expression(134, Add)
-- expression 134 operands: lhs = Expression(135, Add), rhs = Counter(8)
-- expression 135 operands: lhs = Expression(136, Add), rhs = Counter(7)
-- expression 136 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 137 operands: lhs = Expression(138, Add), rhs = Expression(141, Sub)
-- expression 138 operands: lhs = Expression(139, Add), rhs = Expression(140, Add)
-- expression 139 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 140 operands: lhs = Counter(11), rhs = Counter(12)
-- expression 141 operands: lhs = Expression(142, Sub), rhs = Counter(3)
-- expression 142 operands: lhs = Expression(143, Add), rhs = Counter(2)
-- expression 143 operands: lhs = Counter(1), rhs = Zero
+- expression 18 operands: lhs = Counter(17), rhs = Zero
+- expression 19 operands: lhs = Expression(32, Add), rhs = Counter(18)
+- expression 20 operands: lhs = Counter(17), rhs = Zero
+- expression 21 operands: lhs = Expression(31, Sub), rhs = Counter(12)
+- expression 22 operands: lhs = Expression(32, Add), rhs = Counter(18)
+- expression 23 operands: lhs = Counter(17), rhs = Zero
+- expression 24 operands: lhs = Expression(30, Sub), rhs = Counter(19)
+- expression 25 operands: lhs = Expression(31, Sub), rhs = Counter(12)
+- expression 26 operands: lhs = Expression(32, Add), rhs = Counter(18)
+- expression 27 operands: lhs = Counter(17), rhs = Zero
+- expression 28 operands: lhs = Expression(29, Sub), rhs = Counter(20)
+- expression 29 operands: lhs = Expression(30, Sub), rhs = Counter(19)
+- expression 30 operands: lhs = Expression(31, Sub), rhs = Counter(12)
+- expression 31 operands: lhs = Expression(32, Add), rhs = Counter(18)
+- expression 32 operands: lhs = Counter(17), rhs = Zero
+- expression 33 operands: lhs = Expression(41, Add), rhs = Counter(21)
+- expression 34 operands: lhs = Counter(19), rhs = Counter(20)
+- expression 35 operands: lhs = Expression(40, Add), rhs = Counter(22)
+- expression 36 operands: lhs = Expression(41, Add), rhs = Counter(21)
+- expression 37 operands: lhs = Counter(19), rhs = Counter(20)
+- expression 38 operands: lhs = Counter(18), rhs = Expression(39, Add)
+- expression 39 operands: lhs = Expression(40, Add), rhs = Counter(22)
+- expression 40 operands: lhs = Expression(41, Add), rhs = Counter(21)
+- expression 41 operands: lhs = Counter(19), rhs = Counter(20)
+- expression 42 operands: lhs = Counter(24), rhs = Zero
+- expression 43 operands: lhs = Expression(56, Add), rhs = Counter(25)
+- expression 44 operands: lhs = Counter(24), rhs = Zero
+- expression 45 operands: lhs = Expression(55, Sub), rhs = Counter(11)
+- expression 46 operands: lhs = Expression(56, Add), rhs = Counter(25)
+- expression 47 operands: lhs = Counter(24), rhs = Zero
+- expression 48 operands: lhs = Expression(54, Sub), rhs = Counter(26)
+- expression 49 operands: lhs = Expression(55, Sub), rhs = Counter(11)
+- expression 50 operands: lhs = Expression(56, Add), rhs = Counter(25)
+- expression 51 operands: lhs = Counter(24), rhs = Zero
+- expression 52 operands: lhs = Expression(53, Sub), rhs = Counter(27)
+- expression 53 operands: lhs = Expression(54, Sub), rhs = Counter(26)
+- expression 54 operands: lhs = Expression(55, Sub), rhs = Counter(11)
+- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(25)
+- expression 56 operands: lhs = Counter(24), rhs = Zero
+- expression 57 operands: lhs = Expression(66, Add), rhs = Counter(28)
+- expression 58 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 59 operands: lhs = Expression(65, Add), rhs = Counter(29)
+- expression 60 operands: lhs = Expression(66, Add), rhs = Counter(28)
+- expression 61 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 62 operands: lhs = Expression(63, Add), rhs = Zero
+- expression 63 operands: lhs = Counter(25), rhs = Expression(64, Add)
+- expression 64 operands: lhs = Expression(65, Add), rhs = Counter(29)
+- expression 65 operands: lhs = Expression(66, Add), rhs = Counter(28)
+- expression 66 operands: lhs = Counter(26), rhs = Counter(27)
+- expression 67 operands: lhs = Counter(31), rhs = Expression(122, Add)
+- expression 68 operands: lhs = Expression(123, Add), rhs = Counter(35)
+- expression 69 operands: lhs = Expression(124, Add), rhs = Counter(34)
+- expression 70 operands: lhs = Counter(32), rhs = Counter(33)
+- expression 71 operands: lhs = Counter(30), rhs = Zero
+- expression 72 operands: lhs = Expression(85, Add), rhs = Counter(31)
+- expression 73 operands: lhs = Counter(30), rhs = Zero
+- expression 74 operands: lhs = Expression(84, Sub), rhs = Counter(10)
+- expression 75 operands: lhs = Expression(85, Add), rhs = Counter(31)
+- expression 76 operands: lhs = Counter(30), rhs = Zero
+- expression 77 operands: lhs = Expression(83, Sub), rhs = Counter(32)
+- expression 78 operands: lhs = Expression(84, Sub), rhs = Counter(10)
+- expression 79 operands: lhs = Expression(85, Add), rhs = Counter(31)
+- expression 80 operands: lhs = Counter(30), rhs = Zero
+- expression 81 operands: lhs = Expression(82, Sub), rhs = Counter(33)
+- expression 82 operands: lhs = Expression(83, Sub), rhs = Counter(32)
+- expression 83 operands: lhs = Expression(84, Sub), rhs = Counter(10)
+- expression 84 operands: lhs = Expression(85, Add), rhs = Counter(31)
+- expression 85 operands: lhs = Counter(30), rhs = Zero
+- expression 86 operands: lhs = Expression(124, Add), rhs = Counter(34)
+- expression 87 operands: lhs = Counter(32), rhs = Counter(33)
+- expression 88 operands: lhs = Expression(123, Add), rhs = Counter(35)
+- expression 89 operands: lhs = Expression(124, Add), rhs = Counter(34)
+- expression 90 operands: lhs = Counter(32), rhs = Counter(33)
+- expression 91 operands: lhs = Counter(4), rhs = Expression(132, Add)
+- expression 92 operands: lhs = Expression(133, Add), rhs = Counter(8)
+- expression 93 operands: lhs = Expression(134, Add), rhs = Counter(7)
+- expression 94 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 95 operands: lhs = Counter(31), rhs = Expression(122, Add)
+- expression 96 operands: lhs = Expression(123, Add), rhs = Counter(35)
+- expression 97 operands: lhs = Expression(124, Add), rhs = Counter(34)
+- expression 98 operands: lhs = Counter(32), rhs = Counter(33)
+- expression 99 operands: lhs = Expression(121, Add), rhs = Counter(4)
+- expression 100 operands: lhs = Counter(31), rhs = Expression(122, Add)
+- expression 101 operands: lhs = Expression(123, Add), rhs = Counter(35)
+- expression 102 operands: lhs = Expression(124, Add), rhs = Counter(34)
+- expression 103 operands: lhs = Counter(32), rhs = Counter(33)
+- expression 104 operands: lhs = Expression(120, Sub), rhs = Counter(9)
+- expression 105 operands: lhs = Expression(121, Add), rhs = Counter(4)
+- expression 106 operands: lhs = Counter(31), rhs = Expression(122, Add)
+- expression 107 operands: lhs = Expression(123, Add), rhs = Counter(35)
+- expression 108 operands: lhs = Expression(124, Add), rhs = Counter(34)
+- expression 109 operands: lhs = Counter(32), rhs = Counter(33)
+- expression 110 operands: lhs = Expression(119, Sub), rhs = Counter(5)
+- expression 111 operands: lhs = Expression(120, Sub), rhs = Counter(9)
+- expression 112 operands: lhs = Expression(121, Add), rhs = Counter(4)
+- expression 113 operands: lhs = Counter(31), rhs = Expression(122, Add)
+- expression 114 operands: lhs = Expression(123, Add), rhs = Counter(35)
+- expression 115 operands: lhs = Expression(124, Add), rhs = Counter(34)
+- expression 116 operands: lhs = Counter(32), rhs = Counter(33)
+- expression 117 operands: lhs = Expression(118, Sub), rhs = Counter(6)
+- expression 118 operands: lhs = Expression(119, Sub), rhs = Counter(5)
+- expression 119 operands: lhs = Expression(120, Sub), rhs = Counter(9)
+- expression 120 operands: lhs = Expression(121, Add), rhs = Counter(4)
+- expression 121 operands: lhs = Counter(31), rhs = Expression(122, Add)
+- expression 122 operands: lhs = Expression(123, Add), rhs = Counter(35)
+- expression 123 operands: lhs = Expression(124, Add), rhs = Counter(34)
+- expression 124 operands: lhs = Counter(32), rhs = Counter(33)
+- expression 125 operands: lhs = Expression(134, Add), rhs = Counter(7)
+- expression 126 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 127 operands: lhs = Expression(133, Add), rhs = Counter(8)
+- expression 128 operands: lhs = Expression(134, Add), rhs = Counter(7)
+- expression 129 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 130 operands: lhs = Expression(131, Add), rhs = Expression(135, Add)
+- expression 131 operands: lhs = Counter(4), rhs = Expression(132, Add)
+- expression 132 operands: lhs = Expression(133, Add), rhs = Counter(8)
+- expression 133 operands: lhs = Expression(134, Add), rhs = Counter(7)
+- expression 134 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 135 operands: lhs = Expression(136, Add), rhs = Expression(139, Sub)
+- expression 136 operands: lhs = Expression(137, Add), rhs = Expression(138, Add)
+- expression 137 operands: lhs = Counter(9), rhs = Counter(10)
+- expression 138 operands: lhs = Counter(11), rhs = Counter(12)
+- expression 139 operands: lhs = Expression(140, Sub), rhs = Counter(3)
+- expression 140 operands: lhs = Expression(141, Add), rhs = Counter(2)
+- expression 141 operands: lhs = Counter(1), rhs = Zero
 Number of file 0 mappings: 68
 - Code(Counter(0)) at (prev + 3, 1) to (start + 2, 12)
 - Code(Counter(1)) at (prev + 2, 13) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
 - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 10)
     = (c2 + (((c13 + c14) + c15) + c16))
-- Code(Expression(143, Add)) at (prev + 0, 16) to (start + 0, 29)
+- Code(Expression(141, Add)) at (prev + 0, 16) to (start + 0, 29)
     = (c1 + Zero)
 - Code(Counter(2)) at (prev + 1, 9) to (start + 1, 10)
-- Code(Expression(142, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Expression(140, Sub)) at (prev + 2, 15) to (start + 0, 28)
     = ((c1 + Zero) - c2)
 - Code(Counter(3)) at (prev + 1, 12) to (start + 0, 25)
 - Code(Expression(9, Sub)) at (prev + 0, 29) to (start + 0, 42)
@@ -168,94 +166,94 @@ Number of file 0 mappings: 68
 - Code(Counter(16)) at (prev + 2, 10) to (start + 0, 11)
 - Code(Expression(12, Add)) at (prev + 1, 9) to (start + 1, 18)
     = (((c13 + c14) + c15) + c16)
-- Code(Expression(141, Sub)) at (prev + 3, 9) to (start + 0, 15)
+- Code(Expression(139, Sub)) at (prev + 3, 9) to (start + 0, 15)
     = (((c1 + Zero) - c2) - c3)
-- Code(Expression(18, Add)) at (prev + 3, 9) to (start + 1, 12)
-    = ((c2 + (((c13 + c14) + c15) + c16)) + Zero)
+- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 1, 12)
+    = (c2 + (((c13 + c14) + c15) + c16))
 - Code(Counter(17)) at (prev + 1, 13) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
-- Code(Expression(33, Add)) at (prev + 2, 8) to (start + 0, 21)
+- Code(Expression(32, Add)) at (prev + 2, 8) to (start + 0, 21)
     = (c17 + Zero)
 - Code(Counter(18)) at (prev + 0, 22) to (start + 2, 6)
-- Code(Expression(32, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Expression(31, Sub)) at (prev + 2, 15) to (start + 0, 28)
     = ((c17 + Zero) - c18)
-- Code(Expression(31, Sub)) at (prev + 1, 12) to (start + 0, 25)
+- Code(Expression(30, Sub)) at (prev + 1, 12) to (start + 0, 25)
     = (((c17 + Zero) - c18) - c12)
-- Code(Expression(30, Sub)) at (prev + 0, 29) to (start + 0, 42)
+- Code(Expression(29, Sub)) at (prev + 0, 29) to (start + 0, 42)
     = ((((c17 + Zero) - c18) - c12) - c19)
-- Code(Expression(29, Sub)) at (prev + 0, 46) to (start + 0, 60)
+- Code(Expression(28, Sub)) at (prev + 0, 46) to (start + 0, 60)
     = (((((c17 + Zero) - c18) - c12) - c19) - c20)
-- Code(Expression(41, Add)) at (prev + 0, 61) to (start + 2, 10)
+- Code(Expression(40, Add)) at (prev + 0, 61) to (start + 2, 10)
     = ((c19 + c20) + c21)
 - Code(Counter(22)) at (prev + 2, 10) to (start + 0, 11)
-- Code(Expression(40, Add)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Expression(39, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (((c19 + c20) + c21) + c22)
 - Code(Counter(12)) at (prev + 2, 9) to (start + 0, 15)
-- Code(Expression(39, Add)) at (prev + 3, 8) to (start + 0, 12)
+- Code(Expression(38, Add)) at (prev + 3, 8) to (start + 0, 12)
     = (c18 + (((c19 + c20) + c21) + c22))
 - Code(Counter(23)) at (prev + 1, 13) to (start + 1, 16)
 - Code(Counter(24)) at (prev + 1, 17) to (start + 2, 10)
 - Code(Zero) at (prev + 2, 10) to (start + 0, 11)
-- Code(Expression(57, Add)) at (prev + 2, 12) to (start + 0, 25)
+- Code(Expression(56, Add)) at (prev + 2, 12) to (start + 0, 25)
     = (c24 + Zero)
 - Code(Counter(25)) at (prev + 0, 26) to (start + 2, 10)
-- Code(Expression(56, Sub)) at (prev + 3, 17) to (start + 0, 30)
+- Code(Expression(55, Sub)) at (prev + 3, 17) to (start + 0, 30)
     = ((c24 + Zero) - c25)
-- Code(Expression(55, Sub)) at (prev + 1, 16) to (start + 0, 29)
+- Code(Expression(54, Sub)) at (prev + 1, 16) to (start + 0, 29)
     = (((c24 + Zero) - c25) - c11)
-- Code(Expression(54, Sub)) at (prev + 0, 33) to (start + 0, 46)
+- Code(Expression(53, Sub)) at (prev + 0, 33) to (start + 0, 46)
     = ((((c24 + Zero) - c25) - c11) - c26)
-- Code(Expression(53, Sub)) at (prev + 0, 50) to (start + 0, 64)
+- Code(Expression(52, Sub)) at (prev + 0, 50) to (start + 0, 64)
     = (((((c24 + Zero) - c25) - c11) - c26) - c27)
-- Code(Expression(66, Add)) at (prev + 0, 65) to (start + 2, 14)
+- Code(Expression(65, Add)) at (prev + 0, 65) to (start + 2, 14)
     = ((c26 + c27) + c28)
 - Code(Counter(29)) at (prev + 2, 14) to (start + 0, 15)
-- Code(Expression(65, Add)) at (prev + 1, 13) to (start + 0, 27)
+- Code(Expression(64, Add)) at (prev + 1, 13) to (start + 0, 27)
     = (((c26 + c27) + c28) + c29)
 - Code(Counter(11)) at (prev + 2, 13) to (start + 0, 19)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
-- Code(Expression(63, Add)) at (prev + 2, 9) to (start + 1, 12)
+- Code(Expression(62, Add)) at (prev + 2, 9) to (start + 1, 12)
     = ((c25 + (((c26 + c27) + c28) + c29)) + Zero)
 - Code(Counter(30)) at (prev + 1, 13) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
-- Code(Expression(123, Add)) at (prev + 2, 9) to (start + 0, 10)
+- Code(Expression(121, Add)) at (prev + 2, 9) to (start + 0, 10)
     = (c31 + (((c32 + c33) + c34) + c35))
-- Code(Expression(86, Add)) at (prev + 0, 16) to (start + 0, 29)
+- Code(Expression(85, Add)) at (prev + 0, 16) to (start + 0, 29)
     = (c30 + Zero)
 - Code(Counter(31)) at (prev + 0, 30) to (start + 2, 6)
-- Code(Expression(85, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Expression(84, Sub)) at (prev + 2, 15) to (start + 0, 28)
     = ((c30 + Zero) - c31)
-- Code(Expression(84, Sub)) at (prev + 1, 12) to (start + 0, 25)
+- Code(Expression(83, Sub)) at (prev + 1, 12) to (start + 0, 25)
     = (((c30 + Zero) - c31) - c10)
-- Code(Expression(83, Sub)) at (prev + 0, 29) to (start + 0, 42)
+- Code(Expression(82, Sub)) at (prev + 0, 29) to (start + 0, 42)
     = ((((c30 + Zero) - c31) - c10) - c32)
-- Code(Expression(82, Sub)) at (prev + 0, 46) to (start + 0, 60)
+- Code(Expression(81, Sub)) at (prev + 0, 46) to (start + 0, 60)
     = (((((c30 + Zero) - c31) - c10) - c32) - c33)
-- Code(Expression(125, Add)) at (prev + 0, 61) to (start + 2, 10)
+- Code(Expression(123, Add)) at (prev + 0, 61) to (start + 2, 10)
     = ((c32 + c33) + c34)
 - Code(Counter(35)) at (prev + 2, 10) to (start + 0, 11)
-- Code(Expression(124, Add)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Expression(122, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (((c32 + c33) + c34) + c35)
 - Code(Counter(10)) at (prev + 2, 13) to (start + 2, 15)
-- Code(Expression(133, Add)) at (prev + 5, 9) to (start + 0, 10)
+- Code(Expression(131, Add)) at (prev + 5, 9) to (start + 0, 10)
     = (c4 + (((c5 + c6) + c7) + c8))
-- Code(Expression(96, Add)) at (prev + 0, 16) to (start + 0, 29)
-    = ((c31 + (((c32 + c33) + c34) + c35)) + Zero)
+- Code(Expression(121, Add)) at (prev + 0, 16) to (start + 0, 29)
+    = (c31 + (((c32 + c33) + c34) + c35))
 - Code(Counter(4)) at (prev + 0, 30) to (start + 2, 6)
-- Code(Expression(122, Sub)) at (prev + 2, 15) to (start + 0, 28)
+- Code(Expression(120, Sub)) at (prev + 2, 15) to (start + 0, 28)
     = ((c31 + (((c32 + c33) + c34) + c35)) - c4)
-- Code(Expression(121, Sub)) at (prev + 1, 12) to (start + 0, 25)
+- Code(Expression(119, Sub)) at (prev + 1, 12) to (start + 0, 25)
     = (((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9)
-- Code(Expression(120, Sub)) at (prev + 0, 29) to (start + 0, 42)
+- Code(Expression(118, Sub)) at (prev + 0, 29) to (start + 0, 42)
     = ((((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9) - c5)
-- Code(Expression(119, Sub)) at (prev + 0, 46) to (start + 0, 60)
+- Code(Expression(117, Sub)) at (prev + 0, 46) to (start + 0, 60)
     = (((((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9) - c5) - c6)
-- Code(Expression(135, Add)) at (prev + 0, 61) to (start + 2, 10)
+- Code(Expression(133, Add)) at (prev + 0, 61) to (start + 2, 10)
     = ((c5 + c6) + c7)
 - Code(Counter(8)) at (prev + 2, 10) to (start + 0, 11)
-- Code(Expression(134, Add)) at (prev + 1, 9) to (start + 0, 23)
+- Code(Expression(132, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (((c5 + c6) + c7) + c8)
 - Code(Counter(9)) at (prev + 2, 9) to (start + 0, 15)
-- Code(Expression(132, Add)) at (prev + 2, 1) to (start + 0, 2)
+- Code(Expression(130, Add)) at (prev + 2, 1) to (start + 0, 2)
     = ((c4 + (((c5 + c6) + c7) + c8)) + (((c9 + c10) + (c11 + c12)) + (((c1 + Zero) - c2) - c3)))
 
diff --git a/tests/coverage-map/status-quo/continue.cov-map b/tests/coverage-map/status-quo/continue.cov-map
index c78cf293079..82f3d7c6095 100644
--- a/tests/coverage-map/status-quo/continue.cov-map
+++ b/tests/coverage-map/status-quo/continue.cov-map
@@ -1,8 +1,8 @@
 Function name: continue::main
-Raw bytes (216): 0x[01, 01, 1f, 01, 07, 05, 09, 03, 0d, 0d, 1f, 11, 15, 1b, 19, 0d, 1f, 11, 15, 15, 00, 19, 37, 1d, 21, 33, 25, 19, 37, 1d, 21, 1d, 00, 25, 4f, 29, 2d, 4b, 31, 25, 4f, 29, 2d, 31, 67, 35, 39, 5f, 3d, 31, 67, 35, 39, 35, 39, 3d, 41, 73, 45, 3d, 41, 41, 00, 49, 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, 23, 03, 09, 00, 0e, 33, 02, 0e, 00, 13, 2e, 01, 0f, 00, 16, 1d, 01, 15, 02, 0e, 21, 04, 11, 00, 19, 3b, 03, 09, 00, 0e, 4b, 02, 0e, 00, 13, 46, 01, 0c, 00, 13, 29, 01, 0d, 00, 15, 2d, 01, 0a, 01, 0e, 5f, 03, 0e, 00, 13, 5a, 01, 0f, 00, 16, 39, 01, 16, 02, 0e, 35, 03, 12, 02, 0e, 67, 04, 09, 00, 0e, 73, 02, 0e, 00, 13, 6e, 01, 0f, 00, 16, 41, 01, 16, 02, 0e, 49, 04, 11, 00, 16, 77, 03, 09, 00, 0e, 7b, 02, 0d, 01, 02]
+Raw bytes (210): 0x[01, 01, 1c, 01, 07, 05, 09, 03, 0d, 0d, 1f, 11, 15, 1b, 19, 0d, 1f, 11, 15, 19, 33, 1d, 21, 2f, 25, 19, 33, 1d, 21, 25, 47, 29, 2d, 43, 31, 25, 47, 29, 2d, 31, 5f, 35, 39, 57, 3d, 31, 5f, 35, 39, 35, 39, 3d, 41, 6b, 45, 3d, 41, 49, 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, 49, 04, 11, 00, 16, 41, 03, 09, 00, 0e, 6f, 02, 0d, 01, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 31
+Number of expressions: 28
 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
@@ -11,29 +11,26 @@ Number of expressions: 31
 - expression 5 operands: lhs = Expression(6, Add), rhs = Counter(6)
 - expression 6 operands: lhs = Counter(3), rhs = Expression(7, Add)
 - expression 7 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 8 operands: lhs = Counter(5), rhs = Zero
-- expression 9 operands: lhs = Counter(6), rhs = Expression(13, Add)
-- expression 10 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 11 operands: lhs = Expression(12, Add), rhs = Counter(9)
-- expression 12 operands: lhs = Counter(6), rhs = Expression(13, Add)
-- expression 13 operands: lhs = Counter(7), rhs = Counter(8)
-- expression 14 operands: lhs = Counter(7), rhs = Zero
-- expression 15 operands: lhs = Counter(9), rhs = Expression(19, Add)
-- expression 16 operands: lhs = Counter(10), rhs = Counter(11)
-- expression 17 operands: lhs = Expression(18, Add), rhs = Counter(12)
-- expression 18 operands: lhs = Counter(9), rhs = Expression(19, Add)
-- expression 19 operands: lhs = Counter(10), rhs = Counter(11)
-- expression 20 operands: lhs = Counter(12), rhs = Expression(25, Add)
-- expression 21 operands: lhs = Counter(13), rhs = Counter(14)
-- expression 22 operands: lhs = Expression(23, Add), rhs = Counter(15)
-- expression 23 operands: lhs = Counter(12), rhs = Expression(25, Add)
-- expression 24 operands: lhs = Counter(13), rhs = Counter(14)
-- expression 25 operands: lhs = Counter(13), rhs = Counter(14)
+- expression 8 operands: lhs = Counter(6), rhs = Expression(12, Add)
+- expression 9 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 10 operands: lhs = Expression(11, Add), rhs = Counter(9)
+- expression 11 operands: lhs = Counter(6), rhs = Expression(12, Add)
+- expression 12 operands: lhs = Counter(7), rhs = Counter(8)
+- expression 13 operands: lhs = Counter(9), rhs = Expression(17, Add)
+- expression 14 operands: lhs = Counter(10), rhs = Counter(11)
+- expression 15 operands: lhs = Expression(16, Add), rhs = Counter(12)
+- expression 16 operands: lhs = Counter(9), rhs = Expression(17, Add)
+- expression 17 operands: lhs = Counter(10), rhs = Counter(11)
+- expression 18 operands: lhs = Counter(12), rhs = Expression(23, Add)
+- expression 19 operands: lhs = Counter(13), rhs = Counter(14)
+- expression 20 operands: lhs = Expression(21, Add), rhs = Counter(15)
+- expression 21 operands: lhs = Counter(12), rhs = Expression(23, Add)
+- expression 22 operands: lhs = Counter(13), rhs = Counter(14)
+- 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 = Expression(28, Add), rhs = Counter(17)
-- expression 28 operands: lhs = Counter(15), rhs = Counter(16)
-- expression 29 operands: lhs = Counter(16), rhs = Zero
-- expression 30 operands: lhs = Counter(18), rhs = Counter(17)
+- expression 27 operands: lhs = Counter(18), rhs = Counter(17)
 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)
@@ -48,38 +45,35 @@ Number of file 0 mappings: 30
     = ((c3 + (c4 + c5)) - c6)
 - Code(Counter(5)) at (prev + 1, 22) to (start + 2, 14)
 - Code(Counter(4)) at (prev + 4, 17) to (start + 0, 25)
-- Code(Expression(8, Add)) at (prev + 3, 9) to (start + 0, 14)
-    = (c5 + Zero)
-- Code(Expression(12, Add)) at (prev + 2, 14) to (start + 0, 19)
+- 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(11, Sub)) at (prev + 1, 15) to (start + 0, 22)
+- 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(Expression(14, Add)) at (prev + 3, 9) to (start + 0, 14)
-    = (c7 + Zero)
-- Code(Expression(18, Add)) at (prev + 2, 14) to (start + 0, 19)
+- 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(17, Sub)) at (prev + 1, 12) to (start + 0, 19)
+- 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(23, Add)) at (prev + 3, 14) to (start + 0, 19)
+- Code(Expression(21, Add)) at (prev + 3, 14) to (start + 0, 19)
     = (c12 + (c13 + c14))
-- Code(Expression(22, Sub)) at (prev + 1, 15) to (start + 0, 22)
+- 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(25, Add)) at (prev + 4, 9) to (start + 0, 14)
+- Code(Expression(23, Add)) at (prev + 4, 9) to (start + 0, 14)
     = (c13 + c14)
-- Code(Expression(28, Add)) at (prev + 2, 14) to (start + 0, 19)
+- Code(Expression(26, Add)) at (prev + 2, 14) to (start + 0, 19)
     = (c15 + c16)
-- Code(Expression(27, Sub)) at (prev + 1, 15) to (start + 0, 22)
+- 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(Counter(18)) at (prev + 4, 17) to (start + 0, 22)
-- Code(Expression(29, Add)) at (prev + 3, 9) to (start + 0, 14)
-    = (c16 + Zero)
-- Code(Expression(30, Add)) at (prev + 2, 13) to (start + 1, 2)
+- Code(Counter(16)) at (prev + 3, 9) to (start + 0, 14)
+- Code(Expression(27, Add)) at (prev + 2, 13) to (start + 1, 2)
     = (c18 + c17)
 
diff --git a/tests/coverage-map/status-quo/dead_code.cov-map b/tests/coverage-map/status-quo/dead_code.cov-map
index 8d5f88e63ef..0b8a40a8cde 100644
--- a/tests/coverage-map/status-quo/dead_code.cov-map
+++ b/tests/coverage-map/status-quo/dead_code.cov-map
@@ -14,23 +14,23 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: dead_code::unused_fn (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 0f, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 15, 1) to (start + 7, 15)
+- Code(Zero) at (prev + 15, 1) to (start + 7, 15)
 - Code(Zero) at (prev + 7, 16) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 
 Function name: dead_code::unused_pub_fn_not_in_library (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 03, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 03, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 3, 1) to (start + 7, 15)
+- Code(Zero) at (prev + 3, 1) to (start + 7, 15)
 - Code(Zero) at (prev + 7, 16) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
diff --git a/tests/coverage-map/status-quo/generator.cov-map b/tests/coverage-map/status-quo/generator.cov-map
index a66c1af30f9..75704bcc223 100644
--- a/tests/coverage-map/status-quo/generator.cov-map
+++ b/tests/coverage-map/status-quo/generator.cov-map
@@ -14,38 +14,33 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: generator::main
-Raw bytes (71): 0x[01, 01, 0b, 01, 00, 05, 0b, 09, 0d, 11, 00, 11, 15, 2a, 19, 11, 15, 15, 19, 26, 00, 2a, 19, 11, 15, 09, 01, 0f, 01, 02, 16, 03, 07, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 07, 01, 0e, 00, 35, 0f, 02, 0b, 00, 2e, 2a, 01, 22, 00, 27, 26, 00, 2c, 00, 2e, 1f, 01, 0e, 00, 35, 23, 02, 01, 00, 02]
+Raw bytes (65): 0x[01, 01, 08, 05, 07, 09, 0d, 11, 15, 1e, 19, 11, 15, 15, 19, 1e, 19, 11, 15, 09, 01, 0f, 01, 02, 16, 01, 07, 0b, 00, 2e, 11, 01, 2b, 00, 2d, 03, 01, 0e, 00, 35, 11, 02, 0b, 00, 2e, 1e, 01, 22, 00, 27, 1a, 00, 2c, 00, 2e, 17, 01, 0e, 00, 35, 1a, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 11
-- expression 0 operands: lhs = Counter(0), rhs = Zero
-- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
-- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 3 operands: lhs = Counter(4), rhs = Zero
+Number of expressions: 8
+- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add)
+- expression 1 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 2 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 3 operands: lhs = Expression(7, Sub), rhs = Counter(6)
 - expression 4 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 5 operands: lhs = Expression(10, Sub), rhs = Counter(6)
-- expression 6 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 7 operands: lhs = Counter(5), rhs = Counter(6)
-- expression 8 operands: lhs = Expression(9, Sub), rhs = Zero
-- expression 9 operands: lhs = Expression(10, Sub), rhs = Counter(6)
-- expression 10 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 5 operands: lhs = Counter(5), rhs = Counter(6)
+- expression 6 operands: lhs = Expression(7, Sub), rhs = Counter(6)
+- expression 7 operands: lhs = Counter(4), rhs = Counter(5)
 Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 15, 1) to (start + 2, 22)
-- Code(Expression(0, Add)) at (prev + 7, 11) to (start + 0, 46)
-    = (c0 + Zero)
+- Code(Counter(0)) at (prev + 7, 11) to (start + 0, 46)
 - Code(Counter(4)) at (prev + 1, 43) to (start + 0, 45)
-- Code(Expression(1, Add)) at (prev + 1, 14) to (start + 0, 53)
+- Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 53)
     = (c1 + (c2 + c3))
-- Code(Expression(3, Add)) at (prev + 2, 11) to (start + 0, 46)
-    = (c4 + Zero)
-- Code(Expression(10, Sub)) at (prev + 1, 34) to (start + 0, 39)
+- Code(Counter(4)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Expression(7, Sub)) at (prev + 1, 34) to (start + 0, 39)
     = (c4 - c5)
-- Code(Expression(9, Sub)) at (prev + 0, 44) to (start + 0, 46)
+- Code(Expression(6, Sub)) at (prev + 0, 44) to (start + 0, 46)
     = ((c4 - c5) - c6)
-- Code(Expression(7, Add)) at (prev + 1, 14) to (start + 0, 53)
+- Code(Expression(5, Add)) at (prev + 1, 14) to (start + 0, 53)
     = (c5 + c6)
-- Code(Expression(8, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = (((c4 - c5) - c6) + Zero)
+- Code(Expression(6, Sub)) at (prev + 2, 1) to (start + 0, 2)
+    = ((c4 - c5) - c6)
 
 Function name: generator::main::{closure#0}
 Raw bytes (14): 0x[01, 01, 00, 02, 01, 11, 1c, 01, 1f, 05, 02, 10, 01, 06]
diff --git a/tests/coverage-map/status-quo/inline-dead.cov-map b/tests/coverage-map/status-quo/inline-dead.cov-map
index dec43d3e8bb..483f7ef79c6 100644
--- a/tests/coverage-map/status-quo/inline-dead.cov-map
+++ b/tests/coverage-map/status-quo/inline-dead.cov-map
@@ -1,10 +1,10 @@
 Function name: inline_dead::dead (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 19, 01, 02, 02]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 01, 02, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 25, 1) to (start + 2, 2)
+- Code(Zero) at (prev + 25, 1) to (start + 2, 2)
 
 Function name: inline_dead::live::<false>
 Raw bytes (28): 0x[01, 01, 02, 01, 05, 05, 02, 04, 01, 10, 01, 01, 09, 00, 02, 09, 00, 0f, 02, 02, 09, 00, 0a, 07, 02, 01, 00, 02]
@@ -22,15 +22,13 @@ Number of file 0 mappings: 4
     = (c1 + (c0 - c1))
 
 Function name: inline_dead::main
-Raw bytes (16): 0x[01, 01, 01, 01, 00, 02, 01, 04, 01, 03, 0d, 03, 07, 06, 02, 02]
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 03, 0d, 01, 07, 06, 02, 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: 2
 - Code(Counter(0)) at (prev + 4, 1) to (start + 3, 13)
-- Code(Expression(0, Add)) at (prev + 7, 6) to (start + 2, 2)
-    = (c0 + Zero)
+- Code(Counter(0)) at (prev + 7, 6) to (start + 2, 2)
 
 Function name: inline_dead::main::{closure#0}
 Raw bytes (16): 0x[01, 01, 01, 01, 05, 02, 00, 09, 0d, 00, 0e, 03, 02, 05, 00, 06]
diff --git a/tests/coverage-map/status-quo/inline.cov-map b/tests/coverage-map/status-quo/inline.cov-map
index 57ae85623fb..72b10fd0cc2 100644
--- a/tests/coverage-map/status-quo/inline.cov-map
+++ b/tests/coverage-map/status-quo/inline.cov-map
@@ -1,19 +1,17 @@
 Function name: inline::display::<char>
-Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 00, 03, 05, 05, 01, 29, 01, 00, 22, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 10, 07, 00, 11, 02, 06, 0a, 03, 05, 01, 02]
+Raw bytes (33): 0x[01, 01, 02, 01, 05, 03, 05, 05, 01, 29, 01, 00, 22, 05, 01, 09, 00, 0a, 03, 00, 0e, 00, 10, 05, 00, 11, 02, 06, 06, 03, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 3
+Number of expressions: 2
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(1), rhs = Zero
-- expression 2 operands: lhs = Expression(0, Add), rhs = Counter(1)
+- expression 1 operands: lhs = Expression(0, Add), rhs = Counter(1)
 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(Expression(1, Add)) at (prev + 0, 17) to (start + 2, 6)
-    = (c1 + Zero)
-- Code(Expression(2, Sub)) at (prev + 3, 5) to (start + 1, 2)
+- Code(Counter(1)) at (prev + 0, 17) to (start + 2, 6)
+- Code(Expression(1, Sub)) at (prev + 3, 5) to (start + 1, 2)
     = ((c0 + c1) - c1)
 
 Function name: inline::error
@@ -41,15 +39,14 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 5, 1) to (start + 2, 2)
 
 Function name: inline::permutate::<char>
-Raw bytes (54): 0x[01, 01, 05, 01, 05, 02, 0d, 11, 00, 05, 13, 09, 0d, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 11, 01, 0d, 00, 0e, 06, 00, 12, 00, 16, 0b, 00, 17, 04, 0a, 0d, 05, 0c, 02, 06, 0f, 03, 01, 00, 02]
+Raw bytes (52): 0x[01, 01, 04, 01, 05, 02, 0d, 05, 0f, 09, 0d, 08, 01, 0f, 01, 02, 0e, 05, 02, 0f, 02, 06, 02, 02, 0f, 00, 14, 11, 01, 0d, 00, 0e, 06, 00, 12, 00, 16, 11, 00, 17, 04, 0a, 0d, 05, 0c, 02, 06, 0b, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 5
+Number of expressions: 4
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Expression(0, Sub), rhs = Counter(3)
-- expression 2 operands: lhs = Counter(4), rhs = Zero
-- expression 3 operands: lhs = Counter(1), rhs = Expression(4, Add)
-- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
+- expression 2 operands: lhs = Counter(1), rhs = Expression(3, Add)
+- expression 3 operands: lhs = Counter(2), rhs = Counter(3)
 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)
@@ -58,10 +55,9 @@ Number of file 0 mappings: 8
 - Code(Counter(4)) at (prev + 1, 13) to (start + 0, 14)
 - Code(Expression(1, Sub)) at (prev + 0, 18) to (start + 0, 22)
     = ((c0 - c1) - c3)
-- Code(Expression(2, Add)) at (prev + 0, 23) to (start + 4, 10)
-    = (c4 + Zero)
+- Code(Counter(4)) at (prev + 0, 23) to (start + 4, 10)
 - Code(Counter(3)) at (prev + 5, 12) to (start + 2, 6)
-- Code(Expression(3, Add)) at (prev + 3, 1) to (start + 0, 2)
+- Code(Expression(2, Add)) at (prev + 3, 1) to (start + 0, 2)
     = (c1 + (c2 + c3))
 
 Function name: inline::permutations::<char>
diff --git a/tests/coverage-map/status-quo/issue-93054.cov-map b/tests/coverage-map/status-quo/issue-93054.cov-map
index 52fe7f58d15..c2c6e9a6516 100644
--- a/tests/coverage-map/status-quo/issue-93054.cov-map
+++ b/tests/coverage-map/status-quo/issue-93054.cov-map
@@ -1,10 +1,10 @@
 Function name: issue_93054::foo2 (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 16, 01, 00, 1d]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 01, 00, 1d]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 29)
+- Code(Zero) at (prev + 22, 1) to (start + 0, 29)
 
 Function name: issue_93054::main
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 1e, 01, 00, 0d]
@@ -15,10 +15,10 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 30, 1) to (start + 0, 13)
 
 Function name: issue_93054::make (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 01, 02, 02]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 1a, 01, 02, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 26, 1) to (start + 2, 2)
+- Code(Zero) at (prev + 26, 1) to (start + 2, 2)
 
diff --git a/tests/coverage-map/status-quo/lazy_boolean.cov-map b/tests/coverage-map/status-quo/lazy_boolean.cov-map
index b18a9640433..0ad393c40fa 100644
--- a/tests/coverage-map/status-quo/lazy_boolean.cov-map
+++ b/tests/coverage-map/status-quo/lazy_boolean.cov-map
@@ -1,223 +1,219 @@
 Function name: lazy_boolean::main
-Raw bytes (646): 0x[01, 01, a8, 01, 01, 05, 09, 9a, 05, 9f, 05, 09, 05, 02, 05, 02, 9f, 05, 09, 05, 02, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 97, 05, 00, 09, 9a, 05, 9f, 05, 09, 05, 02, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 8f, 05, 00, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 87, 05, 00, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, ff, 04, 00, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, ef, 04, 21, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 21, ea, 04, ef, 04, 21, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, e7, 04, 25, 21, ea, 04, ef, 04, 21, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 25, e2, 04, e7, 04, 25, 21, ea, 04, ef, 04, 21, 1d, f2, 04, f7, 04, 1d, 19, fa, 04, ff, 04, 19, 15, 82, 05, 87, 05, 15, 11, 8a, 05, 8f, 05, 11, 0d, 92, 05, 97, 05, 0d, 09, 9a, 05, 9f, 05, 09, 05, 02, 1c, 01, 03, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 06, 00, 07, 97, 05, 02, 09, 00, 11, 9f, 05, 02, 0d, 00, 12, 9a, 05, 02, 0d, 00, 12, 8f, 05, 03, 09, 00, 11, 33, 02, 0d, 00, 12, 92, 05, 02, 0d, 00, 12, 87, 05, 02, 09, 00, 11, 6f, 00, 14, 00, 19, 11, 00, 1d, 00, 22, ff, 04, 01, 09, 00, 11, ab, 01, 00, 14, 00, 19, 15, 00, 1d, 00, 22, cb, 01, 04, 09, 00, 10, fa, 04, 01, 05, 03, 06, 19, 03, 06, 00, 07, f7, 04, 03, 09, 00, 10, 1d, 01, 05, 03, 06, f2, 04, 05, 05, 03, 06, ef, 04, 05, 09, 00, 10, ea, 04, 00, 11, 02, 06, 21, 02, 06, 00, 07, e7, 04, 02, 08, 00, 0f, 25, 00, 10, 02, 06, e2, 04, 02, 0c, 02, 06, df, 04, 03, 01, 00, 02]
+Raw bytes (636): 0x[01, 01, a4, 01, 01, 05, 09, 8a, 05, 8f, 05, 09, 05, 02, 05, 02, 8f, 05, 09, 05, 02, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 09, 8a, 05, 8f, 05, 09, 05, 02, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, df, 04, 21, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 21, da, 04, df, 04, 21, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, d7, 04, 25, 21, da, 04, df, 04, 21, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 25, d2, 04, d7, 04, 25, 21, da, 04, df, 04, 21, 1d, e2, 04, e7, 04, 1d, 19, ea, 04, ef, 04, 19, 15, f2, 04, f7, 04, 15, 11, fa, 04, ff, 04, 11, 0d, 82, 05, 87, 05, 0d, 09, 8a, 05, 8f, 05, 09, 05, 02, 1c, 01, 03, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 06, 00, 07, 87, 05, 02, 09, 00, 11, 8f, 05, 02, 0d, 00, 12, 8a, 05, 02, 0d, 00, 12, ff, 04, 03, 09, 00, 11, 87, 05, 02, 0d, 00, 12, 82, 05, 02, 0d, 00, 12, f7, 04, 02, 09, 00, 11, ff, 04, 00, 14, 00, 19, 11, 00, 1d, 00, 22, ef, 04, 01, 09, 00, 11, f7, 04, 00, 14, 00, 19, 15, 00, 1d, 00, 22, ef, 04, 04, 09, 00, 10, ea, 04, 01, 05, 03, 06, 19, 03, 06, 00, 07, e7, 04, 03, 09, 00, 10, 1d, 01, 05, 03, 06, e2, 04, 05, 05, 03, 06, df, 04, 05, 09, 00, 10, da, 04, 00, 11, 02, 06, 21, 02, 06, 00, 07, d7, 04, 02, 08, 00, 0f, 25, 00, 10, 02, 06, d2, 04, 02, 0c, 02, 06, cf, 04, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 168
+Number of expressions: 164
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 2 operands: lhs = Expression(167, Add), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 2 operands: lhs = Expression(163, Add), rhs = Counter(2)
 - expression 3 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 - expression 4 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 5 operands: lhs = Expression(167, Add), rhs = Counter(2)
+- expression 5 operands: lhs = Expression(163, Add), rhs = Counter(2)
 - expression 6 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 7 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 8 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 9 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 10 operands: lhs = Expression(167, Add), rhs = Counter(2)
+- expression 7 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 8 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 9 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 10 operands: lhs = Expression(163, Add), rhs = Counter(2)
 - expression 11 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 12 operands: lhs = Expression(165, Add), rhs = Zero
-- expression 13 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 14 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 15 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 16 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 17 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 18 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 19 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 20 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 21 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 22 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 23 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 24 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 25 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 26 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 27 operands: lhs = Expression(163, Add), rhs = Zero
-- expression 28 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 29 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 30 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 31 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 32 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 33 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 34 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 35 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 36 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 37 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 38 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 39 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 40 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 41 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 42 operands: lhs = Expression(161, Add), rhs = Zero
-- expression 43 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 44 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 45 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 46 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 47 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 48 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 49 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 50 operands: lhs = Expression(159, Add), rhs = Zero
-- expression 51 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 52 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 53 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 54 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 55 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 56 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 57 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 58 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 59 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 60 operands: lhs = Expression(159, Add), rhs = Counter(6)
-- expression 61 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 62 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 63 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 64 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 65 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 66 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 67 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 68 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 69 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 70 operands: lhs = Counter(6), rhs = Expression(158, Sub)
-- expression 71 operands: lhs = Expression(159, Add), rhs = Counter(6)
-- expression 72 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 73 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 74 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 75 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 76 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 77 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 78 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 79 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 80 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 81 operands: lhs = Expression(157, Add), rhs = Counter(7)
-- expression 82 operands: lhs = Counter(6), rhs = Expression(158, Sub)
-- expression 83 operands: lhs = Expression(159, Add), rhs = Counter(6)
-- expression 84 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 85 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 86 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 87 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 88 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 89 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 90 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 91 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 92 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 93 operands: lhs = Counter(7), rhs = Expression(156, Sub)
-- expression 94 operands: lhs = Expression(157, Add), rhs = Counter(7)
-- expression 95 operands: lhs = Counter(6), rhs = Expression(158, Sub)
-- expression 96 operands: lhs = Expression(159, Add), rhs = Counter(6)
-- expression 97 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 98 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 99 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 100 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 101 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 102 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 103 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 104 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 105 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 106 operands: lhs = Expression(155, Add), rhs = Counter(8)
-- expression 107 operands: lhs = Counter(7), rhs = Expression(156, Sub)
-- expression 108 operands: lhs = Expression(157, Add), rhs = Counter(7)
-- expression 109 operands: lhs = Counter(6), rhs = Expression(158, Sub)
-- expression 110 operands: lhs = Expression(159, Add), rhs = Counter(6)
-- expression 111 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 112 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 113 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 114 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 115 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 116 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 117 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 118 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 119 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 120 operands: lhs = Counter(8), rhs = Expression(154, Sub)
-- expression 121 operands: lhs = Expression(155, Add), rhs = Counter(8)
-- expression 122 operands: lhs = Counter(7), rhs = Expression(156, Sub)
-- expression 123 operands: lhs = Expression(157, Add), rhs = Counter(7)
-- expression 124 operands: lhs = Counter(6), rhs = Expression(158, Sub)
-- expression 125 operands: lhs = Expression(159, Add), rhs = Counter(6)
-- expression 126 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 127 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 128 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 129 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 130 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 131 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 132 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 133 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 134 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 135 operands: lhs = Expression(153, Add), rhs = Counter(9)
-- expression 136 operands: lhs = Counter(8), rhs = Expression(154, Sub)
-- expression 137 operands: lhs = Expression(155, Add), rhs = Counter(8)
-- expression 138 operands: lhs = Counter(7), rhs = Expression(156, Sub)
-- expression 139 operands: lhs = Expression(157, Add), rhs = Counter(7)
-- expression 140 operands: lhs = Counter(6), rhs = Expression(158, Sub)
-- expression 141 operands: lhs = Expression(159, Add), rhs = Counter(6)
-- expression 142 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 143 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 144 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 145 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 146 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 147 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 148 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 149 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 150 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 151 operands: lhs = Counter(9), rhs = Expression(152, Sub)
-- expression 152 operands: lhs = Expression(153, Add), rhs = Counter(9)
-- expression 153 operands: lhs = Counter(8), rhs = Expression(154, Sub)
-- expression 154 operands: lhs = Expression(155, Add), rhs = Counter(8)
-- expression 155 operands: lhs = Counter(7), rhs = Expression(156, Sub)
-- expression 156 operands: lhs = Expression(157, Add), rhs = Counter(7)
-- expression 157 operands: lhs = Counter(6), rhs = Expression(158, Sub)
-- expression 158 operands: lhs = Expression(159, Add), rhs = Counter(6)
-- expression 159 operands: lhs = Counter(5), rhs = Expression(160, Sub)
-- expression 160 operands: lhs = Expression(161, Add), rhs = Counter(5)
-- expression 161 operands: lhs = Counter(4), rhs = Expression(162, Sub)
-- expression 162 operands: lhs = Expression(163, Add), rhs = Counter(4)
-- expression 163 operands: lhs = Counter(3), rhs = Expression(164, Sub)
-- expression 164 operands: lhs = Expression(165, Add), rhs = Counter(3)
-- expression 165 operands: lhs = Counter(2), rhs = Expression(166, Sub)
-- expression 166 operands: lhs = Expression(167, Add), rhs = Counter(2)
-- expression 167 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 12 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 13 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 14 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 15 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 16 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 17 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 18 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 19 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 20 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 21 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 22 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 23 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 24 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 25 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 26 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 27 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 28 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 29 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 30 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 31 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 32 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 33 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 34 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 35 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 36 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 37 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 38 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 39 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 40 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 41 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 42 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 43 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 44 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 45 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 46 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 47 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 48 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 49 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 50 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 51 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 52 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 53 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 54 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 55 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 56 operands: lhs = Expression(155, Add), rhs = Counter(6)
+- expression 57 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 58 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 59 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 60 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 61 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 62 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 63 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 64 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 65 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 66 operands: lhs = Counter(6), rhs = Expression(154, Sub)
+- expression 67 operands: lhs = Expression(155, Add), rhs = Counter(6)
+- expression 68 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 69 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 70 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 71 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 72 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 73 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 74 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 75 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 76 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 77 operands: lhs = Expression(153, Add), rhs = Counter(7)
+- expression 78 operands: lhs = Counter(6), rhs = Expression(154, Sub)
+- expression 79 operands: lhs = Expression(155, Add), rhs = Counter(6)
+- expression 80 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 81 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 82 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 83 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 84 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 85 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 86 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 87 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 88 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 89 operands: lhs = Counter(7), rhs = Expression(152, Sub)
+- expression 90 operands: lhs = Expression(153, Add), rhs = Counter(7)
+- expression 91 operands: lhs = Counter(6), rhs = Expression(154, Sub)
+- expression 92 operands: lhs = Expression(155, Add), rhs = Counter(6)
+- expression 93 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 94 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 95 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 96 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 97 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 98 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 99 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 100 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 101 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 102 operands: lhs = Expression(151, Add), rhs = Counter(8)
+- expression 103 operands: lhs = Counter(7), rhs = Expression(152, Sub)
+- expression 104 operands: lhs = Expression(153, Add), rhs = Counter(7)
+- expression 105 operands: lhs = Counter(6), rhs = Expression(154, Sub)
+- expression 106 operands: lhs = Expression(155, Add), rhs = Counter(6)
+- expression 107 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 108 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 109 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 110 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 111 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 112 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 113 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 114 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 115 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 116 operands: lhs = Counter(8), rhs = Expression(150, Sub)
+- expression 117 operands: lhs = Expression(151, Add), rhs = Counter(8)
+- expression 118 operands: lhs = Counter(7), rhs = Expression(152, Sub)
+- expression 119 operands: lhs = Expression(153, Add), rhs = Counter(7)
+- expression 120 operands: lhs = Counter(6), rhs = Expression(154, Sub)
+- expression 121 operands: lhs = Expression(155, Add), rhs = Counter(6)
+- expression 122 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 123 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 124 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 125 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 126 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 127 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 128 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 129 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 130 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 131 operands: lhs = Expression(149, Add), rhs = Counter(9)
+- expression 132 operands: lhs = Counter(8), rhs = Expression(150, Sub)
+- expression 133 operands: lhs = Expression(151, Add), rhs = Counter(8)
+- expression 134 operands: lhs = Counter(7), rhs = Expression(152, Sub)
+- expression 135 operands: lhs = Expression(153, Add), rhs = Counter(7)
+- expression 136 operands: lhs = Counter(6), rhs = Expression(154, Sub)
+- expression 137 operands: lhs = Expression(155, Add), rhs = Counter(6)
+- expression 138 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 139 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 140 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 141 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 142 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 143 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 144 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 145 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 146 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 147 operands: lhs = Counter(9), rhs = Expression(148, Sub)
+- expression 148 operands: lhs = Expression(149, Add), rhs = Counter(9)
+- expression 149 operands: lhs = Counter(8), rhs = Expression(150, Sub)
+- expression 150 operands: lhs = Expression(151, Add), rhs = Counter(8)
+- expression 151 operands: lhs = Counter(7), rhs = Expression(152, Sub)
+- expression 152 operands: lhs = Expression(153, Add), rhs = Counter(7)
+- expression 153 operands: lhs = Counter(6), rhs = Expression(154, Sub)
+- expression 154 operands: lhs = Expression(155, Add), rhs = Counter(6)
+- expression 155 operands: lhs = Counter(5), rhs = Expression(156, Sub)
+- expression 156 operands: lhs = Expression(157, Add), rhs = Counter(5)
+- expression 157 operands: lhs = Counter(4), rhs = Expression(158, Sub)
+- expression 158 operands: lhs = Expression(159, Add), rhs = Counter(4)
+- expression 159 operands: lhs = Counter(3), rhs = Expression(160, Sub)
+- expression 160 operands: lhs = Expression(161, Add), rhs = Counter(3)
+- expression 161 operands: lhs = Counter(2), rhs = Expression(162, Sub)
+- expression 162 operands: lhs = Expression(163, Add), rhs = Counter(2)
+- expression 163 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 28
 - Code(Counter(0)) at (prev + 3, 1) to (start + 7, 15)
 - Code(Counter(1)) at (prev + 7, 16) to (start + 4, 6)
 - Code(Expression(0, Sub)) at (prev + 4, 6) to (start + 0, 7)
     = (c0 - c1)
-- Code(Expression(165, Add)) at (prev + 2, 9) to (start + 0, 17)
+- Code(Expression(161, Add)) at (prev + 2, 9) to (start + 0, 17)
     = (c2 + ((c1 + (c0 - c1)) - c2))
-- Code(Expression(167, Add)) at (prev + 2, 13) to (start + 0, 18)
+- Code(Expression(163, Add)) at (prev + 2, 13) to (start + 0, 18)
     = (c1 + (c0 - c1))
-- Code(Expression(166, Sub)) at (prev + 2, 13) to (start + 0, 18)
+- Code(Expression(162, Sub)) at (prev + 2, 13) to (start + 0, 18)
     = ((c1 + (c0 - c1)) - c2)
-- Code(Expression(163, Add)) at (prev + 3, 9) to (start + 0, 17)
+- Code(Expression(159, Add)) at (prev + 3, 9) to (start + 0, 17)
     = (c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3))
-- Code(Expression(12, Add)) at (prev + 2, 13) to (start + 0, 18)
-    = ((c2 + ((c1 + (c0 - c1)) - c2)) + Zero)
-- Code(Expression(164, Sub)) at (prev + 2, 13) to (start + 0, 18)
+- Code(Expression(161, Add)) at (prev + 2, 13) to (start + 0, 18)
+    = (c2 + ((c1 + (c0 - c1)) - c2))
+- Code(Expression(160, Sub)) at (prev + 2, 13) to (start + 0, 18)
     = ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)
-- Code(Expression(161, Add)) at (prev + 2, 9) to (start + 0, 17)
+- Code(Expression(157, Add)) at (prev + 2, 9) to (start + 0, 17)
     = (c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4))
-- Code(Expression(27, Add)) at (prev + 0, 20) to (start + 0, 25)
-    = ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) + Zero)
+- Code(Expression(159, Add)) at (prev + 0, 20) to (start + 0, 25)
+    = (c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3))
 - Code(Counter(4)) at (prev + 0, 29) to (start + 0, 34)
-- Code(Expression(159, Add)) at (prev + 1, 9) to (start + 0, 17)
+- Code(Expression(155, Add)) at (prev + 1, 9) to (start + 0, 17)
     = (c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5))
-- Code(Expression(42, Add)) at (prev + 0, 20) to (start + 0, 25)
-    = ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) + Zero)
+- Code(Expression(157, Add)) at (prev + 0, 20) to (start + 0, 25)
+    = (c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4))
 - Code(Counter(5)) at (prev + 0, 29) to (start + 0, 34)
-- Code(Expression(50, Add)) at (prev + 4, 9) to (start + 0, 16)
-    = ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) + Zero)
-- Code(Expression(158, Sub)) at (prev + 1, 5) to (start + 3, 6)
+- Code(Expression(155, Add)) at (prev + 4, 9) to (start + 0, 16)
+    = (c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5))
+- Code(Expression(154, Sub)) at (prev + 1, 5) to (start + 3, 6)
     = ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)
 - Code(Counter(6)) at (prev + 3, 6) to (start + 0, 7)
-- Code(Expression(157, Add)) at (prev + 3, 9) to (start + 0, 16)
+- Code(Expression(153, Add)) at (prev + 3, 9) to (start + 0, 16)
     = (c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6))
 - Code(Counter(7)) at (prev + 1, 5) to (start + 3, 6)
-- Code(Expression(156, Sub)) at (prev + 5, 5) to (start + 3, 6)
+- Code(Expression(152, Sub)) at (prev + 5, 5) to (start + 3, 6)
     = ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)
-- Code(Expression(155, Add)) at (prev + 5, 9) to (start + 0, 16)
+- Code(Expression(151, Add)) at (prev + 5, 9) to (start + 0, 16)
     = (c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7))
-- Code(Expression(154, Sub)) at (prev + 0, 17) to (start + 2, 6)
+- Code(Expression(150, Sub)) at (prev + 0, 17) to (start + 2, 6)
     = ((c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)) - c8)
 - Code(Counter(8)) at (prev + 2, 6) to (start + 0, 7)
-- Code(Expression(153, Add)) at (prev + 2, 8) to (start + 0, 15)
+- Code(Expression(149, Add)) at (prev + 2, 8) to (start + 0, 15)
     = (c8 + ((c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)) - c8))
 - Code(Counter(9)) at (prev + 0, 16) to (start + 2, 6)
-- Code(Expression(152, Sub)) at (prev + 2, 12) to (start + 2, 6)
+- Code(Expression(148, Sub)) at (prev + 2, 12) to (start + 2, 6)
     = ((c8 + ((c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)) - c8)) - c9)
-- Code(Expression(151, Add)) at (prev + 3, 1) to (start + 0, 2)
+- Code(Expression(147, Add)) at (prev + 3, 1) to (start + 0, 2)
     = (c9 + ((c8 + ((c7 + ((c6 + ((c5 + ((c4 + ((c3 + ((c2 + ((c1 + (c0 - c1)) - c2)) - c3)) - c4)) - c5)) - c6)) - c7)) - c8)) - c9))
 
diff --git a/tests/coverage-map/status-quo/loops_branches.cov-map b/tests/coverage-map/status-quo/loops_branches.cov-map
index 480bbfd9795..ebace8cbd71 100644
--- a/tests/coverage-map/status-quo/loops_branches.cov-map
+++ b/tests/coverage-map/status-quo/loops_branches.cov-map
@@ -1,58 +1,57 @@
 Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt
-Raw bytes (251): 0x[01, 01, 32, 05, 09, 00, 02, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, c3, 01, c7, 01, 0d, 00, 11, 15, ba, 01, 00, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, 00, b2, 01, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, af, 01, 11, 00, b2, 01, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 11, 15, 25, a7, 01, aa, 01, 19, af, 01, 11, 00, b2, 01, b6, 01, 1d, ba, 01, 15, bf, 01, 19, c3, 01, c7, 01, 0d, 00, 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, 0e, 00, 0f, 07, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, ba, 01, 03, 0d, 00, 0e, bf, 01, 00, 12, 00, 17, 27, 01, 10, 00, 14, b6, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b2, 01, 01, 12, 00, 13, af, 01, 01, 11, 00, 22, aa, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, a3, 01, 01, 05, 00, 06]
+Raw bytes (249): 0x[01, 01, 31, 05, 09, 00, 02, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, bf, 01, c3, 01, 0d, 00, 11, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, b2, 01, 1d, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, 00, ae, 01, b2, 01, 1d, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, ab, 01, 11, 00, ae, 01, b2, 01, 1d, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 11, 15, 25, a3, 01, a6, 01, 19, ab, 01, 11, 00, ae, 01, b2, 01, 1d, b6, 01, 15, bb, 01, 19, bf, 01, c3, 01, 0d, 00, 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, 0e, 00, 0f, 07, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, b6, 01, 03, 0d, 00, 0e, bb, 01, 00, 12, 00, 17, b6, 01, 01, 10, 00, 14, b2, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, ae, 01, 01, 12, 00, 13, ab, 01, 01, 11, 00, 22, a6, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, 9f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 50
+Number of expressions: 49
 - expression 0 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 1 operands: lhs = Zero, rhs = Expression(0, Sub)
-- expression 2 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 3 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 2 operands: lhs = Expression(46, Add), rhs = Counter(6)
+- expression 3 operands: lhs = Expression(47, Add), rhs = Expression(48, Add)
 - expression 4 operands: lhs = Counter(3), rhs = Zero
 - expression 5 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 6 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 6 operands: lhs = Expression(47, Add), rhs = Expression(48, Add)
 - expression 7 operands: lhs = Counter(3), rhs = Zero
 - expression 8 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 9 operands: lhs = Expression(46, Sub), rhs = Zero
-- expression 10 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 11 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
-- expression 12 operands: lhs = Counter(3), rhs = Zero
-- expression 13 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 14 operands: lhs = Expression(46, Sub), rhs = Counter(5)
-- expression 15 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 16 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
-- expression 17 operands: lhs = Counter(3), rhs = Zero
-- expression 18 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 19 operands: lhs = Expression(45, Sub), rhs = Counter(7)
-- expression 20 operands: lhs = Expression(46, Sub), rhs = Counter(5)
-- expression 21 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 22 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
-- expression 23 operands: lhs = Counter(3), rhs = Zero
-- expression 24 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 25 operands: lhs = Zero, rhs = Expression(44, Sub)
-- expression 26 operands: lhs = Expression(45, Sub), rhs = Counter(7)
-- expression 27 operands: lhs = Expression(46, Sub), rhs = Counter(5)
-- expression 28 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 29 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
-- expression 30 operands: lhs = Counter(3), rhs = Zero
-- expression 31 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 32 operands: lhs = Expression(43, Add), rhs = Counter(4)
-- expression 33 operands: lhs = Zero, rhs = Expression(44, Sub)
-- expression 34 operands: lhs = Expression(45, Sub), rhs = Counter(7)
-- expression 35 operands: lhs = Expression(46, Sub), rhs = Counter(5)
-- expression 36 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 37 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
-- expression 38 operands: lhs = Counter(3), rhs = Zero
-- expression 39 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 40 operands: lhs = Counter(9), rhs = Expression(41, Add)
-- expression 41 operands: lhs = Expression(42, Sub), rhs = Counter(6)
-- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(4)
-- expression 43 operands: lhs = Zero, rhs = Expression(44, Sub)
-- expression 44 operands: lhs = Expression(45, Sub), rhs = Counter(7)
-- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(5)
-- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(6)
-- expression 47 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
-- expression 48 operands: lhs = Counter(3), rhs = Zero
-- expression 49 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 9 operands: lhs = Expression(46, Add), rhs = Counter(6)
+- expression 10 operands: lhs = Expression(47, Add), rhs = Expression(48, Add)
+- expression 11 operands: lhs = Counter(3), rhs = Zero
+- expression 12 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 13 operands: lhs = Expression(45, Sub), rhs = Counter(5)
+- expression 14 operands: lhs = Expression(46, Add), rhs = Counter(6)
+- expression 15 operands: lhs = Expression(47, Add), rhs = Expression(48, Add)
+- expression 16 operands: lhs = Counter(3), rhs = Zero
+- expression 17 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 18 operands: lhs = Expression(44, Sub), rhs = Counter(7)
+- expression 19 operands: lhs = Expression(45, Sub), rhs = Counter(5)
+- expression 20 operands: lhs = Expression(46, Add), rhs = Counter(6)
+- expression 21 operands: lhs = Expression(47, Add), rhs = Expression(48, Add)
+- expression 22 operands: lhs = Counter(3), rhs = Zero
+- expression 23 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 24 operands: lhs = Zero, rhs = Expression(43, Sub)
+- expression 25 operands: lhs = Expression(44, Sub), rhs = Counter(7)
+- expression 26 operands: lhs = Expression(45, Sub), rhs = Counter(5)
+- expression 27 operands: lhs = Expression(46, Add), rhs = Counter(6)
+- expression 28 operands: lhs = Expression(47, Add), rhs = Expression(48, Add)
+- expression 29 operands: lhs = Counter(3), rhs = Zero
+- expression 30 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 31 operands: lhs = Expression(42, Add), rhs = Counter(4)
+- expression 32 operands: lhs = Zero, rhs = Expression(43, Sub)
+- expression 33 operands: lhs = Expression(44, Sub), rhs = Counter(7)
+- expression 34 operands: lhs = Expression(45, Sub), rhs = Counter(5)
+- expression 35 operands: lhs = Expression(46, Add), rhs = Counter(6)
+- expression 36 operands: lhs = Expression(47, Add), rhs = Expression(48, Add)
+- expression 37 operands: lhs = Counter(3), rhs = Zero
+- expression 38 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 39 operands: lhs = Counter(9), rhs = Expression(40, Add)
+- expression 40 operands: lhs = Expression(41, Sub), rhs = Counter(6)
+- expression 41 operands: lhs = Expression(42, Add), rhs = Counter(4)
+- expression 42 operands: lhs = Zero, rhs = Expression(43, Sub)
+- expression 43 operands: lhs = Expression(44, Sub), rhs = Counter(7)
+- expression 44 operands: lhs = Expression(45, Sub), rhs = Counter(5)
+- expression 45 operands: lhs = Expression(46, Add), rhs = Counter(6)
+- expression 46 operands: lhs = Expression(47, Add), rhs = Expression(48, Add)
+- expression 47 operands: lhs = Counter(3), rhs = Zero
+- expression 48 operands: lhs = Counter(4), rhs = Counter(5)
 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)
@@ -64,84 +63,83 @@ Number of file 0 mappings: 20
     = (Zero + (c1 - c2))
 - Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31)
 - Code(Zero) at (prev + 1, 16) to (start + 1, 10)
-- Code(Expression(46, Sub)) at (prev + 3, 13) to (start + 0, 14)
+- Code(Expression(45, Sub)) at (prev + 3, 13) to (start + 0, 14)
     = (((c3 + Zero) + (c4 + c5)) - c6)
-- Code(Expression(47, Add)) at (prev + 0, 18) to (start + 0, 23)
+- Code(Expression(46, Add)) at (prev + 0, 18) to (start + 0, 23)
     = ((c3 + Zero) + (c4 + c5))
-- Code(Expression(9, Add)) at (prev + 1, 16) to (start + 0, 20)
-    = ((((c3 + Zero) + (c4 + c5)) - c6) + Zero)
-- Code(Expression(45, Sub)) at (prev + 1, 20) to (start + 0, 25)
+- Code(Expression(45, Sub)) at (prev + 1, 16) to (start + 0, 20)
+    = (((c3 + Zero) + (c4 + c5)) - c6)
+- Code(Expression(44, Sub)) at (prev + 1, 20) to (start + 0, 25)
     = ((((c3 + Zero) + (c4 + c5)) - c6) - c5)
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
-- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 19)
+- Code(Expression(43, Sub)) at (prev + 1, 18) to (start + 0, 19)
     = (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)
-- Code(Expression(43, Add)) at (prev + 1, 17) to (start + 0, 34)
+- Code(Expression(42, Add)) at (prev + 1, 17) to (start + 0, 34)
     = (Zero + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7))
-- Code(Expression(42, Sub)) at (prev + 0, 34) to (start + 0, 35)
+- Code(Expression(41, Sub)) at (prev + 0, 34) to (start + 0, 35)
     = ((Zero + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)) - c4)
 - Code(Zero) at (prev + 1, 20) to (start + 1, 14)
 - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15)
-- Code(Expression(40, Add)) at (prev + 1, 5) to (start + 0, 6)
+- Code(Expression(39, Add)) at (prev + 1, 5) to (start + 0, 6)
     = (c9 + (((Zero + (((((c3 + Zero) + (c4 + c5)) - c6) - c5) - c7)) - c4) + c6))
 
 Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt
-Raw bytes (255): 0x[01, 01, 34, 01, 05, 02, 09, 00, 0e, 02, 09, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, c7, 01, cb, 01, 05, 0d, 11, 15, be, 01, 00, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, 00, b6, 01, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, b3, 01, 15, 00, b6, 01, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, ae, 01, cf, 01, b3, 01, 15, 00, b6, 01, ba, 01, 1d, be, 01, 11, c3, 01, 19, c7, 01, cb, 01, 05, 0d, 11, 15, 19, 25, 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, 0e, 01, 0e, 00, 0f, 0b, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, be, 01, 02, 0d, 00, 0e, c3, 01, 00, 12, 00, 17, 2f, 01, 10, 00, 15, 00, 00, 16, 01, 0e, ba, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b6, 01, 01, 12, 00, 13, b3, 01, 01, 11, 00, 22, ae, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, ab, 01, 01, 05, 00, 06]
+Raw bytes (253): 0x[01, 01, 33, 01, 05, 02, 09, 00, 0e, 02, 09, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, c3, 01, c7, 01, 05, 0d, 11, 15, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, b6, 01, 1d, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, 00, b2, 01, b6, 01, 1d, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, af, 01, 15, 00, b2, 01, b6, 01, 1d, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, aa, 01, cb, 01, af, 01, 15, 00, b2, 01, b6, 01, 1d, ba, 01, 11, bf, 01, 19, c3, 01, c7, 01, 05, 0d, 11, 15, 19, 25, 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, 0e, 01, 0e, 00, 0f, 0b, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, ba, 01, 02, 0d, 00, 0e, bf, 01, 00, 12, 00, 17, ba, 01, 01, 10, 00, 15, 00, 00, 16, 01, 0e, b6, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, b2, 01, 01, 12, 00, 13, af, 01, 01, 11, 00, 22, aa, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, a7, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 52
+Number of expressions: 51
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Expression(0, Sub), rhs = Counter(2)
 - expression 2 operands: lhs = Zero, rhs = Expression(3, Sub)
 - expression 3 operands: lhs = Expression(0, Sub), rhs = Counter(2)
-- expression 4 operands: lhs = Expression(48, Add), rhs = Counter(6)
-- expression 5 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
+- expression 4 operands: lhs = Expression(47, Add), rhs = Counter(6)
+- expression 5 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
 - expression 6 operands: lhs = Counter(1), rhs = Counter(3)
 - expression 7 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 8 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
+- expression 8 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
 - expression 9 operands: lhs = Counter(1), rhs = Counter(3)
 - expression 10 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 11 operands: lhs = Expression(47, Sub), rhs = Zero
-- expression 12 operands: lhs = Expression(48, Add), rhs = Counter(6)
-- expression 13 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
-- expression 14 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 15 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 16 operands: lhs = Expression(47, Sub), rhs = Counter(4)
-- expression 17 operands: lhs = Expression(48, Add), rhs = Counter(6)
-- expression 18 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
-- expression 19 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 20 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 21 operands: lhs = Expression(46, Sub), rhs = Counter(7)
-- expression 22 operands: lhs = Expression(47, Sub), rhs = Counter(4)
-- expression 23 operands: lhs = Expression(48, Add), rhs = Counter(6)
-- expression 24 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
-- expression 25 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 26 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 27 operands: lhs = Zero, rhs = Expression(45, Sub)
-- expression 28 operands: lhs = Expression(46, Sub), rhs = Counter(7)
-- expression 29 operands: lhs = Expression(47, Sub), rhs = Counter(4)
-- expression 30 operands: lhs = Expression(48, Add), rhs = Counter(6)
-- expression 31 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
-- expression 32 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 33 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 34 operands: lhs = Expression(44, Add), rhs = Counter(5)
-- expression 35 operands: lhs = Zero, rhs = Expression(45, Sub)
-- expression 36 operands: lhs = Expression(46, Sub), rhs = Counter(7)
-- expression 37 operands: lhs = Expression(47, Sub), rhs = Counter(4)
-- expression 38 operands: lhs = Expression(48, Add), rhs = Counter(6)
-- expression 39 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
-- expression 40 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 41 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 42 operands: lhs = Expression(43, Sub), rhs = Expression(51, Add)
-- expression 43 operands: lhs = Expression(44, Add), rhs = Counter(5)
-- expression 44 operands: lhs = Zero, rhs = Expression(45, Sub)
-- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(7)
-- expression 46 operands: lhs = Expression(47, Sub), rhs = Counter(4)
-- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(6)
-- expression 48 operands: lhs = Expression(49, Add), rhs = Expression(50, Add)
-- expression 49 operands: lhs = Counter(1), rhs = Counter(3)
-- expression 50 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 51 operands: lhs = Counter(6), rhs = Counter(9)
+- expression 11 operands: lhs = Expression(47, Add), rhs = Counter(6)
+- expression 12 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 13 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 14 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 15 operands: lhs = Expression(46, Sub), rhs = Counter(4)
+- expression 16 operands: lhs = Expression(47, Add), rhs = Counter(6)
+- expression 17 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 18 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 19 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 20 operands: lhs = Expression(45, Sub), rhs = Counter(7)
+- expression 21 operands: lhs = Expression(46, Sub), rhs = Counter(4)
+- expression 22 operands: lhs = Expression(47, Add), rhs = Counter(6)
+- expression 23 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 24 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 25 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 26 operands: lhs = Zero, rhs = Expression(44, Sub)
+- expression 27 operands: lhs = Expression(45, Sub), rhs = Counter(7)
+- expression 28 operands: lhs = Expression(46, Sub), rhs = Counter(4)
+- expression 29 operands: lhs = Expression(47, Add), rhs = Counter(6)
+- expression 30 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 31 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 32 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 33 operands: lhs = Expression(43, Add), rhs = Counter(5)
+- expression 34 operands: lhs = Zero, rhs = Expression(44, Sub)
+- expression 35 operands: lhs = Expression(45, Sub), rhs = Counter(7)
+- expression 36 operands: lhs = Expression(46, Sub), rhs = Counter(4)
+- expression 37 operands: lhs = Expression(47, Add), rhs = Counter(6)
+- expression 38 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 39 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 40 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 41 operands: lhs = Expression(42, Sub), rhs = Expression(50, Add)
+- expression 42 operands: lhs = Expression(43, Add), rhs = Counter(5)
+- expression 43 operands: lhs = Zero, rhs = Expression(44, Sub)
+- expression 44 operands: lhs = Expression(45, Sub), rhs = Counter(7)
+- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(4)
+- expression 46 operands: lhs = Expression(47, Add), rhs = Counter(6)
+- expression 47 operands: lhs = Expression(48, Add), rhs = Expression(49, Add)
+- expression 48 operands: lhs = Counter(1), rhs = Counter(3)
+- expression 49 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 50 operands: lhs = Counter(6), rhs = Counter(9)
 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)
@@ -154,25 +152,25 @@ Number of file 0 mappings: 20
 - Code(Expression(2, Add)) at (prev + 1, 13) to (start + 0, 30)
     = (Zero + ((c0 - c1) - c2))
 - Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31)
-- Code(Expression(47, Sub)) at (prev + 2, 13) to (start + 0, 14)
+- Code(Expression(46, Sub)) at (prev + 2, 13) to (start + 0, 14)
     = (((c1 + c3) + (c4 + c5)) - c6)
-- Code(Expression(48, Add)) at (prev + 0, 18) to (start + 0, 23)
+- Code(Expression(47, Add)) at (prev + 0, 18) to (start + 0, 23)
     = ((c1 + c3) + (c4 + c5))
-- Code(Expression(11, Add)) at (prev + 1, 16) to (start + 0, 21)
-    = ((((c1 + c3) + (c4 + c5)) - c6) + Zero)
+- Code(Expression(46, Sub)) at (prev + 1, 16) to (start + 0, 21)
+    = (((c1 + c3) + (c4 + c5)) - c6)
 - Code(Zero) at (prev + 0, 22) to (start + 1, 14)
-- Code(Expression(46, Sub)) at (prev + 2, 20) to (start + 0, 25)
+- Code(Expression(45, Sub)) at (prev + 2, 20) to (start + 0, 25)
     = ((((c1 + c3) + (c4 + c5)) - c6) - c4)
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
-- Code(Expression(45, Sub)) at (prev + 1, 18) to (start + 0, 19)
+- Code(Expression(44, Sub)) at (prev + 1, 18) to (start + 0, 19)
     = (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)
-- Code(Expression(44, Add)) at (prev + 1, 17) to (start + 0, 34)
+- Code(Expression(43, Add)) at (prev + 1, 17) to (start + 0, 34)
     = (Zero + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7))
-- Code(Expression(43, Sub)) at (prev + 0, 34) to (start + 0, 35)
+- Code(Expression(42, Sub)) at (prev + 0, 34) to (start + 0, 35)
     = ((Zero + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)) - c5)
 - Code(Counter(6)) at (prev + 3, 9) to (start + 0, 15)
-- Code(Expression(42, Add)) at (prev + 1, 5) to (start + 0, 6)
+- Code(Expression(41, Add)) at (prev + 1, 5) to (start + 0, 6)
     = (((Zero + (((((c1 + c3) + (c4 + c5)) - c6) - c4) - c7)) - c5) + (c6 + c9))
 
 Function name: loops_branches::main
diff --git a/tests/coverage-map/status-quo/no_cov_crate.cov-map b/tests/coverage-map/status-quo/no_cov_crate.cov-map
index 7ab5995dc28..05b6448bbd2 100644
--- a/tests/coverage-map/status-quo/no_cov_crate.cov-map
+++ b/tests/coverage-map/status-quo/no_cov_crate.cov-map
@@ -15,12 +15,12 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 24, 1) to (start + 2, 2)
 
 Function name: no_cov_crate::add_coverage_not_called (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 1d, 01, 02, 02]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 1d, 01, 02, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 29, 1) to (start + 2, 2)
+- Code(Zero) at (prev + 29, 1) to (start + 2, 2)
 
 Function name: no_cov_crate::main
 Raw bytes (9): 0x[01, 01, 00, 01, 01, 4d, 01, 0b, 02]
diff --git a/tests/coverage-map/status-quo/partial_eq.cov-map b/tests/coverage-map/status-quo/partial_eq.cov-map
index dd61cd77ab6..3549116db7a 100644
--- a/tests/coverage-map/status-quo/partial_eq.cov-map
+++ b/tests/coverage-map/status-quo/partial_eq.cov-map
@@ -1,27 +1,27 @@
 Function name: <partial_eq::Version as core::clone::Clone>::clone (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 04, 0a, 00, 0f]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 04, 0a, 00, 0f]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 4, 10) to (start + 0, 15)
+- Code(Zero) at (prev + 4, 10) to (start + 0, 15)
 
 Function name: <partial_eq::Version as core::cmp::Ord>::cmp (unused)
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 33, 00, 34, 00, 00, 35, 00, 36]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 04, 33, 00, 34, 00, 00, 35, 00, 36]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 4, 51) to (start + 0, 52)
+- Code(Zero) at (prev + 4, 51) to (start + 0, 52)
 - Code(Zero) at (prev + 0, 53) to (start + 0, 54)
 
 Function name: <partial_eq::Version as core::cmp::PartialEq>::eq (unused)
-Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 18, 00, 19, 00, 00, 20, 00, 21]
+Raw bytes (14): 0x[01, 01, 00, 02, 00, 04, 18, 00, 19, 00, 00, 20, 00, 21]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 2
-- Code(Counter(0)) at (prev + 4, 24) to (start + 0, 25)
+- Code(Zero) at (prev + 4, 24) to (start + 0, 25)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 33)
 
 Function name: <partial_eq::Version as core::cmp::PartialOrd>::partial_cmp
diff --git a/tests/coverage-map/status-quo/simple_loop.cov-map b/tests/coverage-map/status-quo/simple_loop.cov-map
index eb49c2324cc..f1691ffc5e6 100644
--- a/tests/coverage-map/status-quo/simple_loop.cov-map
+++ b/tests/coverage-map/status-quo/simple_loop.cov-map
@@ -1,28 +1,27 @@
 Function name: simple_loop::main
-Raw bytes (59): 0x[01, 01, 0a, 01, 05, 27, 09, 05, 02, 23, 09, 27, 09, 05, 02, 1e, 00, 23, 09, 27, 09, 05, 02, 07, 01, 03, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 06, 00, 07, 23, 05, 0d, 02, 0e, 1e, 04, 0d, 00, 12, 09, 02, 0a, 03, 0a, 1b, 06, 01, 00, 02]
+Raw bytes (57): 0x[01, 01, 09, 01, 05, 23, 09, 05, 02, 1f, 09, 23, 09, 05, 02, 1f, 09, 23, 09, 05, 02, 07, 01, 03, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 06, 00, 07, 1f, 05, 0d, 02, 0e, 1a, 04, 0d, 00, 12, 09, 02, 0a, 03, 0a, 1a, 06, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 10
+Number of expressions: 9
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Expression(9, Add), rhs = Counter(2)
+- expression 1 operands: lhs = Expression(8, Add), rhs = Counter(2)
 - expression 2 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 3 operands: lhs = Expression(8, Add), rhs = Counter(2)
-- expression 4 operands: lhs = Expression(9, Add), rhs = Counter(2)
+- expression 3 operands: lhs = Expression(7, Add), rhs = Counter(2)
+- expression 4 operands: lhs = Expression(8, Add), rhs = Counter(2)
 - expression 5 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 6 operands: lhs = Expression(7, Sub), rhs = Zero
+- expression 6 operands: lhs = Expression(7, Add), rhs = Counter(2)
 - expression 7 operands: lhs = Expression(8, Add), rhs = Counter(2)
-- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(2)
-- expression 9 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 8 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 3, 1) to (start + 9, 16)
 - Code(Counter(1)) at (prev + 10, 5) to (start + 5, 6)
 - Code(Expression(0, Sub)) at (prev + 5, 6) to (start + 0, 7)
     = (c0 - c1)
-- Code(Expression(8, Add)) at (prev + 5, 13) to (start + 2, 14)
+- Code(Expression(7, Add)) at (prev + 5, 13) to (start + 2, 14)
     = ((c1 + (c0 - c1)) + c2)
-- Code(Expression(7, Sub)) at (prev + 4, 13) to (start + 0, 18)
+- Code(Expression(6, Sub)) at (prev + 4, 13) to (start + 0, 18)
     = (((c1 + (c0 - c1)) + c2) - c2)
 - Code(Counter(2)) at (prev + 2, 10) to (start + 3, 10)
-- Code(Expression(6, Add)) at (prev + 6, 1) to (start + 0, 2)
-    = ((((c1 + (c0 - c1)) + c2) - c2) + Zero)
+- Code(Expression(6, Sub)) at (prev + 6, 1) to (start + 0, 2)
+    = (((c1 + (c0 - c1)) + c2) - c2)
 
diff --git a/tests/coverage-map/status-quo/simple_match.cov-map b/tests/coverage-map/status-quo/simple_match.cov-map
index d5389f04b26..4a32745d292 100644
--- a/tests/coverage-map/status-quo/simple_match.cov-map
+++ b/tests/coverage-map/status-quo/simple_match.cov-map
@@ -1,36 +1,33 @@
 Function name: simple_match::main
-Raw bytes (82): 0x[01, 01, 0e, 01, 05, 2f, 33, 05, 02, 09, 0d, 2b, 11, 2f, 33, 05, 02, 09, 0d, 26, 00, 2b, 11, 2f, 33, 05, 02, 09, 0d, 09, 00, 0a, 01, 03, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 06, 00, 07, 2b, 05, 09, 00, 0d, 26, 05, 0d, 00, 16, 09, 02, 0d, 00, 0e, 23, 02, 11, 02, 12, 37, 04, 0d, 07, 0e, 0d, 0a, 0d, 00, 0f, 11, 03, 01, 00, 02]
+Raw bytes (78): 0x[01, 01, 0c, 01, 05, 2b, 2f, 05, 02, 09, 0d, 27, 11, 2b, 2f, 05, 02, 09, 0d, 27, 11, 2b, 2f, 05, 02, 09, 0d, 0a, 01, 03, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 06, 00, 07, 27, 05, 09, 00, 0d, 22, 05, 0d, 00, 16, 09, 02, 0d, 00, 0e, 22, 02, 11, 02, 12, 09, 04, 0d, 07, 0e, 0d, 0a, 0d, 00, 0f, 11, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 14
+Number of expressions: 12
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-- expression 1 operands: lhs = Expression(11, Add), rhs = Expression(12, Add)
+- expression 1 operands: lhs = Expression(10, Add), rhs = Expression(11, Add)
 - expression 2 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 - expression 3 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 4 operands: lhs = Expression(10, Add), rhs = Counter(4)
-- expression 5 operands: lhs = Expression(11, Add), rhs = Expression(12, Add)
+- expression 4 operands: lhs = Expression(9, Add), rhs = Counter(4)
+- expression 5 operands: lhs = Expression(10, Add), rhs = Expression(11, Add)
 - expression 6 operands: lhs = Counter(1), rhs = Expression(0, Sub)
 - expression 7 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 8 operands: lhs = Expression(9, Sub), rhs = Zero
-- expression 9 operands: lhs = Expression(10, Add), rhs = Counter(4)
-- expression 10 operands: lhs = Expression(11, Add), rhs = Expression(12, Add)
-- expression 11 operands: lhs = Counter(1), rhs = Expression(0, Sub)
-- expression 12 operands: lhs = Counter(2), rhs = Counter(3)
-- expression 13 operands: lhs = Counter(2), rhs = Zero
+- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(4)
+- expression 9 operands: lhs = Expression(10, Add), rhs = Expression(11, Add)
+- expression 10 operands: lhs = Counter(1), rhs = Expression(0, Sub)
+- expression 11 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 10
 - Code(Counter(0)) at (prev + 3, 1) to (start + 7, 15)
 - Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6)
 - Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
     = (c0 - c1)
-- Code(Expression(10, Add)) at (prev + 5, 9) to (start + 0, 13)
+- Code(Expression(9, Add)) at (prev + 5, 9) to (start + 0, 13)
     = ((c1 + (c0 - c1)) + (c2 + c3))
-- Code(Expression(9, Sub)) at (prev + 5, 13) to (start + 0, 22)
+- Code(Expression(8, Sub)) at (prev + 5, 13) to (start + 0, 22)
     = (((c1 + (c0 - c1)) + (c2 + c3)) - c4)
 - Code(Counter(2)) at (prev + 2, 13) to (start + 0, 14)
-- Code(Expression(8, Add)) at (prev + 2, 17) to (start + 2, 18)
-    = ((((c1 + (c0 - c1)) + (c2 + c3)) - c4) + Zero)
-- Code(Expression(13, Add)) at (prev + 4, 13) to (start + 7, 14)
-    = (c2 + Zero)
+- Code(Expression(8, Sub)) at (prev + 2, 17) to (start + 2, 18)
+    = (((c1 + (c0 - c1)) + (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)
 
diff --git a/tests/coverage-map/status-quo/test_harness.cov-map b/tests/coverage-map/status-quo/test_harness.cov-map
index b0e955dd142..6940d2e2824 100644
--- a/tests/coverage-map/status-quo/test_harness.cov-map
+++ b/tests/coverage-map/status-quo/test_harness.cov-map
@@ -15,10 +15,10 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 9, 1) to (start + 0, 8)
 
 Function name: test_harness::unused (unused)
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 0f]
+Raw bytes (9): 0x[01, 01, 00, 01, 00, 07, 01, 00, 0f]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 15)
+- Code(Zero) at (prev + 7, 1) to (start + 0, 15)
 
diff --git a/tests/coverage-map/status-quo/try_error_result.cov-map b/tests/coverage-map/status-quo/try_error_result.cov-map
index b52e78d1195..8367103a21a 100644
--- a/tests/coverage-map/status-quo/try_error_result.cov-map
+++ b/tests/coverage-map/status-quo/try_error_result.cov-map
@@ -91,136 +91,130 @@ Number of file 0 mappings: 11
     = ((c4 + (c5 + c6)) + c3)
 
 Function name: try_error_result::test2
-Raw bytes (373): 0x[01, 01, 41, 01, 07, 05, 09, 03, 0d, 41, 11, 52, 15, 41, 11, 4a, 1d, 4e, 19, 52, 15, 41, 11, 4e, 00, 52, 15, 41, 11, 4e, 19, 52, 15, 41, 11, 46, 00, 4a, 1d, 4e, 19, 52, 15, 41, 11, 6a, 25, 49, 21, 49, 21, 66, 00, 6a, 25, 49, 21, 9a, 01, 2d, 9e, 01, 29, a2, 01, 41, 03, 0d, a2, 01, 41, 03, 0d, 9e, 01, 29, a2, 01, 41, 03, 0d, 96, 01, 00, 9a, 01, 2d, 9e, 01, 29, a2, 01, 41, 03, 0d, ba, 01, 35, 45, 31, 45, 31, b6, 01, 00, ba, 01, 35, 45, 31, d2, 01, 3d, 4d, 39, 4d, 39, ce, 01, 00, d2, 01, 3d, 4d, 39, db, 01, 0d, 11, df, 01, e3, 01, f3, 01, 15, e7, 01, eb, 01, ef, 01, 19, 1d, 21, 25, f7, 01, fb, 01, 29, 2d, ff, 01, 83, 02, 31, 35, 39, 3d, 28, 01, 3c, 01, 03, 17, 03, 08, 09, 00, 0e, a2, 01, 02, 09, 04, 1a, 41, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 52, 00, 31, 03, 35, 15, 04, 11, 00, 12, 4e, 02, 11, 04, 12, 46, 05, 11, 00, 14, 2b, 00, 17, 00, 41, 19, 00, 41, 00, 42, 4a, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 43, 01, 0d, 00, 20, 66, 01, 11, 00, 14, 49, 00, 17, 00, 41, 21, 00, 41, 00, 42, 6a, 00, 43, 00, 60, 25, 00, 60, 00, 61, 63, 01, 0d, 00, 20, 96, 01, 04, 11, 00, 14, 9e, 01, 00, 17, 00, 42, 29, 00, 42, 00, 43, 9a, 01, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 93, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, ba, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, b3, 01, 01, 0d, 00, 20, ce, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 39, 02, 11, 00, 12, d2, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, cb, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, d7, 01, 01, 01, 00, 02]
+Raw bytes (358): 0x[01, 01, 3b, 01, 07, 05, 09, 03, 0d, 41, 11, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 4a, 15, 41, 11, 46, 19, 4a, 15, 41, 11, 42, 1d, 46, 19, 4a, 15, 41, 11, 5e, 25, 49, 21, 49, 21, 5e, 25, 49, 21, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, 92, 01, 41, 03, 0d, 8e, 01, 29, 92, 01, 41, 03, 0d, 8a, 01, 2d, 8e, 01, 29, 92, 01, 41, 03, 0d, a6, 01, 35, 45, 31, 45, 31, a6, 01, 35, 45, 31, ba, 01, 3d, 4d, 39, 4d, 39, ba, 01, 3d, 4d, 39, c3, 01, 0d, 11, c7, 01, cb, 01, db, 01, 15, cf, 01, d3, 01, d7, 01, 19, 1d, 21, 25, df, 01, e3, 01, 29, 2d, e7, 01, eb, 01, 31, 35, 39, 3d, 28, 01, 3c, 01, 03, 17, 03, 08, 09, 00, 0e, 92, 01, 02, 09, 04, 1a, 41, 06, 0d, 00, 2f, 11, 00, 2f, 00, 30, 4a, 00, 31, 03, 35, 15, 04, 11, 00, 12, 46, 02, 11, 04, 12, 3e, 05, 11, 00, 14, 46, 00, 17, 00, 41, 19, 00, 41, 00, 42, 42, 00, 43, 00, 5f, 1d, 00, 5f, 00, 60, 3e, 01, 0d, 00, 20, 5a, 01, 11, 00, 14, 49, 00, 17, 00, 41, 21, 00, 41, 00, 42, 5e, 00, 43, 00, 60, 25, 00, 60, 00, 61, 5a, 01, 0d, 00, 20, 86, 01, 04, 11, 00, 14, 8e, 01, 00, 17, 00, 42, 29, 00, 42, 00, 43, 8a, 01, 00, 44, 00, 61, 2d, 00, 61, 00, 62, 86, 01, 01, 0d, 00, 20, a2, 01, 01, 11, 00, 14, 45, 00, 17, 01, 36, 31, 01, 36, 00, 37, a6, 01, 01, 12, 00, 2f, 35, 00, 2f, 00, 30, a2, 01, 01, 0d, 00, 20, b6, 01, 01, 11, 00, 14, 4d, 00, 17, 01, 36, 39, 02, 11, 00, 12, ba, 01, 01, 12, 00, 2f, 3d, 01, 11, 00, 12, b6, 01, 02, 0d, 00, 20, 0d, 03, 05, 00, 0b, bf, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 65
+Number of expressions: 59
 - expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
 - expression 1 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 2 operands: lhs = Expression(0, Add), rhs = Counter(3)
 - expression 3 operands: lhs = Counter(16), rhs = Counter(4)
-- expression 4 operands: lhs = Expression(20, Sub), rhs = Counter(5)
+- expression 4 operands: lhs = Expression(18, Sub), rhs = Counter(5)
 - expression 5 operands: lhs = Counter(16), rhs = Counter(4)
-- expression 6 operands: lhs = Expression(18, Sub), rhs = Counter(7)
-- expression 7 operands: lhs = Expression(19, Sub), rhs = Counter(6)
-- expression 8 operands: lhs = Expression(20, Sub), rhs = Counter(5)
+- expression 6 operands: lhs = Expression(16, Sub), rhs = Counter(7)
+- expression 7 operands: lhs = Expression(17, Sub), rhs = Counter(6)
+- expression 8 operands: lhs = Expression(18, Sub), rhs = Counter(5)
 - expression 9 operands: lhs = Counter(16), rhs = Counter(4)
-- expression 10 operands: lhs = Expression(19, Sub), rhs = Zero
-- expression 11 operands: lhs = Expression(20, Sub), rhs = Counter(5)
-- expression 12 operands: lhs = Counter(16), rhs = Counter(4)
-- expression 13 operands: lhs = Expression(19, Sub), rhs = Counter(6)
-- expression 14 operands: lhs = Expression(20, Sub), rhs = Counter(5)
-- expression 15 operands: lhs = Counter(16), rhs = Counter(4)
-- expression 16 operands: lhs = Expression(17, Sub), rhs = Zero
-- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(7)
-- expression 18 operands: lhs = Expression(19, Sub), rhs = Counter(6)
-- expression 19 operands: lhs = Expression(20, Sub), rhs = Counter(5)
-- expression 20 operands: lhs = Counter(16), rhs = Counter(4)
-- expression 21 operands: lhs = Expression(26, Sub), rhs = Counter(9)
-- expression 22 operands: lhs = Counter(18), rhs = Counter(8)
+- expression 10 operands: lhs = Expression(18, Sub), rhs = Counter(5)
+- expression 11 operands: lhs = Counter(16), rhs = Counter(4)
+- expression 12 operands: lhs = Expression(17, Sub), rhs = Counter(6)
+- expression 13 operands: lhs = Expression(18, Sub), rhs = Counter(5)
+- expression 14 operands: lhs = Counter(16), rhs = Counter(4)
+- expression 15 operands: lhs = Expression(16, Sub), rhs = Counter(7)
+- expression 16 operands: lhs = Expression(17, Sub), rhs = Counter(6)
+- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(5)
+- expression 18 operands: lhs = Counter(16), rhs = Counter(4)
+- expression 19 operands: lhs = Expression(23, Sub), rhs = Counter(9)
+- expression 20 operands: lhs = Counter(18), rhs = Counter(8)
+- expression 21 operands: lhs = Counter(18), rhs = Counter(8)
+- expression 22 operands: lhs = Expression(23, Sub), rhs = Counter(9)
 - expression 23 operands: lhs = Counter(18), rhs = Counter(8)
-- expression 24 operands: lhs = Expression(25, Sub), rhs = Zero
-- expression 25 operands: lhs = Expression(26, Sub), rhs = Counter(9)
-- expression 26 operands: lhs = Counter(18), rhs = Counter(8)
-- expression 27 operands: lhs = Expression(38, Sub), rhs = Counter(11)
-- expression 28 operands: lhs = Expression(39, Sub), rhs = Counter(10)
-- expression 29 operands: lhs = Expression(40, Sub), rhs = Counter(16)
-- expression 30 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 31 operands: lhs = Expression(40, Sub), rhs = Counter(16)
+- expression 24 operands: lhs = Expression(34, Sub), rhs = Counter(11)
+- expression 25 operands: lhs = Expression(35, Sub), rhs = Counter(10)
+- expression 26 operands: lhs = Expression(36, Sub), rhs = Counter(16)
+- expression 27 operands: lhs = Expression(0, Add), rhs = Counter(3)
+- expression 28 operands: lhs = Expression(36, Sub), rhs = Counter(16)
+- expression 29 operands: lhs = Expression(0, Add), rhs = Counter(3)
+- expression 30 operands: lhs = Expression(35, Sub), rhs = Counter(10)
+- expression 31 operands: lhs = Expression(36, Sub), rhs = Counter(16)
 - expression 32 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 33 operands: lhs = Expression(39, Sub), rhs = Counter(10)
-- expression 34 operands: lhs = Expression(40, Sub), rhs = Counter(16)
-- expression 35 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 36 operands: lhs = Expression(37, Sub), rhs = Zero
-- expression 37 operands: lhs = Expression(38, Sub), rhs = Counter(11)
-- expression 38 operands: lhs = Expression(39, Sub), rhs = Counter(10)
-- expression 39 operands: lhs = Expression(40, Sub), rhs = Counter(16)
-- expression 40 operands: lhs = Expression(0, Add), rhs = Counter(3)
-- expression 41 operands: lhs = Expression(46, Sub), rhs = Counter(13)
-- expression 42 operands: lhs = Counter(17), rhs = Counter(12)
-- expression 43 operands: lhs = Counter(17), rhs = Counter(12)
-- expression 44 operands: lhs = Expression(45, Sub), rhs = Zero
-- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(13)
-- expression 46 operands: lhs = Counter(17), rhs = Counter(12)
-- expression 47 operands: lhs = Expression(52, Sub), rhs = Counter(15)
-- expression 48 operands: lhs = Counter(19), rhs = Counter(14)
-- expression 49 operands: lhs = Counter(19), rhs = Counter(14)
-- expression 50 operands: lhs = Expression(51, Sub), rhs = Zero
-- expression 51 operands: lhs = Expression(52, Sub), rhs = Counter(15)
-- expression 52 operands: lhs = Counter(19), rhs = Counter(14)
-- expression 53 operands: lhs = Expression(54, Add), rhs = Counter(3)
-- expression 54 operands: lhs = Counter(4), rhs = Expression(55, Add)
-- expression 55 operands: lhs = Expression(56, Add), rhs = Expression(60, Add)
-- expression 56 operands: lhs = Counter(5), rhs = Expression(57, Add)
-- expression 57 operands: lhs = Expression(58, Add), rhs = Expression(59, Add)
-- expression 58 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 59 operands: lhs = Counter(8), rhs = Counter(9)
-- expression 60 operands: lhs = Expression(61, Add), rhs = Expression(62, Add)
-- expression 61 operands: lhs = Counter(10), rhs = Counter(11)
-- expression 62 operands: lhs = Expression(63, Add), rhs = Expression(64, Add)
-- expression 63 operands: lhs = Counter(12), rhs = Counter(13)
-- expression 64 operands: lhs = Counter(14), rhs = Counter(15)
+- expression 33 operands: lhs = Expression(34, Sub), rhs = Counter(11)
+- expression 34 operands: lhs = Expression(35, Sub), rhs = Counter(10)
+- expression 35 operands: lhs = Expression(36, Sub), rhs = Counter(16)
+- expression 36 operands: lhs = Expression(0, Add), rhs = Counter(3)
+- expression 37 operands: lhs = Expression(41, Sub), rhs = Counter(13)
+- expression 38 operands: lhs = Counter(17), rhs = Counter(12)
+- expression 39 operands: lhs = Counter(17), rhs = Counter(12)
+- expression 40 operands: lhs = Expression(41, Sub), rhs = Counter(13)
+- expression 41 operands: lhs = Counter(17), rhs = Counter(12)
+- expression 42 operands: lhs = Expression(46, Sub), rhs = Counter(15)
+- expression 43 operands: lhs = Counter(19), rhs = Counter(14)
+- expression 44 operands: lhs = Counter(19), rhs = Counter(14)
+- expression 45 operands: lhs = Expression(46, Sub), rhs = Counter(15)
+- expression 46 operands: lhs = Counter(19), rhs = Counter(14)
+- expression 47 operands: lhs = Expression(48, Add), rhs = Counter(3)
+- expression 48 operands: lhs = Counter(4), rhs = Expression(49, Add)
+- expression 49 operands: lhs = Expression(50, Add), rhs = Expression(54, Add)
+- expression 50 operands: lhs = Counter(5), rhs = Expression(51, Add)
+- expression 51 operands: lhs = Expression(52, Add), rhs = Expression(53, Add)
+- expression 52 operands: lhs = Counter(6), rhs = Counter(7)
+- expression 53 operands: lhs = Counter(8), rhs = Counter(9)
+- expression 54 operands: lhs = Expression(55, Add), rhs = Expression(56, Add)
+- expression 55 operands: lhs = Counter(10), rhs = Counter(11)
+- expression 56 operands: lhs = Expression(57, Add), rhs = Expression(58, Add)
+- expression 57 operands: lhs = Counter(12), rhs = Counter(13)
+- expression 58 operands: lhs = Counter(14), rhs = Counter(15)
 Number of file 0 mappings: 40
 - Code(Counter(0)) at (prev + 60, 1) to (start + 3, 23)
 - Code(Expression(0, Add)) at (prev + 8, 9) to (start + 0, 14)
     = (c0 + (c1 + c2))
-- Code(Expression(40, Sub)) at (prev + 2, 9) to (start + 4, 26)
+- Code(Expression(36, Sub)) at (prev + 2, 9) to (start + 4, 26)
     = ((c0 + (c1 + c2)) - c3)
 - Code(Counter(16)) at (prev + 6, 13) to (start + 0, 47)
 - Code(Counter(4)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(20, Sub)) at (prev + 0, 49) to (start + 3, 53)
+- Code(Expression(18, Sub)) at (prev + 0, 49) to (start + 3, 53)
     = (c16 - c4)
 - Code(Counter(5)) at (prev + 4, 17) to (start + 0, 18)
-- Code(Expression(19, Sub)) at (prev + 2, 17) to (start + 4, 18)
+- Code(Expression(17, Sub)) at (prev + 2, 17) to (start + 4, 18)
     = ((c16 - c4) - c5)
-- Code(Expression(17, Sub)) at (prev + 5, 17) to (start + 0, 20)
+- Code(Expression(15, Sub)) at (prev + 5, 17) to (start + 0, 20)
     = ((((c16 - c4) - c5) - c6) - c7)
-- Code(Expression(10, Add)) at (prev + 0, 23) to (start + 0, 65)
-    = (((c16 - c4) - c5) + Zero)
+- Code(Expression(17, Sub)) at (prev + 0, 23) to (start + 0, 65)
+    = ((c16 - c4) - c5)
 - Code(Counter(6)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(18, Sub)) at (prev + 0, 67) to (start + 0, 95)
+- Code(Expression(16, Sub)) at (prev + 0, 67) to (start + 0, 95)
     = (((c16 - c4) - c5) - c6)
 - Code(Counter(7)) at (prev + 0, 95) to (start + 0, 96)
-- Code(Expression(16, Add)) at (prev + 1, 13) to (start + 0, 32)
-    = (((((c16 - c4) - c5) - c6) - c7) + Zero)
-- Code(Expression(25, Sub)) at (prev + 1, 17) to (start + 0, 20)
+- Code(Expression(15, Sub)) at (prev + 1, 13) to (start + 0, 32)
+    = ((((c16 - c4) - c5) - c6) - c7)
+- Code(Expression(22, Sub)) at (prev + 1, 17) to (start + 0, 20)
     = ((c18 - c8) - c9)
 - Code(Counter(18)) at (prev + 0, 23) to (start + 0, 65)
 - Code(Counter(8)) at (prev + 0, 65) to (start + 0, 66)
-- Code(Expression(26, Sub)) at (prev + 0, 67) to (start + 0, 96)
+- Code(Expression(23, Sub)) at (prev + 0, 67) to (start + 0, 96)
     = (c18 - c8)
 - Code(Counter(9)) at (prev + 0, 96) to (start + 0, 97)
-- Code(Expression(24, Add)) at (prev + 1, 13) to (start + 0, 32)
-    = (((c18 - c8) - c9) + Zero)
-- Code(Expression(37, Sub)) at (prev + 4, 17) to (start + 0, 20)
+- Code(Expression(22, Sub)) at (prev + 1, 13) to (start + 0, 32)
+    = ((c18 - c8) - c9)
+- Code(Expression(33, Sub)) at (prev + 4, 17) to (start + 0, 20)
     = (((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11)
-- Code(Expression(39, Sub)) at (prev + 0, 23) to (start + 0, 66)
+- Code(Expression(35, Sub)) at (prev + 0, 23) to (start + 0, 66)
     = (((c0 + (c1 + c2)) - c3) - c16)
 - Code(Counter(10)) at (prev + 0, 66) to (start + 0, 67)
-- Code(Expression(38, Sub)) at (prev + 0, 68) to (start + 0, 97)
+- Code(Expression(34, Sub)) at (prev + 0, 68) to (start + 0, 97)
     = ((((c0 + (c1 + c2)) - c3) - c16) - c10)
 - Code(Counter(11)) at (prev + 0, 97) to (start + 0, 98)
-- Code(Expression(36, Add)) at (prev + 1, 13) to (start + 0, 32)
-    = ((((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11) + Zero)
-- Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20)
+- Code(Expression(33, Sub)) at (prev + 1, 13) to (start + 0, 32)
+    = (((((c0 + (c1 + c2)) - c3) - c16) - c10) - c11)
+- Code(Expression(40, 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(46, Sub)) at (prev + 1, 18) to (start + 0, 47)
+- Code(Expression(41, Sub)) at (prev + 1, 18) to (start + 0, 47)
     = (c17 - c12)
 - Code(Counter(13)) at (prev + 0, 47) to (start + 0, 48)
-- Code(Expression(44, Add)) at (prev + 1, 13) to (start + 0, 32)
-    = (((c17 - c12) - c13) + Zero)
-- Code(Expression(51, Sub)) at (prev + 1, 17) to (start + 0, 20)
+- Code(Expression(40, Sub)) at (prev + 1, 13) to (start + 0, 32)
+    = ((c17 - c12) - c13)
+- Code(Expression(45, Sub)) at (prev + 1, 17) to (start + 0, 20)
     = ((c19 - c14) - c15)
 - Code(Counter(19)) at (prev + 0, 23) to (start + 1, 54)
 - Code(Counter(14)) at (prev + 2, 17) to (start + 0, 18)
-- Code(Expression(52, Sub)) at (prev + 1, 18) to (start + 0, 47)
+- Code(Expression(46, Sub)) at (prev + 1, 18) to (start + 0, 47)
     = (c19 - c14)
 - Code(Counter(15)) at (prev + 1, 17) to (start + 0, 18)
-- Code(Expression(50, Add)) at (prev + 2, 13) to (start + 0, 32)
-    = (((c19 - c14) - c15) + Zero)
+- Code(Expression(45, Sub)) at (prev + 2, 13) to (start + 0, 32)
+    = ((c19 - c14) - c15)
 - Code(Counter(3)) at (prev + 3, 5) to (start + 0, 11)
-- Code(Expression(53, Add)) at (prev + 1, 1) to (start + 0, 2)
+- Code(Expression(47, Add)) at (prev + 1, 1) to (start + 0, 2)
     = ((c4 + ((c5 + ((c6 + c7) + (c8 + c9))) + ((c10 + c11) + ((c12 + c13) + (c14 + c15))))) + c3)
 
diff --git a/tests/coverage-map/status-quo/unused.cov-map b/tests/coverage-map/status-quo/unused.cov-map
index c8b8f195fbd..9383d1e90ac 100644
--- a/tests/coverage-map/status-quo/unused.cov-map
+++ b/tests/coverage-map/status-quo/unused.cov-map
@@ -47,45 +47,45 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 37, 1) to (start + 4, 2)
 
 Function name: unused::unused_func (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 13, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 13, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 19, 1) to (start + 1, 14)
+- Code(Zero) at (prev + 19, 1) to (start + 1, 14)
 - Code(Zero) at (prev + 1, 15) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 
 Function name: unused::unused_func2 (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 19, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 25, 1) to (start + 1, 14)
+- Code(Zero) at (prev + 25, 1) to (start + 1, 14)
 - Code(Zero) at (prev + 1, 15) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 
 Function name: unused::unused_func3 (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
-- Code(Counter(0)) at (prev + 31, 1) to (start + 1, 14)
+- Code(Zero) at (prev + 31, 1) to (start + 1, 14)
 - Code(Zero) at (prev + 1, 15) to (start + 2, 6)
 - Code(Zero) at (prev + 2, 6) to (start + 0, 7)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 
 Function name: unused::unused_template_func::<_> (unused)
-Raw bytes (34): 0x[01, 01, 00, 06, 01, 0b, 01, 01, 12, 00, 02, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02]
+Raw bytes (34): 0x[01, 01, 00, 06, 00, 0b, 01, 01, 12, 00, 02, 0b, 00, 11, 00, 01, 09, 00, 0f, 00, 00, 13, 00, 19, 00, 01, 09, 00, 0f, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 18)
+- Code(Zero) at (prev + 11, 1) to (start + 1, 18)
 - Code(Zero) at (prev + 2, 11) to (start + 0, 17)
 - Code(Zero) at (prev + 1, 9) to (start + 0, 15)
 - Code(Zero) at (prev + 0, 19) to (start + 0, 25)
diff --git a/tests/coverage-map/status-quo/yield.cov-map b/tests/coverage-map/status-quo/yield.cov-map
index 16caa2db343..c9c9709fa4f 100644
--- a/tests/coverage-map/status-quo/yield.cov-map
+++ b/tests/coverage-map/status-quo/yield.cov-map
@@ -1,54 +1,44 @@
 Function name: yield::main
-Raw bytes (118): 0x[01, 01, 11, 01, 00, 05, 09, 0d, 00, 0d, 11, 32, 15, 0d, 11, 11, 15, 2e, 00, 32, 15, 0d, 11, 2e, 00, 32, 15, 0d, 11, 19, 1d, 21, 00, 25, 29, 2d, 00, 10, 01, 07, 01, 01, 16, 03, 06, 0b, 00, 2e, 0d, 01, 27, 00, 29, 07, 01, 0e, 00, 34, 0b, 02, 0b, 00, 2e, 32, 01, 22, 00, 27, 2e, 00, 2c, 00, 2e, 1b, 01, 0e, 00, 34, 1f, 03, 09, 00, 16, 2b, 07, 0b, 00, 2e, 21, 01, 27, 00, 29, 37, 01, 0e, 00, 34, 3b, 02, 0b, 00, 2e, 2d, 01, 27, 00, 29, 3f, 01, 0e, 00, 34, 43, 02, 01, 00, 02]
+Raw bytes (106): 0x[01, 01, 0b, 05, 09, 0d, 11, 22, 15, 0d, 11, 11, 15, 22, 15, 0d, 11, 22, 15, 0d, 11, 19, 1d, 25, 29, 10, 01, 07, 01, 01, 16, 01, 06, 0b, 00, 2e, 0d, 01, 27, 00, 29, 03, 01, 0e, 00, 34, 0d, 02, 0b, 00, 2e, 22, 01, 22, 00, 27, 1e, 00, 2c, 00, 2e, 13, 01, 0e, 00, 34, 1e, 03, 09, 00, 16, 1e, 07, 0b, 00, 2e, 21, 01, 27, 00, 29, 27, 01, 0e, 00, 34, 21, 02, 0b, 00, 2e, 2d, 01, 27, 00, 29, 2b, 01, 0e, 00, 34, 2d, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
-Number of expressions: 17
-- expression 0 operands: lhs = Counter(0), rhs = Zero
-- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
-- expression 2 operands: lhs = Counter(3), rhs = Zero
+Number of expressions: 11
+- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
+- expression 1 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 2 operands: lhs = Expression(8, Sub), rhs = Counter(5)
 - expression 3 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 4 operands: lhs = Expression(12, Sub), rhs = Counter(5)
-- expression 5 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 6 operands: lhs = Counter(4), rhs = Counter(5)
-- expression 7 operands: lhs = Expression(11, Sub), rhs = Zero
-- expression 8 operands: lhs = Expression(12, Sub), rhs = Counter(5)
-- expression 9 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 10 operands: lhs = Expression(11, Sub), rhs = Zero
-- expression 11 operands: lhs = Expression(12, Sub), rhs = Counter(5)
-- expression 12 operands: lhs = Counter(3), rhs = Counter(4)
-- expression 13 operands: lhs = Counter(6), rhs = Counter(7)
-- expression 14 operands: lhs = Counter(8), rhs = Zero
-- expression 15 operands: lhs = Counter(9), rhs = Counter(10)
-- expression 16 operands: lhs = Counter(11), rhs = Zero
+- expression 4 operands: lhs = Counter(4), rhs = Counter(5)
+- expression 5 operands: lhs = Expression(8, Sub), rhs = Counter(5)
+- expression 6 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(5)
+- expression 8 operands: lhs = Counter(3), rhs = Counter(4)
+- expression 9 operands: lhs = Counter(6), rhs = Counter(7)
+- expression 10 operands: lhs = Counter(9), rhs = Counter(10)
 Number of file 0 mappings: 16
 - Code(Counter(0)) at (prev + 7, 1) to (start + 1, 22)
-- Code(Expression(0, Add)) at (prev + 6, 11) to (start + 0, 46)
-    = (c0 + Zero)
+- Code(Counter(0)) at (prev + 6, 11) to (start + 0, 46)
 - Code(Counter(3)) at (prev + 1, 39) to (start + 0, 41)
-- Code(Expression(1, Add)) at (prev + 1, 14) to (start + 0, 52)
+- Code(Expression(0, Add)) at (prev + 1, 14) to (start + 0, 52)
     = (c1 + c2)
-- Code(Expression(2, Add)) at (prev + 2, 11) to (start + 0, 46)
-    = (c3 + Zero)
-- Code(Expression(12, Sub)) at (prev + 1, 34) to (start + 0, 39)
+- Code(Counter(3)) at (prev + 2, 11) to (start + 0, 46)
+- Code(Expression(8, Sub)) at (prev + 1, 34) to (start + 0, 39)
     = (c3 - c4)
-- Code(Expression(11, Sub)) at (prev + 0, 44) to (start + 0, 46)
+- Code(Expression(7, Sub)) at (prev + 0, 44) to (start + 0, 46)
     = ((c3 - c4) - c5)
-- Code(Expression(6, Add)) at (prev + 1, 14) to (start + 0, 52)
+- Code(Expression(4, Add)) at (prev + 1, 14) to (start + 0, 52)
     = (c4 + c5)
-- Code(Expression(7, Add)) at (prev + 3, 9) to (start + 0, 22)
-    = (((c3 - c4) - c5) + Zero)
-- Code(Expression(10, Add)) at (prev + 7, 11) to (start + 0, 46)
-    = (((c3 - c4) - c5) + Zero)
+- Code(Expression(7, Sub)) at (prev + 3, 9) to (start + 0, 22)
+    = ((c3 - c4) - c5)
+- Code(Expression(7, Sub)) at (prev + 7, 11) to (start + 0, 46)
+    = ((c3 - c4) - c5)
 - Code(Counter(8)) at (prev + 1, 39) to (start + 0, 41)
-- Code(Expression(13, Add)) at (prev + 1, 14) to (start + 0, 52)
+- Code(Expression(9, Add)) at (prev + 1, 14) to (start + 0, 52)
     = (c6 + c7)
-- Code(Expression(14, Add)) at (prev + 2, 11) to (start + 0, 46)
-    = (c8 + Zero)
+- Code(Counter(8)) at (prev + 2, 11) to (start + 0, 46)
 - Code(Counter(11)) at (prev + 1, 39) to (start + 0, 41)
-- Code(Expression(15, Add)) at (prev + 1, 14) to (start + 0, 52)
+- Code(Expression(10, Add)) at (prev + 1, 14) to (start + 0, 52)
     = (c9 + c10)
-- Code(Expression(16, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = (c11 + Zero)
+- Code(Counter(11)) at (prev + 2, 1) to (start + 0, 2)
 
 Function name: yield::main::{closure#0}
 Raw bytes (14): 0x[01, 01, 00, 02, 01, 08, 1c, 01, 10, 05, 02, 10, 01, 06]
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
index 6779003b693..4a816e024c5 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
@@ -7,11 +7,12 @@
       let mut _2: std::pin::Pin<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>;
       let mut _3: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
       let mut _4: {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+     let mut _5: bool;
++     let mut _6: bool;
       scope 1 {
           debug _r => _1;
       }
 +     scope 2 (inlined g) {
++         let mut _5: {generator@$DIR/inline_generator.rs:16:5: 16:8};
 +     }
 +     scope 3 (inlined Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new) {
 +         debug pointer => _3;
@@ -22,10 +23,10 @@
 +         }
 +     }
 +     scope 6 (inlined g::{closure#0}) {
-+         debug a => _5;
-+         let mut _6: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+         let mut _7: u32;
-+         let mut _8: i32;
++         debug a => _6;
++         let mut _7: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
++         let mut _8: u32;
++         let mut _9: i32;
 +     }
   
       bb0: {
@@ -34,21 +35,24 @@
           StorageLive(_3);
           StorageLive(_4);
 -         _4 = g() -> [return: bb1, unwind unreachable];
-+         _4 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
++         StorageLive(_5);
++         _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
++         _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         StorageDead(_5);
 +         _3 = &mut _4;
 +         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
 +         StorageDead(_3);
-+         StorageLive(_5);
-+         _5 = const false;
-+         _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         _7 = discriminant((*_6));
-+         switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
++         StorageLive(_6);
++         _6 = const false;
++         _7 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         _8 = discriminant((*_7));
++         switchInt(move _8) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
       }
   
       bb1: {
 -         _3 = &mut _4;
 -         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind unreachable];
-+         StorageDead(_5);
++         StorageDead(_6);
 +         StorageDead(_2);
 +         drop(_4) -> [return: bb2, unwind unreachable];
       }
@@ -65,8 +69,8 @@
       bb3: {
 -         StorageDead(_2);
 -         drop(_4) -> [return: bb4, unwind unreachable];
-+         StorageLive(_8);
-+         switchInt(_5) -> [0: bb4, otherwise: bb5];
++         StorageLive(_9);
++         switchInt(_6) -> [0: bb4, otherwise: bb5];
       }
   
       bb4: {
@@ -74,18 +78,18 @@
 -         _0 = const ();
 -         StorageDead(_1);
 -         return;
-+         _8 = const 13_i32;
++         _9 = const 13_i32;
 +         goto -> bb6;
 +     }
 + 
 +     bb5: {
-+         _8 = const 7_i32;
++         _9 = const 7_i32;
 +         goto -> bb6;
 +     }
 + 
 +     bb6: {
-+         _1 = GeneratorState::<i32, bool>::Yielded(move _8);
-+         discriminant((*_6)) = 3;
++         _1 = GeneratorState::<i32, bool>::Yielded(move _9);
++         discriminant((*_7)) = 3;
 +         goto -> bb1;
 +     }
 + 
@@ -94,10 +98,10 @@
 +     }
 + 
 +     bb8: {
-+         StorageLive(_8);
-+         StorageDead(_8);
-+         _1 = GeneratorState::<i32, bool>::Complete(_5);
-+         discriminant((*_6)) = 1;
++         StorageLive(_9);
++         StorageDead(_9);
++         _1 = GeneratorState::<i32, bool>::Complete(_6);
++         discriminant((*_7)) = 1;
 +         goto -> bb1;
 +     }
 + 
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
index 31744be99ec..2b910cd6543 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
@@ -7,11 +7,12 @@
       let mut _2: std::pin::Pin<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>;
       let mut _3: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
       let mut _4: {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+     let mut _5: bool;
++     let mut _6: bool;
       scope 1 {
           debug _r => _1;
       }
 +     scope 2 (inlined g) {
++         let mut _5: {generator@$DIR/inline_generator.rs:16:5: 16:8};
 +     }
 +     scope 3 (inlined Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new) {
 +         debug pointer => _3;
@@ -22,10 +23,10 @@
 +         }
 +     }
 +     scope 6 (inlined g::{closure#0}) {
-+         debug a => _5;
-+         let mut _6: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+         let mut _7: u32;
-+         let mut _8: i32;
++         debug a => _6;
++         let mut _7: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
++         let mut _8: u32;
++         let mut _9: i32;
 +     }
   
       bb0: {
@@ -37,7 +38,10 @@
 -     }
 - 
 -     bb1: {
-+         _4 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
++         StorageLive(_5);
++         _5 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
++         _4 = move (_5 as subtype {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         StorageDead(_5);
           _3 = &mut _4;
 -         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind: bb5];
 -     }
@@ -46,16 +50,16 @@
 +         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
           StorageDead(_3);
 -         _1 = <{generator@$DIR/inline_generator.rs:16:5: 16:8} as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb5];
-+         StorageLive(_5);
-+         _5 = const false;
-+         _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         _7 = discriminant((*_6));
-+         switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
++         StorageLive(_6);
++         _6 = const false;
++         _7 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         _8 = discriminant((*_7));
++         switchInt(move _8) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
       }
   
 -     bb3: {
 +     bb1: {
-+         StorageDead(_5);
++         StorageDead(_6);
           StorageDead(_2);
 -         drop(_4) -> [return: bb4, unwind: bb6];
 +         drop(_4) -> [return: bb2, unwind: bb4];
@@ -81,23 +85,23 @@
 +     }
 + 
 +     bb5: {
-+         StorageLive(_8);
-+         switchInt(_5) -> [0: bb6, otherwise: bb7];
++         StorageLive(_9);
++         switchInt(_6) -> [0: bb6, otherwise: bb7];
 +     }
 + 
 +     bb6: {
-+         _8 = const 13_i32;
++         _9 = const 13_i32;
 +         goto -> bb8;
 +     }
 + 
 +     bb7: {
-+         _8 = const 7_i32;
++         _9 = const 7_i32;
 +         goto -> bb8;
 +     }
 + 
 +     bb8: {
-+         _1 = GeneratorState::<i32, bool>::Yielded(move _8);
-+         discriminant((*_6)) = 3;
++         _1 = GeneratorState::<i32, bool>::Yielded(move _9);
++         discriminant((*_7)) = 3;
 +         goto -> bb1;
 +     }
 + 
@@ -106,10 +110,10 @@
 +     }
 + 
 +     bb10: {
-+         StorageLive(_8);
-+         StorageDead(_8);
-+         _1 = GeneratorState::<i32, bool>::Complete(_5);
-+         discriminant((*_6)) = 1;
++         StorageLive(_9);
++         StorageDead(_9);
++         _1 = GeneratorState::<i32, bool>::Complete(_6);
++         discriminant((*_7)) = 1;
 +         goto -> bb1;
 +     }
 + 
diff --git a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
index afcfde09c02..28a7ffda371 100644
--- a/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/tests/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
@@ -5,7 +5,7 @@
       let mut _0: bool;
   
       bb0: {
-+         Coverage::Counter(0) for /the/src/instrument_coverage.rs:20:1 - 22:2;
++         Coverage::Counter(0) for [/the/src/instrument_coverage.rs:20:1 - 22:2];
           _0 = const true;
           return;
       }
diff --git a/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
index e17c6ddc56e..9a8caa26307 100644
--- a/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
@@ -8,12 +8,12 @@
       let mut _3: !;
   
       bb0: {
-+         Coverage::Counter(0) for /the/src/instrument_coverage.rs:11:1 - 11:11;
++         Coverage::Counter(0) for [/the/src/instrument_coverage.rs:11:1 - 11:11];
           goto -> bb1;
       }
   
       bb1: {
-+         Coverage::Expression(0) = Counter(0) + Counter(1) for /the/src/instrument_coverage.rs:12:5 - 13:17;
++         Coverage::Expression(0) = Counter(0) + Counter(1) for [/the/src/instrument_coverage.rs:12:5 - 13:17];
           falseUnwind -> [real: bb2, unwind: bb6];
       }
   
@@ -27,15 +27,14 @@
       }
   
       bb4: {
-+         Coverage::Expression(2) = Expression(1) + Zero for /the/src/instrument_coverage.rs:17:1 - 17:2;
-+         Coverage::Expression(1) = Expression(0) - Counter(1) for /the/src/instrument_coverage.rs:14:13 - 14:18;
++         Coverage::Expression(1) = Expression(0) - Counter(1) for [/the/src/instrument_coverage.rs:14:13 - 14:18, /the/src/instrument_coverage.rs:17:1 - 17:2];
           _0 = const ();
           StorageDead(_2);
           return;
       }
   
       bb5: {
-+         Coverage::Counter(1) for /the/src/instrument_coverage.rs:15:10 - 15:11;
++         Coverage::Counter(1) for [/the/src/instrument_coverage.rs:15:10 - 15:11];
           _1 = const ();
           StorageDead(_2);
           goto -> bb1;
diff --git a/tests/ui/async-await/issue-108572.fixed b/tests/ui/async-await/issue-108572.fixed
new file mode 100644
index 00000000000..8f0133d97b5
--- /dev/null
+++ b/tests/ui/async-await/issue-108572.fixed
@@ -0,0 +1,16 @@
+// edition: 2021
+// run-rustfix
+#![allow(unused_must_use, dead_code)]
+
+use std::future::Future;
+fn foo() -> impl Future<Output=()> {
+    async { }
+}
+
+fn bar(cx: &mut std::task::Context<'_>) {
+    let fut = foo();
+    let mut pinned = std::pin::pin!(fut);
+    pinned.as_mut().poll(cx);
+    //~^ ERROR no method named `poll` found for opaque type `impl Future<Output = ()>` in the current scope [E0599]
+}
+fn main() {}
diff --git a/tests/ui/async-await/issue-108572.rs b/tests/ui/async-await/issue-108572.rs
index efcb8b8ebab..3596580763c 100644
--- a/tests/ui/async-await/issue-108572.rs
+++ b/tests/ui/async-await/issue-108572.rs
@@ -1,12 +1,15 @@
 // edition: 2021
+// run-rustfix
+#![allow(unused_must_use, dead_code)]
 
 use std::future::Future;
 fn foo() -> impl Future<Output=()> {
     async { }
 }
 
-fn main() {
+fn bar(cx: &mut std::task::Context<'_>) {
     let fut = foo();
-    fut.poll();
+    fut.poll(cx);
     //~^ ERROR no method named `poll` found for opaque type `impl Future<Output = ()>` in the current scope [E0599]
 }
+fn main() {}
diff --git a/tests/ui/async-await/issue-108572.stderr b/tests/ui/async-await/issue-108572.stderr
index 0dbcf4d660a..588669092b0 100644
--- a/tests/ui/async-await/issue-108572.stderr
+++ b/tests/ui/async-await/issue-108572.stderr
@@ -1,11 +1,16 @@
 error[E0599]: no method named `poll` found for opaque type `impl Future<Output = ()>` in the current scope
-  --> $DIR/issue-108572.rs:10:9
+  --> $DIR/issue-108572.rs:12:9
    |
-LL |     fut.poll();
+LL |     fut.poll(cx);
    |         ^^^^ method not found in `impl Future<Output = ()>`
    |
    = help: method `poll` found on `Pin<&mut impl Future<Output = ()>>`, see documentation for `std::pin::Pin`
    = help: self type must be pinned to call `Future::poll`, see https://rust-lang.github.io/async-book/04_pinning/01_chapter.html#pinning-in-practice
+help: consider pinning the expression
+   |
+LL ~     let mut pinned = std::pin::pin!(fut);
+LL ~     pinned.as_mut().poll(cx);
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/async-await/pin-needed-to-poll.stderr b/tests/ui/async-await/pin-needed-to-poll.stderr
index b1f4a73aafe..964709daeda 100644
--- a/tests/ui/async-await/pin-needed-to-poll.stderr
+++ b/tests/ui/async-await/pin-needed-to-poll.stderr
@@ -6,14 +6,12 @@ LL | struct Sleep;
 ...
 LL |         self.sleep.poll(cx)
    |                    ^^^^ method not found in `Sleep`
-  --> $SRC_DIR/core/src/future/future.rs:LL:COL
    |
-   = note: the method is available for `Pin<&mut Sleep>` here
+help: consider pinning the expression
    |
-help: consider wrapping the receiver expression with the appropriate type
+LL ~         let mut pinned = std::pin::pin!(self.sleep);
+LL ~         pinned.as_mut().poll(cx)
    |
-LL |         Pin::new(&mut self.sleep).poll(cx)
-   |         +++++++++++++           +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr
index 51ef354e3ed..61d055e8084 100644
--- a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr
+++ b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `A<_>: Bar<_>` is not satisfied
 LL |     let _ = A;
    |             ^ the trait `Bar<_>` is not implemented for `A<_>`
    |
-   = help: the trait `Bar<N>` is implemented for `A<7>`
+   = help: the trait `Bar<_>` is implemented for `A<7>`
 note: required by a bound in `A`
   --> $DIR/unused-substs-1.rs:9:11
    |
diff --git a/tests/ui/generic-const-items/unsatisfied-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-bounds.stderr
index 2cee53431a4..14894cef770 100644
--- a/tests/ui/generic-const-items/unsatisfied-bounds.stderr
+++ b/tests/ui/generic-const-items/unsatisfied-bounds.stderr
@@ -17,6 +17,7 @@ LL |     let () = K::<()>;
    |                  ^^ the trait `From<()>` is not implemented for `Infallible`
    |
    = help: the trait `From<!>` is implemented for `Infallible`
+   = help: for that trait implementation, expected `!`, found `()`
 note: required by a bound in `K`
   --> $DIR/unsatisfied-bounds.rs:12:17
    |
@@ -48,6 +49,7 @@ LL |     let _ = <() as Trait<&'static str>>::B::<()>;
    |                                              ^^ the trait `From<()>` is not implemented for `Infallible`
    |
    = help: the trait `From<!>` is implemented for `Infallible`
+   = help: for that trait implementation, expected `!`, found `()`
 note: required by a bound in `Trait::B`
   --> $DIR/unsatisfied-bounds.rs:21:21
    |
diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr
index d872291c870..8d969e8e0f3 100644
--- a/tests/ui/impl-trait/issues/issue-62742.stderr
+++ b/tests/ui/impl-trait/issues/issue-62742.stderr
@@ -4,7 +4,7 @@ error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied
 LL |     WrongImpl::foo(0i32);
    |     ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
    |
-   = help: the trait `Raw<[T]>` is implemented for `RawImpl<T>`
+   = help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
 note: required by a bound in `SafeImpl`
   --> $DIR/issue-62742.rs:26:35
    |
@@ -42,7 +42,8 @@ error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied
 LL |     WrongImpl::<()>::foo(0i32);
    |     ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>`
    |
-   = help: the trait `Raw<[T]>` is implemented for `RawImpl<T>`
+   = help: the trait `Raw<[()]>` is implemented for `RawImpl<()>`
+   = help: for that trait implementation, expected `[()]`, found `()`
 note: required by a bound in `SafeImpl`
   --> $DIR/issue-62742.rs:26:35
    |
diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr
index e020d029875..2cb212a0139 100644
--- a/tests/ui/indexing/index-help.stderr
+++ b/tests/ui/indexing/index-help.stderr
@@ -5,7 +5,8 @@ LL |     x[0i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `i32`
    = note: required for `Vec<{integer}>` to implement `Index<i32>`
 
 error: aborting due to previous error
diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr
index 7a741cfc7de..6ea6bb600e9 100644
--- a/tests/ui/indexing/indexing-requires-a-uint.stderr
+++ b/tests/ui/indexing/indexing-requires-a-uint.stderr
@@ -5,7 +5,8 @@ LL |     [0][0u8];
    |         ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `u8`
    = note: required for `[{integer}]` to implement `Index<u8>`
 
 error[E0308]: mismatched types
diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/integral-indexing.stderr
index bbbb2a86a22..97e658617cf 100644
--- a/tests/ui/integral-indexing.stderr
+++ b/tests/ui/integral-indexing.stderr
@@ -5,7 +5,8 @@ LL |     v[3u8];
    |       ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[isize]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `u8`
    = note: required for `Vec<isize>` to implement `Index<u8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i8`
@@ -15,7 +16,8 @@ LL |     v[3i8];
    |       ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[isize]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `i8`
    = note: required for `Vec<isize>` to implement `Index<i8>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `u32`
@@ -25,7 +27,8 @@ LL |     v[3u32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[isize]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `u32`
    = note: required for `Vec<isize>` to implement `Index<u32>`
 
 error[E0277]: the type `[isize]` cannot be indexed by `i32`
@@ -35,7 +38,8 @@ LL |     v[3i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[isize]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `i32`
    = note: required for `Vec<isize>` to implement `Index<i32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u8`
@@ -45,7 +49,8 @@ LL |     s.as_bytes()[3u8];
    |                  ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[u8]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `u8`
    = note: required for `[u8]` to implement `Index<u8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i8`
@@ -55,7 +60,8 @@ LL |     s.as_bytes()[3i8];
    |                  ^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[u8]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `i8`
    = note: required for `[u8]` to implement `Index<i8>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `u32`
@@ -65,7 +71,8 @@ LL |     s.as_bytes()[3u32];
    |                  ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[u8]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `u32`
    = note: required for `[u8]` to implement `Index<u32>`
 
 error[E0277]: the type `[u8]` cannot be indexed by `i32`
@@ -75,7 +82,8 @@ LL |     s.as_bytes()[3i32];
    |                  ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[u8]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `i32`
    = note: required for `[u8]` to implement `Index<i32>`
 
 error: aborting due to 8 previous errors
diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/issues/issue-34334.stderr
index 9d2c315e4db..753942dd1d1 100644
--- a/tests/ui/issues/issue-34334.stderr
+++ b/tests/ui/issues/issue-34334.stderr
@@ -19,7 +19,8 @@ LL |     let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece
    |                                                                                       ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
    |
    = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
-   = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+   = help: the trait `FromIterator<(u32, _, _)>` is implemented for `Vec<(u32, _, _)>`
+   = help: for that trait implementation, expected `(u32, _, _)`, found `()`
 note: the method call chain might not have had the expected associated types
   --> $DIR/issue-34334.rs:5:43
    |
diff --git a/tests/ui/issues/issue-45801.stderr b/tests/ui/issues/issue-45801.stderr
index 8967f49df02..e651e2a68d1 100644
--- a/tests/ui/issues/issue-45801.stderr
+++ b/tests/ui/issues/issue-45801.stderr
@@ -5,6 +5,7 @@ LL |     req.get_ref::<Params>();
    |         ^^^^^^^ the trait `Plugin<i32>` is not implemented for `Params`
    |
    = help: the trait `Plugin<Foo>` is implemented for `Params`
+   = help: for that trait implementation, expected `Foo`, found `i32`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr
index 22b1da64cb3..128288e28f5 100644
--- a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr
+++ b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr
@@ -5,7 +5,8 @@ LL |     let x2: Vec<f64> = x1.into_iter().collect();
    |                                       ^^^^^^^ value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
    |
    = help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
-   = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+   = help: the trait `FromIterator<f64>` is implemented for `Vec<f64>`
+   = help: for that trait implementation, expected `f64`, found `&f64`
 note: the method call chain might not have had the expected associated types
   --> $DIR/issue-66923-show-error-for-correct-call.rs:8:27
    |
@@ -25,7 +26,8 @@ LL |     let x3 = x1.into_iter().collect::<Vec<f64>>();
    |                             required by a bound introduced by this call
    |
    = help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
-   = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+   = help: the trait `FromIterator<f64>` is implemented for `Vec<f64>`
+   = help: for that trait implementation, expected `f64`, found `&f64`
 note: the method call chain might not have had the expected associated types
   --> $DIR/issue-66923-show-error-for-correct-call.rs:12:17
    |
diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr
index b355da5cb76..2601c9c0d69 100644
--- a/tests/ui/iterators/invalid-iterator-chain.stderr
+++ b/tests/ui/iterators/invalid-iterator-chain.stderr
@@ -5,7 +5,8 @@ LL |     i.collect()
    |       ^^^^^^^ value of type `Vec<X>` cannot be built from `std::iter::Iterator<Item=&X>`
    |
    = help: the trait `FromIterator<&X>` is not implemented for `Vec<X>`
-   = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+   = help: the trait `FromIterator<X>` is implemented for `Vec<X>`
+   = help: for that trait implementation, expected `X`, found `&X`
 note: the method call chain might not have had the expected associated types
   --> $DIR/invalid-iterator-chain.rs:4:26
    |
@@ -159,7 +160,8 @@ LL |     let g: Vec<i32> = f.collect();
    |                         ^^^^^^^ value of type `Vec<i32>` cannot be built from `std::iter::Iterator<Item=()>`
    |
    = help: the trait `FromIterator<()>` is not implemented for `Vec<i32>`
-   = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+   = help: the trait `FromIterator<i32>` is implemented for `Vec<i32>`
+   = help: for that trait implementation, expected `i32`, found `()`
 note: the method call chain might not have had the expected associated types
   --> $DIR/invalid-iterator-chain.rs:44:15
    |
diff --git a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
index 54c16230fe6..cb378630589 100644
--- a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
+++ b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
@@ -5,6 +5,7 @@ LL |     <E as From<_>>::from(never);
    |      ^ the trait `From<()>` is not implemented for `E`
    |
    = help: the trait `From<!>` is implemented for `E`
+   = help: for that trait implementation, expected `!`, found `()`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr
index a0fad0acd0b..36d80f3e681 100644
--- a/tests/ui/on-unimplemented/impl-substs.stderr
+++ b/tests/ui/on-unimplemented/impl-substs.stderr
@@ -7,7 +7,8 @@ LL |     Foo::<usize>::foo((1i32, 1i32, 1i32));
    |     required by a bound introduced by this call
    |
    = help: the trait `Foo<usize>` is not implemented for `(i32, i32, i32)`
-   = help: the trait `Foo<A>` is implemented for `(A, B, C)`
+   = help: the trait `Foo<i32>` is implemented for `(i32, i32, i32)`
+   = help: for that trait implementation, expected `i32`, found `usize`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr
index 2253c5992a6..3a0b8353fa5 100644
--- a/tests/ui/on-unimplemented/on-impl.stderr
+++ b/tests/ui/on-unimplemented/on-impl.stderr
@@ -8,6 +8,7 @@ LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
    = help: the trait `Index<usize>` is implemented for `[i32]`
+   = help: for that trait implementation, expected `usize`, found `u32`
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:5
@@ -17,6 +18,7 @@ LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
    = help: the trait `Index<usize>` is implemented for `[i32]`
+   = help: for that trait implementation, expected `usize`, found `u32`
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:5
@@ -26,6 +28,7 @@ LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
    = help: the trait `Index<usize>` is implemented for `[i32]`
+   = help: for that trait implementation, expected `usize`, found `u32`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr
index b9bca211f43..5e0117be529 100644
--- a/tests/ui/on-unimplemented/slice-index.stderr
+++ b/tests/ui/on-unimplemented/slice-index.stderr
@@ -5,7 +5,8 @@ LL |     x[1i32];
    |       ^^^^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[i32]>` is not implemented for `i32`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[i32]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `i32`
    = note: required for `[i32]` to implement `Index<i32>`
 
 error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>`
diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr
index 4457b7893d5..7f182a85787 100644
--- a/tests/ui/or-patterns/missing-bindings.stderr
+++ b/tests/ui/or-patterns/missing-bindings.stderr
@@ -103,22 +103,6 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 |
    |                 variable not in all patterns
 
-error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:33
-   |
-LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
-   |                        -        ^^^^ pattern doesn't bind `c`
-   |                        |
-   |                        variable not in all patterns
-
-error[E0408]: variable `d` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:33
-   |
-LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
-   |                            -    ^^^^ pattern doesn't bind `d`
-   |                            |
-   |                            variable not in all patterns
-
 error[E0408]: variable `e` is not bound in all patterns
   --> $DIR/missing-bindings.rs:45:10
    |
@@ -143,6 +127,22 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 |
    |                 variable not in all patterns
 
+error[E0408]: variable `c` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:45:33
+   |
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |                        -        ^^^^ pattern doesn't bind `c`
+   |                        |
+   |                        variable not in all patterns
+
+error[E0408]: variable `d` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:45:33
+   |
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |                            -    ^^^^ pattern doesn't bind `d`
+   |                            |
+   |                            variable not in all patterns
+
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:61:29
    |
@@ -151,14 +151,6 @@ LL |                     Ok(a) | Err(_),
    |                        |
    |                        variable not in all patterns
 
-error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:69:21
-   |
-LL |                     A(_, a) |
-   |                          - variable not in all patterns
-LL |                     B(b),
-   |                     ^^^^ pattern doesn't bind `a`
-
 error[E0408]: variable `b` is not bound in all patterns
   --> $DIR/missing-bindings.rs:68:21
    |
@@ -168,6 +160,14 @@ LL |                     B(b),
    |                       - variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:69:21
+   |
+LL |                     A(_, a) |
+   |                          - variable not in all patterns
+LL |                     B(b),
+   |                     ^^^^ pattern doesn't bind `a`
+
+error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:72:17
    |
 LL |                     A(_, a) |
@@ -185,6 +185,24 @@ LL |                     B(b),
 LL |                 B(_)
    |                 ^^^^ pattern doesn't bind `b`
 
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:57:13
+   |
+LL | /             V1(
+LL | |
+LL | |
+LL | |                 A(
+...  |
+LL | |                 B(Ok(a) | Err(a))
+LL | |             ) |
+   | |_____________^ pattern doesn't bind `b`
+...
+LL |                       B(b),
+   |                         - variable not in all patterns
+...
+LL |               V3(c),
+   |               ^^^^^ pattern doesn't bind `b`
+
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/missing-bindings.rs:57:13
    |
@@ -219,24 +237,6 @@ LL |                     A(_, a) |
 LL |             V3(c),
    |             ^^^^^ pattern doesn't bind `a`
 
-error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:57:13
-   |
-LL | /             V1(
-LL | |
-LL | |
-LL | |                 A(
-...  |
-LL | |                 B(Ok(a) | Err(a))
-LL | |             ) |
-   | |_____________^ pattern doesn't bind `b`
-...
-LL |                       B(b),
-   |                         - variable not in all patterns
-...
-LL |               V3(c),
-   |               ^^^^^ pattern doesn't bind `b`
-
 error: aborting due to 26 previous errors
 
 For more information about this error, try `rustc --explain E0408`.
diff --git a/tests/ui/resolve/resolve-inconsistent-names.stderr b/tests/ui/resolve/resolve-inconsistent-names.stderr
index 42b7281d7b0..d6240fb8f87 100644
--- a/tests/ui/resolve/resolve-inconsistent-names.stderr
+++ b/tests/ui/resolve/resolve-inconsistent-names.stderr
@@ -1,11 +1,3 @@
-error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/resolve-inconsistent-names.rs:13:12
-   |
-LL |        a | b => {}
-   |        -   ^ pattern doesn't bind `a`
-   |        |
-   |        variable not in all patterns
-
 error[E0408]: variable `b` is not bound in all patterns
   --> $DIR/resolve-inconsistent-names.rs:13:8
    |
@@ -14,6 +6,14 @@ LL |        a | b => {}
    |        |
    |        pattern doesn't bind `b`
 
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/resolve-inconsistent-names.rs:13:12
+   |
+LL |        a | b => {}
+   |        -   ^ pattern doesn't bind `a`
+   |        |
+   |        variable not in all patterns
+
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/resolve-inconsistent-names.rs:19:9
    |
@@ -54,6 +54,19 @@ LL |         (A, B) | (ref B, c) | (c, A) => ()
    |             |
    |             first binding
 
+error[E0408]: variable `Const2` is not bound in all patterns
+  --> $DIR/resolve-inconsistent-names.rs:31:9
+   |
+LL |         (CONST1, _) | (_, Const2) => ()
+   |         ^^^^^^^^^^^       ------ variable not in all patterns
+   |         |
+   |         pattern doesn't bind `Const2`
+   |
+help: if you meant to match on constant `m::Const2`, use the full path in the pattern
+   |
+LL |         (CONST1, _) | (_, m::Const2) => ()
+   |                           ~~~~~~~~~
+
 error[E0408]: variable `CONST1` is not bound in all patterns
   --> $DIR/resolve-inconsistent-names.rs:31:23
    |
@@ -68,19 +81,6 @@ note: you might have meant to match on constant `m::CONST1`, which exists but is
 LL |     const CONST1: usize = 10;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible
 
-error[E0408]: variable `Const2` is not bound in all patterns
-  --> $DIR/resolve-inconsistent-names.rs:31:9
-   |
-LL |         (CONST1, _) | (_, Const2) => ()
-   |         ^^^^^^^^^^^       ------ variable not in all patterns
-   |         |
-   |         pattern doesn't bind `Const2`
-   |
-help: if you meant to match on constant `m::Const2`, use the full path in the pattern
-   |
-LL |         (CONST1, _) | (_, m::Const2) => ()
-   |                           ~~~~~~~~~
-
 error[E0308]: mismatched types
   --> $DIR/resolve-inconsistent-names.rs:19:19
    |
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.rs
new file mode 100644
index 00000000000..1e22ddcea8d
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.rs
@@ -0,0 +1,28 @@
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait MyTrait {
+    fn do_something(&self);
+}
+
+trait OtherTrait {
+    fn do_something_else() where Self: ~const MyTrait;
+    //~^ ERROR `~const` is not allowed here
+}
+
+struct MyStruct<T>(T);
+
+impl const MyTrait for u32 {
+    fn do_something(&self) {}
+}
+
+impl<T> MyStruct<T> {
+    pub fn foo(&self) where T: ~const MyTrait {
+        //~^ ERROR `~const` is not allowed here
+        self.0.do_something();
+    }
+}
+
+fn main() {
+    MyStruct(0u32).foo();
+}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.stderr
new file mode 100644
index 00000000000..9210f642706
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const-bound-on-not-const-associated-fn.stderr
@@ -0,0 +1,26 @@
+error: `~const` is not allowed here
+  --> $DIR/const-bound-on-not-const-associated-fn.rs:9:40
+   |
+LL |     fn do_something_else() where Self: ~const MyTrait;
+   |                                        ^^^^^^^^^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/const-bound-on-not-const-associated-fn.rs:9:8
+   |
+LL |     fn do_something_else() where Self: ~const MyTrait;
+   |        ^^^^^^^^^^^^^^^^^
+
+error: `~const` is not allowed here
+  --> $DIR/const-bound-on-not-const-associated-fn.rs:20:32
+   |
+LL |     pub fn foo(&self) where T: ~const MyTrait {
+   |                                ^^^^^^^^^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/const-bound-on-not-const-associated-fn.rs:20:12
+   |
+LL |     pub fn foo(&self) where T: ~const MyTrait {
+   |            ^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs
index 89d74cecfdb..4b720b534a4 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.rs
@@ -7,7 +7,8 @@ struct Foo<const N: usize>;
 
 impl<const N: usize> Foo<N> {
     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
-        //~^ ERROR mismatched types
+        //~^ ERROR `~const` is not allowed here
+        //~| ERROR mismatched types
         Foo
     }
 }
@@ -30,7 +31,7 @@ fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
 }
 
 fn main() {
-   let foo = Foo::<0>;
-   let foo = bar::<(), _>(foo);
-   let _foo = bar::<(), _>(foo);
+    let foo = Foo::<0>;
+    let foo = bar::<(), _>(foo);
+    let _foo = bar::<(), _>(foo);
 }
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
index ec5d21d33c6..be7a83dc184 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-and-const-params.stderr
@@ -1,17 +1,29 @@
 error: `~const` is not allowed here
-  --> $DIR/tilde-const-and-const-params.rs:26:11
+  --> $DIR/tilde-const-and-const-params.rs:9:15
+   |
+LL |     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
+   |               ^^^^^^^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/tilde-const-and-const-params.rs:9:8
+   |
+LL |     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
+   |        ^^^
+
+error: `~const` is not allowed here
+  --> $DIR/tilde-const-and-const-params.rs:27:11
    |
 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
    |           ^^^^^^^^^^^^
    |
 note: this function is not `const`, so it cannot have `~const` trait bounds
-  --> $DIR/tilde-const-and-const-params.rs:26:4
+  --> $DIR/tilde-const-and-const-params.rs:27:4
    |
 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
    |    ^^^
 
 error[E0308]: mismatched types
-  --> $DIR/tilde-const-and-const-params.rs:26:61
+  --> $DIR/tilde-const-and-const-params.rs:27:61
    |
 LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
    |                                                             ^^^^^^^^^ expected `false`, found `true`
@@ -28,6 +40,6 @@ LL |     fn add<A: ~const Add42>(self) -> Foo<{ A::add(N) }> {
    = note: expected constant `false`
               found constant `true`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs
index 85ca5fc9048..11f353f3f8a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.rs
@@ -6,7 +6,9 @@ trait Bar {}
 trait Foo {
     fn a();
     fn b() where Self: ~const Bar;
+    //~^ ERROR `~const` is not allowed here
     fn c<T: ~const Bar>();
+    //~^ ERROR `~const` is not allowed here
 }
 
 fn test1<T: Foo>() {
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
index 255878e1775..3d6fedbabbf 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr
@@ -1,5 +1,29 @@
+error: `~const` is not allowed here
+  --> $DIR/trait-where-clause.rs:8:24
+   |
+LL |     fn b() where Self: ~const Bar;
+   |                        ^^^^^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/trait-where-clause.rs:8:8
+   |
+LL |     fn b() where Self: ~const Bar;
+   |        ^
+
+error: `~const` is not allowed here
+  --> $DIR/trait-where-clause.rs:10:13
+   |
+LL |     fn c<T: ~const Bar>();
+   |             ^^^^^^^^^^
+   |
+note: this function is not `const`, so it cannot have `~const` trait bounds
+  --> $DIR/trait-where-clause.rs:10:8
+   |
+LL |     fn c<T: ~const Bar>();
+   |        ^
+
 error[E0277]: the trait bound `T: Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:14:5
+  --> $DIR/trait-where-clause.rs:16:5
    |
 LL |     T::b();
    |     ^ the trait `Bar` is not implemented for `T`
@@ -15,13 +39,13 @@ LL | fn test1<T: Foo + Bar>() {
    |                 +++++
 
 error[E0277]: the trait bound `T: Bar` is not satisfied
-  --> $DIR/trait-where-clause.rs:16:12
+  --> $DIR/trait-where-clause.rs:18:12
    |
 LL |     T::c::<T>();
    |            ^ the trait `Bar` is not implemented for `T`
    |
 note: required by a bound in `Foo::c`
-  --> $DIR/trait-where-clause.rs:9:13
+  --> $DIR/trait-where-clause.rs:10:13
    |
 LL |     fn c<T: ~const Bar>();
    |             ^^^^^^^^^^ required by this bound in `Foo::c`
@@ -30,6 +54,6 @@ help: consider further restricting this bound
 LL | fn test1<T: Foo + Bar>() {
    |                 +++++
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed
index ccd65ff4091..a400a1672a4 100644
--- a/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed
+++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed
@@ -8,5 +8,6 @@ impl S {
 }
 
 fn main() {
-    Pin::new(&mut S).x(); //~ ERROR no method named `x` found
+    let mut pinned = std::pin::pin!(S);
+    pinned.as_mut().x(); //~ ERROR no method named `x` found
 }
diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr
index f34ce4dce49..5dcb5861120 100644
--- a/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr
+++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr
@@ -4,16 +4,14 @@ error[E0599]: no method named `x` found for struct `S` in the current scope
 LL | struct S;
    | -------- method `x` not found for this struct
 ...
-LL |     fn x(self: Pin<&mut Self>) {
-   |        - the method is available for `Pin<&mut S>` here
-...
 LL |     S.x();
    |       ^ method not found in `S`
    |
-help: consider wrapping the receiver expression with the appropriate type
+help: consider pinning the expression
+   |
+LL ~     let mut pinned = std::pin::pin!(S);
+LL ~     pinned.as_mut().x();
    |
-LL |     Pin::new(&mut S).x();
-   |     +++++++++++++  +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr
index 81211b20a01..50008083211 100644
--- a/tests/ui/span/issue-39698.stderr
+++ b/tests/ui/span/issue-39698.stderr
@@ -1,3 +1,13 @@
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/issue-39698.rs:10:9
+   |
+LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+   |         ^^^^^^^^^^^            -    ^^^^^^^^   ^^^^^^^^ pattern doesn't bind `b`
+   |         |                      |    |
+   |         |                      |    pattern doesn't bind `b`
+   |         |                      variable not in all patterns
+   |         pattern doesn't bind `b`
+
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/issue-39698.rs:10:9
    |
@@ -8,16 +18,6 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |         |             pattern doesn't bind `c`
    |         pattern doesn't bind `c`
 
-error[E0408]: variable `d` is not bound in all patterns
-  --> $DIR/issue-39698.rs:10:37
-   |
-LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
-   |                  -          -       ^^^^^^^^   ^^^^^^^^ pattern doesn't bind `d`
-   |                  |          |       |
-   |                  |          |       pattern doesn't bind `d`
-   |                  |          variable not in all patterns
-   |                  variable not in all patterns
-
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/issue-39698.rs:10:23
    |
@@ -28,15 +28,15 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |               |       pattern doesn't bind `a`
    |               variable not in all patterns
 
-error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/issue-39698.rs:10:9
+error[E0408]: variable `d` is not bound in all patterns
+  --> $DIR/issue-39698.rs:10:37
    |
 LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
-   |         ^^^^^^^^^^^            -    ^^^^^^^^   ^^^^^^^^ pattern doesn't bind `b`
-   |         |                      |    |
-   |         |                      |    pattern doesn't bind `b`
-   |         |                      variable not in all patterns
-   |         pattern doesn't bind `b`
+   |                  -          -       ^^^^^^^^   ^^^^^^^^ pattern doesn't bind `d`
+   |                  |          |       |
+   |                  |          |       pattern doesn't bind `d`
+   |                  |          variable not in all patterns
+   |                  variable not in all patterns
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr
index cb1a6fcacfc..e8bbb8058fa 100644
--- a/tests/ui/str/str-idx.stderr
+++ b/tests/ui/str/str-idx.stderr
@@ -7,7 +7,8 @@ LL |     let _: u8 = s[4];
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[_]>` is implemented for `usize`
+   = help: for that trait implementation, expected `[_]`, found `str`
    = note: required for `str` to implement `Index<{integer}>`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
@@ -21,7 +22,8 @@ LL |     let _ = s.get(4);
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[_]>` is implemented for `usize`
+   = help: for that trait implementation, expected `[_]`, found `str`
 note: required by a bound in `core::str::<impl str>::get`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
@@ -36,7 +38,8 @@ LL |     let _ = s.get_unchecked(4);
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[_]>` is implemented for `usize`
+   = help: for that trait implementation, expected `[_]`, found `str`
 note: required by a bound in `core::str::<impl str>::get_unchecked`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr
index ca4b86ba306..e6835bb54fb 100644
--- a/tests/ui/str/str-mut-idx.stderr
+++ b/tests/ui/str/str-mut-idx.stderr
@@ -31,7 +31,8 @@ LL |     s[1usize] = bot();
    |       ^^^^^^ string indices are ranges of `usize`
    |
    = help: the trait `SliceIndex<str>` is not implemented for `usize`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[_]>` is implemented for `usize`
+   = help: for that trait implementation, expected `[_]`, found `str`
    = note: required for `str` to implement `Index<usize>`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
@@ -45,7 +46,8 @@ LL |     s.get_mut(1);
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[_]>` is implemented for `usize`
+   = help: for that trait implementation, expected `[_]`, found `str`
 note: required by a bound in `core::str::<impl str>::get_mut`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
@@ -60,7 +62,8 @@ LL |     s.get_unchecked_mut(1);
    = help: the trait `SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[_]>` is implemented for `usize`
+   = help: for that trait implementation, expected `[_]`, found `str`
 note: required by a bound in `core::str::<impl str>::get_unchecked_mut`
   --> $SRC_DIR/core/src/str/mod.rs:LL:COL
 
diff --git a/tests/ui/suggestions/issue-101623.stderr b/tests/ui/suggestions/issue-101623.stderr
index 361483cc08d..9f00de17484 100644
--- a/tests/ui/suggestions/issue-101623.stderr
+++ b/tests/ui/suggestions/issue-101623.stderr
@@ -7,7 +7,8 @@ LL |     Trait::do_stuff({ fun(&mut *inner) });
    |     |               the trait `Trait<'_>` is not implemented for `*mut ()`
    |     required by a bound introduced by this call
    |
-   = help: the trait `Trait<'a>` is implemented for `()`
+   = help: the trait `Trait<'_>` is implemented for `()`
+   = help: for that trait implementation, expected `()`, found `*mut ()`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr
index 147dc9234c5..adf01339972 100644
--- a/tests/ui/suggestions/suggest-dereferencing-index.stderr
+++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr
@@ -5,7 +5,8 @@ LL |     let one_item_please: i32 = [1, 2, 3][i];
    |                                          ^ slice indices are of type `usize` or ranges of `usize`
    |
    = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize`
-   = help: the trait `SliceIndex<[T]>` is implemented for `usize`
+   = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
+   = help: for that trait implementation, expected `usize`, found `&usize`
    = note: required for `[{integer}]` to implement `Index<&usize>`
 help: dereference this index
    |
diff --git a/tests/ui/traits/coercion-generic-bad.stderr b/tests/ui/traits/coercion-generic-bad.stderr
index e7e8a796796..30a3c40db95 100644
--- a/tests/ui/traits/coercion-generic-bad.stderr
+++ b/tests/ui/traits/coercion-generic-bad.stderr
@@ -5,6 +5,7 @@ LL |     let s: Box<dyn Trait<isize>> = Box::new(Struct { person: "Fred" });
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<isize>` is not implemented for `Struct`
    |
    = help: the trait `Trait<&'static str>` is implemented for `Struct`
+   = help: for that trait implementation, expected `&'static str`, found `isize`
    = note: required for the cast from `Box<Struct>` to `Box<dyn Trait<isize>>`
 
 error: aborting due to previous error
diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.rs b/tests/ui/traits/non_lifetime_binders/on-rpit.rs
new file mode 100644
index 00000000000..c501e057e28
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/on-rpit.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(non_lifetime_binders)]
+//~^ WARN the feature `non_lifetime_binders` is incomplete
+
+trait Trait<T: ?Sized> {}
+
+impl<T: ?Sized> Trait<T> for i32 {}
+
+fn produce() -> impl for<T> Trait<T> {
+    16
+}
+
+fn main() {
+    let _ = produce();
+}
diff --git a/tests/ui/traits/non_lifetime_binders/on-rpit.stderr b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr
new file mode 100644
index 00000000000..34c56068c5c
--- /dev/null
+++ b/tests/ui/traits/non_lifetime_binders/on-rpit.stderr
@@ -0,0 +1,11 @@
+warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/on-rpit.rs:3:12
+   |
+LL | #![feature(non_lifetime_binders)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr
index e11c3f81003..b41bf86d3d9 100644
--- a/tests/ui/try-block/try-block-bad-type.stderr
+++ b/tests/ui/try-block/try-block-bad-type.stderr
@@ -6,6 +6,7 @@ LL |         Err("")?;
    |
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the trait `From<Infallible>` is implemented for `TryFromSliceError`
+   = help: for that trait implementation, expected `Infallible`, found `&str`
    = note: required for `Result<u32, TryFromSliceError>` to implement `FromResidual<Result<Infallible, &str>>`
 
 error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr
index 7eb392faa66..d8b9431becc 100644
--- a/tests/ui/try-trait/bad-interconversion.stderr
+++ b/tests/ui/try-trait/bad-interconversion.stderr
@@ -73,7 +73,8 @@ LL |     ControlFlow::Continue(Err("hello")?)
    |                                       ^ this `?` produces `Result<Infallible, &str>`, which is incompatible with `ControlFlow<String>`
    |
    = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `ControlFlow<String>`
-   = help: the trait `FromResidual` is implemented for `ControlFlow<B, C>`
+   = help: the trait `FromResidual<ControlFlow<String, Infallible>>` is implemented for `ControlFlow<String>`
+   = help: for that trait implementation, expected `ControlFlow<String, Infallible>`, found `Result<Infallible, &str>`
 
 error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
   --> $DIR/bad-interconversion.rs:37:12
@@ -84,7 +85,8 @@ LL |     Some(3)?;
    |            ^ this `?` produces `Option<Infallible>`, which is incompatible with `ControlFlow<u64>`
    |
    = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `ControlFlow<u64>`
-   = help: the trait `FromResidual` is implemented for `ControlFlow<B, C>`
+   = help: the trait `FromResidual<ControlFlow<u64, Infallible>>` is implemented for `ControlFlow<u64>`
+   = help: for that trait implementation, expected `ControlFlow<u64, Infallible>`, found `Option<Infallible>`
 
 error[E0277]: the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s (with the same Break type)
   --> $DIR/bad-interconversion.rs:43:29
@@ -96,7 +98,8 @@ LL |     ControlFlow::Break(4_u8)?;
    |
    = help: the trait `FromResidual<ControlFlow<u8, Infallible>>` is not implemented for `ControlFlow<i64>`
    = note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow`
-   = help: the trait `FromResidual` is implemented for `ControlFlow<B, C>`
+   = help: the trait `FromResidual<ControlFlow<i64, Infallible>>` is implemented for `ControlFlow<i64>`
+   = help: for that trait implementation, expected `i64`, found `u8`
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/type/type-check/point-at-inference-issue-116155.rs b/tests/ui/type/type-check/point-at-inference-issue-116155.rs
new file mode 100644
index 00000000000..1e9942d42e8
--- /dev/null
+++ b/tests/ui/type/type-check/point-at-inference-issue-116155.rs
@@ -0,0 +1,17 @@
+struct S<T>(T);
+
+impl<T> S<T> {
+    fn new() -> Self {
+        loop {}
+    }
+
+    fn constrain<F: Fn() -> T>(&self, _f: F) {}
+}
+
+fn main() {
+    let s = S::new();
+    let c = || true;
+    s.constrain(c);
+    let _: S<usize> = s;
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/type/type-check/point-at-inference-issue-116155.stderr b/tests/ui/type/type-check/point-at-inference-issue-116155.stderr
new file mode 100644
index 00000000000..c8c01603cb8
--- /dev/null
+++ b/tests/ui/type/type-check/point-at-inference-issue-116155.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+  --> $DIR/point-at-inference-issue-116155.rs:15:23
+   |
+LL |     s.constrain(c);
+   |     -           - this argument has type `{closure@$DIR/point-at-inference-issue-116155.rs:13:13: 13:15}`...
+   |     |
+   |     ... which causes `s` to have type `S<bool>`
+LL |     let _: S<usize> = s;
+   |            --------   ^ expected `S<usize>`, found `S<bool>`
+   |            |
+   |            expected due to this
+   |
+   = note: expected struct `S<usize>`
+              found struct `S<bool>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/triagebot.toml b/triagebot.toml
index 648997ad6f0..aa103113334 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -570,6 +570,11 @@ message = "`src/tools/x` was changed. Bump version of Cargo.toml in `src/tools/x
 message = "Third-party dependency whitelist may have been modified! You must ensure that any new dependencies have compatible licenses before merging."
 cc = ["@davidtwco", "@wesleywiser"]
 
+[mentions."src/bootstrap/config.rs"]
+message = "This PR changes `src/bootstrap/config.rs`. If appropriate, please also update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/lib.rs` and `change-id` in `config.example.toml`."
+[mentions."config.example.toml"]
+message = "This PR changes `config.example.toml`. If appropriate, please also update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/lib.rs` and `change-id` in `config.example.toml`."
+
 [mentions."src/bootstrap/defaults/config.compiler.toml"]
 message = "This PR changes src/bootstrap/defaults/config.compiler.toml. If appropriate, please also update `config.codegen.toml` so the defaults are in sync."
 [mentions."src/bootstrap/defaults/config.codegen.toml"]