diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f0e151d25778c..88d2642fd8c3f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -130,9 +130,6 @@ jobs:
           # which then uses log commands to actually set them.
           EXTRA_VARIABLES: ${{ toJson(matrix.env) }}
 
-      - name: setup upstream remote
-        run: src/ci/scripts/setup-upstream-remote.sh
-
       - name: ensure the channel matches the target branch
         run: src/ci/scripts/verify-channel.sh
 
@@ -192,6 +189,20 @@ jobs:
       - name: ensure the stable version number is correct
         run: src/ci/scripts/verify-stable-version-number.sh
 
+      # Temporary fix to unblock CI
+      # Remove the latest Windows SDK for 32-bit Windows MSVC builds.
+      # See issue https://github.com/rust-lang/rust/issues/137733 for more details.
+      - name: Remove Windows SDK 10.0.26100.0
+        shell: powershell
+        if: ${{ matrix.image == 'i686-msvc' || matrix.image == 'dist-i686-msvc' }}
+        run: |
+          $kits = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots').KitsRoot10
+          $sdk_version = "10.0.26100.0"
+
+          foreach ($kind in 'Bin', 'Lib', 'Include') {
+            Remove-Item -Force -Recurse $kits\$kind\$sdk_version -ErrorAction Continue
+          }
+
       - name: run the build
         # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
         run: src/ci/scripts/run-build-from-ci.sh 2>&1
diff --git a/.gitmodules b/.gitmodules
index f9bd42edab3f4..9008bcabac8fa 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -37,7 +37,7 @@
 	shallow = true
 [submodule "library/backtrace"]
 	path = library/backtrace
-	url = https://github.com/rust-lang/backtrace-rs.git
+	url = https://github.com/rust9x/backtrace-rs.git
 	shallow = true
 [submodule "src/tools/rustc-perf"]
 	path = src/tools/rustc-perf
diff --git a/Cargo.lock b/Cargo.lock
index 7d22abc8611e5..0c6b6dd51b33a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1983,7 +1983,7 @@ dependencies = [
  "anyhow",
  "clap",
  "fs-err",
- "rustc-hash 2.1.0",
+ "rustc-hash 2.1.1",
  "rustdoc-json-types",
  "serde",
  "serde_json",
@@ -3152,7 +3152,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "rinja_parser",
- "rustc-hash 2.1.0",
+ "rustc-hash 2.1.1",
  "serde",
  "syn 2.0.93",
 ]
@@ -3216,9 +3216,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
 
 [[package]]
 name = "rustc-hash"
-version = "2.1.0"
+version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497"
+checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
 
 [[package]]
 name = "rustc-main"
@@ -3620,7 +3620,7 @@ dependencies = [
  "memmap2",
  "parking_lot",
  "portable-atomic",
- "rustc-hash 2.1.0",
+ "rustc-hash 2.1.1",
  "rustc-rayon",
  "rustc-stable-hash",
  "rustc_arena",
@@ -4323,7 +4323,7 @@ dependencies = [
 name = "rustc_pattern_analysis"
 version = "0.0.0"
 dependencies = [
- "rustc-hash 2.1.0",
+ "rustc-hash 2.1.1",
  "rustc_abi",
  "rustc_apfloat",
  "rustc_arena",
@@ -4719,7 +4719,7 @@ name = "rustdoc-json-types"
 version = "0.1.0"
 dependencies = [
  "bincode",
- "rustc-hash 2.1.0",
+ "rustc-hash 2.1.1",
  "serde",
  "serde_json",
 ]
@@ -5363,7 +5363,7 @@ dependencies = [
  "ignore",
  "miropt-test-tools",
  "regex",
- "rustc-hash 2.1.0",
+ "rustc-hash 2.1.1",
  "semver",
  "similar",
  "termcolor",
diff --git a/RELEASES.md b/RELEASES.md
index 99733bade32c4..ecf76c63cd995 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,275 @@
+Version 1.85.1 (2025-03-18)
+==========================
+
+<a id="1.85.1"></a>
+
+- [Fix the doctest-merging feature of the 2024 Edition.](https://github.com/rust-lang/rust/pull/137899/)
+- [Relax some `target_feature` checks when generating docs.](https://github.com/rust-lang/rust/pull/137632/)
+- [Fix errors in `std::fs::rename` on Windows 1607.](https://github.com/rust-lang/rust/pull/137528/)
+- [Downgrade bootstrap `cc` to fix custom targets.](https://github.com/rust-lang/rust/pull/137460/)
+- [Skip submodule updates when building Rust from a source tarball.](https://github.com/rust-lang/rust/pull/137338/)
+
+Version 1.85.0 (2025-02-20)
+==========================
+
+<a id="1.85.0-Language"></a>
+
+Language
+--------
+- [The 2024 Edition is now stable.](https://github.com/rust-lang/rust/pull/133349)
+  See [the edition guide](https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html) for more details.
+- [Stabilize async closures](https://github.com/rust-lang/rust/pull/132706)
+  See [RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html) for more details.
+- [Stabilize `#[diagnostic::do_not_recommend]`](https://github.com/rust-lang/rust/pull/132056)
+- [Add `unpredictable_function_pointer_comparisons` lint to warn against function pointer comparisons](https://github.com/rust-lang/rust/pull/118833)
+- [Lint on combining `#[no_mangle]` and `#[export_name]` attributes.](https://github.com/rust-lang/rust/pull/131558)
+
+<a id="1.85.0-Compiler"></a>
+
+Compiler
+--------
+- [The unstable flag `-Zpolymorphize` has been removed](https://github.com/rust-lang/rust/pull/133883), see https://github.com/rust-lang/compiler-team/issues/810 for some background.
+
+<a id="1.85.0-Platform-Support"></a>
+
+Platform Support
+----------------
+- [Promote `powerpc64le-unknown-linux-musl` to tier 2 with host tools](https://github.com/rust-lang/rust/pull/133801)
+
+Refer to Rust's [platform support page][platform-support-doc]
+for more information on Rust's tiered platform support.
+
+<a id="1.85.0-Libraries"></a>
+
+Libraries
+---------
+- [Panics in the standard library now have a leading `library/` in their path](https://github.com/rust-lang/rust/pull/132390)
+- [`std::env::home_dir()` on Windows now ignores the non-standard `$HOME` environment variable](https://github.com/rust-lang/rust/pull/132515)
+
+  It will be un-deprecated in a subsequent release.
+- [Add `AsyncFn*` to the prelude in all editions.](https://github.com/rust-lang/rust/pull/132611)
+
+<a id="1.85.0-Stabilized-APIs"></a>
+
+Stabilized APIs
+---------------
+
+- [`BuildHasherDefault::new`](https://doc.rust-lang.org/stable/std/hash/struct.BuildHasherDefault.html#method.new)
+- [`ptr::fn_addr_eq`](https://doc.rust-lang.org/std/ptr/fn.fn_addr_eq.html)
+- [`io::ErrorKind::QuotaExceeded`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.QuotaExceeded)
+- [`io::ErrorKind::CrossesDevices`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.CrossesDevices)
+- [`{float}::midpoint`](https://doc.rust-lang.org/core/primitive.f32.html#method.midpoint)
+- [Unsigned `{integer}::midpoint`](https://doc.rust-lang.org/std/primitive.u64.html#method.midpoint)
+- [`NonZeroU*::midpoint`](https://doc.rust-lang.org/std/num/type.NonZeroU32.html#method.midpoint)
+- [impl `std::iter::Extend` for tuples with arity 1 through 12](https://doc.rust-lang.org/stable/std/iter/trait.Extend.html#impl-Extend%3C(A,)%3E-for-(EA,))
+- [`FromIterator<(A, ...)>` for tuples with arity 1 through 12](https://doc.rust-lang.org/stable/std/iter/trait.FromIterator.html#impl-FromIterator%3C(EA,)%3E-for-(A,))
+- [`std::task::Waker::noop`](https://doc.rust-lang.org/stable/std/task/struct.Waker.html#method.noop)
+
+These APIs are now stable in const contexts:
+
+- [`mem::size_of_val`](https://doc.rust-lang.org/stable/std/mem/fn.size_of_val.html)
+- [`mem::align_of_val`](https://doc.rust-lang.org/stable/std/mem/fn.align_of_val.html)
+- [`Layout::for_value`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.for_value)
+- [`Layout::align_to`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.align_to)
+- [`Layout::pad_to_align`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.pad_to_align)
+- [`Layout::extend`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.extend)
+- [`Layout::array`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.array)
+- [`std::mem::swap`](https://doc.rust-lang.org/stable/std/mem/fn.swap.html)
+- [`std::ptr::swap`](https://doc.rust-lang.org/stable/std/ptr/fn.swap.html)
+- [`NonNull::new`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.new)
+- [`HashMap::with_hasher`](https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html#method.with_hasher)
+- [`HashSet::with_hasher`](https://doc.rust-lang.org/stable/std/collections/struct.HashSet.html#method.with_hasher)
+- [`BuildHasherDefault::new`](https://doc.rust-lang.org/stable/std/hash/struct.BuildHasherDefault.html#method.new)
+- [`<float>::recip`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.recip)
+- [`<float>::to_degrees`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.to_degrees)
+- [`<float>::to_radians`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.to_radians)
+- [`<float>::max`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.max)
+- [`<float>::min`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.min)
+- [`<float>::clamp`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.clamp)
+- [`<float>::abs`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.abs)
+- [`<float>::signum`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.signum)
+- [`<float>::copysign`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.copysign)
+- [`MaybeUninit::write`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.write)
+
+<a id="1.85.0-Cargo"></a>
+
+Cargo
+-----
+- [Add future-incompatibility warning against keywords in cfgs and add raw-idents](https://github.com/rust-lang/cargo/pull/14671/)
+- [Stabilize higher precedence trailing flags](https://github.com/rust-lang/cargo/pull/14900/)
+- [Pass `CARGO_CFG_FEATURE` to build scripts](https://github.com/rust-lang/cargo/pull/14902/)
+
+<a id="1.85.0-Rustdoc"></a>
+
+Rustdoc
+-----
+- [Doc comment on impl blocks shows the first line, even when the impl block is collapsed](https://github.com/rust-lang/rust/pull/132155)
+
+<a id="1.85.0-Compatibility-Notes"></a>
+
+Compatibility Notes
+-------------------
+- [`rustc` no longer treats the `test` cfg as a well known check-cfg](https://github.com/rust-lang/rust/pull/131729), instead it is up to the build systems and users of `--check-cfg`[^check-cfg] to set it as a well known cfg using `--check-cfg=cfg(test)`.
+
+  This is done to enable build systems like Cargo to set it conditionally, as not all source files are suitable for unit tests.
+  [Cargo (for now) unconditionally sets the `test` cfg as a well known cfg](https://github.com/rust-lang/cargo/pull/14963).
+  [^check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html
+- [Disable potentially incorrect type inference if there are trivial and non-trivial where-clauses](https://github.com/rust-lang/rust/pull/132325)
+- `std::env::home_dir()` has been deprecated for years, because it can give surprising results in some Windows configurations if the `HOME` environment variable is set (which is not the normal configuration on Windows). We had previously avoided changing its behavior, out of concern for compatibility with code depending on this non-standard configuration. Given how long this function has been deprecated, we're now fixing its behavior as a bugfix. A subsequent release will remove the deprecation for this function.
+- [Make `core::ffi::c_char` signedness more closely match that of the platform-default `char`](https://github.com/rust-lang/rust/pull/132975)
+
+  This changed `c_char` from an `i8` to `u8` or vice versa on many Tier 2 and 3
+  targets (mostly Arm and RISC-V embedded targets). The new definition may
+  result in compilation failures but fixes compatibility issues with C.
+
+  The `libc` crate matches this change as of its 0.2.169 release.
+- [When compiling a nested `macro_rules` macro from an external crate, the content of the inner `macro_rules` is now built with the edition of the external crate, not the local crate.](https://github.com/rust-lang/rust/pull/133274)
+- [Increase `sparcv9-sun-solaris` and `x86_64-pc-solaris` Solaris baseline to 11.4.](https://github.com/rust-lang/rust/pull/133293)
+- [Show `abi_unsupported_vector_types` lint in future breakage reports](https://github.com/rust-lang/rust/pull/133374)
+- [Error if multiple super-trait instantiations of `dyn Trait` need associated types to be specified but only one is provided](https://github.com/rust-lang/rust/pull/133392)
+- [Change `powerpc64-ibm-aix` default `codemodel` to large](https://github.com/rust-lang/rust/pull/133811)
+
+<a id="1.85.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.
+
+- [Build `x86_64-unknown-linux-gnu` with LTO for C/C++ code (e.g., `jemalloc`)](https://github.com/rust-lang/rust/pull/134690)
+
+Version 1.84.1 (2025-01-30)
+==========================
+
+<a id="1.84.1"></a>
+
+- [Fix ICE 132920 in duplicate-crate diagnostics.](https://github.com/rust-lang/rust/pull/133304/)
+- [Fix errors for overlapping impls in incremental rebuilds.](https://github.com/rust-lang/rust/pull/133828/)
+- [Fix slow compilation related to the next-generation trait solver.](https://github.com/rust-lang/rust/pull/135618/)
+- [Fix debuginfo when LLVM's location discriminator value limit is exceeded.](https://github.com/rust-lang/rust/pull/135643/)
+- Fixes for building Rust from source:
+  - [Only try to distribute `llvm-objcopy` if llvm tools are enabled.](https://github.com/rust-lang/rust/pull/134240/)
+  - [Add Profile Override for Non-Git Sources.](https://github.com/rust-lang/rust/pull/135433/)
+  - [Resolve symlinks of LLVM tool binaries before copying them.](https://github.com/rust-lang/rust/pull/135585/)
+  - [Make it possible to use ci-rustc on tarball sources.](https://github.com/rust-lang/rust/pull/135722/)
+
+Version 1.84.0 (2025-01-09)
+==========================
+
+<a id="1.84.0-Language"></a>
+
+Language
+--------
+- [Allow `#[deny]` inside `#[forbid]` as a no-op](https://github.com/rust-lang/rust/pull/121560/)
+- [Show a warning when `-Ctarget-feature` is used to toggle features that can lead to unsoundness due to ABI mismatches](https://github.com/rust-lang/rust/pull/129884)
+- [Use the next-generation trait solver in coherence](https://github.com/rust-lang/rust/pull/130654)
+- [Allow coercions to drop the principal of trait objects](https://github.com/rust-lang/rust/pull/131857)
+- [Support `/` as the path separator for `include!()` in all cases on Windows](https://github.com/rust-lang/rust/pull/125205)
+- [Taking a raw ref (`raw (const|mut)`) of a deref of a pointer (`*ptr`) is now safe](https://github.com/rust-lang/rust/pull/129248)
+- [Stabilize s390x inline assembly](https://github.com/rust-lang/rust/pull/131258)
+- [Stabilize Arm64EC inline assembly](https://github.com/rust-lang/rust/pull/131781)
+- [Lint against creating pointers to immediately dropped temporaries](https://github.com/rust-lang/rust/pull/128985)
+- [Execute drop glue when unwinding in an `extern "C"` function](https://github.com/rust-lang/rust/pull/129582)
+
+<a id="1.84.0-Compiler"></a>
+
+Compiler
+--------
+- [Add `--print host-tuple` flag to print the host target tuple and affirm the "target tuple" terminology over "target triple"](https://github.com/rust-lang/rust/pull/125579)
+- [Declaring functions with a calling convention not supported on the current target now triggers a hard error](https://github.com/rust-lang/rust/pull/129935)
+- [Set up indirect access to external data for `loongarch64-unknown-linux-{musl,ohos}`](https://github.com/rust-lang/rust/pull/131583)
+- [Enable XRay instrumentation for LoongArch Linux targets](https://github.com/rust-lang/rust/pull/131818)
+- [Extend the `unexpected_cfgs` lint to also warn in external macros](https://github.com/rust-lang/rust/pull/132577)
+- [Stabilize WebAssembly `multivalue`, `reference-types`, and `tail-call` target features](https://github.com/rust-lang/rust/pull/131080)
+- [Added Tier 2 support for the `wasm32v1-none` target](https://github.com/rust-lang/rust/pull/131487)
+
+<a id="1.84.0-Libraries"></a>
+
+Libraries
+---------
+- [Implement `From<&mut {slice}>` for `Box/Rc/Arc<{slice}>`](https://github.com/rust-lang/rust/pull/129329)
+- [Move `<float>::copysign`, `<float>::abs`, `<float>::signum` to `core`](https://github.com/rust-lang/rust/pull/131304)
+- [Add `LowerExp` and `UpperExp` implementations to `NonZero`](https://github.com/rust-lang/rust/pull/131377)
+- [Implement `FromStr` for `CString` and `TryFrom<CString>` for `String`](https://github.com/rust-lang/rust/pull/130608)
+- [`std::os::darwin` has been made public](https://github.com/rust-lang/rust/pull/123723)
+
+<a id="1.84.0-Stabilized-APIs"></a>
+
+Stabilized APIs
+---------------
+
+- [`Ipv6Addr::is_unique_local`](https://doc.rust-lang.org/stable/core/net/struct.Ipv6Addr.html#method.is_unique_local)
+- [`Ipv6Addr::is_unicast_link_local`](https://doc.rust-lang.org/stable/core/net/struct.Ipv6Addr.html#method.is_unicast_link_local)
+- [`core::ptr::with_exposed_provenance`](https://doc.rust-lang.org/stable/core/ptr/fn.with_exposed_provenance.html)
+- [`core::ptr::with_exposed_provenance_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.with_exposed_provenance_mut.html)
+- [`<ptr>::addr`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.addr)
+- [`<ptr>::expose_provenance`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.expose_provenance)
+- [`<ptr>::with_addr`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.with_addr)
+- [`<ptr>::map_addr`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.map_addr)
+- [`<int>::isqrt`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.isqrt)
+- [`<int>::checked_isqrt`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.checked_isqrt)
+- [`<uint>::isqrt`](https://doc.rust-lang.org/stable/core/primitive.u32.html#method.isqrt)
+- [`NonZero::isqrt`](https://doc.rust-lang.org/stable/core/num/struct.NonZero.html#impl-NonZero%3Cu128%3E/method.isqrt)
+- [`core::ptr::without_provenance`](https://doc.rust-lang.org/stable/core/ptr/fn.without_provenance.html)
+- [`core::ptr::without_provenance_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.without_provenance_mut.html)
+- [`core::ptr::dangling`](https://doc.rust-lang.org/stable/core/ptr/fn.dangling.html)
+- [`core::ptr::dangling_mut`](https://doc.rust-lang.org/stable/core/ptr/fn.dangling_mut.html)
+- [`Pin::as_deref_mut`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.as_deref_mut)
+
+These APIs are now stable in const contexts
+
+- [`AtomicBool::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicBool.html#method.from_ptr)
+- [`AtomicPtr::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicPtr.html#method.from_ptr)
+- [`AtomicU8::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU8.html#method.from_ptr)
+- [`AtomicU16::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU16.html#method.from_ptr)
+- [`AtomicU32::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU32.html#method.from_ptr)
+- [`AtomicU64::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicU64.html#method.from_ptr)
+- [`AtomicUsize::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicUsize.html#method.from_ptr)
+- [`AtomicI8::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicI8.html#method.from_ptr)
+- [`AtomicI16::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicI16.html#method.from_ptr)
+- [`AtomicI32::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicI32.html#method.from_ptr)
+- [`AtomicI64::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicI64.html#method.from_ptr)
+- [`AtomicIsize::from_ptr`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicIsize.html#method.from_ptr)
+- [`<ptr>::is_null`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_null-1)
+- [`<ptr>::as_ref`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.as_ref-1)
+- [`<ptr>::as_mut`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.as_mut)
+- [`Pin::new`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.new)
+- [`Pin::new_unchecked`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.new_unchecked)
+- [`Pin::get_ref`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.get_ref)
+- [`Pin::into_ref`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.into_ref)
+- [`Pin::get_mut`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.get_mut)
+- [`Pin::get_unchecked_mut`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.get_unchecked_mut)
+- [`Pin::static_ref`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.static_ref)
+- [`Pin::static_mut`](https://doc.rust-lang.org/stable/core/pin/struct.Pin.html#method.static_mut)
+
+<a id="1.84.0-Cargo"></a>
+
+Cargo
+-----
+- [Stabilize MSRV-aware resolver config](https://github.com/rust-lang/cargo/pull/14639/)
+- [Stabilize resolver v3](https://github.com/rust-lang/cargo/pull/14754/)
+
+<a id="1.84-Rustdoc"></a>
+
+Rustdoc
+-------
+
+- [rustdoc-search: improve type-driven search](https://github.com/rust-lang/rust/pull/127589)
+
+<a id="1.84.0-Compatibility-Notes"></a>
+
+Compatibility Notes
+-------------------
+- [Enable by default the `LSX` target feature for LoongArch Linux targets](https://github.com/rust-lang/rust/pull/132140)
+- [The unstable `-Zprofile` flag (“gcov-style” coverage instrumentation) has been removed.](https://github.com/rust-lang/rust/pull/131829) This does not affect the stable flags for coverage instrumentation (`-Cinstrument-coverage`) and profile-guided optimization (`-Cprofile-generate`, `-Cprofile-use`), which are unrelated and remain available.
+- Support for the target named `wasm32-wasi` has been removed as the target is now named `wasm32-wasip1`. This completes the [transition](https://github.com/rust-lang/compiler-team/issues/607) [plan](https://github.com/rust-lang/compiler-team/issues/695) for this target following [the introduction of `wasm32-wasip1`](https://github.com/rust-lang/rust/pull/120468) in Rust 1.78. Compiler warnings on [use of `wasm32-wasi`](https://github.com/rust-lang/rust/pull/126662) introduced in Rust 1.81 are now gone as well as the target is removed.
+- [The syntax `&pin (mut|const) T` is now parsed as a type which in theory could affect macro expansion results in some edge cases](https://github.com/rust-lang/rust/pull/130635#issuecomment-2375462821)
+- [Legacy syntax for calling `std::arch` functions is no longer permitted to declare items or bodies (such as closures, inline consts, or async blocks).](https://github.com/rust-lang/rust/pull/130443#issuecomment-2445678945)
+- [Declaring functions with a calling convention not supported on the current target now triggers a hard error](https://github.com/rust-lang/rust/pull/129935)
+- [The next-generation trait solver is now enabled for coherence, fixing multiple soundness issues](https://github.com/rust-lang/rust/pull/130654)
+
 Version 1.83.0 (2024-11-28)
 ==========================
 
@@ -243,7 +515,7 @@ Language
 - [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834)
 - [size_of_val_raw: for length 0 this is safe to call](https://github.com/rust-lang/rust/pull/126152/)
 - [Reorder trait bound modifiers *after* `for<...>` binder in trait bounds](https://github.com/rust-lang/rust/pull/127054/)
-- [Stabilize opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672)
+- [Stabilize `+ use<'lt>` opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672)
 - [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679)
 - [Stabilize unsafe extern blocks (RFC 3484)](https://github.com/rust-lang/rust/pull/127921)
 - [Stabilize nested field access in `offset_of!`](https://github.com/rust-lang/rust/pull/128284)
@@ -457,6 +729,7 @@ Libraries
 - [Replace sort implementations with stable `driftsort` and unstable `ipnsort`.](https://github.com/rust-lang/rust/pull/124032/) All `slice::sort*` and `slice::select_nth*` methods are expected to see significant performance improvements. See the [research project](https://github.com/Voultapher/sort-research-rs) for more details.
 - [Document behavior of `create_dir_all` with respect to empty paths.](https://github.com/rust-lang/rust/pull/125112/)
 - [Fix interleaved output in the default panic hook when multiple threads panic simultaneously.](https://github.com/rust-lang/rust/pull/127397/)
+- Fix `Command`'s batch files argument escaping not working when file name has trailing whitespace or periods (CVE-2024-43402).
 
 <a id="1.81.0-Stabilized-APIs"></a>
 
@@ -2067,7 +2340,7 @@ Language
 --------
 
 - [Stabilize default_alloc_error_handler](https://github.com/rust-lang/rust/pull/102318/)
-  This allows usage of `alloc` on stable without requiring the 
+  This allows usage of `alloc` on stable without requiring the
   definition of a handler for allocation failure. Defining custom handlers is still unstable.
 - [Stabilize `efiapi` calling convention.](https://github.com/rust-lang/rust/pull/105795/)
 - [Remove implicit promotion for types with drop glue](https://github.com/rust-lang/rust/pull/105085/)
diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl
index ee4b2f95cb151..ada20e5c614f8 100644
--- a/compiler/rustc_borrowck/messages.ftl
+++ b/compiler/rustc_borrowck/messages.ftl
@@ -213,6 +213,10 @@ borrowck_suggest_create_fresh_reborrow =
 borrowck_suggest_iterate_over_slice =
     consider iterating over a slice of the `{$ty}`'s content to avoid moving into the `for` loop
 
+borrowck_tail_expr_drop_order = relative drop order changing in Rust 2024
+    .label = this temporary value will be dropped at the end of the block
+    .note = consider using a `let` binding to ensure the value will live long enough
+
 borrowck_ty_no_impl_copy =
     {$is_partial_move ->
         [true] partial move
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 22f7f708419b9..26d8326a26269 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -5,7 +5,7 @@
 
 use std::assert_matches::assert_matches;
 
-use rustc_errors::{Applicability, Diag};
+use rustc_errors::{Applicability, Diag, EmissionGuarantee};
 use rustc_hir as hir;
 use rustc_hir::intravisit::Visitor;
 use rustc_index::IndexSlice;
@@ -60,12 +60,12 @@ impl<'tcx> BorrowExplanation<'tcx> {
     pub(crate) fn is_explained(&self) -> bool {
         !matches!(self, BorrowExplanation::Unexplained)
     }
-    pub(crate) fn add_explanation_to_diagnostic(
+    pub(crate) fn add_explanation_to_diagnostic<G: EmissionGuarantee>(
         &self,
         tcx: TyCtxt<'tcx>,
         body: &Body<'tcx>,
         local_names: &IndexSlice<Local, Option<Symbol>>,
-        err: &mut Diag<'_>,
+        err: &mut Diag<'_, G>,
         borrow_desc: &str,
         borrow_span: Option<Span>,
         multiple_borrow_span: Option<(Span, Span)>,
@@ -348,10 +348,10 @@ impl<'tcx> BorrowExplanation<'tcx> {
         }
     }
 
-    fn add_object_lifetime_default_note(
+    fn add_object_lifetime_default_note<G: EmissionGuarantee>(
         &self,
         tcx: TyCtxt<'tcx>,
-        err: &mut Diag<'_>,
+        err: &mut Diag<'_, G>,
         unsize_ty: Ty<'tcx>,
     ) {
         if let ty::Adt(def, args) = unsize_ty.kind() {
@@ -405,9 +405,9 @@ impl<'tcx> BorrowExplanation<'tcx> {
         }
     }
 
-    fn add_lifetime_bound_suggestion_to_diagnostic(
+    fn add_lifetime_bound_suggestion_to_diagnostic<G: EmissionGuarantee>(
         &self,
-        err: &mut Diag<'_>,
+        err: &mut Diag<'_, G>,
         category: &ConstraintCategory<'tcx>,
         span: Span,
         region_name: &RegionName,
@@ -434,14 +434,14 @@ impl<'tcx> BorrowExplanation<'tcx> {
     }
 }
 
-fn suggest_rewrite_if_let(
+fn suggest_rewrite_if_let<G: EmissionGuarantee>(
     tcx: TyCtxt<'_>,
     expr: &hir::Expr<'_>,
     pat: &str,
     init: &hir::Expr<'_>,
     conseq: &hir::Expr<'_>,
     alt: Option<&hir::Expr<'_>>,
-    err: &mut Diag<'_>,
+    err: &mut Diag<'_, G>,
 ) {
     let source_map = tcx.sess.source_map();
     err.span_note(
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 180046ca25620..baa66f01f311e 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1001,6 +1001,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 kind,
             };
         }
+
         normal_ret
     }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index bdb880b2bced3..9349b46ec5b0c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -5,7 +5,7 @@ use std::fmt::{self, Display};
 use std::iter;
 
 use rustc_data_structures::fx::IndexEntry;
-use rustc_errors::Diag;
+use rustc_errors::{Diag, EmissionGuarantee};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_middle::ty::print::RegionHighlightMode;
@@ -108,7 +108,7 @@ impl RegionName {
         }
     }
 
-    pub(crate) fn highlight_region_name(&self, diag: &mut Diag<'_>) {
+    pub(crate) fn highlight_region_name<G: EmissionGuarantee>(&self, diag: &mut Diag<'_, G>) {
         match &self.source {
             RegionNameSource::NamedLateParamRegion(span)
             | RegionNameSource::NamedEarlyParamRegion(span) => {
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index b061a450c83f7..38b1d391be70f 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -15,6 +15,7 @@
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
+use std::borrow::Cow;
 use std::cell::RefCell;
 use std::marker::PhantomData;
 use std::ops::Deref;
@@ -22,7 +23,9 @@ use std::ops::Deref;
 use rustc_abi::FieldIdx;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::graph::dominators::Dominators;
+use rustc_errors::LintDiagnostic;
 use rustc_hir as hir;
+use rustc_hir::CRATE_HIR_ID;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::bit_set::{BitSet, MixedBitSet};
 use rustc_index::{IndexSlice, IndexVec};
@@ -42,7 +45,7 @@ use rustc_mir_dataflow::move_paths::{
     InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex,
 };
 use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results};
-use rustc_session::lint::builtin::UNUSED_MUT;
+use rustc_session::lint::builtin::{TAIL_EXPR_DROP_ORDER, UNUSED_MUT};
 use rustc_span::{Span, Symbol};
 use smallvec::SmallVec;
 use tracing::{debug, instrument};
@@ -636,9 +639,11 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<
             | StatementKind::Coverage(..)
             // These do not actually affect borrowck
             | StatementKind::ConstEvalCounter
-            // This do not affect borrowck
-            | StatementKind::BackwardIncompatibleDropHint { .. }
             | StatementKind::StorageLive(..) => {}
+            // This does not affect borrowck
+            StatementKind::BackwardIncompatibleDropHint { place, reason: BackwardIncompatibleDropReason::Edition2024 } => {
+                self.check_backward_incompatible_drop(location, (**place, span), state);
+            }
             StatementKind::StorageDead(local) => {
                 self.access_place(
                     location,
@@ -823,6 +828,7 @@ use self::ReadOrWrite::{Activation, Read, Reservation, Write};
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 enum ArtificialField {
+    ArrayLength,
     FakeBorrow,
 }
 
@@ -1007,6 +1013,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         }
     }
 
+    fn borrows_in_scope<'s>(
+        &self,
+        location: Location,
+        state: &'s BorrowckDomain,
+    ) -> Cow<'s, BitSet<BorrowIndex>> {
+        if let Some(polonius) = &self.polonius_output {
+            // Use polonius output if it has been enabled.
+            let location = self.location_table.start_index(location);
+            let mut polonius_output = BitSet::new_empty(self.borrow_set.len());
+            for &idx in polonius.errors_at(location) {
+                polonius_output.insert(idx);
+            }
+            Cow::Owned(polonius_output)
+        } else {
+            Cow::Borrowed(&state.borrows)
+        }
+    }
+
     #[instrument(level = "debug", skip(self, state))]
     fn check_access_for_conflict(
         &mut self,
@@ -1018,18 +1042,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
     ) -> bool {
         let mut error_reported = false;
 
-        // Use polonius output if it has been enabled.
-        let mut polonius_output;
-        let borrows_in_scope = if let Some(polonius) = &self.polonius_output {
-            let location = self.location_table.start_index(location);
-            polonius_output = BitSet::new_empty(self.borrow_set.len());
-            for &idx in polonius.errors_at(location) {
-                polonius_output.insert(idx);
-            }
-            &polonius_output
-        } else {
-            &state.borrows
-        };
+        let borrows_in_scope = self.borrows_in_scope(location, state);
 
         each_borrow_involving_path(
             self,
@@ -1149,6 +1162,69 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
         error_reported
     }
 
+    /// Through #123739, backward incompatible drops (BIDs) are introduced.
+    /// We would like to emit lints whether borrow checking fails at these future drop locations.
+    #[instrument(level = "debug", skip(self, state))]
+    fn check_backward_incompatible_drop(
+        &mut self,
+        location: Location,
+        (place, place_span): (Place<'tcx>, Span),
+        state: &BorrowckDomain,
+    ) {
+        let tcx = self.infcx.tcx;
+        // If this type does not need `Drop`, then treat it like a `StorageDead`.
+        // This is needed because we track the borrows of refs to thread locals,
+        // and we'll ICE because we don't track borrows behind shared references.
+        let sd = if place.ty(self.body, tcx).ty.needs_drop(tcx, self.body.typing_env(tcx)) {
+            AccessDepth::Drop
+        } else {
+            AccessDepth::Shallow(None)
+        };
+
+        let borrows_in_scope = self.borrows_in_scope(location, state);
+
+        // This is a very simplified version of `Self::check_access_for_conflict`.
+        // We are here checking on BIDs and specifically still-live borrows of data involving the BIDs.
+        each_borrow_involving_path(
+            self,
+            self.infcx.tcx,
+            self.body,
+            (sd, place),
+            self.borrow_set,
+            |borrow_index| borrows_in_scope.contains(borrow_index),
+            |this, _borrow_index, borrow| {
+                if matches!(borrow.kind, BorrowKind::Fake(_)) {
+                    return Control::Continue;
+                }
+                let borrowed = this.retrieve_borrow_spans(borrow).var_or_use_path_span();
+                let explain = this.explain_why_borrow_contains_point(
+                    location,
+                    borrow,
+                    Some((WriteKind::StorageDeadOrDrop, place)),
+                );
+                this.infcx.tcx.node_span_lint(
+                    TAIL_EXPR_DROP_ORDER,
+                    CRATE_HIR_ID,
+                    borrowed,
+                    |diag| {
+                        session_diagnostics::TailExprDropOrder { borrowed }.decorate_lint(diag);
+                        explain.add_explanation_to_diagnostic(
+                            this.infcx.tcx,
+                            this.body,
+                            &this.local_names,
+                            diag,
+                            "",
+                            None,
+                            None,
+                        );
+                    },
+                );
+                // We may stop at the first case
+                Control::Break
+            },
+        );
+    }
+
     fn mutate_place(
         &mut self,
         location: Location,
@@ -1270,11 +1346,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
                 );
             }
 
-            &Rvalue::Discriminant(place) => {
+            &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
+                let af = match *rvalue {
+                    Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
+                    Rvalue::Discriminant(..) => None,
+                    _ => unreachable!(),
+                };
                 self.access_place(
                     location,
                     (place, span),
-                    (Shallow(None), Read(ReadKind::Copy)),
+                    (Shallow(af), Read(ReadKind::Copy)),
                     LocalMutationIsAllowed::No,
                     state,
                 );
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index 560b8c0349ad6..679e111caa984 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -203,7 +203,8 @@ fn place_components_conflict<'tcx>(
             let base_ty = base.ty(body, tcx).ty;
 
             match (elem, base_ty.kind(), access) {
-                (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
+                (_, _, Shallow(Some(ArtificialField::ArrayLength)))
+                | (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
                     // The array length is like additional fields on the
                     // type; it does not overlap any existing data there.
                     // Furthermore, if cannot actually be a prefix of any
diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
index bb6d593d0d88e..bb73bc9fcbd35 100644
--- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs
@@ -298,11 +298,16 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> {
                 self.consume_operand(location, op);
             }
 
-            &Rvalue::Discriminant(place) => {
+            &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => {
+                let af = match rvalue {
+                    Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
+                    Rvalue::Discriminant(..) => None,
+                    _ => unreachable!(),
+                };
                 self.access_place(
                     location,
                     place,
-                    (Shallow(None), Read(ReadKind::Copy)),
+                    (Shallow(af), Read(ReadKind::Copy)),
                     LocalMutationIsAllowed::No,
                 );
             }
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 627444a4ce5b8..4be5d0dbf4284 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -480,3 +480,10 @@ pub(crate) struct SimdIntrinsicArgConst {
     pub arg: usize,
     pub intrinsic: String,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(borrowck_tail_expr_drop_order)]
+pub(crate) struct TailExprDropOrder {
+    #[label]
+    pub borrowed: Span,
+}
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 10fb8a399a267..084f122a2107d 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2221,6 +2221,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
             Rvalue::RawPtr(..)
             | Rvalue::ThreadLocalRef(..)
+            | Rvalue::Len(..)
             | Rvalue::Discriminant(..)
             | Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {}
         }
@@ -2236,6 +2237,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             | Rvalue::Repeat(..)
             | Rvalue::Ref(..)
             | Rvalue::RawPtr(..)
+            | Rvalue::Len(..)
             | Rvalue::Cast(..)
             | Rvalue::ShallowInitBox(..)
             | Rvalue::BinaryOp(..)
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 956a024fa4dc3..34066eb83fc02 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -828,6 +828,12 @@ fn codegen_stmt<'tcx>(
                         fx.bcx.ins().nop();
                     }
                 }
+                Rvalue::Len(place) => {
+                    let place = codegen_place(fx, place);
+                    let usize_layout = fx.layout_of(fx.tcx.types.usize);
+                    let len = codegen_array_len(fx, place);
+                    lval.write_cvalue(fx, CValue::by_val(len, usize_layout));
+                }
                 Rvalue::ShallowInitBox(ref operand, content_ty) => {
                     let content_ty = fx.monomorphize(content_ty);
                     let box_layout = fx.layout_of(Ty::new_box(fx.tcx, content_ty));
diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs
index 6aeb656c1ab40..5d8c5c199b12c 100644
--- a/compiler/rustc_codegen_gcc/src/debuginfo.rs
+++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs
@@ -113,15 +113,15 @@ fn make_mir_scope<'gcc, 'tcx>(
     let scope_data = &mir.source_scopes[scope];
     let parent_scope = if let Some(parent) = scope_data.parent_scope {
         make_mir_scope(cx, _instance, mir, variables, debug_context, instantiated, parent);
-        debug_context.scopes[parent].unwrap()
+        debug_context.scopes[parent]
     } else {
         // The root is the function itself.
         let file = cx.sess().source_map().lookup_source_file(mir.span.lo());
-        debug_context.scopes[scope] = Some(DebugScope {
+        debug_context.scopes[scope] = DebugScope {
             file_start_pos: file.start_pos,
             file_end_pos: file.end_position(),
-            ..debug_context.scopes[scope].unwrap()
-        });
+            ..debug_context.scopes[scope]
+        };
         instantiated.insert(scope);
         return;
     };
@@ -130,7 +130,7 @@ fn make_mir_scope<'gcc, 'tcx>(
         if !vars.contains(scope) && scope_data.inlined.is_none() {
             // Do not create a DIScope if there are no variables defined in this
             // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
-            debug_context.scopes[scope] = Some(parent_scope);
+            debug_context.scopes[scope] = parent_scope;
             instantiated.insert(scope);
             return;
         }
@@ -157,12 +157,12 @@ fn make_mir_scope<'gcc, 'tcx>(
     // TODO(tempdragon): dbg_scope: Add support for scope extension here.
     inlined_at.or(p_inlined_at);
 
-    debug_context.scopes[scope] = Some(DebugScope {
+    debug_context.scopes[scope] = DebugScope {
         dbg_scope,
         inlined_at,
         file_start_pos: loc.file.start_pos,
         file_end_pos: loc.file.end_position(),
-    });
+    };
     instantiated.insert(scope);
 }
 
@@ -232,12 +232,12 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         }
 
         // Initialize fn debug context (including scopes).
-        let empty_scope = Some(DebugScope {
+        let empty_scope = DebugScope {
             dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)),
             inlined_at: None,
             file_start_pos: BytePos(0),
             file_end_pos: BytePos(0),
-        });
+        };
         let mut fn_debug_context = FunctionDebugContext {
             scopes: IndexVec::from_elem(empty_scope, mir.source_scopes.as_slice()),
             inlined_function_scopes: Default::default(),
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
index 07bd0f4d1c171..11c1f9d39f7fb 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
@@ -9,7 +9,7 @@ use rustc_middle::mir::{Body, SourceScope};
 use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
 use rustc_middle::ty::{self, Instance};
 use rustc_session::config::DebugInfo;
-use rustc_span::{BytePos, hygiene};
+use rustc_span::{BytePos, DUMMY_SP, hygiene};
 
 use super::metadata::file_metadata;
 use super::utils::DIB;
@@ -85,23 +85,15 @@ fn make_mir_scope<'ll, 'tcx>(
             discriminators,
             parent,
         );
-        if let Some(parent_scope) = debug_context.scopes[parent] {
-            parent_scope
-        } else {
-            // If the parent scope could not be represented then no children
-            // can be either.
-            debug_context.scopes[scope] = None;
-            instantiated.insert(scope);
-            return;
-        }
+        debug_context.scopes[parent]
     } else {
         // The root is the function itself.
         let file = cx.sess().source_map().lookup_source_file(mir.span.lo());
-        debug_context.scopes[scope] = Some(DebugScope {
+        debug_context.scopes[scope] = DebugScope {
             file_start_pos: file.start_pos,
             file_end_pos: file.end_position(),
-            ..debug_context.scopes[scope].unwrap()
-        });
+            ..debug_context.scopes[scope]
+        };
         instantiated.insert(scope);
         return;
     };
@@ -112,7 +104,7 @@ fn make_mir_scope<'ll, 'tcx>(
     {
         // Do not create a DIScope if there are no variables defined in this
         // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
-        debug_context.scopes[scope] = Some(parent_scope);
+        debug_context.scopes[scope] = parent_scope;
         instantiated.insert(scope);
         return;
     }
@@ -145,14 +137,7 @@ fn make_mir_scope<'ll, 'tcx>(
         },
     };
 
-    let mut debug_scope = Some(DebugScope {
-        dbg_scope,
-        inlined_at: parent_scope.inlined_at,
-        file_start_pos: loc.file.start_pos,
-        file_end_pos: loc.file.end_position(),
-    });
-
-    if let Some((_, callsite_span)) = scope_data.inlined {
+    let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
         let callsite_span = hygiene::walk_chain_collapsed(callsite_span, mir.span);
         let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span);
         let loc = cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span);
@@ -175,29 +160,29 @@ fn make_mir_scope<'ll, 'tcx>(
         // Note further that we can't key this hashtable on the span itself,
         // because these spans could have distinct SyntaxContexts. We have
         // to key on exactly what we're giving to LLVM.
-        let inlined_at = match discriminators.entry(callsite_span.lo()) {
+        match discriminators.entry(callsite_span.lo()) {
             Entry::Occupied(mut o) => {
                 *o.get_mut() += 1;
+                // NB: We have to emit *something* here or we'll fail LLVM IR verification
+                // in at least some circumstances (see issue #135322) so if the required
+                // discriminant cannot be encoded fall back to the dummy location.
                 unsafe { llvm::LLVMRustDILocationCloneWithBaseDiscriminator(loc, *o.get()) }
+                    .unwrap_or_else(|| {
+                        cx.dbg_loc(callsite_scope, parent_scope.inlined_at, DUMMY_SP)
+                    })
             }
             Entry::Vacant(v) => {
                 v.insert(0);
-                Some(loc)
-            }
-        };
-        match inlined_at {
-            Some(inlined_at) => {
-                debug_scope.as_mut().unwrap().inlined_at = Some(inlined_at);
-            }
-            None => {
-                // LLVM has a maximum discriminator that it can encode (currently
-                // it uses 12 bits for 4096 possible values). If we exceed that
-                // there is little we can do but drop the debug info.
-                debug_scope = None;
+                loc
             }
         }
-    }
+    });
 
-    debug_context.scopes[scope] = debug_scope;
+    debug_context.scopes[scope] = DebugScope {
+        dbg_scope,
+        inlined_at: inlined_at.or(parent_scope.inlined_at),
+        file_start_pos: loc.file.start_pos,
+        file_end_pos: loc.file.end_position(),
+    };
     instantiated.insert(scope);
 }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index fae698bea2a6b..244df1be1d75e 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -293,12 +293,12 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         }
 
         // Initialize fn debug context (including scopes).
-        let empty_scope = Some(DebugScope {
+        let empty_scope = DebugScope {
             dbg_scope: self.dbg_scope_fn(instance, fn_abi, Some(llfn)),
             inlined_at: None,
             file_start_pos: BytePos(0),
             file_end_pos: BytePos(0),
-        });
+        };
         let mut fn_debug_context = FunctionDebugContext {
             scopes: IndexVec::from_elem(empty_scope, &mir.source_scopes),
             inlined_function_scopes: Default::default(),
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 4bc064528f3f0..c50954c96c7ae 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1008,12 +1008,10 @@ fn link_natively(
                         && (code < 1000 || code > 9999)
                     {
                         let is_vs_installed = windows_registry::find_vs_version().is_ok();
+                        let tuple =
+                            sess.opts.target_triple.tuple().to_owned().replace("rust9x", "pc");
                         // FIXME(cc-rs#1265) pass only target arch to find_tool()
-                        let has_linker = windows_registry::find_tool(
-                            sess.opts.target_triple.tuple(),
-                            "link.exe",
-                        )
-                        .is_some();
+                        let has_linker = windows_registry::find_tool(&tuple, "link.exe").is_some();
 
                         sess.dcx().emit_note(errors::LinkExeUnexpectedError);
                         if is_vs_installed && has_linker {
@@ -1104,14 +1102,14 @@ fn link_natively(
         let stripcmd = "rust-objcopy";
         match (strip, crate_type) {
             (Strip::Debuginfo, _) => {
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-S"])
+                strip_with_external_utility(sess, stripcmd, out_filename, &["--strip-debug"])
             }
             // Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988)
             (Strip::Symbols, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro) => {
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-x"])
+                strip_with_external_utility(sess, stripcmd, out_filename, &["-x"])
             }
             (Strip::Symbols, _) => {
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[])
+                strip_with_external_utility(sess, stripcmd, out_filename, &["--strip-all"])
             }
             (Strip::None, _) => {}
         }
@@ -1127,9 +1125,7 @@ fn link_natively(
         let stripcmd = if !sess.host.is_like_solaris { "rust-objcopy" } else { "/usr/bin/strip" };
         match strip {
             // Always preserve the symbol table (-x).
-            Strip::Debuginfo => {
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &["-x"])
-            }
+            Strip::Debuginfo => strip_with_external_utility(sess, stripcmd, out_filename, &["-x"]),
             // Strip::Symbols is handled via the --strip-all linker option.
             Strip::Symbols => {}
             Strip::None => {}
@@ -1145,15 +1141,11 @@ fn link_natively(
         match strip {
             Strip::Debuginfo => {
                 // FIXME: AIX's strip utility only offers option to strip line number information.
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[
-                    "-X32_64", "-l",
-                ])
+                strip_with_external_utility(sess, stripcmd, out_filename, &["-X32_64", "-l"])
             }
             Strip::Symbols => {
                 // Must be noted this option might remove symbol __aix_rust_metadata and thus removes .info section which contains metadata.
-                strip_symbols_with_external_utility(sess, stripcmd, out_filename, &[
-                    "-X32_64", "-r",
-                ])
+                strip_with_external_utility(sess, stripcmd, out_filename, &["-X32_64", "-r"])
             }
             Strip::None => {}
         }
@@ -1166,12 +1158,7 @@ fn link_natively(
     }
 }
 
-fn strip_symbols_with_external_utility(
-    sess: &Session,
-    util: &str,
-    out_filename: &Path,
-    options: &[&str],
-) {
+fn strip_with_external_utility(sess: &Session, util: &str, out_filename: &Path, options: &[&str]) {
     let mut cmd = Command::new(util);
     cmd.args(options);
 
@@ -2607,6 +2594,9 @@ fn add_native_libs_from_crate(
         return;
     }
 
+    // only need unicows hacks for x86
+    let is_target_rust9x_x86 = sess.target.vendor == "rust9x" && sess.target.arch == "x86";
+
     if link_static && cnum != LOCAL_CRATE && !bundled_libs.is_empty() {
         // If rlib contains native libs as archives, unpack them to tmpdir.
         let rlib = &codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap().0;
@@ -2634,6 +2624,17 @@ fn add_native_libs_from_crate(
         };
 
         let name = lib.name.as_str();
+
+        const UNICOWS_LIBS: &[&str] = &[
+            "kernel32", "advapi32", "user32", "gdi32", "shell32", "comdlg32", "version", "mpr",
+            "rasapi32", "winmm", "winspool", "vfw32", "secur32", "oleacc", "oledlg", "sensapi",
+        ];
+        if is_target_rust9x_x86 && UNICOWS_LIBS.contains(&name) {
+            // skip adding unicows-wrapped libraries in order to properly support adding
+            // `unicows.lib` before them
+            continue;
+        }
+
         let verbatim = lib.verbatim;
         match lib.kind {
             NativeLibKind::Static { bundle, whole_archive } => {
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 3c6513ca26bb1..2ab278899e86e 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -50,8 +50,9 @@ pub(crate) fn get_linker<'a>(
     self_contained: bool,
     target_cpu: &'a str,
 ) -> Box<dyn Linker + 'a> {
+    let tuple = sess.opts.target_triple.tuple().to_owned().replace("rust9x", "pc");
     // FIXME(cc-rs#1265) pass only target arch to find_tool()
-    let msvc_tool = windows_registry::find_tool(sess.opts.target_triple.tuple(), "link.exe");
+    let msvc_tool = windows_registry::find_tool(&tuple, "link.exe");
 
     // If our linker looks like a batch script on Windows then to execute this
     // we'll need to spawn `cmd` explicitly. This is primarily done to handle
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 843a996d2bfe5..5924c8991ad64 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -19,9 +19,7 @@ use crate::traits::*;
 
 pub struct FunctionDebugContext<'tcx, S, L> {
     /// Maps from source code to the corresponding debug info scope.
-    /// May be None if the backend is not capable of representing the scope for
-    /// some reason.
-    pub scopes: IndexVec<mir::SourceScope, Option<DebugScope<S, L>>>,
+    pub scopes: IndexVec<mir::SourceScope, DebugScope<S, L>>,
 
     /// Maps from an inlined function to its debug info declaration.
     pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
@@ -232,7 +230,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         &self,
         source_info: mir::SourceInfo,
     ) -> Option<(Bx::DIScope, Option<Bx::DILocation>, Span)> {
-        let scope = &self.debug_context.as_ref()?.scopes[source_info.scope]?;
+        let scope = &self.debug_context.as_ref()?.scopes[source_info.scope];
         let span = hygiene::walk_chain_collapsed(source_info.span, self.mir.span);
         Some((scope.adjust_dbg_scope_for_span(self.cx, span), scope.inlined_at, span))
     }
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 3b62148abb789..cf53739223467 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -10,9 +10,9 @@ use rustc_session::config::OptLevel;
 use rustc_span::{DUMMY_SP, Span};
 use tracing::{debug, instrument};
 
-use super::FunctionCx;
 use super::operand::{OperandRef, OperandValue};
 use super::place::PlaceRef;
+use super::{FunctionCx, LocalRef};
 use crate::common::IntPredicate;
 use crate::traits::*;
 use crate::{MemFlags, base};
@@ -593,6 +593,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 self.codegen_place_to_pointer(bx, place, mk_ptr)
             }
 
+            mir::Rvalue::Len(place) => {
+                let size = self.evaluate_array_len(bx, place);
+                OperandRef {
+                    val: OperandValue::Immediate(size),
+                    layout: bx.cx().layout_of(bx.tcx().types.usize),
+                }
+            }
+
             mir::Rvalue::BinaryOp(op_with_overflow, box (ref lhs, ref rhs))
                 if let Some(op) = op_with_overflow.overflowing_to_wrapping() =>
             {
@@ -792,6 +800,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
+    fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value {
+        // ZST are passed as operands and require special handling
+        // because codegen_place() panics if Local is operand.
+        if let Some(index) = place.as_local() {
+            if let LocalRef::Operand(op) = self.locals[index] {
+                if let ty::Array(_, n) = op.layout.ty.kind() {
+                    let n = n
+                        .try_to_target_usize(bx.tcx())
+                        .expect("expected monomorphic const in codegen");
+                    return bx.cx().const_usize(n);
+                }
+            }
+        }
+        // use common size calculation for non zero-sized types
+        let cg_value = self.codegen_place(bx, place.as_ref());
+        cg_value.len(bx.cx())
+    }
+
     /// Codegen an `Rvalue::RawPtr` or `Rvalue::Ref`
     fn codegen_place_to_pointer(
         &mut self,
@@ -1063,6 +1089,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::Rvalue::Ref(..) |
             mir::Rvalue::CopyForDeref(..) |
             mir::Rvalue::RawPtr(..) |
+            mir::Rvalue::Len(..) |
             mir::Rvalue::Cast(..) | // (*)
             mir::Rvalue::ShallowInitBox(..) | // (*)
             mir::Rvalue::BinaryOp(..) |
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 7e80d014ea282..0c53a731221db 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -10,7 +10,7 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
 use rustc_span::{Span, Symbol, sym};
-use rustc_target::target_features;
+use rustc_target::target_features::{self, Stability};
 
 use crate::errors;
 
@@ -65,11 +65,16 @@ pub(crate) fn from_target_feature_attr(
             // Only allow target features whose feature gates have been enabled
             // and which are permitted to be toggled.
             if let Err(reason) = stability.toggle_allowed(/*enable*/ true) {
-                tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
-                    span: item.span(),
-                    feature,
-                    reason,
-                });
+                // We skip this error in rustdoc, where we want to allow all target features of
+                // all targets, so we can't check their ABI compatibility and anyway we are not
+                // generating code so "it's fine".
+                if !tcx.sess.opts.actually_rustdoc {
+                    tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
+                        span: item.span(),
+                        feature,
+                        reason,
+                    });
+                }
             } else if let Some(nightly_feature) = stability.requires_nightly()
                 && !rust_features.enabled(nightly_feature)
             {
@@ -149,11 +154,38 @@ pub(crate) fn provide(providers: &mut Providers) {
             assert_eq!(cnum, LOCAL_CRATE);
             let target = &tcx.sess.target;
             if tcx.sess.opts.actually_rustdoc {
-                // rustdoc needs to be able to document functions that use all the features, so
-                // whitelist them all
-                rustc_target::target_features::all_rust_features()
-                    .map(|(a, b)| (a.to_string(), b.compute_toggleability(target)))
-                    .collect()
+                // HACK: rustdoc would like to pretend that we have all the target features, so we
+                // have to merge all the lists into one. To ensure an unstable target never prevents
+                // a stable one from working, we merge the stability info of all instances of the
+                // same target feature name, with the "most stable" taking precedence. And then we
+                // hope that this doesn't cause issues anywhere else in the compiler...
+                let mut result: UnordMap<String, Stability<_>> = Default::default();
+                for (name, stability) in rustc_target::target_features::all_rust_features() {
+                    use std::collections::hash_map::Entry;
+                    match result.entry(name.to_owned()) {
+                        Entry::Vacant(vacant_entry) => {
+                            vacant_entry.insert(stability.compute_toggleability(target));
+                        }
+                        Entry::Occupied(mut occupied_entry) => {
+                            // Merge the two stabilities, "more stable" taking precedence.
+                            match (occupied_entry.get(), &stability) {
+                                (Stability::Stable { .. }, _)
+                                | (
+                                    Stability::Unstable { .. },
+                                    Stability::Unstable { .. } | Stability::Forbidden { .. },
+                                )
+                                | (Stability::Forbidden { .. }, Stability::Forbidden { .. }) => {
+                                    // The stability in the entry is at least as good as the new one, just keep it.
+                                }
+                                _ => {
+                                    // Overwrite stabilite.
+                                    occupied_entry.insert(stability.compute_toggleability(target));
+                                }
+                            }
+                        }
+                    }
+                }
+                result
             } else {
                 tcx.sess
                     .target
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index e895c44199b81..cbc0d5b059629 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -488,7 +488,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             Rvalue::Use(_)
             | Rvalue::CopyForDeref(..)
             | Rvalue::Repeat(..)
-            | Rvalue::Discriminant(..) => {}
+            | Rvalue::Discriminant(..)
+            | Rvalue::Len(_) => {}
 
             Rvalue::Aggregate(kind, ..) => {
                 if let AggregateKind::Coroutine(def_id, ..) = kind.as_ref()
@@ -572,27 +573,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
             ) => {}
             Rvalue::ShallowInitBox(_, _) => {}
 
-            Rvalue::UnaryOp(op, operand) => {
+            Rvalue::UnaryOp(_, operand) => {
                 let ty = operand.ty(self.body, self.tcx);
-                match op {
-                    UnOp::Not | UnOp::Neg => {
-                        if is_int_bool_float_or_char(ty) {
-                            // Int, bool, float, and char operations are fine.
-                        } else {
-                            span_bug!(
-                                self.span,
-                                "non-primitive type in `Rvalue::UnaryOp{op:?}`: {ty:?}",
-                            );
-                        }
-                    }
-                    UnOp::PtrMetadata => {
-                        if !ty.is_ref() && !ty.is_unsafe_ptr() {
-                            span_bug!(
-                                self.span,
-                                "non-pointer type in `Rvalue::UnaryOp({op:?})`: {ty:?}",
-                            );
-                        }
-                    }
+                if is_int_bool_float_or_char(ty) {
+                    // Int, bool, float, and char operations are fine.
+                } else {
+                    span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
                 }
             }
 
diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
index b1b7fb406b105..e244b50a4b5d9 100644
--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
@@ -230,7 +230,9 @@ where
             Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx))
         }
 
-        Rvalue::Discriminant(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),
+        Rvalue::Discriminant(place) | Rvalue::Len(place) => {
+            in_place::<Q, _>(cx, in_local, place.as_ref())
+        }
 
         Rvalue::CopyForDeref(place) => in_place::<Q, _>(cx, in_local, place.as_ref()),
 
diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs
index 5a6e7ab2beef4..79df63a9e849a 100644
--- a/compiler/rustc_const_eval/src/check_consts/resolver.rs
+++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs
@@ -197,6 +197,7 @@ where
             | mir::Rvalue::CopyForDeref(..)
             | mir::Rvalue::ThreadLocalRef(..)
             | mir::Rvalue::Repeat(..)
+            | mir::Rvalue::Len(..)
             | mir::Rvalue::BinaryOp(..)
             | mir::Rvalue::NullaryOp(..)
             | mir::Rvalue::UnaryOp(..)
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 32e77fe1024da..b61865be66788 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -9,13 +9,12 @@ use rustc_middle::ty::layout::FnAbiOf;
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::source_map::Spanned;
-use rustc_span::{DesugaringKind, Span};
 use rustc_target::callconv::FnAbi;
 use tracing::{info, instrument, trace};
 
 use super::{
     FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy,
-    Projectable, interp_ok, throw_ub,
+    Projectable, Scalar, interp_ok, throw_ub,
 };
 use crate::util;
 
@@ -81,9 +80,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         use rustc_middle::mir::StatementKind::*;
 
         match &stmt.kind {
-            Assign(box (place, rvalue)) => {
-                self.eval_rvalue_into_place(rvalue, *place, stmt.source_info.span)?
-            }
+            Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
 
             SetDiscriminant { place, variant_index } => {
                 let dest = self.eval_place(**place)?;
@@ -162,7 +159,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         &mut self,
         rvalue: &mir::Rvalue<'tcx>,
         place: mir::Place<'tcx>,
-        span: Span,
     ) -> InterpResult<'tcx> {
         let dest = self.eval_place(place)?;
         // FIXME: ensure some kind of non-aliasing between LHS and RHS?
@@ -218,6 +214,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 self.write_repeat(operand, &dest)?;
             }
 
+            Len(place) => {
+                let src = self.eval_place(place)?;
+                let len = src.len(self)?;
+                self.write_scalar(Scalar::from_target_usize(len, self), &dest)?;
+            }
+
             Ref(_, borrow_kind, place) => {
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(&src)?;
@@ -248,13 +250,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(&src)?;
                 let mut val = ImmTy::from_immediate(place.to_ref(self), dest.layout);
-                if !place_base_raw
-                    && span.desugaring_kind() != Some(DesugaringKind::IndexBoundsCheckReborrow)
-                {
+                if !place_base_raw {
                     // If this was not already raw, it needs retagging.
-                    // As a special hack, we exclude the desugared `PtrMetadata(&raw const *_n)`
-                    // from indexing. (Really we should not do any retag on `&raw` but that does not
-                    // currently work with Stacked Borrows.)
                     val = M::retag_ptr_value(self, mir::RetagKind::Raw, &val)?;
                 }
                 self.write_immediate(*val, &dest)?;
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index ecb7c3fc93cd5..8fd0b93454d98 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -1,12 +1,8 @@
-use std::ops::ControlFlow;
-
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{Allocation, InterpResult, Pointer};
 use rustc_middle::ty::layout::TyAndLayout;
-use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
-};
+use rustc_middle::ty::{TyCtxt, TypeVisitable, TypeVisitableExt};
 use tracing::debug;
 
 use super::{InterpCx, MPlaceTy, MemoryKind, interp_ok, throw_inval};
@@ -20,44 +16,10 @@ where
     T: TypeVisitable<TyCtxt<'tcx>>,
 {
     debug!("ensure_monomorphic_enough: ty={:?}", ty);
-    if !ty.has_param() {
-        return interp_ok(());
-    }
-
-    struct FoundParam;
-    struct UsedParamsNeedInstantiationVisitor {}
-
-    impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor {
-        type Result = ControlFlow<FoundParam>;
-
-        fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
-            if !ty.has_param() {
-                return ControlFlow::Continue(());
-            }
-
-            match *ty.kind() {
-                ty::Param(_) => ControlFlow::Break(FoundParam),
-                ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::FnDef(..) => {
-                    ControlFlow::Continue(())
-                }
-                _ => ty.super_visit_with(self),
-            }
-        }
-
-        fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
-            match c.kind() {
-                ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam),
-                _ => c.super_visit_with(self),
-            }
-        }
-    }
-
-    let mut vis = UsedParamsNeedInstantiationVisitor {};
-    if matches!(ty.visit_with(&mut vis), ControlFlow::Break(FoundParam)) {
+    if ty.has_param() {
         throw_inval!(TooGeneric);
-    } else {
-        interp_ok(())
     }
+    interp_ok(())
 }
 
 impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx> {
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 776de1988ccdc..95b711c894eaf 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -73,7 +73,7 @@ declare_features! (
     /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
     (accepted, async_await, "1.39.0", Some(50547)),
     /// Allows `async || body` closures.
-    (accepted, async_closure, "CURRENT_RUSTC_VERSION", Some(62290)),
+    (accepted, async_closure, "1.85.0", Some(62290)),
     /// Allows async functions to be declared, implemented, and used in traits.
     (accepted, async_fn_in_trait, "1.75.0", Some(91611)),
     /// Allows all literals in attribute lists and values of key-value pairs.
@@ -176,7 +176,7 @@ declare_features! (
     /// Allows using the `#[diagnostic]` attribute tool namespace
     (accepted, diagnostic_namespace, "1.78.0", Some(111996)),
     /// Controls errors in trait implementations.
-    (accepted, do_not_recommend, "CURRENT_RUSTC_VERSION", Some(51992)),
+    (accepted, do_not_recommend, "1.85.0", Some(51992)),
     /// Allows `#[doc(alias = "...")]`.
     (accepted, doc_alias, "1.48.0", Some(50146)),
     /// Allows `..` in tuple (struct) patterns.
@@ -197,9 +197,6 @@ declare_features! (
     (accepted, expr_fragment_specifier_2024, "1.83.0", Some(123742)),
     /// Allows arbitrary expressions in key-value attributes at parse time.
     (accepted, extended_key_value_attributes, "1.54.0", Some(78835)),
-    /// Allows using `efiapi`, `aapcs`, `sysv64` and `win64` as calling
-    /// convention for functions with varargs.
-    (accepted, extended_varargs_abi_support, "CURRENT_RUSTC_VERSION", Some(100189)),
     /// Allows resolving absolute paths as paths from other crates.
     (accepted, extern_absolute_paths, "1.30.0", Some(44660)),
     /// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 388ed9d08fa67..9aa59375706b4 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -120,7 +120,7 @@ declare_features! (
     /// Allows defining generators.
     (removed, generators, "1.21.0", Some(43122), Some("renamed to `coroutines`")),
     /// An extension to the `generic_associated_types` feature, allowing incomplete features.
-    (removed, generic_associated_types_extended, "CURRENT_RUSTC_VERSION", Some(95451),
+    (removed, generic_associated_types_extended, "1.85.0", Some(95451),
         Some(
             "feature needs overhaul and reimplementation pending \
             better implied higher-ranked implied bounds support"
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index d40823d2ed627..d6915d21b29e9 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -331,7 +331,7 @@ declare_features! (
     (unstable, hexagon_target_feature, "1.27.0", Some(44839)),
     (unstable, lahfsahf_target_feature, "1.78.0", Some(44839)),
     (unstable, loongarch_target_feature, "1.73.0", Some(44839)),
-    (unstable, m68k_target_feature, "CURRENT_RUSTC_VERSION", Some(134328)),
+    (unstable, m68k_target_feature, "1.85.0", Some(134328)),
     (unstable, mips_target_feature, "1.27.0", Some(44839)),
     (unstable, powerpc_target_feature, "1.27.0", Some(44839)),
     (unstable, prfchw_target_feature, "1.78.0", Some(44839)),
@@ -342,7 +342,7 @@ declare_features! (
     (unstable, sse4a_target_feature, "1.27.0", Some(44839)),
     (unstable, tbm_target_feature, "1.27.0", Some(44839)),
     (unstable, wasm_target_feature, "1.30.0", Some(44839)),
-    (unstable, x87_target_feature, "CURRENT_RUSTC_VERSION", Some(44839)),
+    (unstable, x87_target_feature, "1.85.0", Some(44839)),
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
     // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
@@ -378,11 +378,11 @@ declare_features! (
     /// Enables experimental inline assembly support for additional architectures.
     (unstable, asm_experimental_arch, "1.58.0", Some(93335)),
     /// Enables experimental register support in inline assembly.
-    (unstable, asm_experimental_reg, "CURRENT_RUSTC_VERSION", Some(133416)),
+    (unstable, asm_experimental_reg, "1.85.0", Some(133416)),
     /// Allows using `label` operands in inline assembly.
     (unstable, asm_goto, "1.78.0", Some(119364)),
     /// Allows using `label` operands in inline assembly together with output operands.
-    (unstable, asm_goto_with_outputs, "CURRENT_RUSTC_VERSION", Some(119364)),
+    (unstable, asm_goto_with_outputs, "1.85.0", Some(119364)),
     /// Allows the `may_unwind` option in inline assembly.
     (unstable, asm_unwind, "1.58.0", Some(93334)),
     /// Allows users to enforce equality of associated constants `TraitImpl<AssocConst=3>`.
@@ -390,13 +390,13 @@ declare_features! (
     /// Allows associated type defaults.
     (unstable, associated_type_defaults, "1.2.0", Some(29661)),
     /// Allows async functions to be called from `dyn Trait`.
-    (incomplete, async_fn_in_dyn_trait, "CURRENT_RUSTC_VERSION", Some(133119)),
+    (incomplete, async_fn_in_dyn_trait, "1.85.0", Some(133119)),
     /// Allows `#[track_caller]` on async functions.
     (unstable, async_fn_track_caller, "1.73.0", Some(110011)),
     /// Allows `for await` loops.
     (unstable, async_for_loop, "1.77.0", Some(118898)),
     /// Allows `async` trait bound modifier.
-    (unstable, async_trait_bounds, "CURRENT_RUSTC_VERSION", Some(62290)),
+    (unstable, async_trait_bounds, "1.85.0", Some(62290)),
     /// Allows using C-variadics.
     (unstable, c_variadic, "1.34.0", Some(44930)),
     /// Allows the use of `#[cfg(<true/false>)]`.
@@ -434,7 +434,7 @@ declare_features! (
     /// Allows `const || {}` closures in const contexts.
     (incomplete, const_closures, "1.68.0", Some(106003)),
     /// Allows using `~const Destruct` bounds and calling drop impls in const contexts.
-    (unstable, const_destruct, "CURRENT_RUSTC_VERSION", Some(133214)),
+    (unstable, const_destruct, "1.85.0", Some(133214)),
     /// Allows `for _ in _` loops in const contexts.
     (unstable, const_for, "1.56.0", Some(87575)),
     /// Be more precise when looking for live drops in a const context.
@@ -458,7 +458,7 @@ declare_features! (
     (unstable, decl_macro, "1.17.0", Some(39412)),
     /// Allows the use of default values on struct definitions and the construction of struct
     /// literals with the functional update syntax without a base.
-    (unstable, default_field_values, "CURRENT_RUSTC_VERSION", Some(132162)),
+    (unstable, default_field_values, "1.85.0", Some(132162)),
     /// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait
     (unstable, deprecated_safe, "1.61.0", Some(94978)),
     /// Allows having using `suggestion` in the `#[deprecated]` attribute.
@@ -479,6 +479,9 @@ declare_features! (
     (unstable, exhaustive_patterns, "1.13.0", Some(51085)),
     /// Allows explicit tail calls via `become` expression.
     (incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
+    /// Allows using `efiapi`, `sysv64` and `win64` as calling convention
+    /// for functions with varargs.
+    (unstable, extended_varargs_abi_support, "1.65.0", Some(100189)),
     /// Allows defining `extern type`s.
     (unstable, extern_types, "1.23.0", Some(43467)),
     /// Allow using 128-bit (quad precision) floating point numbers.
@@ -508,7 +511,7 @@ declare_features! (
     /// Allows registering static items globally, possibly across crates, to iterate over at runtime.
     (unstable, global_registration, "1.80.0", Some(125119)),
     /// Allows using guards in patterns.
-    (incomplete, guard_patterns, "CURRENT_RUSTC_VERSION", Some(129967)),
+    (incomplete, guard_patterns, "1.85.0", Some(129967)),
     /// Allows using `..=X` as a patterns in slices.
     (unstable, half_open_range_patterns_in_slices, "1.66.0", Some(67264)),
     /// Allows `if let` guard in match arms.
@@ -637,9 +640,9 @@ declare_features! (
     /// not changed from prior instances of the same struct (RFC #2528)
     (unstable, type_changing_struct_update, "1.58.0", Some(86555)),
     /// Allows using `unsafe<'a> &'a T` unsafe binder types.
-    (incomplete, unsafe_binders, "CURRENT_RUSTC_VERSION", Some(130516)),
+    (incomplete, unsafe_binders, "1.85.0", Some(130516)),
     /// Allows declaring fields `unsafe`.
-    (incomplete, unsafe_fields, "CURRENT_RUSTC_VERSION", Some(132922)),
+    (incomplete, unsafe_fields, "1.85.0", Some(132922)),
     /// Allows const generic parameters to be defined with types that
     /// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
     (incomplete, unsized_const_params, "1.82.0", Some(95174)),
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 0c3ed9b5c609b..9a87ea87e5089 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -602,7 +602,7 @@ hir_analysis_value_of_associated_struct_already_specified =
     .label = re-bound here
     .previous_bound_label = `{$item_name}` bound here first
 
-hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
+hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions}
     .label = C-variadic function must have a compatible calling convention
 
 hir_analysis_variances_of = {$variances}
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 00ba1741ed729..63f2a8adbde34 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -688,10 +688,11 @@ pub(crate) struct MainFunctionGenericParameters {
 
 #[derive(Diagnostic)]
 #[diag(hir_analysis_variadic_function_compatible_convention, code = E0045)]
-pub(crate) struct VariadicFunctionCompatibleConvention {
+pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
+    pub conventions: &'a str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 87fd4de26a5af..b4a7b8083ed78 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -100,6 +100,8 @@ use rustc_middle::middle;
 use rustc_middle::mir::interpret::GlobalId;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt};
+use rustc_session::parse::feature_err;
+use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_trait_selection::traits;
 
@@ -113,9 +115,34 @@ fn require_c_abi_if_c_variadic(
     abi: ExternAbi,
     span: Span,
 ) {
-    if decl.c_variadic && !abi.supports_varargs() {
-        tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span });
+    const CONVENTIONS_UNSTABLE: &str =
+        "`C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`";
+    const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
+    const UNSTABLE_EXPLAIN: &str =
+        "using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
+
+    if !decl.c_variadic || matches!(abi, ExternAbi::C { .. } | ExternAbi::Cdecl { .. }) {
+        return;
     }
+
+    let extended_abi_support = tcx.features().extended_varargs_abi_support();
+    let conventions = match (extended_abi_support, abi.supports_varargs()) {
+        // User enabled additional ABI support for varargs and function ABI matches those ones.
+        (true, true) => return,
+
+        // Using this ABI would be ok, if the feature for additional ABI support was enabled.
+        // Return CONVENTIONS_STABLE, because we want the other error to look the same.
+        (false, true) => {
+            feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
+                .emit();
+            CONVENTIONS_STABLE
+        }
+
+        (false, false) => CONVENTIONS_STABLE,
+        (true, false) => CONVENTIONS_UNSTABLE,
+    };
+
+    tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });
 }
 
 pub fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 98b28240f4cb9..fdb50bf491172 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -699,7 +699,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Determine the binding mode...
         let bm = match user_bind_annot {
-            BindingMode(ByRef::No, Mutability::Mut) if matches!(def_br, ByRef::Yes(_)) => {
+            BindingMode(ByRef::No, Mutability::Mut) if let ByRef::Yes(def_br_mutbl) = def_br => {
                 if pat.span.at_least_rust_2024()
                     && (self.tcx.features().ref_pat_eat_one_layer_2024()
                         || self.tcx.features().ref_pat_eat_one_layer_2024_structural())
@@ -719,22 +719,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // `mut` resets the binding mode on edition <= 2021
                     self.add_rust_2024_migration_desugared_pat(
                         pat_info.top_info.hir_id,
-                        pat.span,
+                        pat,
                         ident.span,
-                        "requires binding by-value, but the implicit default is by-reference",
+                        def_br_mutbl,
                     );
                     BindingMode(ByRef::No, Mutability::Mut)
                 }
             }
             BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
             BindingMode(ByRef::Yes(_), _) => {
-                if matches!(def_br, ByRef::Yes(_)) {
+                if let ByRef::Yes(def_br_mutbl) = def_br {
                     // `ref`/`ref mut` overrides the binding mode on edition <= 2021
                     self.add_rust_2024_migration_desugared_pat(
                         pat_info.top_info.hir_id,
-                        pat.span,
+                        pat,
                         ident.span,
-                        "cannot override to bind by-reference when that is the implicit default",
+                        def_br_mutbl,
                     );
                 }
                 user_bind_annot
@@ -2263,13 +2263,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         } else {
             // Reset binding mode on old editions
-            if pat_info.binding_mode != ByRef::No {
+            if let ByRef::Yes(inh_mut) = pat_info.binding_mode {
                 pat_info.binding_mode = ByRef::No;
                 self.add_rust_2024_migration_desugared_pat(
                     pat_info.top_info.hir_id,
-                    pat.span,
+                    pat,
                     inner.span,
-                    "cannot implicitly match against multiple layers of reference",
+                    inh_mut,
                 )
             }
         }
@@ -2635,33 +2635,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn add_rust_2024_migration_desugared_pat(
         &self,
         pat_id: HirId,
-        subpat_span: Span,
+        subpat: &'tcx Pat<'tcx>,
         cutoff_span: Span,
-        detailed_label: &str,
+        def_br_mutbl: Mutability,
     ) {
         // Try to trim the span we're labeling to just the `&` or binding mode that's an issue.
         // If the subpattern's span is is from an expansion, the emitted label will not be trimmed.
         let source_map = self.tcx.sess.source_map();
         let cutoff_span = source_map
-            .span_extend_prev_while(cutoff_span, char::is_whitespace)
+            .span_extend_prev_while(cutoff_span, |c| c.is_whitespace() || c == '(')
             .unwrap_or(cutoff_span);
-        // Ensure we use the syntax context and thus edition of `subpat_span`; this will be a hard
+        // Ensure we use the syntax context and thus edition of `subpat.span`; this will be a hard
         // error if the subpattern is of edition >= 2024.
-        let trimmed_span = subpat_span.until(cutoff_span).with_ctxt(subpat_span.ctxt());
+        let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt());
+
+        let mut typeck_results = self.typeck_results.borrow_mut();
+        let mut table = typeck_results.rust_2024_migration_desugared_pats_mut();
+        // FIXME(ref_pat_eat_one_layer_2024): The migration diagnostic doesn't know how to track the
+        // default binding mode in the presence of Rule 3 or Rule 5. As a consequence, the labels it
+        // gives for default binding modes are wrong, as well as suggestions based on the default
+        // binding mode. This keeps it from making those suggestions, as doing so could panic.
+        let info = table.entry(pat_id).or_insert_with(|| ty::Rust2024IncompatiblePatInfo {
+            primary_labels: Vec::new(),
+            bad_modifiers: false,
+            bad_ref_pats: false,
+            suggest_eliding_modes: !self.tcx.features().ref_pat_eat_one_layer_2024()
+                && !self.tcx.features().ref_pat_eat_one_layer_2024_structural(),
+        });
 
         // Only provide a detailed label if the problematic subpattern isn't from an expansion.
         // In the case that it's from a macro, we'll add a more detailed note in the emitter.
-        let desc = if subpat_span.from_expansion() {
-            "default binding mode is reset within expansion"
+        let from_expansion = subpat.span.from_expansion();
+        let primary_label = if from_expansion {
+            // NB: This wording assumes the only expansions that can produce problematic reference
+            // patterns and bindings are macros. If a desugaring or AST pass is added that can do
+            // so, we may want to inspect the span's source callee or macro backtrace.
+            "occurs within macro expansion".to_owned()
         } else {
-            detailed_label
+            let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind {
+                info.bad_modifiers |= true;
+                // If the user-provided binding modifier doesn't match the default binding mode, we'll
+                // need to suggest reference patterns, which can affect other bindings.
+                // For simplicity, we opt to suggest making the pattern fully explicit.
+                info.suggest_eliding_modes &=
+                    user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not);
+                "binding modifier"
+            } else {
+                info.bad_ref_pats |= true;
+                // For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll
+                // suggest adding them instead, which can affect the types assigned to bindings.
+                // As such, we opt to suggest making the pattern fully explicit.
+                info.suggest_eliding_modes = false;
+                "reference pattern"
+            };
+            let dbm_str = match def_br_mutbl {
+                Mutability::Not => "ref",
+                Mutability::Mut => "ref mut",
+            };
+            format!("{pat_kind} not allowed under `{dbm_str}` default binding mode")
         };
-
-        self.typeck_results
-            .borrow_mut()
-            .rust_2024_migration_desugared_pats_mut()
-            .entry(pat_id)
-            .or_default()
-            .push((trimmed_span, desc.to_owned()));
+        info.primary_labels.push((trimmed_span, primary_label));
     }
 }
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index b5dd6cf16eefa..6ceaaf6997e26 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -99,7 +99,7 @@ declare_lint! {
     /// To fix this, remove the `use<'a>`, since the lifetime is already captured
     /// since it is in scope.
     pub IMPL_TRAIT_REDUNDANT_CAPTURES,
-    Warn,
+    Allow,
     "redundant precise-capturing `use<...>` syntax on an `impl Trait`",
 }
 
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 1231ea8856961..60e1ff1d0493f 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -467,9 +467,6 @@ impl<'tcx> Const<'tcx> {
                 let const_val = tcx.valtree_to_const_val((ty, valtree));
                 Self::Val(const_val, ty)
             }
-            ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
-                Self::Unevaluated(UnevaluatedConst { def, args, promoted: None }, ty)
-            }
             _ => Self::Ty(ty, c),
         }
     }
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 47522f00bb1b3..2d1a0e36f9009 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1068,6 +1068,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                 pretty_print_const(b, fmt, false)?;
                 write!(fmt, "]")
             }
+            Len(ref a) => write!(fmt, "Len({a:?})"),
             Cast(ref kind, ref place, ref ty) => {
                 with_no_trimmed_paths!(write!(fmt, "{place:?} as {ty} ({kind:?})"))
             }
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index da3fa9e324a4d..1ce735cec6313 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -424,6 +424,7 @@ impl<'tcx> Rvalue<'tcx> {
             | Rvalue::Ref(_, _, _)
             | Rvalue::ThreadLocalRef(_)
             | Rvalue::RawPtr(_, _)
+            | Rvalue::Len(_)
             | Rvalue::Cast(
                 CastKind::IntToInt
                 | CastKind::FloatToInt
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index bbbaffc5a35cc..0c17a2e0fe5a1 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1351,6 +1351,16 @@ pub enum Rvalue<'tcx> {
     /// model.
     RawPtr(Mutability, Place<'tcx>),
 
+    /// Yields the length of the place, as a `usize`.
+    ///
+    /// If the type of the place is an array, this is the array length. For slices (`[T]`, not
+    /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
+    /// ill-formed for places of other types.
+    ///
+    /// This cannot be a `UnOp(PtrMetadata, _)` because that expects a value, and we only
+    /// have a place, and `UnOp(PtrMetadata, RawPtr(place))` is not a thing.
+    Len(Place<'tcx>),
+
     /// Performs essentially all of the casts that can be performed via `as`.
     ///
     /// This allows for casts from/to a variety of types.
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index cbb26b83c79cf..db77017310af3 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -210,6 +210,7 @@ impl<'tcx> Rvalue<'tcx> {
                 let place_ty = place.ty(local_decls, tcx).ty;
                 Ty::new_ptr(tcx, place_ty, mutability)
             }
+            Rvalue::Len(..) => tcx.types.usize,
             Rvalue::Cast(.., ty) => ty,
             Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) => {
                 let lhs_ty = lhs.ty(local_decls, tcx);
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 12a024a219e8e..058acbd4024d1 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -695,6 +695,14 @@ macro_rules! make_mir_visitor {
                         self.visit_place(path, ctx, location);
                     }
 
+                    Rvalue::Len(path) => {
+                        self.visit_place(
+                            path,
+                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
+                            location
+                        );
+                    }
+
                     Rvalue::Cast(_cast_kind, operand, ty) => {
                         self.visit_operand(operand, location);
                         self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 5e929fbec0bf8..ca7c2888d8eea 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -95,7 +95,7 @@ pub use self::sty::{
 pub use self::trait_def::TraitDef;
 pub use self::typeck_results::{
     CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, IsIdentity,
-    TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
+    Rust2024IncompatiblePatInfo, TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
 };
 pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
 use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index f94f52e4f6180..df34133520896 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -73,9 +73,9 @@ pub struct TypeckResults<'tcx> {
     /// Stores the actual binding mode for all instances of [`BindingMode`].
     pat_binding_modes: ItemLocalMap<BindingMode>,
 
-    /// Top-level patterns whose match ergonomics need to be desugared by the Rust 2021 -> 2024
-    /// migration lint. Problematic subpatterns are stored in the `Vec` for the lint to highlight.
-    rust_2024_migration_desugared_pats: ItemLocalMap<Vec<(Span, String)>>,
+    /// Top-level patterns incompatible with Rust 2024's match ergonomics. These will be translated
+    /// to a form valid in all Editions, either as a lint diagnostic or hard error.
+    rust_2024_migration_desugared_pats: ItemLocalMap<Rust2024IncompatiblePatInfo>,
 
     /// Stores the types which were implicitly dereferenced in pattern binding modes
     /// for later usage in THIR lowering. For example,
@@ -420,7 +420,7 @@ impl<'tcx> TypeckResults<'tcx> {
 
     pub fn rust_2024_migration_desugared_pats(
         &self,
-    ) -> LocalTableInContext<'_, Vec<(Span, String)>> {
+    ) -> LocalTableInContext<'_, Rust2024IncompatiblePatInfo> {
         LocalTableInContext {
             hir_owner: self.hir_owner,
             data: &self.rust_2024_migration_desugared_pats,
@@ -429,7 +429,7 @@ impl<'tcx> TypeckResults<'tcx> {
 
     pub fn rust_2024_migration_desugared_pats_mut(
         &mut self,
-    ) -> LocalTableInContextMut<'_, Vec<(Span, String)>> {
+    ) -> LocalTableInContextMut<'_, Rust2024IncompatiblePatInfo> {
         LocalTableInContextMut {
             hir_owner: self.hir_owner,
             data: &mut self.rust_2024_migration_desugared_pats,
@@ -811,3 +811,17 @@ impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> {
         }
     }
 }
+
+/// Information on a pattern incompatible with Rust 2024, for use by the error/migration diagnostic
+/// emitted during THIR construction.
+#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
+pub struct Rust2024IncompatiblePatInfo {
+    /// Labeled spans for `&`s, `&mut`s, and binding modifiers incompatible with Rust 2024.
+    pub primary_labels: Vec<(Span, String)>,
+    /// Whether any binding modifiers occur under a non-`move` default binding mode.
+    pub bad_modifiers: bool,
+    /// Whether any `&` or `&mut` patterns occur under a non-`move` default binding mode.
+    pub bad_ref_pats: bool,
+    /// If `true`, we can give a simpler suggestion solely by eliding explicit binding modifiers.
+    pub suggest_eliding_modes: bool,
+}
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index edba247c7b0df..3b59b66f2fc56 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -285,7 +285,16 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from
 
 mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
 
-mir_build_rust_2024_incompatible_pat = this pattern relies on behavior which may change in edition 2024
+mir_build_rust_2024_incompatible_pat = {$bad_modifiers ->
+        *[true] binding modifiers{$bad_ref_pats ->
+            *[true] {" "}and reference patterns
+            [false] {""}
+        }
+        [false] reference patterns
+    } may only be written when the default binding mode is `move`{$is_hard_error ->
+        *[true] {""}
+        [false] {" "}in Rust 2024
+    }
 
 mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
     .attributes = no other attributes may be applied
diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs
index 3dd5de0223081..59f440432ebc1 100644
--- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs
@@ -246,6 +246,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
                 let offset = self.parse_operand(args[1])?;
                 Ok(Rvalue::BinaryOp(BinOp::Offset, Box::new((ptr, offset))))
             },
+            @call(mir_len, args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
             @call(mir_ptr_metadata, args) => Ok(Rvalue::UnaryOp(UnOp::PtrMetadata, self.parse_operand(args[0])?)),
             @call(mir_copy_for_deref, args) => Ok(Rvalue::CopyForDeref(self.parse_place(args[0])?)),
             ExprKind::Borrow { borrow_kind, arg } => Ok(
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
index 89c7bb357ef51..b1851e79d5c65 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs
@@ -11,7 +11,7 @@ use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
 use rustc_middle::{bug, span_bug};
-use rustc_span::{DesugaringKind, Span};
+use rustc_span::Span;
 use tracing::{debug, instrument, trace};
 
 use crate::builder::ForGuard::{OutsideGuard, RefWithinGuard};
@@ -630,98 +630,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         block.and(base_place.index(idx))
     }
 
-    /// Given a place that's either an array or a slice, returns an operand
-    /// with the length of the array/slice.
-    ///
-    /// For arrays it'll be `Operand::Constant` with the actual length;
-    /// For slices it'll be `Operand::Move` of a local using `PtrMetadata`.
-    pub(in crate::builder) fn len_of_slice_or_array(
-        &mut self,
-        block: BasicBlock,
-        place: Place<'tcx>,
-        span: Span,
-        source_info: SourceInfo,
-    ) -> Operand<'tcx> {
-        let place_ty = place.ty(&self.local_decls, self.tcx).ty;
-        let usize_ty = self.tcx.types.usize;
-
-        match place_ty.kind() {
-            ty::Array(_elem_ty, len_const) => {
-                let ty_const = if let Some((_, len_ty)) = len_const.try_to_valtree()
-                    && len_ty != self.tcx.types.usize
-                {
-                    // Bad const generics can give us a constant from the type that's
-                    // not actually a `usize`, so in that case give an error instead.
-                    // FIXME: It'd be nice if the type checker made sure this wasn't
-                    // possible, instead.
-                    let err = self.tcx.dcx().span_delayed_bug(
-                        span,
-                        format!(
-                            "Array length should have already been a type error, as it's {len_ty:?}"
-                        ),
-                    );
-                    ty::Const::new_error(self.tcx, err)
-                } else {
-                    // We know how long an array is, so just use that as a constant
-                    // directly -- no locals needed. We do need one statement so
-                    // that borrow- and initialization-checking consider it used,
-                    // though. FIXME: Do we really *need* to count this as a use?
-                    // Could partial array tracking work off something else instead?
-                    self.cfg.push_fake_read(block, source_info, FakeReadCause::ForIndex, place);
-                    *len_const
-                };
-
-                let const_ = Const::from_ty_const(ty_const, usize_ty, self.tcx);
-                Operand::Constant(Box::new(ConstOperand { span, user_ty: None, const_ }))
-            }
-            ty::Slice(_elem_ty) => {
-                let ptr_or_ref = if let [PlaceElem::Deref] = place.projection[..]
-                    && let local_ty = self.local_decls[place.local].ty
-                    && local_ty.is_trivially_pure_clone_copy()
-                {
-                    // It's extremely common that we have something that can be
-                    // directly passed to `PtrMetadata`, so avoid an unnecessary
-                    // temporary and statement in those cases. Note that we can
-                    // only do that for `Copy` types -- not `&mut [_]` -- because
-                    // the MIR we're building here needs to pass NLL later.
-                    Operand::Copy(Place::from(place.local))
-                } else {
-                    let len_span = self.tcx.with_stable_hashing_context(|hcx| {
-                        let span = source_info.span;
-                        span.mark_with_reason(
-                            None,
-                            DesugaringKind::IndexBoundsCheckReborrow,
-                            span.edition(),
-                            hcx,
-                        )
-                    });
-                    let ptr_ty = Ty::new_imm_ptr(self.tcx, place_ty);
-                    let slice_ptr = self.temp(ptr_ty, span);
-                    self.cfg.push_assign(
-                        block,
-                        SourceInfo { span: len_span, ..source_info },
-                        slice_ptr,
-                        Rvalue::RawPtr(Mutability::Not, place),
-                    );
-                    Operand::Move(slice_ptr)
-                };
-
-                let len = self.temp(usize_ty, span);
-                self.cfg.push_assign(
-                    block,
-                    source_info,
-                    len,
-                    Rvalue::UnaryOp(UnOp::PtrMetadata, ptr_or_ref),
-                );
-
-                Operand::Move(len)
-            }
-            _ => {
-                span_bug!(span, "len called on place of type {place_ty:?}")
-            }
-        }
-    }
-
     fn bounds_check(
         &mut self,
         block: BasicBlock,
@@ -730,25 +638,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr_span: Span,
         source_info: SourceInfo,
     ) -> BasicBlock {
-        let slice = slice.to_place(self);
+        let usize_ty = self.tcx.types.usize;
+        let bool_ty = self.tcx.types.bool;
+        // bounds check:
+        let len = self.temp(usize_ty, expr_span);
+        let lt = self.temp(bool_ty, expr_span);
 
         // len = len(slice)
-        let len = self.len_of_slice_or_array(block, slice, expr_span, source_info);
-
+        self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.to_place(self)));
         // lt = idx < len
-        let bool_ty = self.tcx.types.bool;
-        let lt = self.temp(bool_ty, expr_span);
         self.cfg.push_assign(
             block,
             source_info,
             lt,
             Rvalue::BinaryOp(
                 BinOp::Lt,
-                Box::new((Operand::Copy(Place::from(index)), len.to_copy())),
+                Box::new((Operand::Copy(Place::from(index)), Operand::Copy(len))),
             ),
         );
-        let msg = BoundsCheck { len, index: Operand::Copy(Place::from(index)) };
-
+        let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) };
         // assert!(lt, "...")
         self.assert(block, Operand::Move(lt), true, msg, expr_span)
     }
diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs
index 0d36b7bb3ee7b..8cca84d7fcc64 100644
--- a/compiler/rustc_mir_build/src/builder/matches/test.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/test.rs
@@ -243,8 +243,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             TestKind::Len { len, op } => {
+                let usize_ty = self.tcx.types.usize;
+                let actual = self.temp(usize_ty, test.span);
+
                 // actual = len(place)
-                let actual = self.len_of_slice_or_array(block, place, test.span, source_info);
+                self.cfg.push_assign(block, source_info, actual, Rvalue::Len(place));
 
                 // expected = <N>
                 let expected = self.push_usize(block, source_info, len);
@@ -259,7 +262,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     fail_block,
                     source_info,
                     op,
-                    actual,
+                    Operand::Move(actual),
                     Operand::Move(expected),
                 );
             }
diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs
index 35c98037827af..20441530a4790 100644
--- a/compiler/rustc_mir_build/src/builder/scope.rs
+++ b/compiler/rustc_mir_build/src/builder/scope.rs
@@ -1131,15 +1131,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
     /// Schedule emission of a backwards incompatible drop lint hint.
     /// Applicable only to temporary values for now.
+    #[instrument(level = "debug", skip(self))]
     pub(crate) fn schedule_backwards_incompatible_drop(
         &mut self,
         span: Span,
         region_scope: region::Scope,
         local: Local,
     ) {
-        if !self.local_decls[local].ty.has_significant_drop(self.tcx, self.typing_env()) {
-            return;
-        }
+        // Note that we are *not* gating BIDs here on whether they have significant destructor.
+        // We need to know all of them so that we can capture potential borrow-checking errors.
         for scope in self.scopes.scopes.iter_mut().rev() {
             // Since we are inserting linting MIR statement, we have to invalidate the caches
             scope.invalidate_cache();
diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs
index 0659e3ea314bb..921205428dbd4 100644
--- a/compiler/rustc_mir_build/src/check_tail_calls.rs
+++ b/compiler/rustc_mir_build/src/check_tail_calls.rs
@@ -1,4 +1,5 @@
 use rustc_abi::ExternAbi;
+use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::Applicability;
 use rustc_hir::LangItem;
 use rustc_hir::def::DefKind;
@@ -344,12 +345,14 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for TailCallCkVisitor<'a, 'tcx> {
     }
 
     fn visit_expr(&mut self, expr: &'a Expr<'tcx>) {
-        if let ExprKind::Become { value } = expr.kind {
-            let call = &self.thir[value];
-            self.check_tail_call(call, expr);
-        }
+        ensure_sufficient_stack(|| {
+            if let ExprKind::Become { value } = expr.kind {
+                let call = &self.thir[value];
+                self.check_tail_call(call, expr);
+            }
 
-        visit::walk_expr(self, expr);
+            visit::walk_expr(self, expr);
+        });
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index f7071eb139f35..967e523a49c36 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -2,6 +2,7 @@ use std::borrow::Cow;
 use std::mem;
 use std::ops::Bound;
 
+use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::DiagArgValue;
 use rustc_hir::def::DefKind;
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
@@ -473,7 +474,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
             ExprKind::Scope { value, lint_level: LintLevel::Explicit(hir_id), region_scope: _ } => {
                 let prev_id = self.hir_context;
                 self.hir_context = hir_id;
-                self.visit_expr(&self.thir[value]);
+                ensure_sufficient_stack(|| {
+                    self.visit_expr(&self.thir[value]);
+                });
                 self.hir_context = prev_id;
                 return; // don't visit the whole expression
             }
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index be5f8bdffb50b..ccaea1ec9c408 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -1,3 +1,4 @@
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::codes::*;
 use rustc_errors::{
     Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
@@ -1088,41 +1089,70 @@ pub(crate) enum RustcBoxAttrReason {
 
 #[derive(LintDiagnostic)]
 #[diag(mir_build_rust_2024_incompatible_pat)]
-pub(crate) struct Rust2024IncompatiblePat<'a> {
+pub(crate) struct Rust2024IncompatiblePat {
     #[subdiagnostic]
-    pub(crate) sugg: Rust2024IncompatiblePatSugg<'a>,
+    pub(crate) sugg: Rust2024IncompatiblePatSugg,
+    pub(crate) bad_modifiers: bool,
+    pub(crate) bad_ref_pats: bool,
+    pub(crate) is_hard_error: bool,
 }
 
-pub(crate) struct Rust2024IncompatiblePatSugg<'a> {
+pub(crate) struct Rust2024IncompatiblePatSugg {
+    /// If true, our suggestion is to elide explicit binding modifiers.
+    /// If false, our suggestion is to make the pattern fully explicit.
+    pub(crate) suggest_eliding_modes: bool,
     pub(crate) suggestion: Vec<(Span, String)>,
     pub(crate) ref_pattern_count: usize,
     pub(crate) binding_mode_count: usize,
-    /// Labeled spans for subpatterns invalid in Rust 2024.
-    pub(crate) labels: &'a [(Span, String)],
+    /// Internal state: the ref-mutability of the default binding mode at the subpattern being
+    /// lowered, with the span where it was introduced. `None` for a by-value default mode.
+    pub(crate) default_mode_span: Option<(Span, ty::Mutability)>,
+    /// Labels for where incompatibility-causing by-ref default binding modes were introduced.
+    pub(crate) default_mode_labels: FxIndexMap<Span, ty::Mutability>,
 }
 
-impl<'a> Subdiagnostic for Rust2024IncompatiblePatSugg<'a> {
+impl Subdiagnostic for Rust2024IncompatiblePatSugg {
     fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
         self,
         diag: &mut Diag<'_, G>,
         _f: &F,
     ) {
+        // Format and emit explanatory notes about default binding modes. Reversing the spans' order
+        // means if we have nested spans, the innermost ones will be visited first.
+        for (span, def_br_mutbl) in self.default_mode_labels.into_iter().rev() {
+            // Don't point to a macro call site.
+            if !span.from_expansion() {
+                let note_msg = "matching on a reference type with a non-reference pattern changes the default binding mode";
+                let label_msg =
+                    format!("this matches on type `{}_`", def_br_mutbl.ref_prefix_str());
+                let mut label = MultiSpan::from(span);
+                label.push_span_label(span, label_msg);
+                diag.span_note(label, note_msg);
+            }
+        }
+
+        // Format and emit the suggestion.
         let applicability =
             if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) {
                 Applicability::MachineApplicable
             } else {
                 Applicability::MaybeIncorrect
             };
-        let plural_derefs = pluralize!(self.ref_pattern_count);
-        let and_modes = if self.binding_mode_count > 0 {
-            format!(" and variable binding mode{}", pluralize!(self.binding_mode_count))
+        let msg = if self.suggest_eliding_modes {
+            let plural_modes = pluralize!(self.binding_mode_count);
+            format!("remove the unnecessary binding modifier{plural_modes}")
         } else {
-            String::new()
+            let plural_derefs = pluralize!(self.ref_pattern_count);
+            let and_modes = if self.binding_mode_count > 0 {
+                format!(" and variable binding mode{}", pluralize!(self.binding_mode_count))
+            } else {
+                String::new()
+            };
+            format!("make the implied reference pattern{plural_derefs}{and_modes} explicit")
         };
-        diag.multipart_suggestion_verbose(
-            format!("make the implied reference pattern{plural_derefs}{and_modes} explicit"),
-            self.suggestion,
-            applicability,
-        );
+        // FIXME(dianne): for peace of mind, don't risk emitting a 0-part suggestion (that panics!)
+        if !self.suggestion.is_empty() {
+            diag.multipart_suggestion_verbose(msg, self.suggestion, applicability);
+        }
     }
 }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index a13b00e192167..6631086720068 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -1086,14 +1086,7 @@ fn find_fallback_pattern_typo<'tcx>(
                 let vis = cx.tcx.visibility(item.owner_id);
                 if vis.is_accessible_from(parent, cx.tcx) {
                     accessible.push(item_name);
-                    let path = if item_name == name {
-                        // We know that the const wasn't in scope because it has the exact
-                        // same name, so we suggest the full path.
-                        with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id))
-                    } else {
-                        // The const is likely just typoed, and nothing else.
-                        cx.tcx.def_path_str(item.owner_id)
-                    };
+                    let path = with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id));
                     accessible_path.push(path);
                 } else if name == item_name {
                     // The const exists somewhere in this crate, but it can't be imported
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index bdf243c87b6f1..d09017784b1d9 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -35,7 +35,7 @@ struct PatCtxt<'a, 'tcx> {
     typeck_results: &'a ty::TypeckResults<'tcx>,
 
     /// Used by the Rust 2024 migration lint.
-    rust_2024_migration_suggestion: Option<Rust2024IncompatiblePatSugg<'a>>,
+    rust_2024_migration_suggestion: Option<Rust2024IncompatiblePatSugg>,
 }
 
 pub(super) fn pat_from_hir<'a, 'tcx>(
@@ -44,25 +44,30 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
     typeck_results: &'a ty::TypeckResults<'tcx>,
     pat: &'tcx hir::Pat<'tcx>,
 ) -> Box<Pat<'tcx>> {
+    let migration_info = typeck_results.rust_2024_migration_desugared_pats().get(pat.hir_id);
     let mut pcx = PatCtxt {
         tcx,
         typing_env,
         typeck_results,
-        rust_2024_migration_suggestion: typeck_results
-            .rust_2024_migration_desugared_pats()
-            .get(pat.hir_id)
-            .map(|labels| Rust2024IncompatiblePatSugg {
+        rust_2024_migration_suggestion: migration_info.and_then(|info| {
+            Some(Rust2024IncompatiblePatSugg {
+                suggest_eliding_modes: info.suggest_eliding_modes,
                 suggestion: Vec::new(),
                 ref_pattern_count: 0,
                 binding_mode_count: 0,
-                labels: labels.as_slice(),
-            }),
+                default_mode_span: None,
+                default_mode_labels: Default::default(),
+            })
+        }),
     };
     let result = pcx.lower_pattern(pat);
     debug!("pat_from_hir({:?}) = {:?}", pat, result);
-    if let Some(sugg) = pcx.rust_2024_migration_suggestion {
-        let mut spans = MultiSpan::from_spans(sugg.labels.iter().map(|(span, _)| *span).collect());
-        for (span, label) in sugg.labels {
+    if let Some(info) = migration_info
+        && let Some(sugg) = pcx.rust_2024_migration_suggestion
+    {
+        let mut spans =
+            MultiSpan::from_spans(info.primary_labels.iter().map(|(span, _)| *span).collect());
+        for (span, label) in &info.primary_labels {
             spans.push_span_label(*span, label.clone());
         }
         // If a relevant span is from at least edition 2024, this is a hard error.
@@ -70,10 +75,13 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
         if is_hard_error {
             let mut err =
                 tcx.dcx().struct_span_err(spans, fluent::mir_build_rust_2024_incompatible_pat);
-            if let Some(info) = lint::builtin::RUST_2024_INCOMPATIBLE_PAT.future_incompatible {
+            if let Some(lint_info) = lint::builtin::RUST_2024_INCOMPATIBLE_PAT.future_incompatible {
                 // provide the same reference link as the lint
-                err.note(format!("for more information, see {}", info.reference));
+                err.note(format!("for more information, see {}", lint_info.reference));
             }
+            err.arg("bad_modifiers", info.bad_modifiers);
+            err.arg("bad_ref_pats", info.bad_ref_pats);
+            err.arg("is_hard_error", true);
             err.subdiagnostic(sugg);
             err.emit();
         } else {
@@ -81,7 +89,12 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
                 lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
                 pat.hir_id,
                 spans,
-                Rust2024IncompatiblePat { sugg },
+                Rust2024IncompatiblePat {
+                    sugg,
+                    bad_modifiers: info.bad_modifiers,
+                    bad_ref_pats: info.bad_ref_pats,
+                    is_hard_error,
+                },
             );
         }
     }
@@ -90,6 +103,35 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
 
 impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
+        let adjustments: &[Ty<'tcx>] =
+            self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
+
+        let mut opt_old_mode_span = None;
+        if let Some(s) = &mut self.rust_2024_migration_suggestion
+            && !adjustments.is_empty()
+        {
+            let implicit_deref_mutbls = adjustments.iter().map(|ref_ty| {
+                let &ty::Ref(_, _, mutbl) = ref_ty.kind() else {
+                    span_bug!(pat.span, "pattern implicitly dereferences a non-ref type");
+                };
+                mutbl
+            });
+
+            if !s.suggest_eliding_modes {
+                let suggestion_str: String =
+                    implicit_deref_mutbls.clone().map(|mutbl| mutbl.ref_prefix_str()).collect();
+                s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str));
+                s.ref_pattern_count += adjustments.len();
+            }
+
+            // Remember if this changed the default binding mode, in case we want to label it.
+            let min_mutbl = implicit_deref_mutbls.min().unwrap();
+            if s.default_mode_span.is_none_or(|(_, old_mutbl)| min_mutbl < old_mutbl) {
+                opt_old_mode_span = Some(s.default_mode_span);
+                s.default_mode_span = Some((pat.span, min_mutbl));
+            }
+        };
+
         // When implicit dereferences have been inserted in this pattern, the unadjusted lowered
         // pattern has the type that results *after* dereferencing. For example, in this code:
         //
@@ -118,8 +160,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             _ => self.lower_pattern_unadjusted(pat),
         };
 
-        let adjustments: &[Ty<'tcx>] =
-            self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
         let adjusted_pat = adjustments.iter().rev().fold(unadjusted_pat, |thir_pat, ref_ty| {
             debug!("{:?}: wrapping pattern with type {:?}", thir_pat, ref_ty);
             Box::new(Pat {
@@ -130,24 +170,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         });
 
         if let Some(s) = &mut self.rust_2024_migration_suggestion
-            && !adjustments.is_empty()
+            && let Some(old_mode_span) = opt_old_mode_span
         {
-            let suggestion_str: String = adjustments
-                .iter()
-                .map(|ref_ty| {
-                    let &ty::Ref(_, _, mutbl) = ref_ty.kind() else {
-                        span_bug!(pat.span, "pattern implicitly dereferences a non-ref type");
-                    };
-
-                    match mutbl {
-                        ty::Mutability::Not => "&",
-                        ty::Mutability::Mut => "&mut ",
-                    }
-                })
-                .collect();
-            s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str));
-            s.ref_pattern_count += adjustments.len();
-        };
+            s.default_mode_span = old_mode_span;
+        }
 
         adjusted_pat
     }
@@ -347,7 +373,22 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not };
                 PatKind::DerefPattern { subpattern: self.lower_pattern(subpattern), mutability }
             }
-            hir::PatKind::Ref(subpattern, _) | hir::PatKind::Box(subpattern) => {
+            hir::PatKind::Ref(subpattern, _) => {
+                // Track the default binding mode for the Rust 2024 migration suggestion.
+                let old_mode_span = self.rust_2024_migration_suggestion.as_mut().and_then(|s| {
+                    if let Some((default_mode_span, default_ref_mutbl)) = s.default_mode_span {
+                        // If this eats a by-ref default binding mode, label the binding mode.
+                        s.default_mode_labels.insert(default_mode_span, default_ref_mutbl);
+                    }
+                    s.default_mode_span.take()
+                });
+                let subpattern = self.lower_pattern(subpattern);
+                if let Some(s) = &mut self.rust_2024_migration_suggestion {
+                    s.default_mode_span = old_mode_span;
+                }
+                PatKind::Deref { subpattern }
+            }
+            hir::PatKind::Box(subpattern) => {
                 PatKind::Deref { subpattern: self.lower_pattern(subpattern) }
             }
 
@@ -374,19 +415,32 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                     .get(pat.hir_id)
                     .expect("missing binding mode");
 
-                if let Some(s) = &mut self.rust_2024_migration_suggestion
-                    && explicit_ba.0 == ByRef::No
-                    && let ByRef::Yes(mutbl) = mode.0
-                {
-                    let sugg_str = match mutbl {
-                        Mutability::Not => "ref ",
-                        Mutability::Mut => "ref mut ",
-                    };
-                    s.suggestion.push((
-                        pat.span.with_lo(ident.span.lo()).shrink_to_lo(),
-                        sugg_str.to_owned(),
-                    ));
-                    s.binding_mode_count += 1;
+                if let Some(s) = &mut self.rust_2024_migration_suggestion {
+                    if explicit_ba != hir::BindingMode::NONE
+                        && let Some((default_mode_span, default_ref_mutbl)) = s.default_mode_span
+                    {
+                        // If this overrides a by-ref default binding mode, label the binding mode.
+                        s.default_mode_labels.insert(default_mode_span, default_ref_mutbl);
+                        // If our suggestion is to elide redundnt modes, this will be one of them.
+                        if s.suggest_eliding_modes {
+                            s.suggestion.push((pat.span.with_hi(ident.span.lo()), String::new()));
+                            s.binding_mode_count += 1;
+                        }
+                    }
+                    if !s.suggest_eliding_modes
+                        && explicit_ba.0 == ByRef::No
+                        && let ByRef::Yes(mutbl) = mode.0
+                    {
+                        let sugg_str = match mutbl {
+                            Mutability::Not => "ref ",
+                            Mutability::Mut => "ref mut ",
+                        };
+                        s.suggestion.push((
+                            pat.span.with_lo(ident.span.lo()).shrink_to_lo(),
+                            sugg_str.to_owned(),
+                        ));
+                        s.binding_mode_count += 1;
+                    }
                 }
 
                 // A ref x pattern is the same node used for x, and as such it has
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index 217594b3238ab..568d8a5acaf95 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -91,6 +91,7 @@ where
             | Rvalue::Use(..)
             | Rvalue::ThreadLocalRef(..)
             | Rvalue::Repeat(..)
+            | Rvalue::Len(..)
             | Rvalue::BinaryOp(..)
             | Rvalue::NullaryOp(..)
             | Rvalue::UnaryOp(..)
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 80875f32e4f66..d1b3a389e9e5d 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -413,6 +413,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
             Rvalue::Ref(..)
             | Rvalue::RawPtr(..)
             | Rvalue::Discriminant(..)
+            | Rvalue::Len(..)
             | Rvalue::NullaryOp(
                 NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..) | NullOp::UbChecks,
                 _,
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index cc44114782cf3..51af77778af82 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -408,6 +408,18 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
         state: &mut State<FlatSet<Scalar>>,
     ) -> ValueOrPlace<FlatSet<Scalar>> {
         let val = match rvalue {
+            Rvalue::Len(place) => {
+                let place_ty = place.ty(self.local_decls, self.tcx);
+                if let ty::Array(_, len) = place_ty.ty.kind() {
+                    Const::Ty(self.tcx.types.usize, *len)
+                        .try_eval_scalar(self.tcx, self.typing_env)
+                        .map_or(FlatSet::Top, FlatSet::Elem)
+                } else if let [ProjectionElem::Deref] = place.projection[..] {
+                    state.get_len(place.local.into(), &self.map)
+                } else {
+                    FlatSet::Top
+                }
+            }
             Rvalue::Cast(CastKind::IntToInt | CastKind::IntToFloat, operand, ty) => {
                 let Ok(layout) = self.tcx.layout_of(self.typing_env.as_query_input(*ty)) else {
                     return ValueOrPlace::Value(FlatSet::Top);
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index e99bee6a01f5a..8f977d2979ec3 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -574,6 +574,7 @@ impl WriteInfo {
                     | Rvalue::NullaryOp(_, _)
                     | Rvalue::Ref(_, _, _)
                     | Rvalue::RawPtr(_, _)
+                    | Rvalue::Len(_)
                     | Rvalue::Discriminant(_)
                     | Rvalue::CopyForDeref(_) => {}
                 }
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 283ed94b61513..d5a813ec8ec64 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -223,6 +223,8 @@ enum Value<'tcx> {
     Projection(VnIndex, ProjectionElem<VnIndex, Ty<'tcx>>),
     /// Discriminant of the given value.
     Discriminant(VnIndex),
+    /// Length of an array or slice.
+    Len(VnIndex),
 
     // Operations.
     NullaryOp(NullOp<'tcx>, Ty<'tcx>),
@@ -511,6 +513,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                     self.ecx.discriminant_for_variant(base.layout.ty, variant).discard_err()?;
                 discr_value.into()
             }
+            Len(slice) => {
+                let slice = self.evaluated[slice].as_ref()?;
+                let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap();
+                let len = slice.len(&self.ecx).discard_err()?;
+                let imm = ImmTy::from_uint(len, usize_layout);
+                imm.into()
+            }
             NullaryOp(null_op, ty) => {
                 let layout = self.ecx.layout_of(ty).ok()?;
                 if let NullOp::SizeOf | NullOp::AlignOf = null_op
@@ -854,6 +863,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
 
             // Operations.
+            Rvalue::Len(ref mut place) => return self.simplify_len(place, location),
             Rvalue::Cast(ref mut kind, ref mut value, to) => {
                 return self.simplify_cast(kind, value, to, location);
             }
@@ -1423,6 +1433,47 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         Some(self.insert(Value::Cast { kind: *kind, value, from, to }))
     }
 
+    fn simplify_len(&mut self, place: &mut Place<'tcx>, location: Location) -> Option<VnIndex> {
+        // Trivial case: we are fetching a statically known length.
+        let place_ty = place.ty(self.local_decls, self.tcx).ty;
+        if let ty::Array(_, len) = place_ty.kind() {
+            return self.insert_constant(Const::from_ty_const(
+                *len,
+                self.tcx.types.usize,
+                self.tcx,
+            ));
+        }
+
+        let mut inner = self.simplify_place_value(place, location)?;
+
+        // The length information is stored in the wide pointer.
+        // Reborrowing copies length information from one pointer to the other.
+        while let Value::Address { place: borrowed, .. } = self.get(inner)
+            && let [PlaceElem::Deref] = borrowed.projection[..]
+            && let Some(borrowed) = self.locals[borrowed.local]
+        {
+            inner = borrowed;
+        }
+
+        // We have an unsizing cast, which assigns the length to wide pointer metadata.
+        if let Value::Cast { kind, from, to, .. } = self.get(inner)
+            && let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) = kind
+            && let Some(from) = from.builtin_deref(true)
+            && let ty::Array(_, len) = from.kind()
+            && let Some(to) = to.builtin_deref(true)
+            && let ty::Slice(..) = to.kind()
+        {
+            return self.insert_constant(Const::from_ty_const(
+                *len,
+                self.tcx.types.usize,
+                self.tcx,
+            ));
+        }
+
+        // Fallback: a symbolic `Len`.
+        Some(self.insert(Value::Len(inner)))
+    }
+
     fn pointers_have_same_metadata(&self, left_ptr_ty: Ty<'tcx>, right_ptr_ty: Ty<'tcx>) -> bool {
         let left_meta_ty = left_ptr_ty.pointee_metadata_ty_or_projection(self.tcx);
         let right_meta_ty = right_ptr_ty.pointee_metadata_ty_or_projection(self.tcx);
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 1a65affe8121a..f5938e7b60e80 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -46,6 +46,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
                         }
                         ctx.simplify_bool_cmp(rvalue);
                         ctx.simplify_ref_deref(rvalue);
+                        ctx.simplify_len(rvalue);
                         ctx.simplify_ptr_aggregate(rvalue);
                         ctx.simplify_cast(rvalue);
                     }
@@ -130,6 +131,18 @@ impl<'tcx> InstSimplifyContext<'_, 'tcx> {
         }
     }
 
+    /// Transform `Len([_; N])` ==> `N`.
+    fn simplify_len(&self, rvalue: &mut Rvalue<'tcx>) {
+        if let Rvalue::Len(ref place) = *rvalue {
+            let place_ty = place.ty(self.local_decls, self.tcx).ty;
+            if let ty::Array(_, len) = *place_ty.kind() {
+                let const_ = Const::from_ty_const(len, self.tcx.types.usize, self.tcx);
+                let constant = ConstOperand { span: DUMMY_SP, const_, user_ty: None };
+                *rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
+            }
+        }
+    }
+
     /// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
     fn simplify_ptr_aggregate(&self, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index f1705d0c831c2..acf3eb2b62cea 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -440,6 +440,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             | Rvalue::Use(..)
             | Rvalue::CopyForDeref(..)
             | Rvalue::Repeat(..)
+            | Rvalue::Len(..)
             | Rvalue::Cast(..)
             | Rvalue::ShallowInitBox(..)
             | Rvalue::Discriminant(..)
@@ -599,6 +600,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 return None;
             }
 
+            Len(place) => {
+                let len = if let ty::Array(_, n) = place.ty(self.local_decls(), self.tcx).ty.kind()
+                {
+                    n.try_to_target_usize(self.tcx)?
+                } else {
+                    match self.get_const(place)? {
+                        Value::Immediate(src) => src.len(&self.ecx).discard_err()?,
+                        Value::Aggregate { fields, .. } => fields.len() as u64,
+                        Value::Uninit => return None,
+                    }
+                };
+                ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into()
+            }
+
             Ref(..) | RawPtr(..) => return None,
 
             NullaryOp(ref null_op, ty) => {
diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
index e5a183bc75ce5..6590702118c7f 100644
--- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
+++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs
@@ -351,6 +351,11 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
     {
         return;
     }
+
+    // FIXME(typing_env): This should be able to reveal the opaques local to the
+    // body using the typeck results.
+    let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id);
+
     // ## About BIDs in blocks ##
     // Track the set of blocks that contain a backwards-incompatible drop (BID)
     // and, for each block, the vector of locations.
@@ -358,7 +363,7 @@ pub(crate) fn run_lint<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &Body<
     // We group them per-block because they tend to scheduled in the same drop ladder block.
     let mut bid_per_block = IndexMap::default();
     let mut bid_places = UnordSet::new();
-    let typing_env = ty::TypingEnv::post_analysis(tcx, def_id);
+
     let mut ty_dropped_components = UnordMap::default();
     for (block, data) in body.basic_blocks.iter_enumerated() {
         for (statement_index, stmt) in data.statements.iter().enumerate() {
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 7451f4193042b..6be95b1f0f1e6 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -430,7 +430,9 @@ impl<'tcx> Validator<'_, 'tcx> {
                 self.validate_operand(op)?
             }
 
-            Rvalue::Discriminant(place) => self.validate_place(place.as_ref())?,
+            Rvalue::Discriminant(place) | Rvalue::Len(place) => {
+                self.validate_place(place.as_ref())?
+            }
 
             Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),
 
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index a670da94fcc9e..404fbb6b83937 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -1009,6 +1009,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
             }
             Rvalue::Ref(..) => {}
+            Rvalue::Len(p) => {
+                let pty = p.ty(&self.body.local_decls, self.tcx).ty;
+                check_kinds!(
+                    pty,
+                    "Cannot compute length of non-array type {:?}",
+                    ty::Array(..) | ty::Slice(..)
+                );
+            }
             Rvalue::BinaryOp(op, vals) => {
                 use BinOp::*;
                 let a = vals.0.ty(&self.body.local_decls, self.tcx);
@@ -1107,6 +1115,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         );
                     }
                     UnOp::PtrMetadata => {
+                        if !matches!(self.body.phase, MirPhase::Runtime(_)) {
+                            // It would probably be fine to support this in earlier phases, but at
+                            // the time of writing it's only ever introduced from intrinsic
+                            // lowering or other runtime-phase optimization passes, so earlier
+                            // things can just `bug!` on it.
+                            self.fail(location, "PtrMetadata should be in runtime MIR only");
+                        }
+
                         check_kinds!(
                             a,
                             "Cannot PtrMetadata non-pointer non-reference type {:?}",
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 2637ea268c85b..30871db10a42f 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -189,8 +189,9 @@ pub struct Parser<'a> {
 }
 
 // This type is used a lot, e.g. it's cloned when matching many declarative macro rules with
-// nonterminals. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_pointer_width = "64", not(target_arch = "s390x")))]
+// nonterminals. Make sure it doesn't unintentionally get bigger. We only check a few arches
+// though, because `TokenTypeSet(u128)` alignment varies on others, changing the total size.
+#[cfg(all(target_pointer_width = "64", any(target_arch = "aarch64", target_arch = "x86_64")))]
 rustc_data_structures::static_assert_size!(Parser<'_>, 288);
 
 /// Stores span information about a closure.
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 6ee02e9f47f15..d15eca6927010 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1130,7 +1130,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         let None = following_seg else { return };
         for rib in self.ribs[ValueNS].iter().rev() {
             for (def_id, spans) in &rib.patterns_with_skipped_bindings {
-                if let Some(fields) = self.r.field_idents(*def_id) {
+                if let DefKind::Struct | DefKind::Variant = self.r.tcx.def_kind(*def_id)
+                    && let Some(fields) = self.r.field_idents(*def_id)
+                {
                     for field in fields {
                         if field.name == segment.ident.name {
                             if spans.iter().all(|(_, had_error)| had_error.is_err()) {
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index de933952c6a7b..a5a17b4b5730e 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -181,6 +181,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
             RawPtr(mutability, place) => {
                 stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
             }
+            Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),
             Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
                 cast_kind.stable(tables),
                 op.stable(tables),
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 3cdae437b7d46..a5826137181db 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1163,9 +1163,6 @@ pub enum DesugaringKind {
     WhileLoop,
     /// `async Fn()` bound modifier
     BoundModifier,
-    /// Marks a `&raw const *_1` needed as part of getting the length of a mutable
-    /// slice for the bounds check, so that MIRI's retag handling can recognize it.
-    IndexBoundsCheckReborrow,
 }
 
 impl DesugaringKind {
@@ -1182,7 +1179,6 @@ impl DesugaringKind {
             DesugaringKind::ForLoop => "`for` loop",
             DesugaringKind::WhileLoop => "`while` loop",
             DesugaringKind::BoundModifier => "trait bound modifier",
-            DesugaringKind::IndexBoundsCheckReborrow => "slice indexing",
         }
     }
 }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 4ecc4201f89d5..e3f55221d7052 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1283,6 +1283,7 @@ symbols! {
         mir_drop,
         mir_field,
         mir_goto,
+        mir_len,
         mir_make_place,
         mir_move,
         mir_offset,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 02962d55a60ed..e13ef8e52a468 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1825,10 +1825,13 @@ supported_targets! {
     ("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc),
     ("x86_64-uwp-windows-msvc", x86_64_uwp_windows_msvc),
     ("x86_64-win7-windows-msvc", x86_64_win7_windows_msvc),
+    ("x86_64-rust9x-windows-msvc", x86_64_rust9x_windows_msvc),
     ("i686-pc-windows-msvc", i686_pc_windows_msvc),
     ("i686-uwp-windows-msvc", i686_uwp_windows_msvc),
     ("i686-win7-windows-msvc", i686_win7_windows_msvc),
+    ("i686-rust9x-windows-msvc", i686_rust9x_windows_msvc),
     ("i586-pc-windows-msvc", i586_pc_windows_msvc),
+    ("i586-rust9x-windows-msvc", i586_rust9x_windows_msvc),
     ("thumbv7a-pc-windows-msvc", thumbv7a_pc_windows_msvc),
     ("thumbv7a-uwp-windows-msvc", thumbv7a_uwp_windows_msvc),
 
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
index d6b77ffd091a9..3b719ebaf07e8 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs
@@ -7,7 +7,8 @@
 // For example, `-C target-cpu=cortex-a53`.
 
 use crate::spec::{
-    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, StackProbeType, Target, TargetOptions,
+    Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, SanitizerSet, StackProbeType, Target,
+    TargetOptions,
 };
 
 pub(crate) fn target() -> Target {
@@ -19,6 +20,7 @@ pub(crate) fn target() -> Target {
         relocation_model: RelocModel::Static,
         disable_redzone: true,
         max_atomic_width: Some(128),
+        supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
         stack_probes: StackProbeType::Inline,
         panic_strategy: PanicStrategy::Abort,
         ..Default::default()
diff --git a/compiler/rustc_target/src/spec/targets/i586_rust9x_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i586_rust9x_windows_msvc.rs
new file mode 100644
index 0000000000000..ca6c37e32ff9c
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/i586_rust9x_windows_msvc.rs
@@ -0,0 +1,8 @@
+use crate::spec::Target;
+
+pub(crate) fn target() -> Target {
+    let mut base = super::i686_rust9x_windows_msvc::target();
+    base.cpu = "pentium".into();
+    base.llvm_target = "i586-pc-windows-msvc".into();
+    base
+}
diff --git a/compiler/rustc_target/src/spec/targets/i686_rust9x_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_rust9x_windows_msvc.rs
new file mode 100644
index 0000000000000..1147357233bd0
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/i686_rust9x_windows_msvc.rs
@@ -0,0 +1,26 @@
+use crate::spec::{LinkerFlavor, Lld, Target};
+
+pub(crate) fn target() -> Target {
+    let mut base = super::i686_pc_windows_msvc::target();
+    base.vendor = "rust9x".into();
+
+    base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &[
+        // "/LARGEADDRESSAWARE",
+        // "/SAFESEH",
+        // ↑ these are already added in the base target
+
+        // Link to ___CxxFrameHandler (XP and earlier MSVCRT) instead of ___CxxFrameHandler3.
+        // This cannot be done in the MSVC `eh_personality` handling because LLVM hardcodes SEH
+        // support based on that name, sadly
+        "/ALTERNATENAME:___CxxFrameHandler3=___CxxFrameHandler",
+    ]);
+
+    base.metadata = crate::spec::TargetMetadata {
+        description: Some("32-bit MSVC rust9x (Windows 95/NT3.51+)".into()),
+        tier: Some(4),
+        host_tools: Some(false),
+        std: Some(true),
+    };
+
+    base
+}
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_rust9x_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/x86_64_rust9x_windows_msvc.rs
new file mode 100644
index 0000000000000..fdaa306995a8b
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/x86_64_rust9x_windows_msvc.rs
@@ -0,0 +1,26 @@
+use crate::spec::{LinkerFlavor, Lld, Target};
+
+pub(crate) fn target() -> Target {
+    let mut base = super::x86_64_pc_windows_msvc::target();
+    // these aren't available on all x86_64 CPUs
+    // base.features = "+cx16,+sse3,+sahf".into();
+    base.plt_by_default = false;
+    base.max_atomic_width = Some(64);
+    base.vendor = "rust9x".into();
+
+    base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &[
+        // Link to ___CxxFrameHandler (XP and earlier MSVCRT) instead of ___CxxFrameHandler3.
+        // This cannot be done in the MSVC `eh_personality` handling because LLVM hardcodes SEH
+        // support based on that name, sadly
+        "/ALTERNATENAME:___CxxFrameHandler3=___CxxFrameHandler",
+    ]);
+
+    base.metadata = crate::spec::TargetMetadata {
+        description: Some("64-bit MSVC rust9x (Windows XP 64bit+)".into()),
+        tier: Some(4),
+        host_tools: Some(false),
+        std: Some(true),
+    };
+
+    base
+}
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 971d3a8110254..e27143f139641 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -6,7 +6,7 @@
 
 use std::fmt::Debug;
 
-use rustc_data_structures::fx::FxIndexSet;
+use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_errors::{Diag, EmissionGuarantee};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
@@ -116,28 +116,39 @@ pub fn overlapping_impls(
         return None;
     }
 
-    let _overlap_with_bad_diagnostics = overlap(
-        tcx,
-        TrackAmbiguityCauses::No,
-        skip_leak_check,
-        impl1_def_id,
-        impl2_def_id,
-        overlap_mode,
-    )?;
-
-    // In the case where we detect an error, run the check again, but
-    // this time tracking intercrate ambiguity causes for better
-    // diagnostics. (These take time and can lead to false errors.)
-    let overlap = overlap(
-        tcx,
-        TrackAmbiguityCauses::Yes,
-        skip_leak_check,
-        impl1_def_id,
-        impl2_def_id,
-        overlap_mode,
-    )
-    .unwrap();
-    Some(overlap)
+    if tcx.next_trait_solver_in_coherence() {
+        overlap(
+            tcx,
+            TrackAmbiguityCauses::Yes,
+            skip_leak_check,
+            impl1_def_id,
+            impl2_def_id,
+            overlap_mode,
+        )
+    } else {
+        let _overlap_with_bad_diagnostics = overlap(
+            tcx,
+            TrackAmbiguityCauses::No,
+            skip_leak_check,
+            impl1_def_id,
+            impl2_def_id,
+            overlap_mode,
+        )?;
+
+        // In the case where we detect an error, run the check again, but
+        // this time tracking intercrate ambiguity causes for better
+        // diagnostics. (These take time and can lead to false errors.)
+        let overlap = overlap(
+            tcx,
+            TrackAmbiguityCauses::Yes,
+            skip_leak_check,
+            impl1_def_id,
+            impl2_def_id,
+            overlap_mode,
+        )
+        .unwrap();
+        Some(overlap)
+    }
 }
 
 fn fresh_impl_header<'tcx>(infcx: &InferCtxt<'tcx>, impl_def_id: DefId) -> ty::ImplHeader<'tcx> {
@@ -615,6 +626,7 @@ fn compute_intercrate_ambiguity_causes<'tcx>(
 }
 
 struct AmbiguityCausesVisitor<'a, 'tcx> {
+    cache: FxHashSet<Goal<'tcx, ty::Predicate<'tcx>>>,
     causes: &'a mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
 }
 
@@ -624,6 +636,10 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
     }
 
     fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) {
+        if !self.cache.insert(goal.goal()) {
+            return;
+        }
+
         let infcx = goal.infcx();
         for cand in goal.candidates() {
             cand.visit_nested_in_probe(self);
@@ -748,5 +764,10 @@ fn search_ambiguity_causes<'tcx>(
     goal: Goal<'tcx, ty::Predicate<'tcx>>,
     causes: &mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
 ) {
-    infcx.probe(|_| infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { causes }));
+    infcx.probe(|_| {
+        infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor {
+            cache: Default::default(),
+            causes,
+        })
+    });
 }
diff --git a/config.rust9x.toml b/config.rust9x.toml
new file mode 100644
index 0000000000000..c0d567957ecf5
--- /dev/null
+++ b/config.rust9x.toml
@@ -0,0 +1,49 @@
+# Includes one of the default files in src/bootstrap/defaults
+change-id = 134650
+
+[llvm]
+# Will download LLVM from CI if available on your platform.
+download-ci-llvm = true
+# NOTE: if you set ↑ to false, disable other LLVM targets to save lots of build time!
+# targets = "X86"
+# experimental-targets = ""
+
+[build]
+build = "x86_64-pc-windows-msvc"
+target = [
+    "i586-rust9x-windows-msvc",
+    "i686-rust9x-windows-msvc",
+    "x86_64-rust9x-windows-msvc",
+    "x86_64-pc-windows-msvc",
+]
+
+docs = false
+
+# extended = true
+# tools = [
+#     #    "cargo",
+#     #    "clippy",
+#     "rustdoc",
+#     #    "rustfmt",
+#     #    "rust-analyzer",
+#     #    "rust-analyzer-proc-macro-srv",
+#     #    "analysis",
+#     "src",
+#     #    "wasm-component-ld",
+#     #    "miri", "cargo-miri" # for dev/nightly channels
+# ]
+
+[install]
+# for creating a downloadable package: python x.py install, then create and archive this
+prefix = "../dist/rust9x"
+sysconfdir = "."
+
+[rust]
+dist-src = false
+
+# you can override this with -i/--incremental
+# incremental = false
+# incremental = true
+
+[dist]
+src-tarball = false
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 05e5d712a2737..1295bd8551ca8 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -2009,7 +2009,7 @@ impl<Args: Tuple, F: Fn<Args> + ?Sized, A: Allocator> Fn<Args> for Box<F, A> {
 }
 
 #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
 impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args> for Box<F, A> {
     type Output = F::Output;
     type CallOnceFuture = F::CallOnceFuture;
@@ -2020,7 +2020,7 @@ impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args>
 }
 
 #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
 impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> for Box<F, A> {
     type CallRefFuture<'a>
         = F::CallRefFuture<'a>
@@ -2033,7 +2033,7 @@ impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> f
 }
 
 #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
 impl<Args: Tuple, F: AsyncFn<Args> + ?Sized, A: Allocator> AsyncFn<Args> for Box<F, A> {
     extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> {
         F::async_call(self, args)
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 84679827ba1c0..2e654d3d1ff1e 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1204,22 +1204,16 @@ fn test_from_iter_specialization_with_iterator_adapters() {
 #[test]
 fn test_in_place_specialization_step_up_down() {
     fn assert_in_place_trait<T: InPlaceIterable>(_: &T) {}
-    let src = vec![[0u8; 4]; 256];
-    let srcptr = src.as_ptr();
-    let src_cap = src.capacity();
-    let iter = src.into_iter().flatten();
-    assert_in_place_trait(&iter);
-    let sink = iter.collect::<Vec<_>>();
-    let sinkptr = sink.as_ptr();
-    assert_eq!(srcptr as *const u8, sinkptr);
-    assert_eq!(src_cap * 4, sink.capacity());
 
-    let iter = sink.into_iter().array_chunks::<4>();
+    let src = vec![0u8; 1024];
+    let srcptr = src.as_ptr();
+    let src_bytes = src.capacity();
+    let iter = src.into_iter().array_chunks::<4>();
     assert_in_place_trait(&iter);
     let sink = iter.collect::<Vec<_>>();
     let sinkptr = sink.as_ptr();
-    assert_eq!(srcptr, sinkptr);
-    assert_eq!(src_cap, sink.capacity());
+    assert_eq!(srcptr.addr(), sinkptr.addr());
+    assert_eq!(src_bytes, sink.capacity() * 4);
 
     let mut src: Vec<u8> = Vec::with_capacity(17);
     let src_bytes = src.capacity();
@@ -1236,13 +1230,6 @@ fn test_in_place_specialization_step_up_down() {
     let sink: Vec<[u8; 2]> = iter.collect();
     assert_eq!(sink.len(), 8);
     assert!(sink.capacity() <= 25);
-
-    let src = vec![[0u8; 4]; 256];
-    let srcptr = src.as_ptr();
-    let iter = src.into_iter().flat_map(|a| a.into_iter().map(|b| b.wrapping_add(1)));
-    assert_in_place_trait(&iter);
-    let sink = iter.collect::<Vec<_>>();
-    assert_eq!(srcptr as *const u8, sink.as_ptr());
 }
 
 #[test]
@@ -1350,6 +1337,20 @@ fn test_collect_after_iterator_clone() {
     assert_eq!(v, [1, 1, 1, 1, 1]);
     assert!(v.len() <= v.capacity());
 }
+
+// regression test for #135103, similar to the one above Flatten/FlatMap had an unsound InPlaceIterable
+// implementation.
+#[test]
+fn test_flatten_clone() {
+    const S: String = String::new();
+
+    let v = vec![[S, "Hello World!".into()], [S, S]];
+    let mut i = v.into_iter().flatten();
+    let _ = i.next();
+    let result: Vec<String> = i.clone().collect();
+    assert_eq!(result, ["Hello World!", "", ""]);
+}
+
 #[test]
 fn test_cow_from() {
     let borrowed: &[_] = &["borrowed", "(slice)"];
diff --git a/library/backtrace b/library/backtrace
index 4d7906bb24ae9..3a1664ec48ad9 160000
--- a/library/backtrace
+++ b/library/backtrace
@@ -1 +1 @@
-Subproject commit 4d7906bb24ae91ee6587127020d360f5298f9e7e
+Subproject commit 3a1664ec48ad9b7f00cf4632368587b4aeaad7a6
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index e6f39db9dced3..21dfdd926e0af 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -178,7 +178,7 @@ impl Layout {
     /// allocate backing structure for `T` (which could be a trait
     /// or other unsized type like a slice).
     #[stable(feature = "alloc_layout", since = "1.28.0")]
-    #[rustc_const_stable(feature = "const_alloc_layout", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")]
     #[must_use]
     #[inline]
     pub const fn for_value<T: ?Sized>(t: &T) -> Self {
@@ -252,7 +252,7 @@ impl Layout {
     /// Returns an error if the combination of `self.size()` and the given
     /// `align` violates the conditions listed in [`Layout::from_size_align`].
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
-    #[rustc_const_stable(feature = "const_alloc_layout", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")]
     #[inline]
     pub const fn align_to(&self, align: usize) -> Result<Self, LayoutError> {
         if let Some(align) = Alignment::new(align) {
@@ -327,7 +327,7 @@ impl Layout {
     /// This is equivalent to adding the result of `padding_needed_for`
     /// to the layout's current size.
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
-    #[rustc_const_stable(feature = "const_alloc_layout", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")]
     #[must_use = "this returns a new `Layout`, \
                   without modifying the original"]
     #[inline]
@@ -426,7 +426,7 @@ impl Layout {
     /// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16])));
     /// ```
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
-    #[rustc_const_stable(feature = "const_alloc_layout", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")]
     #[inline]
     pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
         let new_align = Alignment::max(self.align, next.align);
@@ -489,7 +489,7 @@ impl Layout {
     /// On arithmetic overflow or when the total size would exceed
     /// `isize::MAX`, returns `LayoutError`.
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
-    #[rustc_const_stable(feature = "const_alloc_layout", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_alloc_layout", since = "1.85.0")]
     #[inline]
     pub const fn array<T>(n: usize) -> Result<Self, LayoutError> {
         // Reduce the amount of code we need to monomorphize per `T`.
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index 84bbf985e8be4..b43cf68421594 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -752,10 +752,10 @@ pub struct BuildHasherDefault<H>(marker::PhantomData<fn() -> H>);
 
 impl<H> BuildHasherDefault<H> {
     /// Creates a new BuildHasherDefault for Hasher `H`.
-    #[stable(feature = "build_hasher_default_const_new", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "build_hasher_default_const_new", since = "1.85.0")]
     #[rustc_const_stable(
         feature = "build_hasher_default_const_new",
-        since = "CURRENT_RUSTC_VERSION"
+        since = "1.85.0"
     )]
     pub const fn new() -> Self {
         BuildHasherDefault(marker::PhantomData)
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index 834f44c7790d9..55dcf7cd47e97 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -233,7 +233,7 @@
 //!
 //!  - Operands implicitly convert to `Use` rvalues.
 //!  - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue.
-//!  - [`Discriminant`] and [`CopyForDeref`] have associated functions.
+//!  - [`Discriminant`], [`Len`], and [`CopyForDeref`] have associated functions.
 //!  - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc.
 //!  - The binary operation `Offset` can be created via [`Offset`].
 //!  - Checked binary operations are represented by wrapping the associated binop in [`Checked`].
@@ -401,6 +401,7 @@ define!("mir_storage_dead", fn StorageDead<T>(local: T));
 define!("mir_assume", fn Assume(operand: bool));
 define!("mir_deinit", fn Deinit<T>(place: T));
 define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
+define!("mir_len", fn Len<T>(place: T) -> usize);
 define!(
     "mir_ptr_metadata",
     fn PtrMetadata<P: ?Sized>(place: *const P) -> <P as ::core::ptr::Pointee>::Metadata
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index 0023b46031f12..9b9353b800a98 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -1,7 +1,7 @@
 use crate::iter::adapters::SourceIter;
 use crate::iter::{
-    Cloned, Copied, Empty, Filter, FilterMap, Fuse, FusedIterator, InPlaceIterable, Map, Once,
-    OnceWith, TrustedFused, TrustedLen,
+    Cloned, Copied, Empty, Filter, FilterMap, Fuse, FusedIterator, Map, Once, OnceWith,
+    TrustedFused, TrustedLen,
 };
 use crate::num::NonZero;
 use crate::ops::{ControlFlow, Try};
@@ -157,21 +157,6 @@ where
 {
 }
 
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I, U, F> InPlaceIterable for FlatMap<I, U, F>
-where
-    I: InPlaceIterable,
-    U: BoundedSize + IntoIterator,
-{
-    const EXPAND_BY: Option<NonZero<usize>> = const {
-        match (I::EXPAND_BY, U::UPPER_BOUND) {
-            (Some(m), Some(n)) => m.checked_mul(n),
-            _ => None,
-        }
-    };
-    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
-}
-
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I, U, F> SourceIter for FlatMap<I, U, F>
 where
@@ -386,21 +371,6 @@ where
 {
 }
 
-#[unstable(issue = "none", feature = "inplace_iteration")]
-unsafe impl<I> InPlaceIterable for Flatten<I>
-where
-    I: InPlaceIterable + Iterator,
-    <I as Iterator>::Item: IntoIterator + BoundedSize,
-{
-    const EXPAND_BY: Option<NonZero<usize>> = const {
-        match (I::EXPAND_BY, I::Item::UPPER_BOUND) {
-            (Some(m), Some(n)) => m.checked_mul(n),
-            _ => None,
-        }
-    };
-    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
-}
-
 #[unstable(issue = "none", feature = "inplace_iteration")]
 unsafe impl<I> SourceIter for Flatten<I>
 where
diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs
index 73e6d93106096..97bb21c8a36e8 100644
--- a/library/core/src/iter/traits/collect.rs
+++ b/library/core/src/iter/traits/collect.rs
@@ -472,7 +472,7 @@ macro_rules! spec_tuple_impl {
             #[doc(fake_variadic)]
             #[doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for \
                      1- and 3- through 12-ary tuples were stabilized after 2-tuples, in \
-                     CURRENT_RUSTC_VERSION."]
+                     1.85.0."]
             => ($ty_name, $var_name, $extend_ty_name, $cnt),
         );
     };
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 58fb5be5812c8..284a58c7278fd 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -507,7 +507,7 @@ impl<T> MaybeUninit<T> {
     /// ```
     #[inline(always)]
     #[stable(feature = "maybe_uninit_write", since = "1.55.0")]
-    #[rustc_const_stable(feature = "const_maybe_uninit_write", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_maybe_uninit_write", since = "1.85.0")]
     pub const fn write(&mut self, val: T) -> &mut T {
         *self = MaybeUninit::new(val);
         // SAFETY: We just initialized this value.
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 2d66e5c2f2a7a..b9bb6d6a13f7f 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -333,7 +333,7 @@ pub const fn size_of<T>() -> usize {
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "const_size_of_val", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_size_of_val", since = "1.85.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")]
 pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
     // SAFETY: `val` is a reference, so it's a valid raw pointer
@@ -484,7 +484,7 @@ pub const fn align_of<T>() -> usize {
 #[inline]
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "const_align_of_val", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_align_of_val", since = "1.85.0")]
 #[allow(deprecated)]
 pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
     // SAFETY: val is a reference, so it's a valid raw pointer
@@ -725,7 +725,7 @@ pub unsafe fn uninitialized<T>() -> T {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_swap", since = "1.85.0")]
 #[rustc_diagnostic_item = "mem_swap"]
 pub const fn swap<T>(x: &mut T, y: &mut T) {
     // SAFETY: `&mut` guarantees these are typed readable and writable
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 4c0d95f95e562..2b6adef65e94a 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -818,7 +818,7 @@ impl f32 {
     /// ```
     #[must_use = "this returns the result of the operation, without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn recip(self) -> f32 {
         1.0 / self
@@ -836,7 +836,7 @@ impl f32 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn to_degrees(self) -> f32 {
         // Use a constant for better precision.
@@ -856,7 +856,7 @@ impl f32 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn to_radians(self) -> f32 {
         const RADS_PER_DEG: f32 = consts::PI / 180.0;
@@ -878,7 +878,7 @@ impl f32 {
     /// ```
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn max(self, other: f32) -> f32 {
         intrinsics::maxnumf32(self, other)
@@ -899,7 +899,7 @@ impl f32 {
     /// ```
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn min(self, other: f32) -> f32 {
         intrinsics::minnumf32(self, other)
@@ -988,8 +988,8 @@ impl f32 {
     /// assert_eq!((-5.5f32).midpoint(8.0), 1.25);
     /// ```
     #[inline]
-    #[stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "num_midpoint", since = "1.85.0")]
+    #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")]
     pub const fn midpoint(self, other: f32) -> f32 {
         cfg_if! {
             // Allow faster implementation that have known good 64-bit float
@@ -1396,7 +1396,7 @@ impl f32 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "clamp", since = "1.50.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn clamp(mut self, min: f32, max: f32) -> f32 {
         const_assert!(
@@ -1433,7 +1433,7 @@ impl f32 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn abs(self) -> f32 {
         // SAFETY: this is actually a safe intrinsic
@@ -1458,7 +1458,7 @@ impl f32 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn signum(self) -> f32 {
         if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) }
@@ -1493,7 +1493,7 @@ impl f32 {
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "copysign", since = "1.35.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     pub const fn copysign(self, sign: f32) -> f32 {
         // SAFETY: this is actually a safe intrinsic
         unsafe { intrinsics::copysignf32(self, sign) }
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 77ca56df06705..037b3afa6c46c 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -835,7 +835,7 @@ impl f64 {
     /// ```
     #[must_use = "this returns the result of the operation, without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn recip(self) -> f64 {
         1.0 / self
@@ -853,7 +853,7 @@ impl f64 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn to_degrees(self) -> f64 {
         // The division here is correctly rounded with respect to the true
@@ -874,7 +874,7 @@ impl f64 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn to_radians(self) -> f64 {
         const RADS_PER_DEG: f64 = consts::PI / 180.0;
@@ -896,7 +896,7 @@ impl f64 {
     /// ```
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn max(self, other: f64) -> f64 {
         intrinsics::maxnumf64(self, other)
@@ -917,7 +917,7 @@ impl f64 {
     /// ```
     #[must_use = "this returns the result of the comparison, without modifying either input"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn min(self, other: f64) -> f64 {
         intrinsics::minnumf64(self, other)
@@ -1006,8 +1006,8 @@ impl f64 {
     /// assert_eq!((-5.5f64).midpoint(8.0), 1.25);
     /// ```
     #[inline]
-    #[stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "num_midpoint", since = "1.85.0")]
+    #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")]
     pub const fn midpoint(self, other: f64) -> f64 {
         const LO: f64 = f64::MIN_POSITIVE * 2.;
         const HI: f64 = f64::MAX / 2.;
@@ -1396,7 +1396,7 @@ impl f64 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "clamp", since = "1.50.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn clamp(mut self, min: f64, max: f64) -> f64 {
         const_assert!(
@@ -1433,7 +1433,7 @@ impl f64 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn abs(self) -> f64 {
         // SAFETY: this is actually a safe intrinsic
@@ -1458,7 +1458,7 @@ impl f64 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn signum(self) -> f64 {
         if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) }
@@ -1492,7 +1492,7 @@ impl f64 {
     /// ```
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "copysign", since = "1.35.0")]
-    #[rustc_const_stable(feature = "const_float_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_float_methods", since = "1.85.0")]
     #[inline]
     pub const fn copysign(self, sign: f64) -> f64 {
         // SAFETY: this is actually a safe intrinsic
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 1f5b8ce6c6e22..67d219654b969 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -138,8 +138,8 @@ macro_rules! midpoint_impl {
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")]
         /// ```
-        #[stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "num_midpoint", since = "1.85.0")]
+        #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
@@ -192,8 +192,8 @@ macro_rules! midpoint_impl {
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")]
         #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".midpoint(4), 2);")]
         /// ```
-        #[stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "num_midpoint", since = "1.85.0")]
+        #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index a9294306b1b61..926723b3dbab7 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1543,8 +1543,8 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
         /// # Some(())
         /// # }
         /// ```
-        #[stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
-        #[rustc_const_stable(feature = "num_midpoint", since = "CURRENT_RUSTC_VERSION")]
+        #[stable(feature = "num_midpoint", since = "1.85.0")]
+        #[rustc_const_stable(feature = "num_midpoint", since = "1.85.0")]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs
index 0073afd496070..a5812a7621750 100644
--- a/library/core/src/ops/async_function.rs
+++ b/library/core/src/ops/async_function.rs
@@ -5,9 +5,8 @@ use crate::marker::Tuple;
 ///
 /// All `async fn` and functions returning futures implement this trait.
 #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
 #[rustc_paren_sugar]
-#[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
 #[lang = "async_fn"]
 pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
@@ -20,9 +19,8 @@ pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
 ///
 /// All `async fn` and functions returning futures implement this trait.
 #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
 #[rustc_paren_sugar]
-#[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
 #[lang = "async_fn_mut"]
 pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
@@ -42,9 +40,8 @@ pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
 ///
 /// All `async fn` and functions returning futures implement this trait.
 #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
 #[rustc_paren_sugar]
-#[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
 #[lang = "async_fn_once"]
 pub trait AsyncFnOnce<Args: Tuple> {
@@ -68,7 +65,7 @@ mod impls {
     use crate::marker::Tuple;
 
     #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
     impl<A: Tuple, F: ?Sized> AsyncFn<A> for &F
     where
         F: AsyncFn<A>,
@@ -79,7 +76,7 @@ mod impls {
     }
 
     #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
     impl<A: Tuple, F: ?Sized> AsyncFnMut<A> for &F
     where
         F: AsyncFn<A>,
@@ -95,7 +92,7 @@ mod impls {
     }
 
     #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
     impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce<A> for &'a F
     where
         F: AsyncFn<A>,
@@ -109,7 +106,7 @@ mod impls {
     }
 
     #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
     impl<A: Tuple, F: ?Sized> AsyncFnMut<A> for &mut F
     where
         F: AsyncFnMut<A>,
@@ -125,7 +122,7 @@ mod impls {
     }
 
     #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+    #[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
     impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce<A> for &'a mut F
     where
         F: AsyncFnMut<A>,
diff --git a/library/core/src/prelude/common.rs b/library/core/src/prelude/common.rs
index e38ef1e147c76..b8640bc381502 100644
--- a/library/core/src/prelude/common.rs
+++ b/library/core/src/prelude/common.rs
@@ -12,6 +12,10 @@ pub use crate::marker::{Copy, Send, Sized, Sync, Unpin};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
+#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
+#[doc(no_inline)]
+pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce};
 
 // Re-exported functions
 #[stable(feature = "core_prelude", since = "1.4.0")]
diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs
index 9b23874bcf7ba..d3fda1cd273f9 100644
--- a/library/core/src/prelude/mod.rs
+++ b/library/core/src/prelude/mod.rs
@@ -71,7 +71,7 @@ pub mod rust_2021 {
 /// The 2024 version of the core prelude.
 ///
 /// See the [module-level documentation](self) for more.
-#[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "prelude_2024", since = "1.85.0")]
 pub mod rust_2024 {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::common::*;
@@ -84,7 +84,7 @@ pub mod rust_2024 {
     #[doc(no_inline)]
     pub use crate::convert::{TryFrom, TryInto};
 
-    #[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "prelude_2024", since = "1.85.0")]
     #[doc(no_inline)]
     pub use crate::future::{Future, IntoFuture};
 }
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index a70af793004b2..3d9ad0706eb0b 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1009,7 +1009,7 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "const_swap", since = "1.85.0")]
 #[rustc_diagnostic_item = "ptr_swap"]
 pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
     // Give ourselves some scratch space to work with.
@@ -2150,7 +2150,7 @@ pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool {
 /// ```
 ///
 /// [subtype]: https://doc.rust-lang.org/reference/subtyping.html
-#[stable(feature = "ptr_fn_addr_eq", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "ptr_fn_addr_eq", since = "1.85.0")]
 #[inline(always)]
 #[must_use = "function pointer comparison produces a value"]
 pub fn fn_addr_eq<T: FnPtr, U: FnPtr>(f: T, g: U) -> bool {
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index d75d570a969f8..5d9d337f101a5 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1594,7 +1594,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`ptr::swap`]: crate::ptr::swap()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_swap", since = "1.85.0")]
     #[inline(always)]
     pub const unsafe fn swap(self, with: *mut T)
     where
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 1058fa42cc1e3..21bde4b8cc1fb 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -224,7 +224,7 @@ impl<T: ?Sized> NonNull<T> {
     /// }
     /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
-    #[rustc_const_stable(feature = "const_nonnull_new", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_nonnull_new", since = "1.85.0")]
     #[inline]
     pub const fn new(ptr: *mut T) -> Option<Self> {
         if !ptr.is_null() {
@@ -1146,7 +1146,7 @@ impl<T: ?Sized> NonNull<T> {
     /// [`ptr::swap`]: crate::ptr::swap()
     #[inline(always)]
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
-    #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_swap", since = "1.85.0")]
     pub const unsafe fn swap(self, with: NonNull<T>)
     where
         T: Sized,
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index df9720698d32f..c6206fc99ea68 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -913,7 +913,7 @@ impl<T> [T] {
     /// assert!(v == ["a", "b", "e", "d", "c"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_swap", since = "1.85.0")]
     #[inline]
     #[track_caller]
     pub const fn swap(&mut self, a: usize, b: usize) {
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index ba429005fab3d..4c51ca0a5e437 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -60,7 +60,7 @@ impl RawWaker {
         RawWaker { data, vtable }
     }
 
-    #[stable(feature = "noop_waker", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "noop_waker", since = "1.85.0")]
     const NOOP: RawWaker = {
         const VTABLE: RawWakerVTable = RawWakerVTable::new(
             // Cloning just returns a new no-op raw waker
@@ -564,8 +564,8 @@ impl Waker {
     /// ```
     #[inline]
     #[must_use]
-    #[stable(feature = "noop_waker", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "noop_waker", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "noop_waker", since = "1.85.0")]
+    #[rustc_const_stable(feature = "noop_waker", since = "1.85.0")]
     pub const fn noop() -> &'static Waker {
         const WAKER: &Waker = &Waker { waker: RawWaker::NOOP };
         WAKER
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 6380c941e6ab5..28bcd5e6e2b9b 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -144,4 +144,5 @@ check-cfg = [
     # and to the `backtrace` crate which messes-up with Cargo list
     # of declared features, we therefor expect any feature cfg
     'cfg(feature, values(any()))',
+    'cfg(target_vendor, values("rust9x"))',
 ]
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 56d734ba2fbfb..f7d2eec90743c 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -298,7 +298,7 @@ impl<K, V, S> HashMap<K, V, S> {
     #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
     #[rustc_const_stable(
         feature = "const_collections_with_hasher",
-        since = "CURRENT_RUSTC_VERSION"
+        since = "1.85.0"
     )]
     pub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
         HashMap { base: base::HashMap::with_hasher(hash_builder) }
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index bcf6d6b4ccf3a..c1b794c58f120 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -390,7 +390,7 @@ impl<T, S> HashSet<T, S> {
     #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
     #[rustc_const_stable(
         feature = "const_collections_with_hasher",
-        since = "CURRENT_RUSTC_VERSION"
+        since = "1.85.0"
     )]
     pub const fn with_hasher(hasher: S) -> HashSet<T, S> {
         HashSet { base: base::HashSet::with_hasher(hasher) }
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 535236ff89a37..11a29cdae62e2 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -622,7 +622,7 @@ impl Error for JoinPathsError {
 ///
 /// In UWP (Universal Windows Platform) targets this function is unimplemented and always returns `None`.
 ///
-/// Before Rust CURRENT_RUSTC_VERSION, this function used to return the value of the 'HOME' environment variable
+/// Before Rust 1.85.0, this function used to return the value of the 'HOME' environment variable
 /// on Windows, which in Cygwin or Mingw environments could return non-standard paths like `/home/you`
 /// instead of `C:\Users\you`.
 ///
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 9b752ed14437c..f390fabad29dc 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2402,7 +2402,7 @@ pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 /// # Platform-specific behavior
 ///
 /// This function currently corresponds to the `rename` function on Unix
-/// and the `SetFileInformationByHandle` function on Windows.
+/// and the `MoveFileExW` or `SetFileInformationByHandle` function on Windows.
 ///
 /// Because of this, the behavior when both `from` and `to` exist differs. On
 /// Unix, if `from` is a directory, `to` must also be an (empty) directory. If
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 28f16da1ed8d2..c4664d5eae825 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1855,7 +1855,7 @@ fn windows_unix_socket_exists() {
     // std doesn't currently support Unix sockets on Windows so manually create one here.
     net::init();
     unsafe {
-        let socket = c::WSASocketW(
+        let socket = c::WSASocketA(
             c::AF_UNIX as i32,
             c::SOCK_STREAM,
             0,
diff --git a/library/std/src/hash/random.rs b/library/std/src/hash/random.rs
index 236803b24a2ec..8f677f587ba84 100644
--- a/library/std/src/hash/random.rs
+++ b/library/std/src/hash/random.rs
@@ -65,13 +65,16 @@ impl RandomState {
         // iteration order allows a form of DOS attack. To counter that we
         // increment one of the seeds on every RandomState creation, giving
         // every corresponding HashMap a different iteration order.
-        thread_local!(static KEYS: Cell<(u64, u64)> = {
+        thread_local!(static KEYS: Cell<[u8; 16]> = {
             Cell::new(hashmap_random_keys())
         });
 
         KEYS.with(|keys| {
-            let (k0, k1) = keys.get();
-            keys.set((k0.wrapping_add(1), k1));
+            let [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15] = keys.get();
+            let k0 = u64::from_ne_bytes([n0, n1, n2, n3, n4, n5, n6, n7]);
+            let k1 = u64::from_ne_bytes([n8, n9, n10, n11, n12, n13, n14, n15]);
+            let [n0, n1, n2, n3, n4, n5, n6, n7] = k0.wrapping_add(1).to_ne_bytes();
+            keys.set([n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15]);
             RandomState { k0, k1 }
         })
     }
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 476c403c21f33..38b723366175f 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -339,7 +339,7 @@ pub enum ErrorKind {
     #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     NotSeekable,
     /// Filesystem quota or some other kind of quota was exceeded.
-    #[stable(feature = "io_error_quota_exceeded", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_quota_exceeded", since = "1.85.0")]
     QuotaExceeded,
     /// File larger than allowed or supported.
     ///
@@ -364,7 +364,7 @@ pub enum ErrorKind {
     #[stable(feature = "io_error_a_bit_more", since = "1.83.0")]
     Deadlock,
     /// Cross-device or cross-filesystem (hard) link or rename.
-    #[stable(feature = "io_error_crosses_devices", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "io_error_crosses_devices", since = "1.85.0")]
     CrossesDevices,
     /// Too many (hard) links to the same filesystem object.
     ///
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 2f8f5c5c58180..c2ad0832a1a74 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -289,6 +289,7 @@
 #![feature(doc_masked)]
 #![feature(doc_notable_trait)]
 #![feature(dropck_eyepatch)]
+#![feature(extended_varargs_abi_support)]
 #![feature(f128)]
 #![feature(f16)]
 #![feature(formatting_options)]
@@ -301,6 +302,7 @@
 #![feature(macro_metavar_expr_concat)]
 #![feature(min_specialization)]
 #![feature(must_not_suspend)]
+#![feature(naked_functions)]
 #![feature(needs_panic_runtime)]
 #![feature(negative_impls)]
 #![feature(never_type)]
diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs
index c6d7bad944093..05557edc1e0b6 100644
--- a/library/std/src/os/windows/io/socket.rs
+++ b/library/std/src/os/windows/io/socket.rs
@@ -87,7 +87,7 @@ impl OwnedSocket {
 
     // FIXME(strict_provenance_magic): we defined RawSocket to be a u64 ;-;
     #[allow(fuzzy_provenance_casts)]
-    #[cfg(not(target_vendor = "uwp"))]
+    #[cfg(not(any(target_vendor = "uwp", target_vendor = "rust9x")))]
     pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
         cvt(unsafe {
             sys::c::SetHandleInformation(
@@ -98,6 +98,31 @@ impl OwnedSocket {
         })
         .map(drop)
     }
+    #[allow(fuzzy_provenance_casts)]
+    #[cfg(target_vendor = "rust9x")]
+    pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
+        let res = cvt(unsafe {
+            sys::c::SetHandleInformation(
+                self.as_raw_socket() as sys::c::HANDLE,
+                sys::c::HANDLE_FLAG_INHERIT,
+                0,
+            )
+        })
+        .map(drop);
+
+        match res {
+            // SetHandleInformation is exported by kernel32 on Win9X/ME, but only returns
+            // `ERROR_CALL_NOT_IMPLEMENTED`. Sockets are non-inheritable on these systems anyways,
+            // so we "fail successfully" here.
+            // https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/150523#MORE_INFORMATION
+
+            // SetHandleInformation is also unavailable on WinNT before 3.51. This is fine,
+            // however, because MS did not supply WinSock 2 for Windows NT before 4.0, so this
+            // function is not called.
+            Err(e) if e.raw_os_error() == Some(sys::c::ERROR_CALL_NOT_IMPLEMENTED as i32) => Ok(()),
+            res => res,
+        }
+    }
 
     #[cfg(target_vendor = "uwp")]
     pub(crate) fn set_no_inherit(&self) -> io::Result<()> {
@@ -110,9 +135,9 @@ impl BorrowedSocket<'_> {
     /// object as the existing `BorrowedSocket` instance.
     #[stable(feature = "io_safety", since = "1.63.0")]
     pub fn try_clone_to_owned(&self) -> io::Result<OwnedSocket> {
-        let mut info = unsafe { mem::zeroed::<sys::c::WSAPROTOCOL_INFOW>() };
+        let mut info = unsafe { mem::zeroed::<sys::c::WSAPROTOCOL_INFOA>() };
         let result = unsafe {
-            sys::c::WSADuplicateSocketW(
+            sys::c::WSADuplicateSocketA(
                 self.as_raw_socket() as sys::c::SOCKET,
                 sys::c::GetCurrentProcessId(),
                 &mut info,
@@ -120,7 +145,7 @@ impl BorrowedSocket<'_> {
         };
         sys::net::cvt(result)?;
         let socket = unsafe {
-            sys::c::WSASocketW(
+            sys::c::WSASocketA(
                 info.iAddressFamily,
                 info.iSocketType,
                 info.iProtocol,
@@ -140,7 +165,7 @@ impl BorrowedSocket<'_> {
             }
 
             let socket = unsafe {
-                sys::c::WSASocketW(
+                sys::c::WSASocketA(
                     info.iAddressFamily,
                     info.iSocketType,
                     info.iProtocol,
diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs
index 22a364074c52d..713e417e0440c 100644
--- a/library/std/src/prelude/common.rs
+++ b/library/std/src/prelude/common.rs
@@ -13,7 +13,7 @@ pub use crate::marker::{Send, Sized, Sync, Unpin};
 #[doc(no_inline)]
 pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
 #[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
-#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
+#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "1.85.0"))]
 #[doc(no_inline)]
 pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce};
 
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index 64349987fcfb8..4ec328208f015 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -169,12 +169,12 @@ pub mod rust_2021 {
 /// The 2024 version of the prelude of The Rust Standard Library.
 ///
 /// See the [module-level documentation](self) for more.
-#[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "prelude_2024", since = "1.85.0")]
 pub mod rust_2024 {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::common::*;
 
-    #[stable(feature = "prelude_2024", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "prelude_2024", since = "1.85.0")]
     #[doc(no_inline)]
     pub use core::prelude::rust_2024::*;
 }
diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs
index 3447a0157e4c5..ffebbc223f947 100644
--- a/library/std/src/sys/pal/windows/args.rs
+++ b/library/std/src/sys/pal/windows/args.rs
@@ -333,7 +333,17 @@ pub(crate) fn make_bat_command_line(
     // hence the trailing quote here. It will be closed after all arguments
     // have been added.
     // Using /e:ON enables "command extensions" which is essential for the `%` hack to work.
+    #[cfg(not(target_vendor = "rust9x"))]
     let mut cmd: Vec<u16> = "cmd.exe /e:ON /v:OFF /d /c \"".encode_utf16().collect();
+    #[cfg(target_vendor = "rust9x")]
+    let mut cmd: Vec<u16> = if crate::sys::compat::checks::is_windows_nt() {
+        // Using /X instead of /e:ON for old NT versions.
+        "cmd.exe /X /v:OFF /d /c \""
+    } else {
+        "command.com /c \""
+    }
+    .encode_utf16()
+    .collect();
 
     // Push the script name surrounded by its quote pair.
     cmd.push(b'"' as u16);
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 9ce3e912caf1b..9b7d9216622a6 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -5,12 +5,19 @@
 #![unstable(issue = "none", feature = "windows_c")]
 #![allow(clippy::style)]
 
-use core::ffi::{CStr, c_uint, c_ulong, c_ushort, c_void};
+#[allow(unused_imports)]
+use core::ffi::c_void;
+use core::ffi::{c_uint, c_ulong, c_ushort};
 use core::{mem, ptr};
 
 mod windows_sys;
 pub use windows_sys::*;
 
+#[cfg(target_vendor = "rust9x")]
+pub(crate) mod fileextd;
+#[cfg(target_vendor = "rust9x")]
+pub(crate) mod wspiapi;
+
 pub type WCHAR = u16;
 
 pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::without_provenance_mut(-1i32 as _);
@@ -19,9 +26,9 @@ pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::without_provenance_mut(-1i
 pub const EXIT_SUCCESS: u32 = 0;
 pub const EXIT_FAILURE: u32 = 1;
 
-#[cfg(target_vendor = "win7")]
+#[cfg(any(target_vendor = "win7", target_vendor = "rust9x"))]
 pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() };
-#[cfg(target_vendor = "win7")]
+#[cfg(any(target_vendor = "win7", target_vendor = "rust9x"))]
 pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() };
 #[cfg(not(target_thread_local))]
 pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() };
@@ -109,7 +116,7 @@ if #[cfg(not(target_vendor = "uwp"))] {
 }
 
 // Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
-#[cfg(not(target_vendor = "win7"))]
+#[cfg(not(any(target_vendor = "win7", target_vendor = "rust9x")))]
 #[cfg_attr(
     target_arch = "x86",
     link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")
@@ -122,7 +129,7 @@ extern "system" {
 // Functions that aren't available on every version of Windows that we support,
 // but we still use them and just provide some form of a fallback implementation.
 compat_fn_with_fallback! {
-    pub static KERNEL32: &CStr = c"kernel32";
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
 
     // >= Win10 1607
     // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
@@ -138,7 +145,7 @@ compat_fn_with_fallback! {
 
     // >= Win8 / Server 2012
     // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
-    #[cfg(target_vendor = "win7")]
+    #[cfg(any(target_vendor = "win7", target_vendor = "rust9x"))]
     pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {
         unsafe { GetSystemTimeAsFileTime(lpsystemtimeasfiletime) }
     }
@@ -150,7 +157,7 @@ compat_fn_with_fallback! {
     }
 }
 
-#[cfg(not(target_vendor = "win7"))]
+#[cfg(not(any(target_vendor = "win7", target_vendor = "rust9x")))]
 // Use raw-dylib to import synchronization functions to workaround issues with the older mingw import library.
 #[cfg_attr(
     target_arch = "x86",
@@ -187,11 +194,31 @@ compat_fn_optional! {
     pub fn WakeByAddressSingle(address: *const c_void);
 }
 
-#[cfg(any(target_vendor = "win7", target_vendor = "uwp"))]
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static SYNCH: &CStr = c"api-ms-win-core-synch-l1-2-0" => { load: true, unicows: false };
+
+    pub fn WaitOnAddress(
+        address: *const c_void,
+        compareaddress: *const c_void,
+        addresssize: usize,
+        dwmilliseconds: u32
+    ) -> BOOL {
+        rtabort!("unimplemented")
+    }
+    pub fn WakeByAddressSingle(address: *const c_void) {
+        rtabort!("unimplemented")
+    }
+    pub fn WakeByAddressAll(address: *const c_void) {
+        rtabort!("unimplemented")
+    }
+}
+
+#[cfg(any(target_vendor = "win7", target_vendor = "rust9x", target_vendor = "uwp"))]
 compat_fn_with_fallback! {
-    pub static NTDLL: &CStr = c"ntdll";
+    pub static NTDLL: &CStr = c"ntdll" => { load: true, unicows: false };
 
-    #[cfg(target_vendor = "win7")]
+    #[cfg(any(target_vendor = "win7", target_vendor = "rust9x"))]
     pub fn NtCreateKeyedEvent(
         KeyedEventHandle: *mut HANDLE,
         DesiredAccess: u32,
@@ -200,7 +227,7 @@ compat_fn_with_fallback! {
     ) -> NTSTATUS {
         panic!("keyed events not available")
     }
-    #[cfg(target_vendor = "win7")]
+    #[cfg(any(target_vendor = "win7", target_vendor = "rust9x"))]
     pub fn NtReleaseKeyedEvent(
         EventHandle: HANDLE,
         Key: *const c_void,
@@ -209,7 +236,7 @@ compat_fn_with_fallback! {
     ) -> NTSTATUS {
         panic!("keyed events not available")
     }
-    #[cfg(target_vendor = "win7")]
+    #[cfg(any(target_vendor = "win7", target_vendor = "rust9x"))]
     pub fn NtWaitForKeyedEvent(
         EventHandle: HANDLE,
         Key: *const c_void,
@@ -236,7 +263,7 @@ compat_fn_with_fallback! {
     ) -> NTSTATUS {
         STATUS_NOT_IMPLEMENTED
     }
-    #[cfg(target_vendor = "uwp")]
+    #[cfg(any(target_vendor = "uwp", target_vendor = "rust9x"))]
     pub fn NtReadFile(
         filehandle: HANDLE,
         event: HANDLE,
@@ -250,7 +277,7 @@ compat_fn_with_fallback! {
     ) -> NTSTATUS {
         STATUS_NOT_IMPLEMENTED
     }
-    #[cfg(target_vendor = "uwp")]
+    #[cfg(any(target_vendor = "uwp", target_vendor = "rust9x"))]
     pub fn NtWriteFile(
         filehandle: HANDLE,
         event: HANDLE,
@@ -264,8 +291,460 @@ compat_fn_with_fallback! {
     ) -> NTSTATUS {
         STATUS_NOT_IMPLEMENTED
     }
-    #[cfg(target_vendor = "uwp")]
+    #[cfg(any(target_vendor = "uwp", target_vendor = "rust9x"))]
     pub fn RtlNtStatusToDosError(Status: NTSTATUS) -> u32 {
         Status as u32
     }
+
+    #[cfg(target_vendor = "rust9x")]
+    pub fn NtOpenFile(
+        filehandle: *mut HANDLE,
+        desiredaccess: u32,
+        objectattributes: *const OBJECT_ATTRIBUTES,
+        iostatusblock: *mut IO_STATUS_BLOCK,
+        shareaccess: u32,
+        openoptions: u32
+    ) -> NTSTATUS {
+        rtabort!("unimplemented")
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+
+    // >= NT 4
+    // https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-signalobjectandwait
+    pub fn SignalObjectAndWait(
+        hobjecttosignal: HANDLE,
+        hobjecttowaiton: HANDLE,
+        dwmilliseconds: u32,
+        balertable: BOOL
+    ) -> WAIT_EVENT { rtabort!("unimplemented") }
+    // >= NT 4
+    // https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-tryentercriticalsection
+    pub fn TryEnterCriticalSection(lpcriticalsection: *mut CRITICAL_SECTION) -> BOOL {
+        rtabort!("unimplemented")
+    }
+    // >= Win7 / Server 2008 R2
+    // https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-tryacquiresrwlockexclusive
+    pub fn TryAcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> BOOLEAN { rtabort!("unimplemented") }
+    pub fn TryAcquireSRWLockShared(srwlock: *mut SRWLOCK) -> BOOLEAN { rtabort!("unimplemented") }
+    // >= Vista / Server 2008
+    // https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-acquiresrwlockexclusive
+    pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> () { rtabort!("unimplemented") }
+    pub fn AcquireSRWLockShared(srwlock: *mut SRWLOCK) -> () { rtabort!("unimplemented") }
+    pub fn ReleaseSRWLockExclusive(srwlock: *mut SRWLOCK) -> () { rtabort!("unimplemented") }
+    pub fn ReleaseSRWLockShared(srwlock: *mut SRWLOCK) -> () { rtabort!("unimplemented") }
+    pub fn SleepConditionVariableSRW(
+        conditionvariable: *mut CONDITION_VARIABLE,
+        srwlock: *mut SRWLOCK,
+        dwmilliseconds: u32,
+        flags: u32,
+    ) -> BOOL { rtabort!("unimplemented") }
+    pub fn WakeAllConditionVariable(conditionvariable: *mut CONDITION_VARIABLE) -> () {
+        rtabort!("unimplemented")
+    }
+    pub fn WakeConditionVariable(conditionvariable: *mut CONDITION_VARIABLE) -> () {
+        rtabort!("unimplemented")
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= XP
+    // https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-addvectoredexceptionhandler
+    pub fn AddVectoredExceptionHandler(
+        first: u32,
+        handler: PVECTORED_EXCEPTION_HANDLER
+    ) -> *mut core::ffi::c_void { core::ptr::null_mut() }
+    // >= Vista / Server 2003 SP1 / XPx64
+    // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadstackguarantee
+    pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL { TRUE }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= 95 / NT 3.5
+    // https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime
+    pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: *mut FILETIME) {
+        unsafe {
+            // implementation based on old MSDN docs
+            let mut st: SYSTEMTIME = crate::mem::zeroed();
+            GetSystemTime(&mut st);
+            crate::sys::cvt(SystemTimeToFileTime(&st, lpSystemTimeAsFileTime)).unwrap();
+        }
+    }
+    // >= NT 4
+    // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-switchtothread
+    pub fn SwitchToThread() -> BOOL {
+        unsafe { Sleep(0); }
+        TRUE
+    }
+
+    // >= Vista / Server 2008
+    // https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createwaitabletimerexw
+    pub fn CreateWaitableTimerExW(
+        lptimerattributes: *const SECURITY_ATTRIBUTES,
+        lptimername: PCWSTR,
+        dwflags: u32,
+        dwdesiredaccess: u32
+    ) -> HANDLE {
+        ptr::null_mut()
+    }
+
+    // >= 98 / NT 4
+    // https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-setwaitabletimer
+    pub fn SetWaitableTimer(htimer: HANDLE,
+        lpduetime: *const i64,
+        lperiod: i32,
+        pfncompletionroutine: PTIMERAPCROUTINE,
+        lpargtocompletionroutine: *const core::ffi::c_void,
+        fresume: BOOL
+    ) -> BOOL {
+        rtabort!("unimplemented")
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= 2000
+    // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfilepointerex
+    pub fn SetFilePointerEx(
+        hfile: HANDLE,
+        lidistancetomove: i64,
+        lpnewfilepointer: *mut i64,
+        dwmovemethod: SET_FILE_POINTER_MOVE_METHOD,
+    ) -> BOOL {
+        unsafe {
+            let distance_low = lidistancetomove as i32;
+            let mut distance_high = (lidistancetomove >> 32) as i32;
+
+            let new_pos_low = SetFilePointer(hfile, distance_low, &mut distance_high, dwmovemethod);
+
+            // since (-1 as u32) could be a valid value for the lower 32 bits of the new file
+            // pointer position, a call to GetLastError is needed to actually see if it failed
+            if new_pos_low == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR {
+                return FALSE;
+            }
+
+            if !lpnewfilepointer.is_null() {
+                *lpnewfilepointer = (distance_high as i64) << 32 | (new_pos_low as i64);
+            }
+
+            TRUE
+        }
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= Vista / Server 2008
+    // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsymboliclinkw
+    pub fn CreateSymbolicLinkW(
+        lpsymlinkfilename: PCWSTR,
+        lptargetfilename: PCWSTR,
+        dwflags: SYMBOLIC_LINK_FLAGS,
+    ) -> BOOLEAN {
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); };
+        0
+    }
+    // >= Vista / Server 2008
+    // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew
+    pub fn GetFinalPathNameByHandleW(
+        hfile: HANDLE,
+        lpszfilepath: PWSTR,
+        cchfilepath: u32,
+        dwflags: GETFINALPATHNAMEBYHANDLE_FLAGS
+    ) -> u32 {
+        rtabort!("unimplemented")
+    }
+    // >= 2000
+    // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createhardlinkw
+    pub fn CreateHardLinkW(
+        lpfilename: PCWSTR,
+        lpexistingfilename: PCWSTR,
+        lpsecurityattributes: *const SECURITY_ATTRIBUTES,
+    ) -> BOOL {
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); };
+        FALSE
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static advapi32: &CStr = c"advapi32" => { load: true, unicows: false };
+    // >= XP / Server 2003
+    // https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
+    pub fn SystemFunction036(
+        randombuffer: *mut core::ffi::c_void,
+        randombufferlength: u32
+    ) -> BOOLEAN {
+        rtabort!("unimplemented")
+    }
+
+    // >= NT 4.0 / Windows 95 OSR2 / Windows 95 with IE 3.02
+    // https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta
+    pub fn CryptAcquireContextA(
+        phprov: *mut usize,
+        szcontainer: PCSTR,
+        szprovider: PCSTR,
+        dwprovtype: u32,
+        dwflags: u32
+    ) -> BOOL {
+        rtabort!("unimplemented")
+    }
+    pub fn CryptReleaseContext(hprov: usize, dwflags: u32) -> BOOL {
+        rtabort!("unimplemented")
+    }
+    pub fn CryptGenRandom(hprov: usize, dwlen: u32, pbbuffer: *mut u8) -> BOOL {
+        rtabort!("unimplemented")
+    }
+}
+#[cfg(target_vendor = "rust9x")]
+pub use self::SystemFunction036 as RtlGenRandom;
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static userenv: &CStr = c"userenv" => { load: true, unicows: false };
+    // >= NT 4.0
+    // https://learn.microsoft.com/en-us/windows/win32/api/userenv/nf-userenv-getuserprofiledirectoryw
+    pub fn GetUserProfileDirectoryW(
+        htoken: HANDLE,
+        lpprofiledir: PWSTR,
+        lpcchsize: *mut u32
+    ) -> BOOL {
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); };
+        FALSE
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static advapi32: &CStr = c"advapi32" => { load: true, unicows: false };
+    // >= NT
+    // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocesstoken
+    pub fn OpenProcessToken(
+        processhandle: HANDLE,
+        desiredaccess: TOKEN_ACCESS_MASK,
+        tokenhandle: *mut HANDLE
+    ) -> BOOL {
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); };
+        FALSE
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= NT 3.51+
+    // https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-sethandleinformation
+    pub fn SetHandleInformation(hobject: HANDLE, dwmask: u32, dwflags: HANDLE_FLAGS) -> BOOL {
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); };
+        FALSE
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+mod ws2_32 {
+    use super::*;
+    compat_fn_with_fallback! {
+        pub static WS2_32: &CStr = c"ws2_32" => { load: true, unicows: false };
+
+        // >= NT4/2000 with IPv6 Tech Preview
+        // https://learn.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo
+        pub fn getaddrinfo(
+            pnodename: PCSTR,
+            pservicename: PCSTR,
+            phints: *const ADDRINFOA,
+            ppresult: *mut *mut ADDRINFOA,
+        ) -> i32 {
+            unsafe { wship6::getaddrinfo(pnodename, pservicename, phints, ppresult) }
+        }
+        // >= NT4/2000 with IPv6 Tech Preview
+        pub fn freeaddrinfo(paddrinfo: *const ADDRINFOA) -> () {
+            unsafe { wship6::freeaddrinfo(paddrinfo) }
+        }
+    }
+}
+#[cfg(target_vendor = "rust9x")]
+pub use ws2_32::{freeaddrinfo, getaddrinfo};
+
+#[cfg(target_vendor = "rust9x")]
+mod wship6 {
+    use super::wspiapi::{wspiapi_freeaddrinfo, wspiapi_getaddrinfo};
+    use super::{ADDRINFOA, PCSTR};
+
+    compat_fn_with_fallback! {
+        pub static WSHIP6: &CStr = c"wship6" => { load: true, unicows: false };
+
+        // >= 2000 with IPv6 Tech Preview
+        pub fn getaddrinfo(
+            pnodename: PCSTR,
+            pservicename: PCSTR,
+            phints: *const ADDRINFOA,
+            ppresult: *mut *mut ADDRINFOA,
+        ) -> i32 {
+            unsafe { wspiapi_getaddrinfo(pnodename, pservicename, phints, ppresult) }
+        }
+        // >= 2000 with IPv6 Tech Preview
+        pub fn freeaddrinfo(paddrinfo: *const ADDRINFOA)-> () {
+            unsafe { wspiapi_freeaddrinfo(paddrinfo) }
+        }
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= Vista / Server 2008
+    // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-initializeprocthreadattributelist
+    pub fn InitializeProcThreadAttributeList(
+        lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST,
+        dwattributecount: u32,
+        dwflags: u32,
+        lpsize: *mut usize
+    ) -> BOOL {
+        rtabort!("unimplemented")
+    }
+    // >= Vista / Server 2008
+    pub fn UpdateProcThreadAttribute(
+        lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST,
+        dwflags: u32,
+        attribute: usize,
+        lpvalue: *const core::ffi::c_void,
+        cbsize: usize,
+        lppreviousvalue: *mut core::ffi::c_void,
+        lpreturnsize: *const usize
+    ) -> BOOL {
+        rtabort!("unimplemented")
+    }
+    // >= Vista / Server 2008
+    pub fn DeleteProcThreadAttributeList(lpattributelist: LPPROC_THREAD_ATTRIBUTE_LIST) {
+        rtabort!("unimplemented")
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: true };
+    // >= NT 3.5+, 95+
+    // https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-freeenvironmentstringsw
+    pub fn FreeEnvironmentStringsW(penv: PCWSTR) -> BOOL {
+        // just leak it on NT 3.1
+        TRUE
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= Vista / Server 2008
+    // https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal
+    pub fn CompareStringOrdinal(
+        lpstring1: PCWSTR,
+        cchcount1: i32,
+        lpstring2: PCWSTR,
+        cchcount2: i32,
+        bignorecase: BOOL,
+    ) -> COMPARESTRING_RESULT {
+        rtabort!("unimplemented")
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= 98+, NT4.0
+    // https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal
+    pub fn CancelIo(hfile: HANDLE) -> BOOL {
+        rtabort!("unimplemented")
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= NT4.0
+    // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfileexw
+    pub fn FindFirstFileExW(
+        lpfilename: PCWSTR,
+        finfolevelid: FINDEX_INFO_LEVELS,
+        lpfindfiledata: *mut core::ffi::c_void,
+        fsearchop: FINDEX_SEARCH_OPS,
+        lpsearchfilter: *const core::ffi::c_void,
+        dwadditionalflags: FIND_FIRST_EX_FLAGS
+    ) -> HANDLE {
+        rtabort!("unimplemented")
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static KERNEL32: &CStr = c"kernel32" => { load: false, unicows: false };
+    // >= NT
+    // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-lockfileex
+    pub fn LockFileEx(
+        hfile: HANDLE,
+        dwflags: LOCK_FILE_FLAGS,
+        dwreserved: u32,
+        nnumberofbytestolocklow: u32,
+        nnumberofbytestolockhigh: u32,
+        lpoverlapped: *mut OVERLAPPED
+    ) -> BOOL {
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); };
+        FALSE
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+pub(crate) use fileextd::{
+    get_file_information_by_handle_ex as GetFileInformationByHandleEx,
+    set_file_information_by_handle as SetFileInformationByHandle,
+};
+#[cfg(target_vendor = "rust9x")]
+compat_fn_with_fallback! {
+    pub static NTDLL: &CStr = c"ntdll" => { load: true, unicows: false };
+    // all NT only
+    fn NtQueryDirectoryFile(
+        filehandle: HANDLE,
+        event: HANDLE,
+        apcroutine: PIO_APC_ROUTINE,
+        apccontext: *const core::ffi::c_void,
+        iostatusblock: *mut IO_STATUS_BLOCK,
+        fileinformation: *mut core::ffi::c_void,
+        length: u32,
+        fileinformationclass: FILE_INFORMATION_CLASS,
+        returnsingleentry: BOOLEAN,
+        filename: *const UNICODE_STRING,
+        restartscan: BOOLEAN
+    ) -> NTSTATUS {
+        rtabort!("unimplemented")
+    }
+    fn NtQueryInformationFile(filehandle: HANDLE,
+        iostatusblock: *mut IO_STATUS_BLOCK,
+        fileinformation: *mut core::ffi::c_void,
+        length: u32,
+        fileinformationclass: FILE_INFORMATION_CLASS
+    ) -> NTSTATUS {
+        rtabort!("unimplemented")
+    }
+    fn NtSetInformationFile(filehandle: HANDLE,
+        iostatusblock: *mut IO_STATUS_BLOCK,
+        fileinformation: *const core::ffi::c_void,
+        length: u32,
+        fileinformationclass: FILE_INFORMATION_CLASS
+    ) -> NTSTATUS {
+        rtabort!("unimplemented")
+    }
+    fn NtWaitForSingleObject(handle: HANDLE,
+        alertable: BOOLEAN,
+        timeout: *mut i64
+    ) -> NTSTATUS {
+        rtabort!("unimplemented")
+    }
 }
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index c06f274685c24..fcd202adccadb 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -9,6 +9,7 @@ Windows.Wdk.Storage.FileSystem.FILE_CREATE_TREE_CONNECTION
 Windows.Wdk.Storage.FileSystem.FILE_DELETE_ON_CLOSE
 Windows.Wdk.Storage.FileSystem.FILE_DIRECTORY_FILE
 Windows.Wdk.Storage.FileSystem.FILE_DISALLOW_EXCLUSIVE
+Windows.Wdk.Storage.FileSystem.FILE_INFORMATION_CLASS
 Windows.Wdk.Storage.FileSystem.FILE_NO_COMPRESSION
 Windows.Wdk.Storage.FileSystem.FILE_NO_EA_KNOWLEDGE
 Windows.Wdk.Storage.FileSystem.FILE_NO_INTERMEDIATE_BUFFERING
@@ -31,13 +32,25 @@ Windows.Wdk.Storage.FileSystem.FILE_SUPERSEDE
 Windows.Wdk.Storage.FileSystem.FILE_SYNCHRONOUS_IO_ALERT
 Windows.Wdk.Storage.FileSystem.FILE_SYNCHRONOUS_IO_NONALERT
 Windows.Wdk.Storage.FileSystem.FILE_WRITE_THROUGH
+Windows.Wdk.Storage.FileSystem.FileAttributeTagInformation
+Windows.Wdk.Storage.FileSystem.FileBasicInformation
+Windows.Wdk.Storage.FileSystem.FileDispositionInformation
+Windows.Wdk.Storage.FileSystem.FileDispositionInformationEx
+Windows.Wdk.Storage.FileSystem.FileEndOfFileInformation
+Windows.Wdk.Storage.FileSystem.FileFullDirectoryInformation
+Windows.Wdk.Storage.FileSystem.FileFullDirectoryInformation
+Windows.Wdk.Storage.FileSystem.FileNameInformation
 Windows.Wdk.Storage.FileSystem.NtCreateFile
 Windows.Wdk.Storage.FileSystem.NTCREATEFILE_CREATE_DISPOSITION
 Windows.Wdk.Storage.FileSystem.NTCREATEFILE_CREATE_OPTIONS
 Windows.Wdk.Storage.FileSystem.NtOpenFile
+Windows.Wdk.Storage.FileSystem.NtQueryDirectoryFile
+Windows.Wdk.Storage.FileSystem.NtQueryInformationFile
 Windows.Wdk.Storage.FileSystem.NtReadFile
+Windows.Wdk.Storage.FileSystem.NtSetInformationFile
 Windows.Wdk.Storage.FileSystem.NtWriteFile
 Windows.Wdk.Storage.FileSystem.SYMLINK_FLAG_RELATIVE
+Windows.Wdk.System.Threading.NtWaitForSingleObject
 Windows.Win32.Foundation.BOOL
 Windows.Win32.Foundation.BOOLEAN
 Windows.Win32.Foundation.CloseHandle
@@ -1978,11 +1991,15 @@ Windows.Win32.Networking.WinSock.FD_SET
 Windows.Win32.Networking.WinSock.FIONBIO
 Windows.Win32.Networking.WinSock.freeaddrinfo
 Windows.Win32.Networking.WinSock.getaddrinfo
+Windows.Win32.Networking.WinSock.gethostbyname
 Windows.Win32.Networking.WinSock.getpeername
+Windows.Win32.Networking.WinSock.getservbyname
 Windows.Win32.Networking.WinSock.getsockname
 Windows.Win32.Networking.WinSock.getsockopt
 Windows.Win32.Networking.WinSock.IN6_ADDR
 Windows.Win32.Networking.WinSock.IN_ADDR
+Windows.Win32.Networking.WinSock.inet_addr
+Windows.Win32.Networking.WinSock.inet_ntoa
 Windows.Win32.Networking.WinSock.INVALID_SOCKET
 Windows.Win32.Networking.WinSock.ioctlsocket
 Windows.Win32.Networking.WinSock.IP_ADD_MEMBERSHIP
@@ -2119,6 +2136,7 @@ Windows.Win32.Networking.WinSock.WSABASEERR
 Windows.Win32.Networking.WinSock.WSABUF
 Windows.Win32.Networking.WinSock.WSACleanup
 Windows.Win32.Networking.WinSock.WSADATA
+Windows.Win32.Networking.WinSock.WSADuplicateSocketA
 Windows.Win32.Networking.WinSock.WSADuplicateSocketW
 Windows.Win32.Networking.WinSock.WSAEACCES
 Windows.Win32.Networking.WinSock.WSAEADDRINUSE
@@ -2175,11 +2193,13 @@ Windows.Win32.Networking.WinSock.WSAHOST_NOT_FOUND
 Windows.Win32.Networking.WinSock.WSANO_DATA
 Windows.Win32.Networking.WinSock.WSANO_RECOVERY
 Windows.Win32.Networking.WinSock.WSANOTINITIALISED
+Windows.Win32.Networking.WinSock.WSAPROTOCOL_INFOA
 Windows.Win32.Networking.WinSock.WSAPROTOCOL_INFOW
 Windows.Win32.Networking.WinSock.WSAPROTOCOLCHAIN
 Windows.Win32.Networking.WinSock.WSARecv
 Windows.Win32.Networking.WinSock.WSASend
 Windows.Win32.Networking.WinSock.WSASERVICE_NOT_FOUND
+Windows.Win32.Networking.WinSock.WSASocketA
 Windows.Win32.Networking.WinSock.WSASocketW
 Windows.Win32.Networking.WinSock.WSAStartup
 Windows.Win32.Networking.WinSock.WSASYSCALLFAILURE
@@ -2188,6 +2208,11 @@ Windows.Win32.Networking.WinSock.WSATRY_AGAIN
 Windows.Win32.Networking.WinSock.WSATYPE_NOT_FOUND
 Windows.Win32.Networking.WinSock.WSAVERNOTSUPPORTED
 Windows.Win32.Security.Authentication.Identity.RtlGenRandom
+Windows.Win32.Security.Cryptography.CRYPT_VERIFYCONTEXT
+Windows.Win32.Security.Cryptography.CryptAcquireContextA
+Windows.Win32.Security.Cryptography.CryptGenRandom
+Windows.Win32.Security.Cryptography.CryptReleaseContext
+Windows.Win32.Security.Cryptography.PROV_RSA_FULL
 Windows.Win32.Security.SECURITY_ATTRIBUTES
 Windows.Win32.Security.TOKEN_ACCESS_MASK
 Windows.Win32.Security.TOKEN_ACCESS_PSEUDO_HANDLE
@@ -2283,6 +2308,7 @@ Windows.Win32.Storage.FileSystem.FILE_FLAG_SEQUENTIAL_SCAN
 Windows.Win32.Storage.FileSystem.FILE_FLAG_SESSION_AWARE
 Windows.Win32.Storage.FileSystem.FILE_FLAG_WRITE_THROUGH
 Windows.Win32.Storage.FileSystem.FILE_FLAGS_AND_ATTRIBUTES
+Windows.Win32.Storage.FileSystem.FILE_FULL_DIR_INFO
 Windows.Win32.Storage.FileSystem.FILE_GENERIC_EXECUTE
 Windows.Win32.Storage.FileSystem.FILE_GENERIC_READ
 Windows.Win32.Storage.FileSystem.FILE_GENERIC_WRITE
@@ -2290,6 +2316,7 @@ Windows.Win32.Storage.FileSystem.FILE_ID_BOTH_DIR_INFO
 Windows.Win32.Storage.FileSystem.FILE_INFO_BY_HANDLE_CLASS
 Windows.Win32.Storage.FileSystem.FILE_IO_PRIORITY_HINT_INFO
 Windows.Win32.Storage.FileSystem.FILE_LIST_DIRECTORY
+Windows.Win32.Storage.FileSystem.FILE_NAME_INFO
 Windows.Win32.Storage.FileSystem.FILE_NAME_NORMALIZED
 Windows.Win32.Storage.FileSystem.FILE_NAME_OPENED
 Windows.Win32.Storage.FileSystem.FILE_READ_ATTRIBUTES
@@ -2341,6 +2368,7 @@ Windows.Win32.Storage.FileSystem.FindClose
 Windows.Win32.Storage.FileSystem.FindExInfoBasic
 Windows.Win32.Storage.FileSystem.FindExSearchNameMatch
 Windows.Win32.Storage.FileSystem.FindFirstFileExW
+Windows.Win32.Storage.FileSystem.FindFirstFileW
 Windows.Win32.Storage.FileSystem.FindNextFileW
 Windows.Win32.Storage.FileSystem.FlushFileBuffers
 Windows.Win32.Storage.FileSystem.GetFileAttributesW
@@ -2352,6 +2380,8 @@ Windows.Win32.Storage.FileSystem.GetFinalPathNameByHandleW
 Windows.Win32.Storage.FileSystem.GetFullPathNameW
 Windows.Win32.Storage.FileSystem.GetTempPathW
 Windows.Win32.Storage.FileSystem.INVALID_FILE_ATTRIBUTES
+Windows.Win32.Storage.FileSystem.INVALID_SET_FILE_POINTER
+Windows.Win32.Storage.FileSystem.LockFile
 Windows.Win32.Storage.FileSystem.LOCKFILE_EXCLUSIVE_LOCK
 Windows.Win32.Storage.FileSystem.LOCKFILE_FAIL_IMMEDIATELY
 Windows.Win32.Storage.FileSystem.LockFileEx
@@ -2385,8 +2415,10 @@ Windows.Win32.Storage.FileSystem.SECURITY_IMPERSONATION
 Windows.Win32.Storage.FileSystem.SECURITY_SQOS_PRESENT
 Windows.Win32.Storage.FileSystem.SECURITY_VALID_SQOS_FLAGS
 Windows.Win32.Storage.FileSystem.SET_FILE_POINTER_MOVE_METHOD
+Windows.Win32.Storage.FileSystem.SetEndOfFile
 Windows.Win32.Storage.FileSystem.SetFileAttributesW
 Windows.Win32.Storage.FileSystem.SetFileInformationByHandle
+Windows.Win32.Storage.FileSystem.SetFilePointer
 Windows.Win32.Storage.FileSystem.SetFilePointerEx
 Windows.Win32.Storage.FileSystem.SetFileTime
 Windows.Win32.Storage.FileSystem.SPECIFIC_RIGHTS_ALL
@@ -2407,6 +2439,7 @@ Windows.Win32.Storage.FileSystem.VOLUME_NAME_NONE
 Windows.Win32.Storage.FileSystem.WIN32_FIND_DATAW
 Windows.Win32.Storage.FileSystem.WRITE_DAC
 Windows.Win32.Storage.FileSystem.WRITE_OWNER
+Windows.Win32.Storage.FileSystem.WriteFile
 Windows.Win32.Storage.FileSystem.WriteFileEx
 Windows.Win32.System.Console.CONSOLE_MODE
 Windows.Win32.System.Console.CONSOLE_READCONSOLE_CONTROL
@@ -2475,6 +2508,7 @@ Windows.Win32.System.LibraryLoader.GetModuleFileNameW
 Windows.Win32.System.LibraryLoader.GetModuleHandleA
 Windows.Win32.System.LibraryLoader.GetModuleHandleW
 Windows.Win32.System.LibraryLoader.GetProcAddress
+Windows.Win32.System.LibraryLoader.LoadLibraryA
 Windows.Win32.System.Performance.QueryPerformanceCounter
 Windows.Win32.System.Performance.QueryPerformanceFrequency
 Windows.Win32.System.Pipes.CreateNamedPipeW
@@ -2492,8 +2526,11 @@ Windows.Win32.System.Pipes.PIPE_TYPE_MESSAGE
 Windows.Win32.System.Pipes.PIPE_WAIT
 Windows.Win32.System.SystemInformation.GetSystemDirectoryW
 Windows.Win32.System.SystemInformation.GetSystemInfo
+Windows.Win32.System.SystemInformation.GetSystemTime
 Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime
 Windows.Win32.System.SystemInformation.GetSystemTimePreciseAsFileTime
+Windows.Win32.System.SystemInformation.GetTickCount
+Windows.Win32.System.SystemInformation.GetVersion
 Windows.Win32.System.SystemInformation.GetWindowsDirectoryW
 Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE
 Windows.Win32.System.SystemInformation.SYSTEM_INFO
@@ -2524,14 +2561,18 @@ Windows.Win32.System.Threading.CREATE_SUSPENDED
 Windows.Win32.System.Threading.CREATE_UNICODE_ENVIRONMENT
 Windows.Win32.System.Threading.CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
 Windows.Win32.System.Threading.CREATE_WAITABLE_TIMER_MANUAL_RESET
+Windows.Win32.System.Threading.CreateEventA
 Windows.Win32.System.Threading.CreateEventW
+Windows.Win32.System.Threading.CreateMutexA
 Windows.Win32.System.Threading.CreateProcessW
 Windows.Win32.System.Threading.CreateThread
 Windows.Win32.System.Threading.CreateWaitableTimerExW
 Windows.Win32.System.Threading.DEBUG_ONLY_THIS_PROCESS
 Windows.Win32.System.Threading.DEBUG_PROCESS
+Windows.Win32.System.Threading.DeleteCriticalSection
 Windows.Win32.System.Threading.DeleteProcThreadAttributeList
 Windows.Win32.System.Threading.DETACHED_PROCESS
+Windows.Win32.System.Threading.EnterCriticalSection
 Windows.Win32.System.Threading.ExitProcess
 Windows.Win32.System.Threading.EXTENDED_STARTUPINFO_PRESENT
 Windows.Win32.System.Threading.GetActiveProcessorCount
@@ -2546,9 +2587,11 @@ Windows.Win32.System.Threading.INFINITE
 Windows.Win32.System.Threading.INHERIT_CALLER_PRIORITY
 Windows.Win32.System.Threading.INHERIT_PARENT_AFFINITY
 Windows.Win32.System.Threading.INIT_ONCE_INIT_FAILED
+Windows.Win32.System.Threading.InitializeCriticalSection
 Windows.Win32.System.Threading.InitializeProcThreadAttributeList
 Windows.Win32.System.Threading.InitOnceBeginInitialize
 Windows.Win32.System.Threading.InitOnceComplete
+Windows.Win32.System.Threading.LeaveCriticalSection
 Windows.Win32.System.Threading.LPPROC_THREAD_ATTRIBUTE_LIST
 Windows.Win32.System.Threading.LPTHREAD_START_ROUTINE
 Windows.Win32.System.Threading.NORMAL_PRIORITY_CLASS
@@ -2561,10 +2604,14 @@ Windows.Win32.System.Threading.PROFILE_KERNEL
 Windows.Win32.System.Threading.PROFILE_SERVER
 Windows.Win32.System.Threading.PROFILE_USER
 Windows.Win32.System.Threading.REALTIME_PRIORITY_CLASS
+Windows.Win32.System.Threading.ReleaseMutex
 Windows.Win32.System.Threading.ReleaseSRWLockExclusive
 Windows.Win32.System.Threading.ReleaseSRWLockShared
+Windows.Win32.System.Threading.ResetEvent
+Windows.Win32.System.Threading.SetEvent
 Windows.Win32.System.Threading.SetThreadStackGuarantee
 Windows.Win32.System.Threading.SetWaitableTimer
+Windows.Win32.System.Threading.SignalObjectAndWait
 Windows.Win32.System.Threading.Sleep
 Windows.Win32.System.Threading.SleepConditionVariableSRW
 Windows.Win32.System.Threading.SleepEx
@@ -2600,11 +2647,13 @@ Windows.Win32.System.Threading.TlsGetValue
 Windows.Win32.System.Threading.TlsSetValue
 Windows.Win32.System.Threading.TryAcquireSRWLockExclusive
 Windows.Win32.System.Threading.TryAcquireSRWLockShared
+Windows.Win32.System.Threading.TryEnterCriticalSection
 Windows.Win32.System.Threading.UpdateProcThreadAttribute
 Windows.Win32.System.Threading.WaitForMultipleObjects
 Windows.Win32.System.Threading.WaitForSingleObject
 Windows.Win32.System.Threading.WakeAllConditionVariable
 Windows.Win32.System.Threading.WakeConditionVariable
+Windows.Win32.System.Time.SystemTimeToFileTime
 Windows.Win32.System.WindowsProgramming.FILE_RENAME_FLAG_POSIX_SEMANTICS
 Windows.Win32.System.WindowsProgramming.FILE_RENAME_FLAG_REPLACE_IF_EXISTS
 Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE
diff --git a/library/std/src/sys/pal/windows/c/fileextd.rs b/library/std/src/sys/pal/windows/c/fileextd.rs
new file mode 100644
index 0000000000000..1216aac2b9414
--- /dev/null
+++ b/library/std/src/sys/pal/windows/c/fileextd.rs
@@ -0,0 +1,174 @@
+//! Manual implementation of a subset of `GetFileInformationByHandleEx` and
+//! `SetFileInformationByHandle` based on `fileextd.lib` from Microsoft. Many of their later-added
+//! APIs do exist all the way back to NT3.1, but were not exposed via a Win32 API until later.
+
+use super::*;
+
+pub(crate) unsafe fn get_file_information_by_handle_ex(
+    file_handle: HANDLE,
+    fileinformationclass: FILE_INFO_BY_HANDLE_CLASS,
+    lpfileinformation: *mut core::ffi::c_void,
+    dwbuffersize: u32,
+) -> BOOL {
+    if !crate::sys::compat::checks::is_windows_nt() {
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED) };
+        return FALSE;
+    }
+
+    unsafe {
+        #[allow(non_upper_case_globals)]
+        let (class, min_buffer_size, use_directory_api_info): (
+            FILE_INFORMATION_CLASS,
+            u32,
+            Option<bool>,
+        ) = match fileinformationclass {
+            FileBasicInfo => {
+                (FileBasicInformation, core::mem::size_of::<FILE_BASIC_INFO>() as u32, None)
+            }
+            FileNameInfo => {
+                (FileNameInformation, core::mem::size_of::<FILE_NAME_INFO>() as u32, None)
+            }
+            FileAttributeTagInfo => (
+                // NT API: 2000 and up
+                FileAttributeTagInformation,
+                core::mem::size_of::<FILE_ATTRIBUTE_TAG_INFO>() as u32,
+                None,
+            ),
+            // rust9x: replaced with the following two
+            // FileIdBothDirectoryInfo => (
+            //     // NT API: XP/2003 and up; exposed via Win32 API since Vista
+            //     FileIdBothDirectoryInformation,
+            //     core::mem::size_of::<FILE_ID_BOTH_DIR_INFO>() as u32,
+            //     Some(false),
+            // ),
+            // FileIdBothDirectoryRestartInfo => (
+            //     // NT API: XP/2003 and up; exposed via Win32 API since Vista
+            //     FileIdBothDirectoryInformation,
+            //     core::mem::size_of::<FILE_ID_BOTH_DIR_INFO>() as u32,
+            //     Some(true),
+            // ),
+            FileFullDirectoryInfo => (
+                // NT API: at least NT4 but likely 3.1+; exposed via Win32 API since Win8
+                FileFullDirectoryInformation,
+                core::mem::size_of::<FILE_FULL_DIR_INFO>() as u32,
+                Some(false),
+            ),
+            FileFullDirectoryRestartInfo => (
+                // NT API: at least NT4 but likely 3.1+; exposed via Win32 API since Win8
+                FileFullDirectoryInformation,
+                core::mem::size_of::<FILE_FULL_DIR_INFO>() as u32,
+                Some(true),
+            ),
+            _ => {
+                SetLastError(ERROR_INVALID_PARAMETER);
+                return FALSE;
+            }
+        };
+
+        if dwbuffersize < min_buffer_size {
+            SetLastError(ERROR_BAD_LENGTH);
+            return FALSE;
+        }
+
+        let mut io_status_block: IO_STATUS_BLOCK = core::mem::zeroed();
+        let mut status = if let Some(restart_scan) = use_directory_api_info {
+            NtQueryDirectoryFile(
+                file_handle,
+                core::ptr::null_mut(),
+                None,
+                core::ptr::null(),
+                &mut io_status_block,
+                lpfileinformation,
+                dwbuffersize,
+                class,
+                false as BOOLEAN,
+                core::ptr::null(),
+                restart_scan as BOOLEAN,
+            )
+        } else {
+            NtQueryInformationFile(
+                file_handle,
+                &mut io_status_block,
+                lpfileinformation,
+                dwbuffersize,
+                class,
+            )
+        };
+
+        if status == STATUS_PENDING {
+            status = NtWaitForSingleObject(file_handle, false as BOOLEAN, core::ptr::null_mut());
+        }
+
+        if status < 0 {
+            set_last_error_from_ntstatus(status);
+            return FALSE;
+        }
+
+        // keeping for reference; FileStreamInformation is not used by the standard library
+        // currently if class == FileStreamInformation && io_status_block.Information == 0 {
+        //     set_last_error_from_ntstatus(STATUS_END_OF_FILE); return FALSE; }
+    }
+    TRUE
+}
+
+pub(crate) unsafe fn set_file_information_by_handle(
+    file_handle: HANDLE,
+    fileinformationclass: FILE_INFO_BY_HANDLE_CLASS,
+    lpfileinformation: *const core::ffi::c_void,
+    dwbuffersize: u32,
+) -> BOOL {
+    if !crate::sys::compat::checks::is_windows_nt() {
+        unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED) };
+        return FALSE;
+    }
+
+    unsafe {
+        #[allow(non_upper_case_globals)]
+        let (class, min_buffer_size): (FILE_INFORMATION_CLASS, u32) = match fileinformationclass {
+            FileBasicInfo => (FileBasicInformation, core::mem::size_of::<FILE_BASIC_INFO>() as u32),
+            FileEndOfFileInfo => {
+                (FileEndOfFileInformation, core::mem::size_of::<FILE_END_OF_FILE_INFO>() as u32)
+            }
+            FileDispositionInfo => {
+                (FileDispositionInformation, core::mem::size_of::<FILE_DISPOSITION_INFO>() as u32)
+            }
+            FileDispositionInfoEx => (
+                // NT API: some Windows 10 version
+                FileDispositionInformationEx,
+                core::mem::size_of::<FILE_DISPOSITION_INFO_EX>() as u32,
+            ),
+            _ => {
+                SetLastError(ERROR_INVALID_PARAMETER);
+                return FALSE;
+            }
+        };
+
+        if dwbuffersize < min_buffer_size {
+            SetLastError(ERROR_BAD_LENGTH);
+            return FALSE;
+        }
+
+        let mut io_status_block: IO_STATUS_BLOCK = core::mem::zeroed();
+        let status = NtSetInformationFile(
+            file_handle,
+            &mut io_status_block,
+            lpfileinformation,
+            dwbuffersize,
+            class,
+        );
+
+        if status < 0 {
+            set_last_error_from_ntstatus(status);
+            return FALSE;
+        }
+    }
+
+    TRUE
+}
+
+fn set_last_error_from_ntstatus(status: NTSTATUS) {
+    unsafe {
+        let error = RtlNtStatusToDosError(status);
+        SetLastError(error);
+    }
+}
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index 79513d33a1ac7..4b672f5ffe8d3 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -1,6 +1,9 @@
 // Bindings generated by `windows-bindgen` 0.58.0
 
 #![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
+windows_targets::link!("advapi32.dll" "system" fn CryptAcquireContextA(phprov : *mut usize, szcontainer : PCSTR, szprovider : PCSTR, dwprovtype : u32, dwflags : u32) -> BOOL);
+windows_targets::link!("advapi32.dll" "system" fn CryptGenRandom(hprov : usize, dwlen : u32, pbbuffer : *mut u8) -> BOOL);
+windows_targets::link!("advapi32.dll" "system" fn CryptReleaseContext(hprov : usize, dwflags : u32) -> BOOL);
 windows_targets::link!("advapi32.dll" "system" fn OpenProcessToken(processhandle : HANDLE, desiredaccess : TOKEN_ACCESS_MASK, tokenhandle : *mut HANDLE) -> BOOL);
 windows_targets::link!("advapi32.dll" "system" "SystemFunction036" fn RtlGenRandom(randombuffer : *mut core::ffi::c_void, randombufferlength : u32) -> BOOLEAN);
 windows_targets::link!("kernel32.dll" "system" fn AcquireSRWLockExclusive(srwlock : *mut SRWLOCK));
@@ -11,22 +14,27 @@ windows_targets::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE)
 windows_targets::link!("kernel32.dll" "system" fn CompareStringOrdinal(lpstring1 : PCWSTR, cchcount1 : i32, lpstring2 : PCWSTR, cchcount2 : i32, bignorecase : BOOL) -> COMPARESTRING_RESULT);
 windows_targets::link!("kernel32.dll" "system" fn CopyFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, lpprogressroutine : LPPROGRESS_ROUTINE, lpdata : *const core::ffi::c_void, pbcancel : *mut BOOL, dwcopyflags : u32) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn CreateDirectoryW(lppathname : PCWSTR, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn CreateEventA(lpeventattributes : *const SECURITY_ATTRIBUTES, bmanualreset : BOOL, binitialstate : BOOL, lpname : PCSTR) -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn CreateEventW(lpeventattributes : *const SECURITY_ATTRIBUTES, bmanualreset : BOOL, binitialstate : BOOL, lpname : PCWSTR) -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn CreateFileW(lpfilename : PCWSTR, dwdesiredaccess : u32, dwsharemode : FILE_SHARE_MODE, lpsecurityattributes : *const SECURITY_ATTRIBUTES, dwcreationdisposition : FILE_CREATION_DISPOSITION, dwflagsandattributes : FILE_FLAGS_AND_ATTRIBUTES, htemplatefile : HANDLE) -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn CreateHardLinkW(lpfilename : PCWSTR, lpexistingfilename : PCWSTR, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn CreateMutexA(lpmutexattributes : *const SECURITY_ATTRIBUTES, binitialowner : BOOL, lpname : PCSTR) -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn CreateNamedPipeW(lpname : PCWSTR, dwopenmode : FILE_FLAGS_AND_ATTRIBUTES, dwpipemode : NAMED_PIPE_MODE, nmaxinstances : u32, noutbuffersize : u32, ninbuffersize : u32, ndefaulttimeout : u32, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn CreatePipe(hreadpipe : *mut HANDLE, hwritepipe : *mut HANDLE, lppipeattributes : *const SECURITY_ATTRIBUTES, nsize : u32) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn CreateProcessW(lpapplicationname : PCWSTR, lpcommandline : PWSTR, lpprocessattributes : *const SECURITY_ATTRIBUTES, lpthreadattributes : *const SECURITY_ATTRIBUTES, binherithandles : BOOL, dwcreationflags : PROCESS_CREATION_FLAGS, lpenvironment : *const core::ffi::c_void, lpcurrentdirectory : PCWSTR, lpstartupinfo : *const STARTUPINFOW, lpprocessinformation : *mut PROCESS_INFORMATION) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn CreateSymbolicLinkW(lpsymlinkfilename : PCWSTR, lptargetfilename : PCWSTR, dwflags : SYMBOLIC_LINK_FLAGS) -> BOOLEAN);
 windows_targets::link!("kernel32.dll" "system" fn CreateThread(lpthreadattributes : *const SECURITY_ATTRIBUTES, dwstacksize : usize, lpstartaddress : LPTHREAD_START_ROUTINE, lpparameter : *const core::ffi::c_void, dwcreationflags : THREAD_CREATION_FLAGS, lpthreadid : *mut u32) -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn CreateWaitableTimerExW(lptimerattributes : *const SECURITY_ATTRIBUTES, lptimername : PCWSTR, dwflags : u32, dwdesiredaccess : u32) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn DeleteCriticalSection(lpcriticalsection : *mut CRITICAL_SECTION));
 windows_targets::link!("kernel32.dll" "system" fn DeleteFileW(lpfilename : PCWSTR) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn DeleteProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST));
 windows_targets::link!("kernel32.dll" "system" fn DeviceIoControl(hdevice : HANDLE, dwiocontrolcode : u32, lpinbuffer : *const core::ffi::c_void, ninbuffersize : u32, lpoutbuffer : *mut core::ffi::c_void, noutbuffersize : u32, lpbytesreturned : *mut u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn DuplicateHandle(hsourceprocesshandle : HANDLE, hsourcehandle : HANDLE, htargetprocesshandle : HANDLE, lptargethandle : *mut HANDLE, dwdesiredaccess : u32, binherithandle : BOOL, dwoptions : DUPLICATE_HANDLE_OPTIONS) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn EnterCriticalSection(lpcriticalsection : *mut CRITICAL_SECTION));
 windows_targets::link!("kernel32.dll" "system" fn ExitProcess(uexitcode : u32) -> !);
 windows_targets::link!("kernel32.dll" "system" fn FindClose(hfindfile : HANDLE) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn FindFirstFileExW(lpfilename : PCWSTR, finfolevelid : FINDEX_INFO_LEVELS, lpfindfiledata : *mut core::ffi::c_void, fsearchop : FINDEX_SEARCH_OPS, lpsearchfilter : *const core::ffi::c_void, dwadditionalflags : FIND_FIRST_EX_FLAGS) -> HANDLE);
+windows_targets::link!("kernel32.dll" "system" fn FindFirstFileW(lpfilename : PCWSTR, lpfindfiledata : *mut WIN32_FIND_DATAW) -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn FindNextFileW(hfindfile : HANDLE, lpfindfiledata : *mut WIN32_FIND_DATAW) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn FlushFileBuffers(hfile : HANDLE) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn FormatMessageW(dwflags : FORMAT_MESSAGE_OPTIONS, lpsource : *const core::ffi::c_void, dwmessageid : u32, dwlanguageid : u32, lpbuffer : PWSTR, nsize : u32, arguments : *const *const i8) -> u32);
@@ -58,14 +66,21 @@ windows_targets::link!("kernel32.dll" "system" fn GetProcessId(process : HANDLE)
 windows_targets::link!("kernel32.dll" "system" fn GetStdHandle(nstdhandle : STD_HANDLE) -> HANDLE);
 windows_targets::link!("kernel32.dll" "system" fn GetSystemDirectoryW(lpbuffer : PWSTR, usize : u32) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn GetSystemInfo(lpsysteminfo : *mut SYSTEM_INFO));
+windows_targets::link!("kernel32.dll" "system" fn GetSystemTime(lpsystemtime : *mut SYSTEMTIME));
 windows_targets::link!("kernel32.dll" "system" fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime : *mut FILETIME));
 windows_targets::link!("kernel32.dll" "system" fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime : *mut FILETIME));
 windows_targets::link!("kernel32.dll" "system" fn GetTempPathW(nbufferlength : u32, lpbuffer : PWSTR) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetTickCount() -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetVersion() -> u32);
 windows_targets::link!("kernel32.dll" "system" fn GetWindowsDirectoryW(lpbuffer : PWSTR, usize : u32) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn InitOnceBeginInitialize(lpinitonce : *mut INIT_ONCE, dwflags : u32, fpending : *mut BOOL, lpcontext : *mut *mut core::ffi::c_void) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn InitOnceComplete(lpinitonce : *mut INIT_ONCE, dwflags : u32, lpcontext : *const core::ffi::c_void) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn InitializeCriticalSection(lpcriticalsection : *mut CRITICAL_SECTION));
 windows_targets::link!("kernel32.dll" "system" fn InitializeProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwattributecount : u32, dwflags : u32, lpsize : *mut usize) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn LeaveCriticalSection(lpcriticalsection : *mut CRITICAL_SECTION));
+windows_targets::link!("kernel32.dll" "system" fn LoadLibraryA(lplibfilename : PCSTR) -> HMODULE);
 windows_targets::link!("kernel32.dll" "system" fn LocalFree(hmem : HLOCAL) -> HLOCAL);
+windows_targets::link!("kernel32.dll" "system" fn LockFile(hfile : HANDLE, dwfileoffsetlow : u32, dwfileoffsethigh : u32, nnumberofbytestolocklow : u32, nnumberofbytestolockhigh : u32) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn LockFileEx(hfile : HANDLE, dwflags : LOCK_FILE_FLAGS, dwreserved : u32, nnumberofbytestolocklow : u32, nnumberofbytestolockhigh : u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn MoveFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, dwflags : MOVE_FILE_FLAGS) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn MultiByteToWideChar(codepage : u32, dwflags : MULTI_BYTE_TO_WIDE_CHAR_FLAGS, lpmultibytestr : PCSTR, cbmultibyte : i32, lpwidecharstr : PWSTR, cchwidechar : i32) -> i32);
@@ -74,23 +89,30 @@ windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceFrequency(lpfr
 windows_targets::link!("kernel32.dll" "system" fn ReadConsoleW(hconsoleinput : HANDLE, lpbuffer : *mut core::ffi::c_void, nnumberofcharstoread : u32, lpnumberofcharsread : *mut u32, pinputcontrol : *const CONSOLE_READCONSOLE_CONTROL) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn ReadFile(hfile : HANDLE, lpbuffer : *mut u8, nnumberofbytestoread : u32, lpnumberofbytesread : *mut u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn ReadFileEx(hfile : HANDLE, lpbuffer : *mut u8, nnumberofbytestoread : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPOVERLAPPED_COMPLETION_ROUTINE) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn ReleaseMutex(hmutex : HANDLE) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn ReleaseSRWLockExclusive(srwlock : *mut SRWLOCK));
 windows_targets::link!("kernel32.dll" "system" fn ReleaseSRWLockShared(srwlock : *mut SRWLOCK));
 windows_targets::link!("kernel32.dll" "system" fn RemoveDirectoryW(lppathname : PCWSTR) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn ResetEvent(hevent : HANDLE) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn SetCurrentDirectoryW(lppathname : PCWSTR) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetEndOfFile(hfile : HANDLE) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn SetEnvironmentVariableW(lpname : PCWSTR, lpvalue : PCWSTR) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetEvent(hevent : HANDLE) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn SetFileAttributesW(lpfilename : PCWSTR, dwfileattributes : FILE_FLAGS_AND_ATTRIBUTES) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn SetFileInformationByHandle(hfile : HANDLE, fileinformationclass : FILE_INFO_BY_HANDLE_CLASS, lpfileinformation : *const core::ffi::c_void, dwbuffersize : u32) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SetFilePointer(hfile : HANDLE, ldistancetomove : i32, lpdistancetomovehigh : *mut i32, dwmovemethod : SET_FILE_POINTER_MOVE_METHOD) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn SetFilePointerEx(hfile : HANDLE, lidistancetomove : i64, lpnewfilepointer : *mut i64, dwmovemethod : SET_FILE_POINTER_MOVE_METHOD) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn SetFileTime(hfile : HANDLE, lpcreationtime : *const FILETIME, lplastaccesstime : *const FILETIME, lplastwritetime : *const FILETIME) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn SetHandleInformation(hobject : HANDLE, dwmask : u32, dwflags : HANDLE_FLAGS) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn SetLastError(dwerrcode : WIN32_ERROR));
 windows_targets::link!("kernel32.dll" "system" fn SetThreadStackGuarantee(stacksizeinbytes : *mut u32) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn SetWaitableTimer(htimer : HANDLE, lpduetime : *const i64, lperiod : i32, pfncompletionroutine : PTIMERAPCROUTINE, lpargtocompletionroutine : *const core::ffi::c_void, fresume : BOOL) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SignalObjectAndWait(hobjecttosignal : HANDLE, hobjecttowaiton : HANDLE, dwmilliseconds : u32, balertable : BOOL) -> WAIT_EVENT);
 windows_targets::link!("kernel32.dll" "system" fn Sleep(dwmilliseconds : u32));
 windows_targets::link!("kernel32.dll" "system" fn SleepConditionVariableSRW(conditionvariable : *mut CONDITION_VARIABLE, srwlock : *mut SRWLOCK, dwmilliseconds : u32, flags : u32) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn SleepEx(dwmilliseconds : u32, balertable : BOOL) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn SwitchToThread() -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn SystemTimeToFileTime(lpsystemtime : *const SYSTEMTIME, lpfiletime : *mut FILETIME) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn TerminateProcess(hprocess : HANDLE, uexitcode : u32) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn TlsAlloc() -> u32);
 windows_targets::link!("kernel32.dll" "system" fn TlsFree(dwtlsindex : u32) -> BOOL);
@@ -98,6 +120,7 @@ windows_targets::link!("kernel32.dll" "system" fn TlsGetValue(dwtlsindex : u32)
 windows_targets::link!("kernel32.dll" "system" fn TlsSetValue(dwtlsindex : u32, lptlsvalue : *const core::ffi::c_void) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockExclusive(srwlock : *mut SRWLOCK) -> BOOLEAN);
 windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockShared(srwlock : *mut SRWLOCK) -> BOOLEAN);
+windows_targets::link!("kernel32.dll" "system" fn TryEnterCriticalSection(lpcriticalsection : *mut CRITICAL_SECTION) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn UnlockFile(hfile : HANDLE, dwfileoffsetlow : u32, dwfileoffsethigh : u32, nnumberofbytestounlocklow : u32, nnumberofbytestounlockhigh : u32) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn UpdateProcThreadAttribute(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwflags : u32, attribute : usize, lpvalue : *const core::ffi::c_void, cbsize : usize, lppreviousvalue : *mut core::ffi::c_void, lpreturnsize : *const usize) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn WaitForMultipleObjects(ncount : u32, lphandles : *const HANDLE, bwaitall : BOOL, dwmilliseconds : u32) -> WAIT_EVENT);
@@ -106,18 +129,25 @@ windows_targets::link!("kernel32.dll" "system" fn WakeAllConditionVariable(condi
 windows_targets::link!("kernel32.dll" "system" fn WakeConditionVariable(conditionvariable : *mut CONDITION_VARIABLE));
 windows_targets::link!("kernel32.dll" "system" fn WideCharToMultiByte(codepage : u32, dwflags : u32, lpwidecharstr : PCWSTR, cchwidechar : i32, lpmultibytestr : PSTR, cbmultibyte : i32, lpdefaultchar : PCSTR, lpuseddefaultchar : *mut BOOL) -> i32);
 windows_targets::link!("kernel32.dll" "system" fn WriteConsoleW(hconsoleoutput : HANDLE, lpbuffer : PCWSTR, nnumberofcharstowrite : u32, lpnumberofcharswritten : *mut u32, lpreserved : *const core::ffi::c_void) -> BOOL);
+windows_targets::link!("kernel32.dll" "system" fn WriteFile(hfile : HANDLE, lpbuffer : *const u8, nnumberofbytestowrite : u32, lpnumberofbyteswritten : *mut u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn WriteFileEx(hfile : HANDLE, lpbuffer : *const u8, nnumberofbytestowrite : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPOVERLAPPED_COMPLETION_ROUTINE) -> BOOL);
 windows_targets::link!("ntdll.dll" "system" fn NtCreateFile(filehandle : *mut HANDLE, desiredaccess : FILE_ACCESS_RIGHTS, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, allocationsize : *const i64, fileattributes : FILE_FLAGS_AND_ATTRIBUTES, shareaccess : FILE_SHARE_MODE, createdisposition : NTCREATEFILE_CREATE_DISPOSITION, createoptions : NTCREATEFILE_CREATE_OPTIONS, eabuffer : *const core::ffi::c_void, ealength : u32) -> NTSTATUS);
 windows_targets::link!("ntdll.dll" "system" fn NtOpenFile(filehandle : *mut HANDLE, desiredaccess : u32, objectattributes : *const OBJECT_ATTRIBUTES, iostatusblock : *mut IO_STATUS_BLOCK, shareaccess : u32, openoptions : u32) -> NTSTATUS);
+windows_targets::link!("ntdll.dll" "system" fn NtQueryDirectoryFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, fileinformation : *mut core::ffi::c_void, length : u32, fileinformationclass : FILE_INFORMATION_CLASS, returnsingleentry : BOOLEAN, filename : *const UNICODE_STRING, restartscan : BOOLEAN) -> NTSTATUS);
+windows_targets::link!("ntdll.dll" "system" fn NtQueryInformationFile(filehandle : HANDLE, iostatusblock : *mut IO_STATUS_BLOCK, fileinformation : *mut core::ffi::c_void, length : u32, fileinformationclass : FILE_INFORMATION_CLASS) -> NTSTATUS);
 windows_targets::link!("ntdll.dll" "system" fn NtReadFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *mut core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
+windows_targets::link!("ntdll.dll" "system" fn NtSetInformationFile(filehandle : HANDLE, iostatusblock : *mut IO_STATUS_BLOCK, fileinformation : *const core::ffi::c_void, length : u32, fileinformationclass : FILE_INFORMATION_CLASS) -> NTSTATUS);
+windows_targets::link!("ntdll.dll" "system" fn NtWaitForSingleObject(handle : HANDLE, alertable : BOOLEAN, timeout : *mut i64) -> NTSTATUS);
 windows_targets::link!("ntdll.dll" "system" fn NtWriteFile(filehandle : HANDLE, event : HANDLE, apcroutine : PIO_APC_ROUTINE, apccontext : *const core::ffi::c_void, iostatusblock : *mut IO_STATUS_BLOCK, buffer : *const core::ffi::c_void, length : u32, byteoffset : *const i64, key : *const u32) -> NTSTATUS);
 windows_targets::link!("ntdll.dll" "system" fn RtlNtStatusToDosError(status : NTSTATUS) -> u32);
 windows_targets::link!("userenv.dll" "system" fn GetUserProfileDirectoryW(htoken : HANDLE, lpprofiledir : PWSTR, lpcchsize : *mut u32) -> BOOL);
 windows_targets::link!("ws2_32.dll" "system" fn WSACleanup() -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn WSADuplicateSocketA(s : SOCKET, dwprocessid : u32, lpprotocolinfo : *mut WSAPROTOCOL_INFOA) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn WSADuplicateSocketW(s : SOCKET, dwprocessid : u32, lpprotocolinfo : *mut WSAPROTOCOL_INFOW) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn WSAGetLastError() -> WSA_ERROR);
 windows_targets::link!("ws2_32.dll" "system" fn WSARecv(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytesrecvd : *mut u32, lpflags : *mut u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn WSASend(s : SOCKET, lpbuffers : *const WSABUF, dwbuffercount : u32, lpnumberofbytessent : *mut u32, dwflags : u32, lpoverlapped : *mut OVERLAPPED, lpcompletionroutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn WSASocketA(af : i32, r#type : i32, protocol : i32, lpprotocolinfo : *const WSAPROTOCOL_INFOA, g : u32, dwflags : u32) -> SOCKET);
 windows_targets::link!("ws2_32.dll" "system" fn WSASocketW(af : i32, r#type : i32, protocol : i32, lpprotocolinfo : *const WSAPROTOCOL_INFOW, g : u32, dwflags : u32) -> SOCKET);
 windows_targets::link!("ws2_32.dll" "system" fn WSAStartup(wversionrequested : u16, lpwsadata : *mut WSADATA) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn accept(s : SOCKET, addr : *mut SOCKADDR, addrlen : *mut i32) -> SOCKET);
@@ -126,9 +156,13 @@ windows_targets::link!("ws2_32.dll" "system" fn closesocket(s : SOCKET) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn connect(s : SOCKET, name : *const SOCKADDR, namelen : i32) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn freeaddrinfo(paddrinfo : *const ADDRINFOA));
 windows_targets::link!("ws2_32.dll" "system" fn getaddrinfo(pnodename : PCSTR, pservicename : PCSTR, phints : *const ADDRINFOA, ppresult : *mut *mut ADDRINFOA) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn gethostbyname(name : PCSTR) -> *mut HOSTENT);
 windows_targets::link!("ws2_32.dll" "system" fn getpeername(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn getservbyname(name : PCSTR, proto : PCSTR) -> *mut SERVENT);
 windows_targets::link!("ws2_32.dll" "system" fn getsockname(s : SOCKET, name : *mut SOCKADDR, namelen : *mut i32) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn getsockopt(s : SOCKET, level : i32, optname : i32, optval : PSTR, optlen : *mut i32) -> i32);
+windows_targets::link!("ws2_32.dll" "system" fn inet_addr(cp : PCSTR) -> u32);
+windows_targets::link!("ws2_32.dll" "system" fn inet_ntoa(r#in : IN_ADDR) -> PSTR);
 windows_targets::link!("ws2_32.dll" "system" fn ioctlsocket(s : SOCKET, cmd : i32, argp : *mut u32) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn listen(s : SOCKET, backlog : i32) -> i32);
 windows_targets::link!("ws2_32.dll" "system" fn recv(s : SOCKET, buf : PSTR, len : i32, flags : SEND_RECV_FLAGS) -> i32);
@@ -397,6 +431,30 @@ pub const CREATE_SUSPENDED: PROCESS_CREATION_FLAGS = 4u32;
 pub const CREATE_UNICODE_ENVIRONMENT: PROCESS_CREATION_FLAGS = 1024u32;
 pub const CREATE_WAITABLE_TIMER_HIGH_RESOLUTION: u32 = 2u32;
 pub const CREATE_WAITABLE_TIMER_MANUAL_RESET: u32 = 1u32;
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct CRITICAL_SECTION {
+    pub DebugInfo: *mut CRITICAL_SECTION_DEBUG,
+    pub LockCount: i32,
+    pub RecursionCount: i32,
+    pub OwningThread: HANDLE,
+    pub LockSemaphore: HANDLE,
+    pub SpinCount: usize,
+}
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct CRITICAL_SECTION_DEBUG {
+    pub Type: u16,
+    pub CreatorBackTraceIndex: u16,
+    pub CriticalSection: *mut CRITICAL_SECTION,
+    pub ProcessLocksList: LIST_ENTRY,
+    pub EntryCount: u32,
+    pub ContentionCount: u32,
+    pub Flags: u32,
+    pub CreatorBackTraceIndexHigh: u16,
+    pub Identifier: u16,
+}
+pub const CRYPT_VERIFYCONTEXT: u32 = 4026531840u32;
 pub const CSTR_EQUAL: COMPARESTRING_RESULT = 2i32;
 pub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3i32;
 pub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1i32;
@@ -2424,6 +2482,22 @@ pub const FILE_FLAG_RANDOM_ACCESS: FILE_FLAGS_AND_ATTRIBUTES = 268435456u32;
 pub const FILE_FLAG_SEQUENTIAL_SCAN: FILE_FLAGS_AND_ATTRIBUTES = 134217728u32;
 pub const FILE_FLAG_SESSION_AWARE: FILE_FLAGS_AND_ATTRIBUTES = 8388608u32;
 pub const FILE_FLAG_WRITE_THROUGH: FILE_FLAGS_AND_ATTRIBUTES = 2147483648u32;
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct FILE_FULL_DIR_INFO {
+    pub NextEntryOffset: u32,
+    pub FileIndex: u32,
+    pub CreationTime: i64,
+    pub LastAccessTime: i64,
+    pub LastWriteTime: i64,
+    pub ChangeTime: i64,
+    pub EndOfFile: i64,
+    pub AllocationSize: i64,
+    pub FileAttributes: u32,
+    pub FileNameLength: u32,
+    pub EaSize: u32,
+    pub FileName: [u16; 1],
+}
 pub const FILE_GENERIC_EXECUTE: FILE_ACCESS_RIGHTS = 1179808u32;
 pub const FILE_GENERIC_READ: FILE_ACCESS_RIGHTS = 1179785u32;
 pub const FILE_GENERIC_WRITE: FILE_ACCESS_RIGHTS = 1179926u32;
@@ -2446,6 +2520,7 @@ pub struct FILE_ID_BOTH_DIR_INFO {
     pub FileId: i64,
     pub FileName: [u16; 1],
 }
+pub type FILE_INFORMATION_CLASS = i32;
 pub type FILE_INFO_BY_HANDLE_CLASS = i32;
 #[repr(C)]
 #[derive(Clone, Copy)]
@@ -2453,6 +2528,12 @@ pub struct FILE_IO_PRIORITY_HINT_INFO {
     pub PriorityHint: PRIORITY_HINT,
 }
 pub const FILE_LIST_DIRECTORY: FILE_ACCESS_RIGHTS = 1u32;
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct FILE_NAME_INFO {
+    pub FileNameLength: u32,
+    pub FileName: [u16; 1],
+}
 pub const FILE_NAME_NORMALIZED: GETFINALPATHNAMEBYHANDLE_FLAGS = 0u32;
 pub const FILE_NAME_OPENED: GETFINALPATHNAMEBYHANDLE_FLAGS = 8u32;
 pub const FILE_NON_DIRECTORY_FILE: NTCREATEFILE_CREATE_OPTIONS = 64u32;
@@ -2565,13 +2646,19 @@ pub const FSCTL_SET_REPARSE_POINT: u32 = 589988u32;
 pub const FileAlignmentInfo: FILE_INFO_BY_HANDLE_CLASS = 17i32;
 pub const FileAllocationInfo: FILE_INFO_BY_HANDLE_CLASS = 5i32;
 pub const FileAttributeTagInfo: FILE_INFO_BY_HANDLE_CLASS = 9i32;
+pub const FileAttributeTagInformation: FILE_INFORMATION_CLASS = 35i32;
 pub const FileBasicInfo: FILE_INFO_BY_HANDLE_CLASS = 0i32;
+pub const FileBasicInformation: FILE_INFORMATION_CLASS = 4i32;
 pub const FileCaseSensitiveInfo: FILE_INFO_BY_HANDLE_CLASS = 23i32;
 pub const FileCompressionInfo: FILE_INFO_BY_HANDLE_CLASS = 8i32;
 pub const FileDispositionInfo: FILE_INFO_BY_HANDLE_CLASS = 4i32;
 pub const FileDispositionInfoEx: FILE_INFO_BY_HANDLE_CLASS = 21i32;
+pub const FileDispositionInformation: FILE_INFORMATION_CLASS = 13i32;
+pub const FileDispositionInformationEx: FILE_INFORMATION_CLASS = 64i32;
 pub const FileEndOfFileInfo: FILE_INFO_BY_HANDLE_CLASS = 6i32;
+pub const FileEndOfFileInformation: FILE_INFORMATION_CLASS = 20i32;
 pub const FileFullDirectoryInfo: FILE_INFO_BY_HANDLE_CLASS = 14i32;
+pub const FileFullDirectoryInformation: FILE_INFORMATION_CLASS = 2i32;
 pub const FileFullDirectoryRestartInfo: FILE_INFO_BY_HANDLE_CLASS = 15i32;
 pub const FileIdBothDirectoryInfo: FILE_INFO_BY_HANDLE_CLASS = 10i32;
 pub const FileIdBothDirectoryRestartInfo: FILE_INFO_BY_HANDLE_CLASS = 11i32;
@@ -2580,6 +2667,7 @@ pub const FileIdExtdDirectoryRestartInfo: FILE_INFO_BY_HANDLE_CLASS = 20i32;
 pub const FileIdInfo: FILE_INFO_BY_HANDLE_CLASS = 18i32;
 pub const FileIoPriorityHintInfo: FILE_INFO_BY_HANDLE_CLASS = 12i32;
 pub const FileNameInfo: FILE_INFO_BY_HANDLE_CLASS = 2i32;
+pub const FileNameInformation: FILE_INFORMATION_CLASS = 9i32;
 pub const FileNormalizedNameInfo: FILE_INFO_BY_HANDLE_CLASS = 24i32;
 pub const FileRemoteProtocolInfo: FILE_INFO_BY_HANDLE_CLASS = 13i32;
 pub const FileRenameInfo: FILE_INFO_BY_HANDLE_CLASS = 3i32;
@@ -2620,6 +2708,15 @@ pub const HANDLE_FLAG_PROTECT_FROM_CLOSE: HANDLE_FLAGS = 2u32;
 pub const HIGH_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 128u32;
 pub type HLOCAL = *mut core::ffi::c_void;
 pub type HMODULE = *mut core::ffi::c_void;
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct HOSTENT {
+    pub h_name: PSTR,
+    pub h_aliases: *mut *mut i8,
+    pub h_addrtype: i16,
+    pub h_length: i16,
+    pub h_addr_list: *mut *mut i8,
+}
 pub type HRESULT = i32;
 pub const IDLE_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 64u32;
 #[repr(C)]
@@ -2643,6 +2740,7 @@ pub union INIT_ONCE {
 }
 pub const INIT_ONCE_INIT_FAILED: u32 = 4u32;
 pub const INVALID_FILE_ATTRIBUTES: u32 = 4294967295u32;
+pub const INVALID_SET_FILE_POINTER: u32 = 4294967295u32;
 pub const INVALID_SOCKET: SOCKET = -1i32 as _;
 #[repr(C)]
 #[derive(Clone, Copy)]
@@ -2749,6 +2847,12 @@ pub struct LINGER {
     pub l_onoff: u16,
     pub l_linger: u16,
 }
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct LIST_ENTRY {
+    pub Flink: *mut LIST_ENTRY,
+    pub Blink: *mut LIST_ENTRY,
+}
 pub const LOCKFILE_EXCLUSIVE_LOCK: LOCK_FILE_FLAGS = 2u32;
 pub const LOCKFILE_FAIL_IMMEDIATELY: LOCK_FILE_FLAGS = 1u32;
 pub type LOCK_FILE_FLAGS = u32;
@@ -2888,6 +2992,7 @@ pub const PROFILE_KERNEL: PROCESS_CREATION_FLAGS = 536870912u32;
 pub const PROFILE_SERVER: PROCESS_CREATION_FLAGS = 1073741824u32;
 pub const PROFILE_USER: PROCESS_CREATION_FLAGS = 268435456u32;
 pub const PROGRESS_CONTINUE: u32 = 0u32;
+pub const PROV_RSA_FULL: u32 = 1u32;
 pub type PSTR = *mut u8;
 pub type PTIMERAPCROUTINE = Option<
     unsafe extern "system" fn(
@@ -2920,6 +3025,24 @@ pub const SECURITY_IMPERSONATION: FILE_FLAGS_AND_ATTRIBUTES = 131072u32;
 pub const SECURITY_SQOS_PRESENT: FILE_FLAGS_AND_ATTRIBUTES = 1048576u32;
 pub const SECURITY_VALID_SQOS_FLAGS: FILE_FLAGS_AND_ATTRIBUTES = 2031616u32;
 pub type SEND_RECV_FLAGS = i32;
+#[repr(C)]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
+#[derive(Clone, Copy)]
+pub struct SERVENT {
+    pub s_name: PSTR,
+    pub s_aliases: *mut *mut i8,
+    pub s_proto: PSTR,
+    pub s_port: i16,
+}
+#[repr(C)]
+#[cfg(target_arch = "x86")]
+#[derive(Clone, Copy)]
+pub struct SERVENT {
+    pub s_name: PSTR,
+    pub s_aliases: *mut *mut i8,
+    pub s_port: i16,
+    pub s_proto: PSTR,
+}
 pub type SET_FILE_POINTER_MOVE_METHOD = u32;
 #[repr(C)]
 #[derive(Clone, Copy)]
@@ -3031,6 +3154,18 @@ pub type SYNCHRONIZATION_ACCESS_RIGHTS = u32;
 pub const SYNCHRONIZE: FILE_ACCESS_RIGHTS = 1048576u32;
 #[repr(C)]
 #[derive(Clone, Copy)]
+pub struct SYSTEMTIME {
+    pub wYear: u16,
+    pub wMonth: u16,
+    pub wDayOfWeek: u16,
+    pub wDay: u16,
+    pub wHour: u16,
+    pub wMinute: u16,
+    pub wSecond: u16,
+    pub wMilliseconds: u16,
+}
+#[repr(C)]
+#[derive(Clone, Copy)]
 pub struct SYSTEM_INFO {
     pub Anonymous: SYSTEM_INFO_0,
     pub dwPageSize: u32,
@@ -3222,6 +3357,30 @@ pub struct WSAPROTOCOLCHAIN {
 }
 #[repr(C)]
 #[derive(Clone, Copy)]
+pub struct WSAPROTOCOL_INFOA {
+    pub dwServiceFlags1: u32,
+    pub dwServiceFlags2: u32,
+    pub dwServiceFlags3: u32,
+    pub dwServiceFlags4: u32,
+    pub dwProviderFlags: u32,
+    pub ProviderId: GUID,
+    pub dwCatalogEntryId: u32,
+    pub ProtocolChain: WSAPROTOCOLCHAIN,
+    pub iVersion: i32,
+    pub iAddressFamily: i32,
+    pub iMaxSockAddr: i32,
+    pub iMinSockAddr: i32,
+    pub iSocketType: i32,
+    pub iProtocol: i32,
+    pub iProtocolMaxOffset: i32,
+    pub iNetworkByteOrder: i32,
+    pub iSecurityScheme: i32,
+    pub dwMessageSize: u32,
+    pub dwProviderReserved: u32,
+    pub szProtocol: [i8; 256],
+}
+#[repr(C)]
+#[derive(Clone, Copy)]
 pub struct WSAPROTOCOL_INFOW {
     pub dwServiceFlags1: u32,
     pub dwServiceFlags2: u32,
diff --git a/library/std/src/sys/pal/windows/c/wspiapi.rs b/library/std/src/sys/pal/windows/c/wspiapi.rs
new file mode 100644
index 0000000000000..fcd743e81914c
--- /dev/null
+++ b/library/std/src/sys/pal/windows/c/wspiapi.rs
@@ -0,0 +1,524 @@
+//! WSPiApi.h getaddr/freeaddrinfo shim converted to rust
+
+use crate::ffi::{CStr, c_int, c_ulong};
+use crate::ptr;
+use crate::sys::c::{
+    ADDRESS_FAMILY, ADDRINFOA, AF_INET, PCSTR, PSTR, SOCK_DGRAM, SOCK_STREAM, WSAGetLastError,
+};
+use crate::sys::net::netc::{in_addr, sockaddr_in};
+
+const WSABASEERR: c_int = 10000;
+const WSAHOST_NOT_FOUND: c_int = WSABASEERR + 1001;
+const WSATRY_AGAIN: c_int = WSABASEERR + 1002;
+const WSANO_RECOVERY: c_int = WSABASEERR + 1003;
+const WSANO_DATA: c_int = WSABASEERR + 1004;
+
+const EAI_NONAME: c_int = WSAHOST_NOT_FOUND;
+
+// https://lists.freebsd.org/pipermail/freebsd-ports/2003-October/005757.html
+const EAI_NODATA: c_int = EAI_NONAME;
+const EAI_AGAIN: c_int = WSATRY_AGAIN;
+const EAI_FAIL: c_int = WSANO_RECOVERY;
+const EAI_BADFLAGS: c_int = 10022;
+const EAI_FAMILY: c_int = 10047;
+const EAI_SOCKTYPE: c_int = 10044;
+const EAI_SERVICE: c_int = 10109;
+
+const WSA_NOT_ENOUGH_MEMORY: c_int = 8;
+const EAI_MEMORY: c_int = WSA_NOT_ENOUGH_MEMORY;
+
+const AI_PASSIVE: i32 = 0x00000001;
+const AI_CANONNAME: i32 = 0x00000002;
+const AI_NUMERICHOST: i32 = 0x00000004;
+
+const PF_UNSPEC: i32 = 0;
+const PF_INET: i32 = 2;
+
+const SOCK_RAW: i32 = 3;
+
+const INADDR_ANY: u32 = 0x00000000;
+const INADDR_LOOPBACK: u32 = 0x7f000001;
+
+const NI_MAXHOST: usize = 1025;
+
+pub unsafe fn wspiapi_freeaddrinfo(head: *const ADDRINFOA) {
+    let mut head = head as *mut ADDRINFOA;
+    let mut next_ptr = head;
+
+    unsafe {
+        while !next_ptr.is_null() {
+            // scope to make sure the `next` borrow is dropped before freeeing the `ADDRINFOA` it
+            // references
+            {
+                let next = &*next_ptr;
+                if !next.ai_canonname.is_null() {
+                    drop(crate::ffi::CString::from_raw(next.ai_canonname.cast()));
+                }
+
+                if !next.ai_addr.is_null() {
+                    drop(Box::<sockaddr_in>::from_raw(next.ai_addr as *mut _));
+                }
+
+                head = next.ai_next;
+            }
+
+            drop(Box::<ADDRINFOA>::from_raw(next_ptr));
+            next_ptr = head;
+        }
+    }
+}
+
+/// Protocol-independent name-to-address translation.
+///
+/// As specified in RFC 2553, Section 6.4.
+/// This is the hacked version that only supports IPv4.
+///
+/// Arguments
+/// -   node              node name to lookup.
+/// -   service           service name to lookup.
+/// -   hints             hints about how to process request.
+/// -   res               where to return result.
+///
+/// Return Value
+/// -   returns zero if successful, an EAI_* error code if not.
+pub unsafe fn wspiapi_getaddrinfo(
+    node: PCSTR,
+    service: PCSTR,
+    hints: *const ADDRINFOA,
+    res: *mut *mut ADDRINFOA,
+) -> c_int {
+    unsafe {
+        // initialize res with default return value.
+        *res = ptr::null_mut();
+
+        // the node name and the service name can't both be NULL.
+        if node.is_null() && service.is_null() {
+            return EAI_NONAME;
+        }
+
+        let mut flags: i32 = 0;
+        let mut socket_type: i32 = 0;
+        let mut protocol: i32 = 0;
+
+        // validate hints.
+        if let Some(hints) = ptr::NonNull::<ADDRINFOA>::new(hints as *mut _) {
+            let hints = hints.as_ref();
+
+            // all members other than ai_flags, ai_family, ai_socktype
+            // and ai_protocol must be zero or a null pointer.
+            if hints.ai_addrlen != 0
+                || !hints.ai_canonname.is_null()
+                || !hints.ai_addr.is_null()
+                || !hints.ai_next.is_null()
+            {
+                return EAI_FAIL;
+            }
+
+            // the spec has the "bad flags" error code, so presumably we
+            // should check something here.  insisting that there aren't
+            // any unspecified flags set would break forward compatibility,
+            // however.  so we just check for non-sensical combinations.
+            //
+            // we cannot come up with a canonical name given a null node name.
+            flags = hints.ai_flags;
+            if flags & AI_CANONNAME != 0 && node.is_null() {
+                return EAI_BADFLAGS;
+            }
+
+            // we only support a limited number of protocol families.
+            if !matches!(hints.ai_family, PF_UNSPEC | PF_INET) {
+                return EAI_FAMILY;
+            }
+
+            // we only support only these socket types.
+            socket_type = hints.ai_socktype;
+            if !matches!(socket_type, 0 | SOCK_STREAM | SOCK_DGRAM | SOCK_RAW) {
+                return EAI_SOCKTYPE;
+            }
+
+            // REVIEW: What if ai_socktype and ai_protocol are at odds?
+            protocol = hints.ai_protocol;
+        }
+
+        let mut port: u16 = 0;
+        let mut udp_port: u16 = 0;
+        let mut clone: bool = false;
+
+        // do service lookup
+        if !service.is_null() {
+            if let Some(raw_port) =
+                CStr::from_ptr(service.cast()).to_str().ok().and_then(|s| s.parse::<c_ulong>().ok())
+            {
+                // numeric port string
+
+                port = (raw_port as u16).to_be();
+                udp_port = port;
+
+                if socket_type == 0 {
+                    clone = true;
+                    socket_type = SOCK_STREAM;
+                }
+            } else {
+                let mut tcp_port: u16 = 0;
+
+                // non numeric port string
+
+                if socket_type == 0 || socket_type == SOCK_DGRAM {
+                    let servent = getservbyname(service, c"udp".as_ptr().cast());
+                    if !servent.is_null() {
+                        port = (*servent).s_port;
+                        udp_port = port;
+                    }
+                }
+
+                if socket_type == 0 || socket_type == SOCK_STREAM {
+                    let servent = getservbyname(service, c"tcp".as_ptr().cast());
+                    if !servent.is_null() {
+                        port = (*servent).s_port;
+                        tcp_port = port;
+                    }
+                }
+
+                // assumes 0 is an invalid service port...
+                if port == 0 {
+                    // no service exists
+                    return if socket_type != 0 { EAI_SERVICE } else { EAI_NONAME };
+                }
+
+                if socket_type == 0 {
+                    // if both tcp and udp, process tcp now & clone udp later.
+                    socket_type = if tcp_port != 0 { SOCK_STREAM } else { SOCK_DGRAM };
+                    clone = tcp_port != 0 && udp_port != 0;
+                }
+            }
+        }
+
+        // do node name lookup
+
+        // if we weren't given a node name,
+        // return the wildcard or loopback address (depending on AI_PASSIVE).
+        //
+        // if we have a numeric host address string,
+        // return the binary address.
+        //
+
+        let address: Option<u32> = if node.is_null() {
+            Some((if flags & AI_PASSIVE != 0 { INADDR_ANY } else { INADDR_LOOPBACK }).to_be())
+        } else {
+            wspiapi_parse_v4_address(CStr::from_ptr(node.cast()))
+        };
+
+        let mut error: i32 = 0;
+
+        if let Some(address) = address {
+            // create an addrinfo structure...
+            *res = wspiapi_new_addr_info(socket_type, protocol, port, address);
+
+            if error != 0 && !node.is_null() {
+                // implementation specific behavior: set AI_NUMERICHOST
+                // to indicate that we got a numeric host address string.
+                (**res).ai_flags |= AI_NUMERICHOST;
+
+                // return the numeric address string as the canonical name
+                if flags & AI_CANONNAME != 0 {
+                    (**res).ai_canonname = wspiapi_strdup(inet_ntoa(in_addr { s_addr: address }));
+
+                    if (**res).ai_canonname.is_null() {
+                        error = EAI_MEMORY;
+                    }
+                }
+            }
+        } else if flags & AI_NUMERICHOST != 0 {
+            // if we do not have a numeric host address string and
+            // AI_NUMERICHOST flag is set, return an error!
+            error = EAI_NONAME;
+        } else {
+            // since we have a non-numeric node name,
+            // we have to do a regular node name lookup.
+            error = wspiapi_lookup_node(
+                CStr::from_ptr(node.cast()),
+                socket_type,
+                protocol,
+                port,
+                flags & AI_CANONNAME != 0,
+                res,
+            );
+        }
+
+        if error == 0 && clone {
+            error = wspiapi_clone(udp_port, *res);
+        }
+
+        if error != 0 {
+            wspiapi_freeaddrinfo(*res);
+            *res = ptr::null_mut();
+        }
+
+        return error;
+    }
+}
+
+unsafe fn wspiapi_clone(udp_port: u16, res: *mut ADDRINFOA) -> i32 {
+    let mut next_ptr = res;
+
+    unsafe {
+        while !next_ptr.is_null() {
+            let next = &mut *next_ptr;
+
+            // create an addrinfo structure...
+            let new_ptr = wspiapi_new_addr_info(
+                SOCK_DGRAM,
+                next.ai_protocol,
+                udp_port,
+                (*(next.ai_addr as *mut sockaddr_in)).sin_addr.s_addr,
+            );
+            let new = &mut *new_ptr;
+
+            // link the cloned addrinfo
+            new.ai_next = next.ai_next;
+            next.ai_next = new_ptr;
+            next_ptr = new.ai_next;
+        }
+    }
+
+    0
+}
+
+/// Resolve a nodename and return a list of addrinfo structures.
+/// IPv4 specific internal function, not exported.
+///
+/// *res would need to be freed if an error is returned.
+///
+/// NOTE: if `ai_canonname` is true, the canonical name should be
+///       returned in the first addrinfo structure.
+///
+/// Arguments
+/// - node                name of node to resolve.
+/// - socket_type         SOCK_*.  can be wildcarded (zero).
+/// - protocol            IPPROTO_*.  can be wildcarded (zero).
+/// - port                port number of service (in network order).
+/// - ai_canonname        whether the AI_CANONNAME flag is set.
+/// - res                 where to return result.
+///
+/// Return Value
+/// - Returns 0 on success, an EAI_* style error value otherwise.
+unsafe fn wspiapi_lookup_node(
+    node: &CStr,
+    socket_type: i32,
+    protocol: i32,
+    port: u16,
+    ai_canonname: bool,
+    res: *mut *mut ADDRINFOA,
+) -> i32 {
+    let mut error: i32;
+    let mut alias_count = 0;
+
+    let mut name = [0u8; NI_MAXHOST];
+    wspiapi_strcpy_ni_maxhost(&mut name, node.to_bytes());
+
+    let mut alias = [0u8; NI_MAXHOST];
+
+    let mut name_ref = &mut name;
+    let mut alias_ref = &mut alias;
+
+    unsafe {
+        loop {
+            error = wspiapi_query_dns(node, socket_type, protocol, port, alias_ref, res);
+
+            if error != 0 {
+                break;
+            }
+
+            // if we found addresses, then we are done.
+            if !(*res).is_null() {
+                break;
+            }
+
+            if alias_ref[0] == b'\0'
+                || CStr::from_ptr(name_ref.as_ptr() as *const _)
+                    == CStr::from_ptr(alias_ref.as_ptr() as *const _)
+                || {
+                    alias_count += 1;
+                    alias_count
+                } == 16
+            {
+                error = EAI_FAIL;
+                break;
+            }
+
+            crate::mem::swap(&mut name_ref, &mut alias_ref);
+        }
+
+        if error == 0 && ai_canonname {
+            (**res).ai_canonname = wspiapi_strdup(alias_ref.as_ptr());
+        }
+    }
+
+    error
+}
+
+fn wspiapi_strcpy_ni_maxhost(dest: &mut [u8; NI_MAXHOST], source_without_nul: &[u8]) {
+    let len = source_without_nul.len().min(NI_MAXHOST - 1);
+    dest[0..len].copy_from_slice(&source_without_nul[0..len]);
+    dest[len] = b'\0';
+}
+
+unsafe fn wspiapi_query_dns(
+    node: &CStr,
+    socket_type: i32,
+    protocol: i32,
+    port: u16,
+    alias_ref: &mut [u8; NI_MAXHOST],
+    res: *mut *mut ADDRINFOA,
+) -> i32 {
+    unsafe {
+        let mut next = res;
+
+        alias_ref[0] = b'\0';
+
+        let host = gethostbyname(node.as_ptr().cast());
+        if let Some(host) = ptr::NonNull::<hostent>::new(host as *mut _) {
+            let host = host.as_ref();
+
+            if host.h_addrtype == AF_INET as i16
+                && host.h_length == crate::mem::size_of::<in_addr>() as i16
+            {
+                let mut addresses = host.h_addr_list;
+
+                while !(*addresses).is_null() {
+                    *next = wspiapi_new_addr_info(
+                        socket_type,
+                        protocol,
+                        port,
+                        (*((*addresses) as *const in_addr)).s_addr,
+                    );
+
+                    next = ptr::addr_of_mut!((**next).ai_next);
+
+                    addresses = addresses.add(1);
+                }
+            }
+
+            wspiapi_strcpy_ni_maxhost(alias_ref, CStr::from_ptr(host.h_name.cast()).to_bytes());
+
+            return 0;
+        }
+
+        match WSAGetLastError() {
+            WSAHOST_NOT_FOUND => EAI_NONAME,
+            WSATRY_AGAIN => EAI_AGAIN,
+            WSANO_RECOVERY => EAI_FAIL,
+            WSANO_DATA => EAI_NODATA,
+            _ => EAI_NONAME,
+        }
+    }
+}
+
+unsafe fn wspiapi_new_addr_info(
+    socket_type: i32,
+    protocol: i32,
+    port: u16,
+    address: u32,
+) -> *mut ADDRINFOA {
+    let sockaddr = Box::new(sockaddr_in {
+        sin_family: AF_INET as ADDRESS_FAMILY,
+        sin_port: port,
+        sin_addr: in_addr { s_addr: address },
+        sin_zero: [0; 8],
+    });
+
+    let new = Box::new(ADDRINFOA {
+        ai_family: PF_INET,
+        ai_socktype: socket_type,
+        ai_protocol: protocol,
+        ai_addrlen: crate::mem::size_of::<sockaddr_in>(),
+        ai_addr: Box::into_raw(sockaddr) as *mut _,
+        ai_canonname: ptr::null_mut(),
+        ai_flags: 0,
+        ai_next: ptr::null_mut(),
+    });
+
+    Box::into_raw(new)
+}
+
+/// Get the IPv4 address (in network byte order) from its string representation.
+/// The syntax should be `a.b.c.d`.
+///
+/// Arguments
+/// - pszArgument         string representation of the IPv4 address
+/// - ptAddress           pointer to the resulting IPv4 address
+///
+/// Return Value
+/// - Returns FALSE if there is an error, TRUE for success.
+fn wspiapi_parse_v4_address(address: &CStr) -> Option<u32> {
+    // ensure there are 3 '.' (periods)
+    if address.to_bytes().iter().filter(|&&c| c == b'.').count() != 3 {
+        return None;
+    }
+
+    // return an error if dwAddress is INADDR_NONE (255.255.255.255)
+    // since this is never a valid argument to getaddrinfo.
+    let addr: u32 = unsafe { inet_addr(address.as_ptr().cast()) };
+
+    const INADDR_NONE: u32 = 0xffffffff;
+    if addr == INADDR_NONE {
+        return None;
+    }
+
+    return Some(addr);
+}
+
+unsafe fn wspiapi_strdup(string: PCSTR) -> PSTR {
+    if string.is_null() {
+        ptr::null_mut()
+    } else {
+        unsafe { CStr::from_ptr(string.cast()).to_owned().into_raw().cast() }
+    }
+}
+
+// from Winsock2.h
+#[repr(C)]
+pub struct servent {
+    s_name: *mut PSTR,
+    s_aliases: *mut *mut i8,
+    #[cfg(target_pointer_width = "32")]
+    s_port: u16,
+    #[cfg(target_pointer_width = "32")]
+    s_proto: *mut PSTR,
+    #[cfg(target_pointer_width = "64")]
+    s_proto: *mut PSTR,
+    #[cfg(target_pointer_width = "64")]
+    s_port: u16,
+}
+
+#[repr(C)]
+pub struct hostent {
+    pub h_name: PSTR,
+    pub h_aliases: *mut *mut i8,
+    pub h_addrtype: i16,
+    pub h_length: i16,
+    pub h_addr_list: *mut *mut i8,
+}
+
+compat_fn_with_fallback! {
+    // load is not needed, we already need ws2_32 to get here
+    pub static WS2_32: &CStr = c"ws2_32" => { load: false, unicows: false };
+
+    /// The pointer that is returned points to the SERVENT structure allocated by the
+    /// Windows Sockets library. The application must never attempt to modify this
+    /// structure or to free any of its components. Furthermore only one copy of this
+    /// structure is allocated per thread, so the application should copy any information
+    /// it needs before issuing any other Windows Sockets function calls.
+    pub fn getservbyname(name: PCSTR, proto: PCSTR) -> *const servent { unimplemented!(); }
+    /// The `gethostbyname` function returns a pointer to a hostent structure—a structure allocated
+    /// by Windows Sockets. The hostent structure contains the results of a successful search for
+    /// the host specified in the name parameter.
+    ///
+    /// The application must never attempt to modify this structure or to free any of its
+    /// components. Furthermore, only one copy of this structure is allocated per thread, so the
+    /// application should copy any information it needs before issuing any other Windows Sockets
+    /// function calls.
+    pub fn gethostbyname(name: PCSTR) -> *const hostent { unimplemented!(); }
+    pub fn inet_addr(cp: PCSTR) -> u32 { unimplemented!(); }
+    pub fn inet_ntoa(r#in: in_addr) -> PSTR { unimplemented!(); }
+}
diff --git a/library/std/src/sys/pal/windows/compat.rs b/library/std/src/sys/pal/windows/compat.rs
index 42999da166451..d75d05ddde40e 100644
--- a/library/std/src/sys/pal/windows/compat.rs
+++ b/library/std/src/sys/pal/windows/compat.rs
@@ -23,6 +23,12 @@ use crate::ffi::{CStr, c_void};
 use crate::ptr::NonNull;
 use crate::sys::c;
 
+#[cfg(target_vendor = "rust9x")]
+pub(crate) mod checks;
+
+#[cfg(target_vendor = "rust9x")]
+pub(crate) mod thread_parking;
+
 // This uses a static initializer to preload some imported functions.
 // The CRT (C runtime) executes static initializers before `main`
 // is called (for binaries) and before `DllMain` is called (for DLLs).
@@ -37,7 +43,7 @@ use crate::sys::c;
 // file an issue for discussion; currently we don't guarantee any functionality
 // before main.
 // See https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-170
-#[cfg(target_vendor = "win7")]
+#[cfg(any(target_vendor = "win7", target_vendor = "rust9x"))]
 #[used]
 #[link_section = ".CRT$XCT"]
 static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
@@ -68,6 +74,21 @@ unsafe extern "C" fn init() {
     load_synch_functions();
 }
 
+#[cfg(target_vendor = "rust9x")]
+unsafe extern "C" fn init() {
+    // In an exe this code is executed before main() so is single threaded.
+    // In a DLL the system's loader lock will be held thereby synchronizing
+    // access. So the same best practices apply here as they do to running in DllMain:
+    // https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices
+    //
+    // DO NOT do anything interesting or complicated in this function! DO NOT call
+    // any Rust functions or CRT functions if those functions touch any global state,
+    // because this function runs during global initialization. For example, DO NOT
+    // do any dynamic allocation, don't call LoadLibrary, etc.
+
+    checks::init_rust9x_checks();
+}
+
 /// Helper macro for creating CStrs from literals and symbol names.
 macro_rules! ansi_str {
     (sym $ident:ident) => {{ crate::sys::compat::const_cstr_from_bytes(concat!(stringify!($ident), "\0").as_bytes()) }};
@@ -118,6 +139,15 @@ impl Module {
         }
     }
 
+    #[allow(dead_code)]
+    pub unsafe fn load(name: &CStr) -> Option<Self> {
+        // SAFETY: A CStr is always null terminated.
+        unsafe {
+            let module = c::LoadLibraryA(name.as_ptr().cast::<u8>());
+            NonNull::new(module).map(Self)
+        }
+    }
+
     // Try to get the address of a function.
     pub fn proc_address(self, name: &CStr) -> Option<NonNull<c_void>> {
         unsafe {
@@ -131,43 +161,54 @@ impl Module {
     }
 }
 
+pub static UNICOWS: &CStr = c"unicows";
+
 /// Load a function or use a fallback implementation if that fails.
 macro_rules! compat_fn_with_fallback {
-    (pub static $module:ident: &CStr = $name:expr; $(
-        $(#[$meta:meta])*
-        $vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty $fallback_body:block
-    )*) => (
-        pub static $module: &CStr = $name;
+    {
+        pub static $module:ident: &CStr = $name:expr => { load: $load:expr, unicows: $unicows:expr };
+        $(
+            $(#[$meta:meta])*
+            $vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),* $(,)?) $(-> $rettype:ty)? $fallback_body:block
+        )*
+    } => {
     $(
         $(#[$meta])*
         pub mod $symbol {
             #[allow(unused_imports)]
             use super::*;
             use crate::mem;
-            use crate::ffi::CStr;
+            use crate::ffi::{CStr, c_void};
             use crate::sync::atomic::{AtomicPtr, Ordering};
-            use crate::sys::compat::Module;
 
-            type F = unsafe extern "system" fn($($argtype),*) -> $rettype;
+            type F = unsafe extern "system" fn($($argtype),*) $(-> $rettype)?;
 
             /// `PTR` contains a function pointer to one of three functions.
             /// It starts with the `load` function.
             /// When that is called it attempts to load the requested symbol.
             /// If it succeeds, `PTR` is set to the address of that symbol.
             /// If it fails, then `PTR` is set to `fallback`.
-            static PTR: AtomicPtr<c_void> = AtomicPtr::new(load as *mut _);
+            pub(in crate::sys) static PTR: AtomicPtr<c_void> = AtomicPtr::new(load as *mut _);
 
-            unsafe extern "system" fn load($($argname: $argtype),*) -> $rettype {
+            unsafe extern "system" fn load($($argname: $argtype),*) $(-> $rettype)? {
                 unsafe {
-                    let func = load_from_module(Module::new($module));
+                    let func = load_from_module();
                     func($($argname),*)
                 }
             }
 
-            fn load_from_module(module: Option<Module>) -> F {
+            fn load_from_module() -> F {
                 unsafe {
                     static SYMBOL_NAME: &CStr = ansi_str!(sym $symbol);
-                    if let Some(f) = module.and_then(|m| m.proc_address(SYMBOL_NAME)) {
+
+                    let f = crate::sys::compat::load_from_module(
+                        $name,
+                        SYMBOL_NAME,
+                        $load,
+                        $unicows
+                    );
+
+                    if let Some(f) = f {
                         PTR.store(f.as_ptr(), Ordering::Relaxed);
                         mem::transmute(f)
                     } else {
@@ -177,13 +218,27 @@ macro_rules! compat_fn_with_fallback {
                 }
             }
 
+            #[allow(dead_code)]
+            pub fn available() -> Option<F> {
+                let mut ptr = PTR.load(Ordering::Relaxed);
+                if ptr == load as *mut _ {
+                    ptr = load_from_module() as *mut _;
+                }
+
+                if ptr != fallback as *mut _ {
+                    Some(unsafe { mem::transmute(ptr) })
+                } else {
+                    None
+                }
+            }
+
             #[allow(unused_variables)]
-            unsafe extern "system" fn fallback($($argname: $argtype),*) -> $rettype {
+            unsafe extern "system" fn fallback($($argname: $argtype),*) $(-> $rettype)? {
                 $fallback_body
             }
 
             #[inline(always)]
-            pub unsafe fn call($($argname: $argtype),*) -> $rettype {
+            pub unsafe fn call($($argname: $argtype),*) $(-> $rettype)? {
                 unsafe {
                     let func: F = mem::transmute(PTR.load(Ordering::Relaxed));
                     func($($argname),*)
@@ -193,7 +248,8 @@ macro_rules! compat_fn_with_fallback {
         #[allow(unused)]
         $(#[$meta])*
         $vis use $symbol::call as $symbol;
-    )*)
+    )*
+    }
 }
 
 /// Optionally loaded functions.
@@ -203,7 +259,7 @@ macro_rules! compat_fn_with_fallback {
 macro_rules! compat_fn_optional {
     ($(
         $(#[$meta:meta])*
-        $vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),*) $(-> $rettype:ty)?;
+        $vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),* $(,)?) $(-> $rettype:ty)?;
     )+) => (
         $(
             pub mod $symbol {
@@ -219,8 +275,19 @@ macro_rules! compat_fn_optional {
                 type F = unsafe extern "system" fn($($argtype),*) $(-> $rettype)?;
 
                 #[inline(always)]
+                #[allow(dead_code)]
                 pub fn option() -> Option<F> {
-                    NonNull::new(PTR.load(Ordering::Relaxed)).map(|f| unsafe { mem::transmute(f) })
+                    unsafe {
+                        NonNull::new(PTR.load(Ordering::Relaxed)).map(|f| unsafe { mem::transmute(f) })
+                    }
+                }
+
+                #[inline(always)]
+                #[allow(dead_code)]
+                pub unsafe fn call($($argname: $argtype),*) $(-> $rettype)? {
+                    unsafe {
+                        (mem::transmute::<_, F>(PTR.load(Ordering::Relaxed)))($($argname),*)
+                    }
                 }
             }
             #[inline]
@@ -231,6 +298,28 @@ macro_rules! compat_fn_optional {
     )
 }
 
+pub(crate) fn load_from_module(
+    module_name: &CStr,
+    symbol_name: &CStr,
+    load: bool,
+    unicows: bool,
+) -> Option<NonNull<c_void>> {
+    let in_unicows = if unicows {
+        unsafe { Module::new(UNICOWS).and_then(|m| m.proc_address(symbol_name)) }
+    } else {
+        None
+    };
+
+    in_unicows.or_else(|| {
+        if load {
+            unsafe { Module::new(module_name) }
+        } else {
+            unsafe { Module::load(module_name) }
+        }
+        .and_then(|m| m.proc_address(symbol_name))
+    })
+}
+
 /// Load all needed functions from "api-ms-win-core-synch-l1-2-0".
 #[cfg(target_vendor = "win7")]
 pub(super) fn load_synch_functions() {
@@ -250,6 +339,4 @@ pub(super) fn load_synch_functions() {
         c::WakeByAddressSingle::PTR.store(wake_by_address_single.as_ptr(), Ordering::Relaxed);
         Some(())
     }
-
-    try_load();
 }
diff --git a/library/std/src/sys/pal/windows/compat/checks.rs b/library/std/src/sys/pal/windows/compat/checks.rs
new file mode 100644
index 0000000000000..188d9bed1c658
--- /dev/null
+++ b/library/std/src/sys/pal/windows/compat/checks.rs
@@ -0,0 +1,78 @@
+use crate::sys::c;
+
+/// Returns true if we are running on a Windows NT-based system. Only use this for APIs where the
+/// same API differs in behavior or capability on 9x/ME compared to NT.
+#[allow(dead_code)]
+#[inline(always)]
+#[cfg(target_arch = "x86")]
+pub fn is_windows_nt() -> bool {
+    unsafe { IS_NT }
+}
+
+#[allow(dead_code)]
+#[inline(always)]
+#[cfg(target_arch = "x86_64")]
+pub fn is_windows_nt() -> bool {
+    true // let me know once someone ported 9x to 64bit LOL
+}
+
+#[inline(always)]
+pub fn supports_async_io() -> bool {
+    unsafe { SUPPORTS_ASYNC_IO }
+}
+
+pub fn init_rust9x_checks() {
+    // DO NOT do anything interesting or complicated in this function! DO NOT call
+    // any Rust functions or CRT functions if those functions touch any global state,
+    // because this function runs during global initialization. For example, DO NOT
+    // do any dynamic allocation, don't call LoadLibrary, etc.
+
+    init_windows_version_check();
+    init_mutex_kind_check();
+}
+
+static mut IS_NT: bool = true;
+static mut SUPPORTS_ASYNC_IO: bool = true;
+
+fn init_windows_version_check() {
+    // according to old MSDN info, the high-order bit is set only on 95/98/ME.
+    unsafe {
+        IS_NT = c::GetVersion() < 0x8000_0000;
+        SUPPORTS_ASYNC_IO = IS_NT && c::CancelIo::available().is_some();
+    };
+}
+
+#[derive(Clone, Copy, PartialEq)]
+pub(crate) enum MutexKind {
+    /// Win 7+ (Vista doesn't support the `Try*` APIs)
+    SrwLock,
+    /// NT 4+ (9x/ME/NT3.x support critical sections, but don't support `TryEnterCriticalSection`)
+    CriticalSection,
+    /// `CreateMutex`, available everywhere
+    Legacy,
+}
+
+static mut MUTEX_KIND: MutexKind = MutexKind::Legacy;
+
+#[inline(always)]
+pub(crate) fn mutex_kind() -> MutexKind {
+    unsafe { MUTEX_KIND }
+}
+
+fn init_mutex_kind_check() {
+    let kind = if c::TryAcquireSRWLockExclusive::available().is_some() {
+        MutexKind::SrwLock
+    } else if {
+        // Windows 9x exports `TryEnterCriticalSection`, but it returns ERROR_CALL_NOT_IMPLEMENTED.
+        // MSDN specifies that the function is available on NT4 and later.
+        is_windows_nt() && c::TryEnterCriticalSection::available().is_some()
+    } {
+        MutexKind::CriticalSection
+    } else {
+        MutexKind::Legacy
+    };
+
+    unsafe {
+        MUTEX_KIND = kind;
+    }
+}
diff --git a/library/std/src/sys/pal/windows/compat/thread_parking.rs b/library/std/src/sys/pal/windows/compat/thread_parking.rs
new file mode 100644
index 0000000000000..1533f16257a9f
--- /dev/null
+++ b/library/std/src/sys/pal/windows/compat/thread_parking.rs
@@ -0,0 +1,40 @@
+static mut THREAD_PARKING_IMPL: Option<ThreadParkingImpl> = None;
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub(crate) enum ThreadParkingImpl {
+    // WaitOnAddress-based, Windows 8+
+    Futex,
+    // NtCreatedKeyedEvent-based, Windows XP+
+    KeyedEvent,
+    // Generic thread parker based on Mutex+Condvar
+    Generic,
+}
+
+// This CANNOT be called during global init because it has to `LoadLibrary` to figure out which impl
+// is available.
+pub(crate) fn thread_parking_impl() -> ThreadParkingImpl {
+    if let Some(implementation) = unsafe { THREAD_PARKING_IMPL } {
+        return implementation;
+    }
+
+    let implementation = {
+        if crate::sys::c::WaitOnAddress::available().is_some()
+            && crate::sys::c::WakeByAddressSingle::available().is_some()
+        {
+            ThreadParkingImpl::Futex
+        } else if crate::sys::c::NtCreateKeyedEvent::available().is_some()
+            && crate::sys::c::NtReleaseKeyedEvent::available().is_some()
+            && crate::sys::c::NtWaitForKeyedEvent::available().is_some()
+        {
+            ThreadParkingImpl::KeyedEvent
+        } else {
+            ThreadParkingImpl::Generic
+        }
+    };
+
+    unsafe {
+        THREAD_PARKING_IMPL = Some(implementation);
+    }
+
+    implementation
+}
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index b3659351b8c11..c321015ba7c2e 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -1,10 +1,10 @@
 use super::api::{self, WinError};
 use super::{IoResult, to_u16s};
-use crate::alloc::{alloc, handle_alloc_error};
+use crate::alloc::{Layout, alloc, dealloc};
 use crate::borrow::Cow;
 use crate::ffi::{OsStr, OsString, c_void};
 use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
-use crate::mem::{self, MaybeUninit};
+use crate::mem::{self, MaybeUninit, offset_of};
 use crate::os::windows::io::{AsHandle, BorrowedHandle};
 use crate::os::windows::prelude::*;
 use crate::path::{Path, PathBuf};
@@ -184,6 +184,7 @@ impl DirEntry {
 }
 
 impl OpenOptions {
+    #[cfg(not(target_vendor = "rust9x"))]
     pub fn new() -> OpenOptions {
         OpenOptions {
             // generic
@@ -203,6 +204,31 @@ impl OpenOptions {
         }
     }
 
+    #[cfg(target_vendor = "rust9x")]
+    pub fn new() -> OpenOptions {
+        OpenOptions {
+            // generic
+            read: false,
+            write: false,
+            append: false,
+            truncate: false,
+            create: false,
+            create_new: false,
+            // system-specific
+            custom_flags: 0,
+            access_mode: None,
+            share_mode: if crate::sys::compat::checks::is_windows_nt() {
+                c::FILE_SHARE_READ | c::FILE_SHARE_WRITE | c::FILE_SHARE_DELETE
+            } else {
+                // _DELETE is only supported on NT-based systems.
+                c::FILE_SHARE_READ | c::FILE_SHARE_WRITE
+            },
+            attributes: 0,
+            security_qos_flags: 0,
+            security_attributes: ptr::null_mut(),
+        }
+    }
+
     pub fn read(&mut self, read: bool) {
         self.read = read;
     }
@@ -243,6 +269,7 @@ impl OpenOptions {
         self.security_attributes = attrs;
     }
 
+    #[cfg(not(target_vendor = "rust9x"))]
     fn get_access_mode(&self) -> io::Result<u32> {
         match (self.read, self.write, self.append, self.access_mode) {
             (.., Some(mode)) => Ok(mode),
@@ -259,6 +286,35 @@ impl OpenOptions {
         }
     }
 
+    #[cfg(target_vendor = "rust9x")]
+    fn get_access_mode(&self) -> io::Result<u32> {
+        // 9x/ME only supports a limited number of access rights (DELETE, FILE_WRITE_ATTRIBUTES,
+        // GENERIC_READ, and GENERIC_WRITE). This means that we can't use the special append-only
+        // behavior (atomic appends). Additionally, files opened with `append(true)` *will* be able
+        // to seek back and overwrite existing data on these systems.
+        let is_nt = crate::sys::compat::checks::is_windows_nt();
+
+        match (self.read, self.write, self.append, self.access_mode) {
+            (.., Some(mode)) => Ok(mode),
+            (true, false, false, None) => Ok(c::GENERIC_READ),
+            (false, true, false, None) => Ok(c::GENERIC_WRITE),
+            (true, true, false, None) => Ok(c::GENERIC_READ | c::GENERIC_WRITE),
+            (false, _, true, None) => Ok(if is_nt {
+                c::FILE_GENERIC_WRITE & !c::FILE_WRITE_DATA
+            } else {
+                c::GENERIC_WRITE
+            }),
+            (true, _, true, None) => Ok(if is_nt {
+                c::GENERIC_READ | (c::FILE_GENERIC_WRITE & !c::FILE_WRITE_DATA)
+            } else {
+                c::GENERIC_READ | c::GENERIC_WRITE
+            }),
+            (false, false, false, None) => {
+                Err(Error::from_raw_os_error(c::ERROR_INVALID_PARAMETER as i32))
+            }
+        }
+    }
+
     fn get_creation_mode(&self) -> io::Result<u32> {
         match (self.write, self.append) {
             (true, false) => {}
@@ -296,6 +352,10 @@ impl OpenOptions {
 impl File {
     pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
         let path = maybe_verbatim(path)?;
+        Self::open_native(&path, opts)
+    }
+
+    fn open_native(path: &[u16], opts: &OpenOptions) -> io::Result<File> {
         let creation = opts.get_creation_mode()?;
         let handle = unsafe {
             c::CreateFileW(
@@ -328,23 +388,21 @@ impl File {
                         mem::size_of::<c::FILE_ALLOCATION_INFO>() as u32,
                     );
                     if result == 0 {
-                        if api::get_last_error().code != 0 {
-                            panic!("FILE_ALLOCATION_INFO failed!!!");
-                        }
-                        let eof = c::FILE_END_OF_FILE_INFO { EndOfFile: 0 };
-                        let result = c::SetFileInformationByHandle(
-                            handle.as_raw_handle(),
-                            c::FileEndOfFileInfo,
-                            (&raw const eof).cast::<c_void>(),
-                            mem::size_of::<c::FILE_END_OF_FILE_INFO>() as u32,
-                        );
-                        if result == 0 {
-                            return Err(io::Error::last_os_error());
-                        }
+                        Self::truncate_inner(handle.as_raw_handle(), 0)?
                     }
                 }
             }
-            Ok(File { handle: Handle::from_inner(handle) })
+            let file = File { handle: Handle::from_inner(handle) };
+
+            // 9x/ME do not support FILE_APPEND_DATA/FILE_WRITE_DATA, which means that we cannot get
+            // the append-only behaviors: atomic appends, cursor starts at the end of the file. The
+            // latter can be emulated, at least, by just seeking to the end.
+            #[cfg(target_vendor = "rust9x")]
+            if opts.append && !crate::sys::compat::checks::is_windows_nt() {
+                file.seek(SeekFrom::End(0))?;
+            }
+
+            Ok(file)
         } else {
             Err(Error::last_os_error())
         }
@@ -362,7 +420,7 @@ impl File {
     fn acquire_lock(&self, flags: c::LOCK_FILE_FLAGS) -> io::Result<()> {
         unsafe {
             let mut overlapped: c::OVERLAPPED = mem::zeroed();
-            let event = c::CreateEventW(ptr::null_mut(), c::FALSE, c::FALSE, ptr::null());
+            let event = c::CreateEventA(ptr::null_mut(), c::FALSE, c::FALSE, ptr::null());
             if event.is_null() {
                 return Err(io::Error::last_os_error());
             }
@@ -401,6 +459,15 @@ impl File {
     }
 
     pub fn lock(&self) -> io::Result<()> {
+        #[cfg(target_vendor = "rust9x")]
+        {
+            // try `LockFile`/`try_lock`, as that one is available on 9x/ME
+            if self.try_lock()? {
+                return Ok(());
+            }
+
+            // otherwise just fail the call to `LockFileEx` here
+        }
         self.acquire_lock(c::LOCKFILE_EXCLUSIVE_LOCK)
     }
 
@@ -409,17 +476,8 @@ impl File {
     }
 
     pub fn try_lock(&self) -> io::Result<bool> {
-        let result = cvt(unsafe {
-            let mut overlapped = mem::zeroed();
-            c::LockFileEx(
-                self.handle.as_raw_handle(),
-                c::LOCKFILE_EXCLUSIVE_LOCK | c::LOCKFILE_FAIL_IMMEDIATELY,
-                0,
-                u32::MAX,
-                u32::MAX,
-                &mut overlapped,
-            )
-        });
+        let result =
+            cvt(unsafe { c::LockFile(self.handle.as_raw_handle(), 0, 0, u32::MAX, u32::MAX) });
 
         match result {
             Ok(_) => Ok(true),
@@ -474,8 +532,37 @@ impl File {
     }
 
     pub fn truncate(&self, size: u64) -> io::Result<()> {
+        Self::truncate_inner(self.handle.as_raw_handle(), size)
+    }
+
+    #[cfg(not(target_vendor = "rust9x"))]
+    pub fn truncate_inner(handle: RawHandle, size: u64) -> io::Result<()> {
         let info = c::FILE_END_OF_FILE_INFO { EndOfFile: size as i64 };
-        api::set_file_information_by_handle(self.handle.as_raw_handle(), &info).io_result()
+        api::set_file_information_by_handle(handle, &info).io_result()
+    }
+
+    #[cfg(target_vendor = "rust9x")]
+    pub fn truncate_inner(handle: RawHandle, size: u64) -> io::Result<()> {
+        if crate::sys::compat::checks::is_windows_nt() {
+            let info = c::FILE_END_OF_FILE_INFO { EndOfFile: size as i64 };
+            api::set_file_information_by_handle(handle, &info).io_result()
+        } else {
+            let mut saved_pos = 0i64;
+            unsafe {
+                // get current file pointer position
+                cvt(c::SetFilePointerEx(handle, 0, &mut saved_pos, c::FILE_CURRENT))?;
+
+                // seek to new end position
+                cvt(c::SetFilePointerEx(handle, size as i64, ptr::null_mut(), c::FILE_BEGIN))?;
+
+                // set current position as end of file
+                cvt(c::SetEndOfFile(handle))?;
+
+                // go back to saved position
+                cvt(c::SetFilePointerEx(handle, saved_pos, ptr::null_mut(), c::FILE_BEGIN))?;
+            }
+            Ok(())
+        }
     }
 
     #[cfg(not(target_vendor = "uwp"))]
@@ -486,6 +573,11 @@ impl File {
             let mut reparse_tag = 0;
             if info.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
                 let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed();
+                // rust9x: If a reparse point attribute is returned, we must be on NT-based Windows
+                // with support for FileAttributeTagInformation, so our
+                // fallback implementation of `GetFileInformationByHandleEx` will work without
+                // further checks.
+
                 cvt(c::GetFileInformationByHandleEx(
                     self.handle.as_raw_handle(),
                     c::FileAttributeTagInfo,
@@ -830,6 +922,10 @@ impl File {
     /// you will always iterate an empty directory regardless of the target.
     #[allow(unused)]
     fn fill_dir_buff(&self, buffer: &mut DirBuff, restart: bool) -> Result<bool, WinError> {
+        #[cfg(target_vendor = "rust9x")]
+        let class =
+            if restart { c::FileFullDirectoryRestartInfo } else { c::FileFullDirectoryInfo };
+        #[cfg(not(target_vendor = "rust9x"))]
         let class =
             if restart { c::FileIdBothDirectoryRestartInfo } else { c::FileIdBothDirectoryInfo };
 
@@ -907,6 +1003,9 @@ impl<'a> Iterator for DirBuffIter<'a> {
         //   `FILE_ID_BOTH_DIR_INFO` and the trailing filename (for at least
         //   `FileNameLength` bytes)
         let (name, is_directory, next_entry) = unsafe {
+            #[cfg(target_vendor = "rust9x")]
+            let info = buffer.as_ptr().cast::<c::FILE_FULL_DIR_INFO>();
+            #[cfg(not(target_vendor = "rust9x"))]
             let info = buffer.as_ptr().cast::<c::FILE_ID_BOTH_DIR_INFO>();
             // While this is guaranteed to be aligned in documentation for
             // https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_both_dir_info
@@ -1182,6 +1281,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
         //
         // We can pass FIND_FIRST_EX_LARGE_FETCH to dwAdditionalFlags to speed up things more,
         // but as we don't know user's use profile of this function, lets be conservative.
+        #[cfg(not(target_vendor = "rust9x"))]
         let find_handle = c::FindFirstFileExW(
             path.as_ptr(),
             c::FindExInfoBasic,
@@ -1191,6 +1291,11 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
             0,
         );
 
+        // We take the hit of filling in the alternate file name because both `FindFirstFileExW` and
+        // `FindExInfoBasic` aren't necessarily supported.
+        #[cfg(target_vendor = "rust9x")]
+        let find_handle = c::FindFirstFileW(path.as_ptr(), &mut wfd);
+
         if find_handle != c::INVALID_HANDLE_VALUE {
             Ok(ReadDir {
                 handle: FindNextFileHandle(find_handle),
@@ -1237,141 +1342,72 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
     let old = maybe_verbatim(old)?;
     let new = maybe_verbatim(new)?;
 
-    let new_len_without_nul_in_bytes = (new.len() - 1).try_into().unwrap();
-
-    // The last field of FILE_RENAME_INFO, the file name, is unsized,
-    // and FILE_RENAME_INFO has two padding bytes.
-    // Therefore we need to make sure to not allocate less than
-    // size_of::<c::FILE_RENAME_INFO>() bytes, which would be the case with
-    // 0 or 1 character paths + a null byte.
-    let struct_size = mem::size_of::<c::FILE_RENAME_INFO>()
-        .max(mem::offset_of!(c::FILE_RENAME_INFO, FileName) + new.len() * mem::size_of::<u16>());
-
-    let struct_size: u32 = struct_size.try_into().unwrap();
-
-    let create_file = |extra_access, extra_flags| {
-        let handle = unsafe {
-            HandleOrInvalid::from_raw_handle(c::CreateFileW(
-                old.as_ptr(),
-                c::SYNCHRONIZE | c::DELETE | extra_access,
-                c::FILE_SHARE_READ | c::FILE_SHARE_WRITE | c::FILE_SHARE_DELETE,
-                ptr::null(),
-                c::OPEN_EXISTING,
-                c::FILE_ATTRIBUTE_NORMAL | c::FILE_FLAG_BACKUP_SEMANTICS | extra_flags,
-                ptr::null_mut(),
-            ))
-        };
-
-        OwnedHandle::try_from(handle).map_err(|_| io::Error::last_os_error())
-    };
-
-    // The following code replicates `MoveFileEx`'s behavior as reverse-engineered from its disassembly.
-    // If `old` refers to a mount point, we move it instead of the target.
-    let handle = match create_file(c::FILE_READ_ATTRIBUTES, c::FILE_FLAG_OPEN_REPARSE_POINT) {
-        Ok(handle) => {
-            let mut file_attribute_tag_info: MaybeUninit<c::FILE_ATTRIBUTE_TAG_INFO> =
-                MaybeUninit::uninit();
-
-            let result = unsafe {
-                cvt(c::GetFileInformationByHandleEx(
-                    handle.as_raw_handle(),
-                    c::FileAttributeTagInfo,
-                    file_attribute_tag_info.as_mut_ptr().cast(),
-                    mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
-                ))
+    if unsafe { c::MoveFileExW(old.as_ptr(), new.as_ptr(), c::MOVEFILE_REPLACE_EXISTING) } == 0 {
+        let err = api::get_last_error();
+        // if `MoveFileExW` fails with ERROR_ACCESS_DENIED then try to move
+        // the file while ignoring the readonly attribute.
+        // This is accomplished by calling `SetFileInformationByHandle` with `FileRenameInfoEx`.
+        if err == WinError::ACCESS_DENIED {
+            let mut opts = OpenOptions::new();
+            opts.access_mode(c::DELETE);
+            opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT | c::FILE_FLAG_BACKUP_SEMANTICS);
+            let Ok(f) = File::open_native(&old, &opts) else { return Err(err).io_result() };
+
+            // Calculate the layout of the `FILE_RENAME_INFO` we pass to `SetFileInformation`
+            // This is a dynamically sized struct so we need to get the position of the last field to calculate the actual size.
+            let Ok(new_len_without_nul_in_bytes): Result<u32, _> = ((new.len() - 1) * 2).try_into()
+            else {
+                return Err(err).io_result();
             };
-
-            if let Err(err) = result {
-                if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _)
-                    || err.raw_os_error() == Some(c::ERROR_INVALID_FUNCTION as _)
-                {
-                    // `GetFileInformationByHandleEx` documents that not all underlying drivers support all file information classes.
-                    // Since we know we passed the correct arguments, this means the underlying driver didn't understand our request;
-                    // `MoveFileEx` proceeds by reopening the file without inhibiting reparse point behavior.
-                    None
-                } else {
-                    Some(Err(err))
-                }
-            } else {
-                // SAFETY: The struct has been initialized by GetFileInformationByHandleEx
-                let file_attribute_tag_info = unsafe { file_attribute_tag_info.assume_init() };
-                let file_type = FileType::new(
-                    file_attribute_tag_info.FileAttributes,
-                    file_attribute_tag_info.ReparseTag,
-                );
-
-                if file_type.is_symlink() {
-                    // The file is a mount point, junction point or symlink so
-                    // don't reopen the file so that the link gets renamed.
-                    Some(Ok(handle))
-                } else {
-                    // Otherwise reopen the file without inhibiting reparse point behavior.
-                    None
+            let offset: u32 = offset_of!(c::FILE_RENAME_INFO, FileName).try_into().unwrap();
+            let struct_size = offset + new_len_without_nul_in_bytes + 2;
+            let layout =
+                Layout::from_size_align(struct_size as usize, align_of::<c::FILE_RENAME_INFO>())
+                    .unwrap();
+
+            // SAFETY: We allocate enough memory for a full FILE_RENAME_INFO struct and a filename.
+            let file_rename_info;
+            unsafe {
+                file_rename_info = alloc(layout).cast::<c::FILE_RENAME_INFO>();
+                if file_rename_info.is_null() {
+                    return Err(io::ErrorKind::OutOfMemory.into());
                 }
-            }
-        }
-        // The underlying driver may not support `FILE_FLAG_OPEN_REPARSE_POINT`: Retry without it.
-        Err(err) if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _) => None,
-        Err(err) => Some(Err(err)),
-    }
-    .unwrap_or_else(|| create_file(0, 0))?;
-
-    let layout = core::alloc::Layout::from_size_align(
-        struct_size as _,
-        mem::align_of::<c::FILE_RENAME_INFO>(),
-    )
-    .unwrap();
-
-    let file_rename_info = unsafe { alloc(layout) } as *mut c::FILE_RENAME_INFO;
-
-    if file_rename_info.is_null() {
-        handle_alloc_error(layout);
-    }
 
-    // SAFETY: file_rename_info is a non-null pointer pointing to memory allocated by the global allocator.
-    let mut file_rename_info = unsafe { Box::from_raw(file_rename_info) };
-
-    // SAFETY: We have allocated enough memory for a full FILE_RENAME_INFO struct and a filename.
-    unsafe {
-        (&raw mut (*file_rename_info).Anonymous).write(c::FILE_RENAME_INFO_0 {
-            Flags: c::FILE_RENAME_FLAG_REPLACE_IF_EXISTS | c::FILE_RENAME_FLAG_POSIX_SEMANTICS,
-        });
-
-        (&raw mut (*file_rename_info).RootDirectory).write(ptr::null_mut());
-        (&raw mut (*file_rename_info).FileNameLength).write(new_len_without_nul_in_bytes);
-
-        new.as_ptr()
-            .copy_to_nonoverlapping((&raw mut (*file_rename_info).FileName) as *mut u16, new.len());
-    }
+                (&raw mut (*file_rename_info).Anonymous).write(c::FILE_RENAME_INFO_0 {
+                    Flags: c::FILE_RENAME_FLAG_REPLACE_IF_EXISTS
+                        | c::FILE_RENAME_FLAG_POSIX_SEMANTICS,
+                });
 
-    // We don't use `set_file_information_by_handle` here as `FILE_RENAME_INFO` is used for both `FileRenameInfo` and `FileRenameInfoEx`.
-    let result = unsafe {
-        cvt(c::SetFileInformationByHandle(
-            handle.as_raw_handle(),
-            c::FileRenameInfoEx,
-            (&raw const *file_rename_info).cast::<c_void>(),
-            struct_size,
-        ))
-    };
+                (&raw mut (*file_rename_info).RootDirectory).write(ptr::null_mut());
+                // Don't include the NULL in the size
+                (&raw mut (*file_rename_info).FileNameLength).write(new_len_without_nul_in_bytes);
 
-    if let Err(err) = result {
-        if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as _) {
-            // FileRenameInfoEx and FILE_RENAME_FLAG_POSIX_SEMANTICS were added in Windows 10 1607; retry with FileRenameInfo.
-            file_rename_info.Anonymous.ReplaceIfExists = 1;
+                new.as_ptr().copy_to_nonoverlapping(
+                    (&raw mut (*file_rename_info).FileName).cast::<u16>(),
+                    new.len(),
+                );
+            }
 
-            cvt(unsafe {
+            let result = unsafe {
                 c::SetFileInformationByHandle(
-                    handle.as_raw_handle(),
-                    c::FileRenameInfo,
-                    (&raw const *file_rename_info).cast::<c_void>(),
+                    f.as_raw_handle(),
+                    c::FileRenameInfoEx,
+                    file_rename_info.cast::<c_void>(),
                     struct_size,
                 )
-            })?;
+            };
+            unsafe { dealloc(file_rename_info.cast::<u8>(), layout) };
+            if result == 0 {
+                if api::get_last_error() == WinError::DIR_NOT_EMPTY {
+                    return Err(WinError::DIR_NOT_EMPTY).io_result();
+                } else {
+                    return Err(err).io_result();
+                }
+            }
         } else {
-            return Err(err);
+            return Err(err).io_result();
         }
     }
-
     Ok(())
 }
 
@@ -1382,6 +1418,22 @@ pub fn rmdir(p: &Path) -> io::Result<()> {
 }
 
 pub fn remove_dir_all(path: &Path) -> io::Result<()> {
+    #[cfg(target_vendor = "rust9x")]
+    {
+        // if the modern file/directory APIs are not available, we'll fall back to the old (unsafe, see
+        // https://github.com/rust-lang/rust/pull/93112) directory removal implementation
+        if !crate::sys::compat::checks::is_windows_nt() {
+            let filetype = lstat(path)?.file_type();
+            if filetype.is_symlink() {
+                // On Windows symlinks to files and directories are removed differently.
+                // rmdir only deletes dir symlinks and junctions, not file symlinks.
+                return rmdir(path);
+            } else {
+                return remove_dir_all::remove_dir_all_recursive_old(path);
+            }
+        }
+    }
+
     // Open a file or directory without following symlinks.
     let mut opts = OpenOptions::new();
     opts.access_mode(c::FILE_LIST_DIRECTORY);
@@ -1492,13 +1544,60 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result<FileAttr> {
     let mut opts = OpenOptions::new();
     // No read or write permissions are necessary
     opts.access_mode(0);
+
+    #[cfg(not(target_vendor = "rust9x"))]
     opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | reparse.as_flag());
+    #[cfg(target_vendor = "rust9x")]
+    if crate::sys::compat::checks::is_windows_nt() {
+        opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | reparse.as_flag());
+    }
 
     // Attempt to open the file normally.
     // If that fails with `ERROR_SHARING_VIOLATION` then retry using `FindFirstFileExW`.
     // If the fallback fails for any reason we return the original error.
     match File::open(path, &opts) {
         Ok(file) => file.file_attr(),
+        #[cfg(target_vendor = "rust9x")]
+        Err(e) if !crate::sys::compat::checks::is_windows_nt() => {
+            let path = maybe_verbatim(path)?;
+            unsafe {
+                // Get at least the attributes in case `FindFirstFile` fails down below
+                let attr = c::GetFileAttributesW(path.as_ptr());
+                if attr == c::INVALID_FILE_ATTRIBUTES {
+                    return Err(e);
+                }
+
+                // Since we don't have access to `FILE_FLAG_BACKUP_SEMANTICS` on 9x/ME, fall back to
+                // `FindFirstFile` for directories
+                let mut find_data: c::WIN32_FIND_DATAW = mem::zeroed();
+                let handle = c::FindFirstFileW(path.as_ptr(), &mut find_data);
+
+                if handle == c::INVALID_HANDLE_VALUE {
+                    // You can't get info about the root directory via FindFirstFile, so in that
+                    // case and any other cases where FindFirstFile fails, fall back to the
+                    // already-retrieved attributes.
+                    //
+                    // For directories, we can only get attributes on 9x/ME.
+                    return Ok(FileAttr {
+                        attributes: attr,
+                        creation_time: mem::zeroed(),
+                        last_access_time: mem::zeroed(),
+                        last_write_time: mem::zeroed(),
+                        change_time: None,
+                        file_size: 0,
+                        reparse_tag: 0,
+                        volume_serial_number: None,
+                        number_of_links: None,
+                        file_index: None,
+                    });
+                }
+
+                let attrs = FileAttr::from(find_data);
+                c::FindClose(handle);
+
+                return Ok(attrs);
+            }
+        }
         Err(e)
             if [Some(c::ERROR_SHARING_VIOLATION as _), Some(c::ERROR_ACCESS_DENIED as _)]
                 .contains(&e.raw_os_error()) =>
@@ -1518,6 +1617,7 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result<FileAttr> {
                 // therefore it's safe to assume the file name given does not
                 // include wildcards.
                 let mut wfd: c::WIN32_FIND_DATAW = mem::zeroed();
+
                 let handle = c::FindFirstFileExW(
                     path.as_ptr(),
                     c::FindExInfoBasic,
@@ -1567,6 +1667,7 @@ fn get_path(f: &File) -> io::Result<PathBuf> {
     )
 }
 
+#[cfg(not(target_vendor = "rust9x"))]
 pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
     let mut opts = OpenOptions::new();
     // No read or write permissions are necessary
@@ -1577,6 +1678,28 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
     get_path(&f)
 }
 
+#[cfg(target_vendor = "rust9x")]
+pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
+    if c::GetFinalPathNameByHandleW::available().is_some() {
+        let mut opts = OpenOptions::new();
+        // No read or write permissions are necessary
+        opts.access_mode(0);
+        // This flag is so we can open directories too
+        opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS);
+        let f = File::open(p, &opts)?;
+        get_path(&f)
+    } else {
+        // systems that don't support GetFinalPathNameByHandleW also don't support symlinks, so we
+        // fall back to using GetFullPathName.
+        let path = maybe_verbatim(p)?;
+        let mut file_part = ptr::null_mut();
+        super::fill_utf16_buf(
+            |buf, sz| unsafe { c::GetFullPathNameW(path.as_ptr(), sz, buf, &mut file_part) },
+            |buf| PathBuf::from(OsString::from_wide(buf)),
+        )
+    }
+}
+
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     unsafe extern "system" fn callback(
         _TotalFileSize: i64,
@@ -1691,6 +1814,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> {
     }
 }
 
+#[cfg(not(target_vendor = "rust9x"))]
 // Try to see if a file exists but, unlike `exists`, report I/O errors.
 pub fn exists(path: &Path) -> io::Result<bool> {
     // Open the file to ensure any symlinks are followed to their target.
@@ -1725,3 +1849,58 @@ pub fn exists(path: &Path) -> io::Result<bool> {
         Ok(_) => Ok(true),
     }
 }
+
+#[cfg(target_vendor = "rust9x")]
+// Try to see if a file exists but, unlike `exists`, report I/O errors.
+pub fn exists(path: &Path) -> io::Result<bool> {
+    fn match_kind(e: crate::io::Error) -> io::Result<bool> {
+        match e.kind() {
+            // The file definitely does not exist
+            io::ErrorKind::NotFound => Ok(false),
+
+            // `ERROR_SHARING_VIOLATION` means that the file has been locked by
+            // another process. This is often temporary so we simply report it
+            // as the file existing.
+            _ if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as i32) => Ok(true),
+
+            // `ERROR_CANT_ACCESS_FILE` means that a file exists but that the
+            // reparse point could not be handled by `CreateFile`.
+            // This can happen for special files such as:
+            // * Unix domain sockets which you need to `connect` to
+            // * App exec links which require using `CreateProcess`
+            _ if e.raw_os_error() == Some(c::ERROR_CANT_ACCESS_FILE as i32) => Ok(true),
+
+            // Other errors such as `ERROR_ACCESS_DENIED` may indicate that the
+            // file exists. However, these types of errors are usually more
+            // permanent so we report them here.
+            _ => Err(e),
+        }
+    }
+
+    // Open the file to ensure any symlinks are followed to their target.
+    let mut opts = OpenOptions::new();
+    // No read, write, etc access rights are needed.
+    opts.access_mode(0);
+
+    if crate::sys::compat::checks::is_windows_nt() {
+        // Backup semantics enables opening directories as well as files.
+        opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS);
+    } else {
+        let path = maybe_verbatim(path)?;
+        let attr = unsafe { c::GetFileAttributesW(path.as_ptr()) };
+        if attr == c::INVALID_FILE_ATTRIBUTES {
+            return match_kind(io::Error::last_os_error());
+        } else {
+            // can't open a directory on 9x/ME anyways
+            if attr & c::FILE_ATTRIBUTE_DIRECTORY != 0 {
+                return Ok(true);
+            }
+        }
+    }
+
+    match File::open(path, &opts) {
+        Err(e) => match_kind(e),
+        // The file was opened successfully therefore it must exist,
+        Ok(_) => Ok(true),
+    }
+}
diff --git a/library/std/src/sys/pal/windows/fs/remove_dir_all.rs b/library/std/src/sys/pal/windows/fs/remove_dir_all.rs
index 9416049da78f8..071be387c8c30 100644
--- a/library/std/src/sys/pal/windows/fs/remove_dir_all.rs
+++ b/library/std/src/sys/pal/windows/fs/remove_dir_all.rs
@@ -203,3 +203,21 @@ pub fn remove_dir_all_iterative(dir: File) -> Result<(), WinError> {
     }
     Ok(())
 }
+
+#[cfg(target_vendor = "rust9x")]
+pub fn remove_dir_all_recursive_old(path: &crate::path::Path) -> crate::io::Result<()> {
+    use super::*;
+
+    for child in readdir(path)? {
+        let child = child?;
+        let child_type = child.file_type()?;
+        if child_type.is_dir() {
+            remove_dir_all_recursive_old(&child.path())?;
+        } else if child_type.is_symlink_dir() {
+            rmdir(&child.path())?;
+        } else {
+            unlink(&child.path())?;
+        }
+    }
+    rmdir(path)
+}
diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs
index 38afb8c043b3b..f30630ceb2168 100644
--- a/library/std/src/sys/pal/windows/futex.rs
+++ b/library/std/src/sys/pal/windows/futex.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code)]
+
 use core::ffi::c_void;
 use core::sync::atomic::{
     AtomicBool, AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize, AtomicPtr, AtomicU8,
diff --git a/library/std/src/sys/pal/windows/handle.rs b/library/std/src/sys/pal/windows/handle.rs
index 82a880faf5fa7..15088136d17e1 100644
--- a/library/std/src/sys/pal/windows/handle.rs
+++ b/library/std/src/sys/pal/windows/handle.rs
@@ -23,7 +23,7 @@ impl Handle {
     pub fn new_event(manual: bool, init: bool) -> io::Result<Handle> {
         unsafe {
             let event =
-                c::CreateEventW(ptr::null_mut(), manual as c::BOOL, init as c::BOOL, ptr::null());
+                c::CreateEventA(ptr::null_mut(), manual as c::BOOL, init as c::BOOL, ptr::null());
             if event.is_null() {
                 Err(io::Error::last_os_error())
             } else {
@@ -245,6 +245,32 @@ impl Handle {
 
         // The length is clamped at u32::MAX.
         let len = cmp::min(len, u32::MAX as usize) as u32;
+
+        #[cfg(target_vendor = "rust9x")]
+        if !crate::sys::compat::checks::supports_async_io() {
+            unsafe {
+                if let Some(offset) = offset {
+                    cvt(c::SetFilePointerEx(
+                        self.as_raw_handle(),
+                        offset as i64,
+                        ptr::null_mut(),
+                        c::FILE_BEGIN,
+                    ))?;
+                }
+
+                let mut bytes_read = 0;
+                cvt(c::ReadFile(
+                    self.as_raw_handle(),
+                    buf.cast(),
+                    len,
+                    &mut bytes_read,
+                    ptr::null_mut(),
+                ))?;
+
+                return Ok(bytes_read as usize);
+            }
+        }
+
         // SAFETY: It's up to the caller to ensure `buf` is writeable up to
         // the provided `len`.
         let status = unsafe {
@@ -297,6 +323,32 @@ impl Handle {
 
         // The length is clamped at u32::MAX.
         let len = cmp::min(buf.len(), u32::MAX as usize) as u32;
+
+        #[cfg(target_vendor = "rust9x")]
+        if !crate::sys::compat::checks::supports_async_io() {
+            unsafe {
+                if let Some(offset) = offset {
+                    cvt(c::SetFilePointerEx(
+                        self.as_raw_handle(),
+                        offset as i64,
+                        ptr::null_mut(),
+                        c::FILE_BEGIN,
+                    ))?;
+                }
+
+                let mut bytes_written = 0;
+                cvt(c::WriteFile(
+                    self.as_raw_handle(),
+                    buf.as_ptr(),
+                    len,
+                    &mut bytes_written,
+                    ptr::null_mut(),
+                ))?;
+
+                return Ok(bytes_written as usize);
+            }
+        }
+
         let status = unsafe {
             c::NtWriteFile(
                 self.as_raw_handle(),
diff --git a/library/std/src/sys/pal/windows/io.rs b/library/std/src/sys/pal/windows/io.rs
index f2865d2ffc168..5953574d4577c 100644
--- a/library/std/src/sys/pal/windows/io.rs
+++ b/library/std/src/sys/pal/windows/io.rs
@@ -124,6 +124,11 @@ fn msys_tty_on(handle: BorrowedHandle<'_>) -> bool {
     let mut name_info = FILE_NAME_INFO { FileNameLength: 0, FileName: [0; c::MAX_PATH as usize] };
     // Safety: buffer length is fixed.
     let res = unsafe {
+        #[cfg(target_vendor = "rust9x")]
+        if !crate::sys::compat::checks::is_windows_nt() {
+            return false;
+        }
+
         c::GetFileInformationByHandleEx(
             handle.as_raw_handle(),
             c::FileNameInfo,
diff --git a/library/std/src/sys/pal/windows/net.rs b/library/std/src/sys/pal/windows/net.rs
index a92853c642c06..24b1807b1bc8f 100644
--- a/library/std/src/sys/pal/windows/net.rs
+++ b/library/std/src/sys/pal/windows/net.rs
@@ -189,7 +189,7 @@ impl Socket {
             SocketAddr::V6(..) => netc::AF_INET6,
         };
         let socket = unsafe {
-            c::WSASocketW(
+            c::WSASocketA(
                 family,
                 ty,
                 0,
@@ -209,7 +209,7 @@ impl Socket {
             }
 
             let socket =
-                unsafe { c::WSASocketW(family, ty, 0, ptr::null_mut(), 0, c::WSA_FLAG_OVERLAPPED) };
+                unsafe { c::WSASocketA(family, ty, 0, ptr::null_mut(), 0, c::WSA_FLAG_OVERLAPPED) };
 
             if socket == c::INVALID_SOCKET {
                 return Err(last_error());
diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs
index 5231a34469abf..fe386669bad0f 100644
--- a/library/std/src/sys/pal/windows/os.rs
+++ b/library/std/src/sys/pal/windows/os.rs
@@ -31,12 +31,7 @@ pub fn error_string(mut errnum: i32) -> String {
         // GetLastError. For more information about Windows error codes, see
         // `[MS-ERREF]`: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/0642cb2f-2075-4469-918c-4441e69c548a
         if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
-            // format according to https://support.microsoft.com/en-us/help/259693
-            const NTDLL_DLL: &[u16] = &[
-                'N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _, '.' as _, 'D' as _, 'L' as _,
-                'L' as _, 0,
-            ];
-            module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
+            module = c::GetModuleHandleA(c"NTDLL.DLL".as_ptr().cast());
 
             if !module.is_null() {
                 errnum ^= c::FACILITY_NT_BIT as i32;
@@ -320,7 +315,7 @@ pub fn temp_dir() -> PathBuf {
     super::fill_utf16_buf(|buf, sz| unsafe { c::GetTempPath2W(sz, buf) }, super::os2path).unwrap()
 }
 
-#[cfg(all(not(target_vendor = "uwp"), not(target_vendor = "win7")))]
+#[cfg(all(not(target_vendor = "uwp"), not(target_vendor = "win7"), not(target_vendor = "rust9x")))]
 fn home_dir_crt() -> Option<PathBuf> {
     unsafe {
         // Defined in processthreadsapi.h.
@@ -346,7 +341,7 @@ fn home_dir_crt() -> Option<PathBuf> {
     }
 }
 
-#[cfg(target_vendor = "win7")]
+#[cfg(any(target_vendor = "win7", target_vendor = "rust9x"))]
 fn home_dir_crt() -> Option<PathBuf> {
     unsafe {
         use crate::sys::handle::Handle;
diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs
index a8f6617c9dc8f..f4e44e58955de 100644
--- a/library/std/src/sys/pal/windows/pipe.rs
+++ b/library/std/src/sys/pal/windows/pipe.rs
@@ -60,6 +60,63 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
     // A 64kb pipe capacity is the same as a typical Linux default.
     const PIPE_BUFFER_CAPACITY: u32 = 64 * 1024;
 
+    #[cfg(target_vendor = "rust9x")]
+    {
+        // Since Windows 9X/ME does not support creating named pipes (only connecting to remote pipes
+        // created on NT), we'll have to make do with anonymous pipes, without overlapped I/O. In
+        // particular, this means that we'll have to do reading from two threads in the case where both
+        // stdout and stderr being piped (see `read2`).
+
+        // 9X/ME *does* have a kernel32 export entry for `CreateNamedPipe`, so an availability check
+        // would not work. We're just gonna check the bit that's only set on non-unicode Windows
+        // versions instead...
+
+        // The `AnonPipe` impl used in `read2` below needs to be able to cancel the overlapped i/o
+        // operation, so we also have to check for `CancelIo` being available. This means that the
+        // "modern" path is taken only for NT4+.
+        if !crate::sys::compat::checks::supports_async_io() {
+            let size = mem::size_of::<c::SECURITY_ATTRIBUTES>();
+            let mut sa = c::SECURITY_ATTRIBUTES {
+                nLength: size as u32,
+                lpSecurityDescriptor: ptr::null_mut(),
+                // We follow the old "Creating a Child Process with Redirected Input and Output" MSDN
+                // entry (pre-`SetHandleInformation`) here, duplicating the handle that is not being
+                // sent to the child process as non-inheritable and then closing the inheritable one.
+                // Usually, this would be racy, but this function is only called in `Stdio::to_handle`,
+                // which is in turn only called form `process::spawn`, which acquires a lock on process
+                // spawning because of this.
+                bInheritHandle: c::TRUE,
+            };
+
+            unsafe {
+                let mut read_pipe = mem::zeroed();
+                let mut write_pipe = mem::zeroed();
+                crate::sys::cvt(c::CreatePipe(
+                    &mut read_pipe,
+                    &mut write_pipe,
+                    &mut sa,
+                    PIPE_BUFFER_CAPACITY,
+                ))?;
+                let read_pipe = Handle::from_raw_handle(read_pipe);
+                let write_pipe = Handle::from_raw_handle(write_pipe);
+
+                let (ours_inheritable, theirs) =
+                    if ours_readable { (read_pipe, write_pipe) } else { (write_pipe, read_pipe) };
+
+                // Make `ours` non-inheritable by duplicating it with the approriate setting
+                let ours = ours_inheritable.duplicate(0, false, c::DUPLICATE_SAME_ACCESS)?;
+
+                // close the old, inheritable handle to the pipe end that is ours
+                drop(ours_inheritable);
+
+                return Ok(Pipes {
+                    ours: AnonPipe { inner: ours },
+                    theirs: AnonPipe { inner: theirs },
+                });
+            }
+        }
+    }
+
     // Note that we specifically do *not* use `CreatePipe` here because
     // unfortunately the anonymous pipes returned do not support overlapped
     // operations. Instead, we create a "hopefully unique" name and create a
@@ -232,6 +289,11 @@ impl AnonPipe {
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        #[cfg(target_vendor = "rust9x")]
+        if !crate::sys::compat::checks::supports_async_io() {
+            return self.inner.read(buf);
+        }
+
         let result = unsafe {
             let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;
             let ptr = buf.as_mut_ptr();
@@ -251,6 +313,11 @@ impl AnonPipe {
     }
 
     pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
+        #[cfg(target_vendor = "rust9x")]
+        if !crate::sys::compat::checks::supports_async_io() {
+            return self.inner.read_buf(buf);
+        }
+
         let result = unsafe {
             let len = crate::cmp::min(buf.capacity(), u32::MAX as usize) as u32;
             let ptr = buf.as_mut().as_mut_ptr().cast::<u8>();
@@ -289,6 +356,11 @@ impl AnonPipe {
     }
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        #[cfg(target_vendor = "rust9x")]
+        if !crate::sys::compat::checks::supports_async_io() {
+            return self.inner.write(buf);
+        }
+
         unsafe {
             let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32;
             self.alertable_io_internal(|overlapped, callback| {
@@ -408,6 +480,24 @@ pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) ->
     let p1 = p1.into_handle();
     let p2 = p2.into_handle();
 
+    #[cfg(target_vendor = "rust9x")]
+    if !crate::sys::compat::checks::supports_async_io() {
+        // Since we are using anonymous pipes (= without overlapped I/O support) here, we can't do
+        // async waiting on both stdout and stderr at the same time on one thread, so we have to
+        // spawn an additional thread to do the waiting for the second pipe.
+
+        // See https://github.com/rust-lang/rust/pull/31618, where this was removed initially.
+        let second_pipe = crate::thread::spawn(move || {
+            let mut ret = Vec::new();
+            (&p2).read_to_end(&mut ret).map(|_| ret)
+        });
+
+        (&p1).read_to_end(v1)?;
+        *v2 = second_pipe.join().unwrap()?;
+
+        return Ok(());
+    }
+
     let mut p1 = AsyncPipe::new(p1, v1)?;
     let mut p2 = AsyncPipe::new(p2, v2)?;
     let objs = [p1.event.as_raw_handle(), p2.event.as_raw_handle()];
diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs
index 2ca20a21dfe51..e10262fe6d6dd 100644
--- a/library/std/src/sys/pal/windows/process.rs
+++ b/library/std/src/sys/pal/windows/process.rs
@@ -69,6 +69,13 @@ impl EnvKey {
 // [4] https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal
 impl Ord for EnvKey {
     fn cmp(&self, other: &Self) -> cmp::Ordering {
+        #[cfg(target_vendor = "rust9x")]
+        {
+            if c::CompareStringOrdinal::available().is_none() {
+                return self.os_string.cmp(&other.os_string);
+            }
+        }
+
         unsafe {
             let result = c::CompareStringOrdinal(
                 self.utf16.as_ptr(),
@@ -120,6 +127,15 @@ impl PartialEq<str> for EnvKey {
 // they are compared using a caseless string mapping.
 impl From<OsString> for EnvKey {
     fn from(k: OsString) -> Self {
+        #[cfg(target_vendor = "rust9x")]
+        {
+            if c::CompareStringOrdinal::available().is_none() {
+                let mut k = k;
+                k.make_ascii_uppercase();
+                return EnvKey { utf16: Vec::new(), os_string: k };
+            }
+        }
+
         EnvKey { utf16: k.encode_wide().collect(), os_string: k }
     }
 }
@@ -268,6 +284,7 @@ impl Command {
             None
         };
         let program = resolve_exe(&self.program, || env::var_os("PATH"), child_paths)?;
+        #[cfg(not(target_vendor = "rust9x"))]
         let has_bat_extension = |program: &[u16]| {
             matches!(
                 // Case insensitive "ends_with" of UTF-16 encoded ".bat" or ".cmd"
@@ -275,6 +292,20 @@ impl Command {
                 Some([46, 98 | 66, 97 | 65, 116 | 84] | [46, 99 | 67, 109 | 77, 100 | 68])
             )
         };
+        #[cfg(target_vendor = "rust9x")]
+        let has_bat_extension = |program: &[u16]| {
+            let ext = program.len().checked_sub(4).and_then(|i| program.get(i..));
+            if crate::sys::compat::checks::is_windows_nt() {
+                matches!(
+                    // Case insensitive "ends_with" of UTF-16 encoded ".bat" or ".cmd"
+                    ext,
+                    Some([46, 98 | 66, 97 | 65, 116 | 84] | [46, 99 | 67, 109 | 77, 100 | 68])
+                )
+            } else {
+                // Case insensitive "ends_with" of UTF-16 encoded ".bat"
+                matches!(ext, Some([46, 98 | 66, 97 | 65, 116 | 84, 0]))
+            }
+        };
         let is_batch_file = if path::is_verbatim(&program) {
             has_bat_extension(&program[..program.len() - 1])
         } else {
@@ -298,7 +329,16 @@ impl Command {
         cmd_str.push(0); // add null terminator
 
         // stolen from the libuv code.
+        #[cfg(not(target_vendor = "rust9x"))]
         let mut flags = self.flags | c::CREATE_UNICODE_ENVIRONMENT;
+        #[cfg(target_vendor = "rust9x")]
+        let mut flags = {
+            let mut flags = self.flags;
+            if crate::sys::compat::checks::is_windows_nt() {
+                flags |= c::CREATE_UNICODE_ENVIRONMENT;
+            }
+            flags
+        };
         if self.detach {
             flags |= c::DETACHED_PROCESS | c::CREATE_NEW_PROCESS_GROUP;
         }
@@ -353,7 +393,17 @@ impl Command {
 
         let mut si_ex;
 
-        if let Some(proc_thread_attribute_list) = proc_thread_attribute_list {
+        #[allow(unused)]
+        let mut proc_thread_addributes_supported = true;
+        #[cfg(target_vendor = "rust9x")]
+        {
+            proc_thread_addributes_supported =
+                c::InitializeProcThreadAttributeList::available().is_some();
+        }
+
+        if let Some(proc_thread_attribute_list) = proc_thread_attribute_list
+            && proc_thread_addributes_supported
+        {
             si.cb = mem::size_of::<c::STARTUPINFOEXW>() as u32;
             flags |= c::EXTENDED_STARTUPINFO_PRESENT;
 
@@ -390,6 +440,7 @@ impl Command {
                 Process {
                     handle: Handle::from_raw_handle(pi.hProcess),
                     main_thread_handle: Handle::from_raw_handle(pi.hThread),
+                    id: pi.dwProcessId,
                 },
                 pipes,
             ))
@@ -610,6 +661,17 @@ impl Stdio {
                 opts.read(stdio_id == c::STD_INPUT_HANDLE);
                 opts.write(stdio_id != c::STD_INPUT_HANDLE);
                 opts.security_attributes(&mut sa);
+
+                #[cfg(target_vendor = "rust9x")]
+                {
+                    let p = if crate::sys::compat::checks::is_windows_nt() {
+                        r"\\.\NUL"
+                    } else {
+                        r"NUL"
+                    };
+                    File::open(Path::new(p), &opts).map(|file| file.into_inner())
+                }
+                #[cfg(not(target_vendor = "rust9x"))]
                 File::open(Path::new(r"\\.\NUL"), &opts).map(|file| file.into_inner())
             }
         }
@@ -652,6 +714,7 @@ impl From<io::Stderr> for Stdio {
 pub struct Process {
     handle: Handle,
     main_thread_handle: Handle,
+    id: u32,
 }
 
 impl Process {
@@ -670,7 +733,7 @@ impl Process {
     }
 
     pub fn id(&self) -> u32 {
-        unsafe { c::GetProcessId(self.handle.as_raw_handle()) }
+        self.id
     }
 
     pub fn main_thread_handle(&self) -> BorrowedHandle<'_> {
@@ -846,12 +909,34 @@ fn make_command_line(argv0: &OsStr, args: &[Arg], force_quotes: bool) -> io::Res
 
 // Get `cmd.exe` for use with bat scripts, encoded as a UTF-16 string.
 fn command_prompt() -> io::Result<Vec<u16>> {
-    let mut system: Vec<u16> = super::fill_utf16_buf(
-        |buf, size| unsafe { c::GetSystemDirectoryW(buf, size) },
-        |buf| buf.into(),
-    )?;
-    system.extend("\\cmd.exe".encode_utf16().chain([0]));
-    Ok(system)
+    #[cfg(target_vendor = "rust9x")]
+    {
+        if crate::sys::compat::checks::is_windows_nt() {
+            let mut system: Vec<u16> = super::fill_utf16_buf(
+                |buf, size| unsafe { c::GetSystemDirectoryW(buf, size) },
+                |buf| buf.into(),
+            )?;
+            system.extend("\\cmd.exe".encode_utf16().chain([0]));
+            Ok(system)
+        } else {
+            let mut system: Vec<u16> = super::fill_utf16_buf(
+                |buf, size| unsafe { c::GetWindowsDirectoryW(buf, size) },
+                |buf| buf.into(),
+            )?;
+            system.extend("\\command.com".encode_utf16().chain([0]));
+            Ok(system)
+        }
+    }
+
+    #[cfg(not(target_vendor = "rust9x"))]
+    {
+        let mut system: Vec<u16> = super::fill_utf16_buf(
+            |buf, size| unsafe { c::GetSystemDirectoryW(buf, size) },
+            |buf| buf.into(),
+        )?;
+        system.extend("\\cmd.exe".encode_utf16().chain([0]));
+        Ok(system)
+    }
 }
 
 fn make_envp(maybe_env: Option<BTreeMap<EnvKey, OsString>>) -> io::Result<(*mut c_void, Vec<u16>)> {
diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs
index 1b735e7f0cb2e..b139a4eece87c 100644
--- a/library/std/src/sys/pal/windows/stdio.rs
+++ b/library/std/src/sys/pal/windows/stdio.rs
@@ -197,12 +197,15 @@ fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usiz
         // Note that this theoretically checks validity twice in the (most common) case
         // where the underlying byte sequence is valid utf-8 (given the check in `write()`).
         let result = c::MultiByteToWideChar(
-            c::CP_UTF8,                          // CodePage
-            c::MB_ERR_INVALID_CHARS,             // dwFlags
-            utf8.as_ptr(),                       // lpMultiByteStr
-            utf8.len() as i32,                   // cbMultiByte
+            c::CP_UTF8, // CodePage
+            #[cfg(target_vendor = "rust9x")]
+            0, // dwFlags
+            #[cfg(not(target_vendor = "rust9x"))]
+            c::MB_ERR_INVALID_CHARS, // dwFlags
+            utf8.as_ptr(), // lpMultiByteStr
+            utf8.len() as i32, // cbMultiByte
             utf16.as_mut_ptr() as *mut c::WCHAR, // lpWideCharStr
-            utf16.len() as i32,                  // cchWideChar
+            utf16.len() as i32, // cchWideChar
         );
         assert!(result != 0, "Unexpected error in MultiByteToWideChar");
 
@@ -216,6 +219,13 @@ fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usiz
     if written == utf16.len() {
         Ok(utf8.len())
     } else {
+        #[cfg(target_vendor = "rust9x")]
+        if !crate::sys::compat::checks::is_windows_nt() {
+            // FIXME: This function should manually convert to the target codepage on 9x/ME, and
+            // handle incomplete writes by calculating how many utf8-effective bytes were written.
+            // For now, we assume that the 8KB buffer is always fully written.
+            return Ok(utf8.len());
+        }
         // Make sure we didn't end up writing only half of a surrogate pair (even though the chance
         // is tiny). Because it is not possible for user code to re-slice `data` in such a way that
         // a missing surrogate can be produced (and also because of the UTF-8 validation above),
@@ -400,6 +410,10 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
         return Ok(0);
     }
 
+    #[cfg(target_vendor = "rust9x")]
+    let is_nt = crate::sys::compat::checks::is_windows_nt();
+
+    #[cfg(not(target_vendor = "rust9x"))]
     let result = unsafe {
         c::WideCharToMultiByte(
             c::CP_UTF8,              // CodePage
@@ -412,6 +426,39 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result<usize> {
             ptr::null_mut(),         // lpUsedDefaultChar
         )
     };
+
+    #[cfg(target_vendor = "rust9x")]
+    let result = {
+        let mut result = unsafe {
+            c::WideCharToMultiByte(
+                c::CP_UTF8,                                      // CodePage
+                if is_nt { c::WC_ERR_INVALID_CHARS } else { 0 }, // dwFlags
+                utf16.as_ptr(),                                  // lpWideCharStr
+                utf16.len() as i32,                              // cchWideChar
+                utf8.as_mut_ptr(),                               // lpMultiByteStr
+                utf8.len() as i32,                               // cbMultiByte
+                ptr::null(),                                     // lpDefaultChar
+                ptr::null_mut(),                                 // lpUsedDefaultChar
+            )
+        };
+
+        if result == 0 && unsafe { c::GetLastError() } == c::ERROR_INVALID_FLAGS && is_nt {
+            result = unsafe {
+                c::WideCharToMultiByte(
+                    c::CP_UTF8,         // CodePage
+                    0,                  // dwFlags (0 for pre-Vista compatibility)
+                    utf16.as_ptr(),     // lpWideCharStr
+                    utf16.len() as i32, // cchWideChar
+                    utf8.as_mut_ptr(),  // lpMultiByteStr
+                    utf8.len() as i32,  // cbMultiByte
+                    ptr::null(),        // lpDefaultChar
+                    ptr::null_mut(),    // lpUsedDefaultChar
+                )
+            };
+        }
+        result
+    };
+
     if result == 0 {
         // We can't really do any better than forget all data and return an error.
         Err(io::const_error!(
diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs
index 45e52cf4d047f..4684c63aad563 100644
--- a/library/std/src/sys/pal/windows/thread.rs
+++ b/library/std/src/sys/pal/windows/thread.rs
@@ -28,13 +28,14 @@ impl Thread {
         // SAFETY: `thread_start` has the right ABI for a thread's entry point.
         // `p` is simply passed through to the new thread without being touched.
         let ret = unsafe {
+            let mut thread_id = 0;
             let ret = c::CreateThread(
                 ptr::null_mut(),
                 stack,
                 Some(thread_start),
                 p as *mut _,
                 c::STACK_SIZE_PARAM_IS_A_RESERVATION,
-                ptr::null_mut(),
+                &mut thread_id,
             );
             HandleOrNull::from_raw_handle(ret)
         };
diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs
index de042fa3f82ab..0e939bf2ebc12 100644
--- a/library/std/src/sys/path/windows.rs
+++ b/library/std/src/sys/path/windows.rs
@@ -219,6 +219,12 @@ fn parse_next_component(path: &OsStr, verbatim: bool) -> (&OsStr, &OsStr) {
 /// This path may or may not have a verbatim prefix.
 pub(crate) fn maybe_verbatim(path: &Path) -> io::Result<Vec<u16>> {
     let path = to_u16s(path)?;
+
+    #[cfg(target_vendor = "rust9x")]
+    if !crate::sys::compat::checks::is_windows_nt() {
+        return Ok(path);
+    }
+
     get_long_path(path, true)
 }
 
diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs
index f42351deb92c0..d5cdf91b3dc42 100644
--- a/library/std/src/sys/random/mod.rs
+++ b/library/std/src/sys/random/mod.rs
@@ -89,10 +89,8 @@ cfg_if::cfg_if! {
     all(target_family = "wasm", target_os = "unknown"),
     target_os = "xous",
 )))]
-pub fn hashmap_random_keys() -> (u64, u64) {
+pub fn hashmap_random_keys() -> [u8; 16] {
     let mut buf = [0; 16];
     fill_bytes(&mut buf);
-    let k1 = u64::from_ne_bytes(buf[..8].try_into().unwrap());
-    let k2 = u64::from_ne_bytes(buf[8..].try_into().unwrap());
-    (k1, k2)
+    buf
 }
diff --git a/library/std/src/sys/random/windows.rs b/library/std/src/sys/random/windows.rs
index 7566000f9e6ff..f14f74e76307d 100644
--- a/library/std/src/sys/random/windows.rs
+++ b/library/std/src/sys/random/windows.rs
@@ -1,6 +1,6 @@
 use crate::sys::c;
 
-#[cfg(not(target_vendor = "win7"))]
+#[cfg(not(any(target_vendor = "win7", target_vendor = "rust9x")))]
 #[inline]
 pub fn fill_bytes(bytes: &mut [u8]) {
     let ret = unsafe { c::ProcessPrng(bytes.as_mut_ptr(), bytes.len()) };
@@ -18,3 +18,97 @@ pub fn fill_bytes(mut bytes: &mut [u8]) {
         bytes = &mut bytes[len as usize..];
     }
 }
+
+#[cfg(target_vendor = "rust9x")]
+mod rust9x {
+    use super::*;
+    use crate::pin::Pin;
+    use crate::sys::sync::OnceBox;
+
+    pub fn fill_bytes(mut bytes: &mut [u8]) {
+        if let Some(f) = c::RtlGenRandom::available() {
+            while !bytes.is_empty() {
+                let len = bytes.len().try_into().unwrap_or(u32::MAX);
+                let ret = unsafe { f(bytes.as_mut_ptr().cast(), len) };
+                assert_ne!(ret, 0, "failed to generate random data");
+                bytes = &mut bytes[len as usize..];
+            }
+        } else if let Some(f) = c::CryptGenRandom::available() {
+            let ctx = CRYPT_CONTEXT.get_or_init(init_crypt_context);
+            while !bytes.is_empty() {
+                let len = bytes.len().try_into().unwrap_or(u32::MAX);
+                let ret = unsafe { f(ctx.0, len, bytes.as_mut_ptr().cast()) };
+                assert_ne!(ret, 0, "failed to generate random data");
+                bytes = &mut bytes[len as usize..];
+            }
+        } else {
+            // well, we tried, fall back to a non-cryptographically-secure PRNG
+            // for NT <4.0 and 95 without IE3.02 or higher.
+
+            // seed with stack address and tick count
+            let mut state: [u32; 2] = [unsafe { c::GetTickCount() }, 0];
+            state[1] = (&raw const state) as u32;
+
+            let mut chunks = bytes.chunks_exact_mut(4);
+            for chunk in &mut chunks {
+                let [a, b, c, d] = xoroshiro64_star_star(&mut state).to_ne_bytes();
+                chunk[0] = a;
+                chunk[1] = b;
+                chunk[2] = c;
+                chunk[3] = d;
+            }
+
+            let remainder = chunks.into_remainder();
+            if remainder.is_empty() {
+                return;
+            }
+
+            for (rem, val) in
+                remainder.iter_mut().zip(xoroshiro64_star_star(&mut state).to_ne_bytes())
+            {
+                *rem = val;
+            }
+        }
+    }
+
+    static CRYPT_CONTEXT: OnceBox<HCryptProvider> = OnceBox::new();
+
+    struct HCryptProvider(usize);
+    impl Drop for HCryptProvider {
+        fn drop(&mut self) {
+            unsafe {
+                c::CryptReleaseContext(self.0, 0);
+            }
+        }
+    }
+
+    fn init_crypt_context() -> Pin<Box<HCryptProvider>> {
+        let mut crypt_context = 0;
+        unsafe {
+            let ret = c::CryptAcquireContextA(
+                &mut crypt_context,
+                core::ptr::null(),
+                core::ptr::null(),
+                c::PROV_RSA_FULL,
+                c::CRYPT_VERIFYCONTEXT,
+            );
+            assert_ne!(ret, c::FALSE, "failed to acquire crypt context: {:#X}", c::GetLastError());
+        };
+        Box::pin(HCryptProvider(crypt_context))
+    }
+
+    // xoroshiro64**
+    // 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+    // https://prng.di.unimi.it/xoroshiro64starstar.c
+    fn xoroshiro64_star_star(state: &mut [u32; 2]) -> u32 {
+        let result = state[0].wrapping_mul(0x9E3779BB).rotate_left(5).wrapping_mul(5);
+        state[1] ^= state[0];
+        state[0] = state[0].rotate_left(26) ^ state[1] ^ (state[1] << 9);
+        state[1] = state[1].rotate_left(13);
+
+        result
+    }
+}
+
+#[cfg(target_vendor = "rust9x")]
+pub use rust9x::fill_bytes;
diff --git a/library/std/src/sys/sync/condvar/mod.rs b/library/std/src/sys/sync/condvar/mod.rs
index d0c998a559737..fff55940ea4df 100644
--- a/library/std/src/sys/sync/condvar/mod.rs
+++ b/library/std/src/sys/sync/condvar/mod.rs
@@ -1,6 +1,6 @@
 cfg_if::cfg_if! {
     if #[cfg(any(
-        all(target_os = "windows", not(target_vendor="win7")),
+        all(target_os = "windows", not(any(target_vendor="win7", target_vendor = "rust9x"))),
         target_os = "linux",
         target_os = "android",
         target_os = "freebsd",
@@ -21,6 +21,10 @@ cfg_if::cfg_if! {
     } else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] {
         mod windows7;
         pub use windows7::Condvar;
+    } else if #[cfg(all(target_os = "windows", target_vendor = "rust9x"))] {
+        mod windows7;
+        mod rust9x;
+        pub use rust9x::Condvar;
     } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
         mod sgx;
         pub use sgx::Condvar;
diff --git a/library/std/src/sys/sync/condvar/rust9x.rs b/library/std/src/sys/sync/condvar/rust9x.rs
new file mode 100644
index 0000000000000..887c9ac27cd9a
--- /dev/null
+++ b/library/std/src/sys/sync/condvar/rust9x.rs
@@ -0,0 +1,75 @@
+use super::windows7;
+use crate::mem::{ManuallyDrop, MaybeUninit};
+use crate::sys::compat::checks::{MutexKind, mutex_kind};
+use crate::sys::sync::Mutex;
+use crate::time::Duration;
+
+mod legacy;
+
+pub union Condvar {
+    windows7: ManuallyDrop<windows7::Condvar>,
+    legacy: ManuallyDrop<legacy::Condvar>,
+}
+
+impl Drop for Condvar {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            match mutex_kind() {
+                MutexKind::SrwLock => ManuallyDrop::drop(&mut self.windows7),
+                MutexKind::CriticalSection | MutexKind::Legacy => {
+                    ManuallyDrop::drop(&mut self.legacy)
+                }
+            }
+        }
+    }
+}
+
+unsafe impl Send for Condvar {}
+unsafe impl Sync for Condvar {}
+
+impl Condvar {
+    #[inline]
+    pub const fn new() -> Condvar {
+        // SAFETY: all variants are valid when zero-initialized:
+        // - Windows 7 CONDITION_VARIABLE: The initialized value `CONDITION_VARIABLE_INIT` is a zero
+        //   pointer value.
+        // - Legacy: The `OnceBox` is valid when zero-initialized.
+        unsafe { MaybeUninit::zeroed().assume_init() }
+    }
+
+    #[inline]
+    pub unsafe fn wait(&self, mutex: &Mutex) {
+        match mutex_kind() {
+            MutexKind::SrwLock => self.windows7.wait(mutex),
+            MutexKind::CriticalSection | MutexKind::Legacy => self.legacy.wait(mutex),
+        }
+    }
+
+    pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
+        match mutex_kind() {
+            MutexKind::SrwLock => self.windows7.wait_timeout(mutex, dur),
+            MutexKind::CriticalSection | MutexKind::Legacy => self.legacy.wait_timeout(mutex, dur),
+        }
+    }
+
+    #[inline]
+    pub fn notify_one(&self) {
+        unsafe {
+            match mutex_kind() {
+                MutexKind::SrwLock => self.windows7.notify_one(),
+                MutexKind::CriticalSection | MutexKind::Legacy => self.legacy.notify_one(),
+            }
+        }
+    }
+
+    #[inline]
+    pub fn notify_all(&self) {
+        unsafe {
+            match mutex_kind() {
+                MutexKind::SrwLock => self.windows7.notify_all(),
+                MutexKind::CriticalSection | MutexKind::Legacy => self.legacy.notify_all(),
+            }
+        }
+    }
+}
diff --git a/library/std/src/sys/sync/condvar/rust9x/legacy.rs b/library/std/src/sys/sync/condvar/rust9x/legacy.rs
new file mode 100644
index 0000000000000..d941673ab78ce
--- /dev/null
+++ b/library/std/src/sys/sync/condvar/rust9x/legacy.rs
@@ -0,0 +1,130 @@
+use crate::os::windows::io::{AsRawHandle, FromRawHandle, OwnedHandle};
+use crate::pin::Pin;
+use crate::sys::c;
+use crate::sys::compat::checks::{MutexKind, is_windows_nt, mutex_kind};
+use crate::sys::pal::{cvt, dur2timeout};
+use crate::sys::sync::{Mutex, OnceBox};
+use crate::time::Duration;
+use crate::{io, ptr};
+
+/// Very basic condvar implementation for pre-Win7.
+pub struct Condvar {
+    inner: OnceBox<OwnedHandle>,
+}
+
+unsafe impl Send for Condvar {}
+unsafe impl Sync for Condvar {}
+
+impl Condvar {
+    #[inline]
+    #[cfg_attr(
+        target_vendor = "rust9x",
+        allow(dead_code, reason = "initialized via rust9x::Mutex::new")
+    )]
+    pub const fn new() -> Condvar {
+        Condvar { inner: OnceBox::new() }
+    }
+
+    fn init() -> Pin<Box<OwnedHandle>> {
+        unsafe {
+            let event = c::CreateEventA(
+                ptr::null_mut(),
+                c::TRUE, // manual reset event
+                c::FALSE,
+                ptr::null(),
+            );
+
+            if event.is_null() {
+                panic!("failed creating event: {}", io::Error::last_os_error());
+            }
+
+            Box::pin(OwnedHandle::from_raw_handle(event))
+        }
+    }
+
+    #[inline]
+    pub unsafe fn wait(&self, mutex: &Mutex) {
+        let event = self.inner.get_or_init(Self::init);
+        let use_signal_object_and_wait = if mutex_kind() == MutexKind::Legacy && is_windows_nt() {
+            c::SignalObjectAndWait::available()
+        } else {
+            None
+        };
+
+        unsafe {
+            if let Some(signal_object_and_wait) = use_signal_object_and_wait {
+                if signal_object_and_wait(
+                    mutex.legacy.inner.get_unchecked().as_raw_handle(),
+                    event.as_raw_handle(),
+                    c::INFINITE,
+                    c::FALSE,
+                ) != c::WAIT_OBJECT_0
+                {
+                    panic!("event wait failed: {}", io::Error::last_os_error())
+                }
+                mutex.lock();
+            } else {
+                mutex.unlock();
+                if (c::WaitForSingleObject(event.as_raw_handle(), c::INFINITE)) != c::WAIT_OBJECT_0
+                {
+                    panic!("event wait failed: {}", io::Error::last_os_error())
+                }
+                mutex.lock();
+            }
+        }
+    }
+
+    pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
+        let event = self.inner.get_or_init(Self::init);
+        let use_signal_object_and_wait = if mutex_kind() == MutexKind::Legacy && is_windows_nt() {
+            c::SignalObjectAndWait::available()
+        } else {
+            None
+        };
+
+        unsafe {
+            if let Some(signal_object_and_wait) = use_signal_object_and_wait {
+                let ret = match signal_object_and_wait(
+                    mutex.legacy.inner.get_unchecked().as_raw_handle(),
+                    event.as_raw_handle(),
+                    dur2timeout(dur),
+                    c::FALSE,
+                ) {
+                    c::WAIT_OBJECT_0 => true,
+                    c::WAIT_TIMEOUT => false,
+                    _ => panic!("event wait failed: {}", io::Error::last_os_error()),
+                };
+                mutex.lock();
+
+                ret
+            } else {
+                mutex.unlock();
+                let ret = match c::WaitForSingleObject(event.as_raw_handle(), dur2timeout(dur)) {
+                    c::WAIT_OBJECT_0 => true,
+                    c::WAIT_TIMEOUT => false,
+                    _ => panic!("event wait failed: {}", io::Error::last_os_error()),
+                };
+                mutex.lock();
+
+                ret
+            }
+        }
+    }
+
+    #[inline]
+    pub fn notify_one(&self) {
+        // lots of spurious wakeups, but that's valid
+        self.notify_all();
+    }
+
+    #[inline]
+    pub fn notify_all(&self) {
+        let event = self.inner.get_or_init(Self::init);
+
+        unsafe {
+            cvt(c::SetEvent(event.as_raw_handle())).unwrap();
+            crate::thread::yield_now();
+            cvt(c::ResetEvent(event.as_raw_handle())).unwrap();
+        }
+    }
+}
diff --git a/library/std/src/sys/sync/condvar/windows7.rs b/library/std/src/sys/sync/condvar/windows7.rs
index f03feef222124..96014a7c83840 100644
--- a/library/std/src/sys/sync/condvar/windows7.rs
+++ b/library/std/src/sys/sync/condvar/windows7.rs
@@ -12,6 +12,10 @@ unsafe impl Sync for Condvar {}
 
 impl Condvar {
     #[inline]
+    #[cfg_attr(
+        target_vendor = "rust9x",
+        allow(dead_code, reason = "initialized via rust9x::Mutex::new")
+    )]
     pub const fn new() -> Condvar {
         Condvar { inner: UnsafeCell::new(c::CONDITION_VARIABLE_INIT) }
     }
diff --git a/library/std/src/sys/sync/mod.rs b/library/std/src/sys/sync/mod.rs
index 0691e96785198..d4f1cc525cbff 100644
--- a/library/std/src/sys/sync/mod.rs
+++ b/library/std/src/sys/sync/mod.rs
@@ -9,6 +9,6 @@ pub use condvar::Condvar;
 pub use mutex::Mutex;
 pub use once::{Once, OnceState};
 #[allow(unused)] // Only used on some platforms.
-use once_box::OnceBox;
+pub(crate) use once_box::OnceBox;
 pub use rwlock::RwLock;
 pub use thread_parking::Parker;
diff --git a/library/std/src/sys/sync/mutex/mod.rs b/library/std/src/sys/sync/mutex/mod.rs
index 360df3fc4b55d..cbeede3dca4ca 100644
--- a/library/std/src/sys/sync/mutex/mod.rs
+++ b/library/std/src/sys/sync/mutex/mod.rs
@@ -1,6 +1,6 @@
 cfg_if::cfg_if! {
     if #[cfg(any(
-        all(target_os = "windows", not(target_vendor = "win7")),
+        all(target_os = "windows", not(any(target_vendor = "win7", target_vendor = "rust9x"))),
         target_os = "linux",
         target_os = "android",
         target_os = "freebsd",
@@ -23,6 +23,10 @@ cfg_if::cfg_if! {
     } else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] {
         mod windows7;
         pub use windows7::{Mutex, raw};
+    } else if #[cfg(all(target_os = "windows", target_vendor = "rust9x"))] {
+        mod windows7;
+        mod rust9x;
+        pub use rust9x::{Mutex, raw};
     } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
         mod sgx;
         pub use sgx::Mutex;
diff --git a/library/std/src/sys/sync/mutex/rust9x.rs b/library/std/src/sys/sync/mutex/rust9x.rs
new file mode 100644
index 0000000000000..0c336d4605076
--- /dev/null
+++ b/library/std/src/sys/sync/mutex/rust9x.rs
@@ -0,0 +1,79 @@
+use super::windows7;
+use crate::mem::{ManuallyDrop, MaybeUninit};
+use crate::sys::c;
+use crate::sys::compat::checks::{MutexKind, mutex_kind};
+
+mod critical_section;
+mod legacy;
+
+/// Only to be used with MutexKind::SrwLock.
+#[inline]
+pub unsafe fn raw(m: &Mutex) -> *mut c::SRWLOCK {
+    unsafe { windows7::raw(&m.srwlock) }
+}
+
+pub union Mutex {
+    pub(crate) srwlock: ManuallyDrop<windows7::Mutex>,
+    critical_section: ManuallyDrop<critical_section::CriticalSectionMutex>,
+    pub(crate) legacy: ManuallyDrop<legacy::LegacyMutex>,
+}
+
+unsafe impl Send for Mutex {}
+unsafe impl Sync for Mutex {}
+
+impl Drop for Mutex {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            match mutex_kind() {
+                MutexKind::SrwLock => ManuallyDrop::drop(&mut self.srwlock),
+                MutexKind::CriticalSection => ManuallyDrop::drop(&mut self.critical_section),
+                MutexKind::Legacy => ManuallyDrop::drop(&mut self.legacy),
+            }
+        }
+    }
+}
+
+impl Mutex {
+    #[inline]
+    pub const fn new() -> Mutex {
+        // SAFETY: all variants are valid when zero-initialized:
+        // - Windows 7 SRWLOCK: The initialized value `SRWLOCK_INIT` is a zero pointer value.
+        // - Critical section: The `OnceBox` is valid when zero-initialized. `held` is a `bool` that
+        //   should be initialized to `false`.
+        // - Legacy: The `OnceBox` is valid when zero-initialized. `held` is a `bool` that should be
+        //   initialized to `false`.
+        unsafe { MaybeUninit::zeroed().assume_init() }
+    }
+
+    #[inline]
+    pub fn lock(&self) {
+        unsafe {
+            match mutex_kind() {
+                MutexKind::SrwLock => self.srwlock.lock(),
+                MutexKind::CriticalSection => self.critical_section.lock(),
+                MutexKind::Legacy => self.legacy.lock(),
+            }
+        }
+    }
+
+    #[inline]
+    pub fn try_lock(&self) -> bool {
+        unsafe {
+            match mutex_kind() {
+                MutexKind::SrwLock => self.srwlock.try_lock(),
+                MutexKind::CriticalSection => self.critical_section.try_lock(),
+                MutexKind::Legacy => self.legacy.try_lock(),
+            }
+        }
+    }
+
+    #[inline]
+    pub unsafe fn unlock(&self) {
+        match mutex_kind() {
+            MutexKind::SrwLock => self.srwlock.unlock(),
+            MutexKind::CriticalSection => self.critical_section.unlock(),
+            MutexKind::Legacy => self.legacy.unlock(),
+        }
+    }
+}
diff --git a/library/std/src/sys/sync/mutex/rust9x/critical_section.rs b/library/std/src/sys/sync/mutex/rust9x/critical_section.rs
new file mode 100644
index 0000000000000..b630b89459402
--- /dev/null
+++ b/library/std/src/sys/sync/mutex/rust9x/critical_section.rs
@@ -0,0 +1,103 @@
+use crate::cell::UnsafeCell;
+use crate::mem::MaybeUninit;
+use crate::pin::Pin;
+use crate::sys::c;
+use crate::sys::sync::OnceBox;
+
+/// Mutex based on critical sections.
+///
+/// Critical sections are available on all windows versions, but `TryEnterCriticalSection` was only
+/// added with NT4, and never to the 9x range.
+///
+/// Critical sections cannot be moved while initialized, so they have to be boxed. For this reason
+/// we use `OnceBox`, which also allows for a `const` constructor.
+pub struct CriticalSectionMutex {
+    inner: OnceBox<UnsafeCell<c::CRITICAL_SECTION>>,
+    // used to prevent reentrancy:
+    //
+    // > The exact behavior on locking a mutex in the thread which already holds the lock is left
+    // > unspecified. However, this function will not return on the second call (it might panic or
+    // > deadlock, for example).
+    held: UnsafeCell<bool>,
+}
+
+unsafe impl Send for CriticalSectionMutex {}
+unsafe impl Sync for CriticalSectionMutex {}
+
+impl CriticalSectionMutex {
+    #[inline]
+    #[allow(dead_code, reason = "initialized via rust9x::Mutex::new")]
+    pub const fn new() -> Self {
+        Self { inner: OnceBox::new(), held: UnsafeCell::new(false) }
+    }
+
+    fn init() -> Pin<Box<UnsafeCell<c::CRITICAL_SECTION>>> {
+        unsafe {
+            let boxed = Box::pin(UnsafeCell::new(MaybeUninit::zeroed().assume_init()));
+            c::InitializeCriticalSection(UnsafeCell::get(&boxed));
+            boxed
+        }
+    }
+
+    #[inline]
+    pub unsafe fn lock(&self) {
+        let cell = self.inner.get_or_init(Self::init);
+        c::EnterCriticalSection(UnsafeCell::get(&cell));
+
+        if !self.flag_locked() {
+            self.unlock();
+            panic!("cannot recursively lock a mutex");
+        }
+    }
+
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        let cell = self.inner.get_or_init(Self::init);
+        let successful = c::TryEnterCriticalSection(UnsafeCell::get(&cell)) != 0;
+
+        if !successful {
+            false
+        } else if self.flag_locked() {
+            true
+        } else {
+            self.unlock();
+            false
+        }
+    }
+
+    #[inline]
+    pub unsafe fn unlock(&self) {
+        *self.held.get() = false;
+
+        // SAFETY: The outer mutex code prevents calls to unlock before lock, so the mutex is
+        // guaranteed to be initialized.
+        let cell = self.inner.get_unchecked();
+        c::LeaveCriticalSection(UnsafeCell::get(&cell));
+    }
+
+    unsafe fn flag_locked(&self) -> bool {
+        if *self.held.get() {
+            false
+        } else {
+            *self.held.get() = true;
+            true
+        }
+    }
+}
+
+impl Drop for CriticalSectionMutex {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            if self.try_lock() {
+                self.unlock();
+                let cell = self.inner.get_unchecked();
+                c::DeleteCriticalSection(UnsafeCell::get(&cell));
+            } else {
+                // The mutex is locked. This happens if a MutexGuard is leaked.
+                // In this case, we have to leak the Mutex too.
+                core::mem::forget(self.inner.take());
+            }
+        }
+    }
+}
diff --git a/library/std/src/sys/sync/mutex/rust9x/legacy.rs b/library/std/src/sys/sync/mutex/rust9x/legacy.rs
new file mode 100644
index 0000000000000..137de0179b4ef
--- /dev/null
+++ b/library/std/src/sys/sync/mutex/rust9x/legacy.rs
@@ -0,0 +1,108 @@
+use crate::cell::UnsafeCell;
+use crate::os::windows::io::{AsRawHandle, FromRawHandle, OwnedHandle};
+use crate::pin::Pin;
+use crate::sys::sync::OnceBox;
+use crate::sys::{c, cvt};
+use crate::{io, ptr};
+
+/// Mutex based on `CreateMutex`. Slow, but available everywhere.
+///
+/// Doesn't need to stay fixed in place, but we need to lazily initialize it to have a const
+/// constructor, so we use a `OnceBox` for that.
+pub struct LegacyMutex {
+    pub(crate) inner: OnceBox<OwnedHandle>,
+    // used to prevent reentrancy:
+    //
+    // > The exact behavior on locking a mutex in the thread which already holds the lock is left
+    // > unspecified. However, this function will not return on the second call (it might panic or
+    // > deadlock, for example).
+    held: UnsafeCell<bool>,
+}
+
+unsafe impl Send for LegacyMutex {}
+unsafe impl Sync for LegacyMutex {}
+
+impl LegacyMutex {
+    #[inline]
+    #[allow(dead_code, reason = "initialized via rust9x::Mutex::new")]
+    pub const fn new() -> Self {
+        Self { inner: OnceBox::new(), held: UnsafeCell::new(false) }
+    }
+
+    fn init() -> Pin<Box<OwnedHandle>> {
+        unsafe {
+            let handle = c::CreateMutexA(ptr::null_mut(), c::FALSE, ptr::null());
+            if handle.is_null() {
+                panic!("failed creating mutex: {}", io::Error::last_os_error());
+            }
+
+            Box::pin(OwnedHandle::from_raw_handle(handle))
+        }
+    }
+
+    #[inline]
+    pub unsafe fn lock(&self) {
+        let handle = self.inner.get_or_init(Self::init);
+        if c::WaitForSingleObject(handle.as_raw_handle(), c::INFINITE) != c::WAIT_OBJECT_0 {
+            panic!("mutex lock failed: {}", io::Error::last_os_error())
+        }
+
+        if !self.flag_locked() {
+            self.unlock();
+            panic!("cannot recursively lock a mutex");
+        }
+    }
+
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        let handle = self.inner.get_or_init(Self::init);
+        let successful = match c::WaitForSingleObject(handle.as_raw_handle(), 0) {
+            c::WAIT_OBJECT_0 => true,
+            c::WAIT_TIMEOUT => false,
+            _ => panic!("try lock error: {}", io::Error::last_os_error()),
+        };
+
+        if !successful {
+            false
+        } else if self.flag_locked() {
+            true
+        } else {
+            self.unlock();
+            false
+        }
+    }
+
+    #[inline]
+    pub unsafe fn unlock(&self) {
+        *self.held.get() = false;
+
+        // SAFETY: The outer mutex code prevents calls to unlock before lock, so the mutex is
+        // guaranteed to be initialized.
+        let handle = self.inner.get_unchecked();
+        cvt(c::ReleaseMutex(handle.as_raw_handle())).unwrap();
+    }
+
+    unsafe fn flag_locked(&self) -> bool {
+        if *self.held.get() {
+            false
+        } else {
+            *self.held.get() = true;
+            true
+        }
+    }
+}
+
+impl Drop for LegacyMutex {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            if self.try_lock() {
+                self.unlock();
+            } else {
+                // The mutex is locked. This happens if a MutexGuard is leaked.
+                // In this case, we have to leak the Mutex too.
+                core::mem::forget(self.inner.take());
+            }
+        }
+    }
+}
diff --git a/library/std/src/sys/sync/mutex/windows7.rs b/library/std/src/sys/sync/mutex/windows7.rs
index 689dba10f01ed..2a74fcb590cf5 100644
--- a/library/std/src/sys/sync/mutex/windows7.rs
+++ b/library/std/src/sys/sync/mutex/windows7.rs
@@ -31,6 +31,10 @@ pub unsafe fn raw(m: &Mutex) -> *mut c::SRWLOCK {
 
 impl Mutex {
     #[inline]
+    #[cfg_attr(
+        target_vendor = "rust9x",
+        allow(dead_code, reason = "initialized via rust9x::Mutex::new")
+    )]
     pub const fn new() -> Mutex {
         Mutex { srwlock: UnsafeCell::new(c::SRWLOCK_INIT) }
     }
diff --git a/library/std/src/sys/sync/once/mod.rs b/library/std/src/sys/sync/once/mod.rs
index 0e38937b1219a..047599db8ad66 100644
--- a/library/std/src/sys/sync/once/mod.rs
+++ b/library/std/src/sys/sync/once/mod.rs
@@ -9,7 +9,7 @@
 
 cfg_if::cfg_if! {
     if #[cfg(any(
-        all(target_os = "windows", not(target_vendor="win7")),
+        all(target_os = "windows", not(any(target_vendor = "win7", target_vendor = "rust9x"))),
         target_os = "linux",
         target_os = "android",
         all(target_arch = "wasm32", target_feature = "atomics"),
diff --git a/library/std/src/sys/sync/rwlock/mod.rs b/library/std/src/sys/sync/rwlock/mod.rs
index 70ba6bf38ef55..953aad197547c 100644
--- a/library/std/src/sys/sync/rwlock/mod.rs
+++ b/library/std/src/sys/sync/rwlock/mod.rs
@@ -1,6 +1,6 @@
 cfg_if::cfg_if! {
     if #[cfg(any(
-        all(target_os = "windows", not(target_vendor = "win7")),
+        all(target_os = "windows", not(any(target_vendor = "win7", target_vendor = "rust9x"))),
         target_os = "linux",
         target_os = "android",
         target_os = "freebsd",
@@ -14,7 +14,7 @@ cfg_if::cfg_if! {
         pub use futex::RwLock;
     } else if #[cfg(any(
         target_family = "unix",
-        all(target_os = "windows", target_vendor = "win7"),
+        all(target_os = "windows", any(target_vendor = "win7", target_vendor = "rust9x")),
         all(target_vendor = "fortanix", target_env = "sgx"),
         target_os = "xous",
     ))] {
diff --git a/library/std/src/sys/sync/thread_parking/generic.rs b/library/std/src/sys/sync/thread_parking/generic.rs
new file mode 100644
index 0000000000000..3209bffe353ed
--- /dev/null
+++ b/library/std/src/sys/sync/thread_parking/generic.rs
@@ -0,0 +1,125 @@
+//! Parker implementation based on a Mutex and Condvar.
+
+use crate::pin::Pin;
+use crate::sync::atomic::AtomicUsize;
+use crate::sync::atomic::Ordering::SeqCst;
+use crate::sync::{Condvar, Mutex};
+use crate::time::Duration;
+
+const EMPTY: usize = 0;
+const PARKED: usize = 1;
+const NOTIFIED: usize = 2;
+
+pub struct Parker {
+    state: AtomicUsize,
+    lock: Mutex<()>,
+    cvar: Condvar,
+}
+
+impl Parker {
+    /// Construct the generic parker. The UNIX parker implementation
+    /// requires this to happen in-place.
+    pub unsafe fn new_in_place(parker: *mut Parker) {
+        parker.write(Parker {
+            state: AtomicUsize::new(EMPTY),
+            lock: Mutex::new(()),
+            cvar: Condvar::new(),
+        });
+    }
+
+    // This implementation doesn't require `unsafe` and `Pin`, but other implementations do.
+    pub unsafe fn park(self: Pin<&Self>) {
+        // If we were previously notified then we consume this notification and
+        // return quickly.
+        if self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() {
+            return;
+        }
+
+        // Otherwise we need to coordinate going to sleep
+        let mut m = self.lock.lock().unwrap();
+        match self.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
+            Ok(_) => {}
+            Err(NOTIFIED) => {
+                // We must read here, even though we know it will be `NOTIFIED`.
+                // This is because `unpark` may have been called again since we read
+                // `NOTIFIED` in the `compare_exchange` above. We must perform an
+                // acquire operation that synchronizes with that `unpark` to observe
+                // any writes it made before the call to unpark. To do that we must
+                // read from the write it made to `state`.
+                let old = self.state.swap(EMPTY, SeqCst);
+                assert_eq!(old, NOTIFIED, "park state changed unexpectedly");
+                return;
+            } // should consume this notification, so prohibit spurious wakeups in next park.
+            Err(_) => panic!("inconsistent park state"),
+        }
+        loop {
+            m = self.cvar.wait(m).unwrap();
+            match self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst) {
+                Ok(_) => return, // got a notification
+                Err(_) => {}     // spurious wakeup, go back to sleep
+            }
+        }
+    }
+
+    // This implementation doesn't require `unsafe` and `Pin`, but other implementations do.
+    pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) {
+        // Like `park` above we have a fast path for an already-notified thread, and
+        // afterwards we start coordinating for a sleep.
+        // return quickly.
+        if self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() {
+            return;
+        }
+        let m = self.lock.lock().unwrap();
+        match self.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) {
+            Ok(_) => {}
+            Err(NOTIFIED) => {
+                // We must read again here, see `park`.
+                let old = self.state.swap(EMPTY, SeqCst);
+                assert_eq!(old, NOTIFIED, "park state changed unexpectedly");
+                return;
+            } // should consume this notification, so prohibit spurious wakeups in next park.
+            Err(_) => panic!("inconsistent park_timeout state"),
+        }
+
+        // Wait with a timeout, and if we spuriously wake up or otherwise wake up
+        // from a notification we just want to unconditionally set the state back to
+        // empty, either consuming a notification or un-flagging ourselves as
+        // parked.
+        let (_m, _result) = self.cvar.wait_timeout(m, dur).unwrap();
+        match self.state.swap(EMPTY, SeqCst) {
+            NOTIFIED => {} // got a notification, hurray!
+            PARKED => {}   // no notification, alas
+            n => panic!("inconsistent park_timeout state: {n}"),
+        }
+    }
+
+    // This implementation doesn't require `Pin`, but other implementations do.
+    pub fn unpark(self: Pin<&Self>) {
+        // To ensure the unparked thread will observe any writes we made
+        // before this call, we must perform a release operation that `park`
+        // can synchronize with. To do that we must write `NOTIFIED` even if
+        // `state` is already `NOTIFIED`. That is why this must be a swap
+        // rather than a compare-and-swap that returns if it reads `NOTIFIED`
+        // on failure.
+        match self.state.swap(NOTIFIED, SeqCst) {
+            EMPTY => return,    // no one was waiting
+            NOTIFIED => return, // already unparked
+            PARKED => {}        // gotta go wake someone up
+            _ => panic!("inconsistent state in unpark"),
+        }
+
+        // There is a period between when the parked thread sets `state` to
+        // `PARKED` (or last checked `state` in the case of a spurious wake
+        // up) and when it actually waits on `cvar`. If we were to notify
+        // during this period it would be ignored and then when the parked
+        // thread went to sleep it would never wake up. Fortunately, it has
+        // `lock` locked at this stage so we can acquire `lock` to wait until
+        // it is ready to receive the notification.
+        //
+        // Releasing `lock` before the call to `notify_one` means that when the
+        // parked thread wakes it doesn't get woken only to have to wait for us
+        // to release `lock`.
+        drop(self.lock.lock().unwrap());
+        self.cvar.notify_one()
+    }
+}
diff --git a/library/std/src/sys/sync/thread_parking/mod.rs b/library/std/src/sys/sync/thread_parking/mod.rs
index f4d8fa0a58c11..7b6b422b6ca33 100644
--- a/library/std/src/sys/sync/thread_parking/mod.rs
+++ b/library/std/src/sys/sync/thread_parking/mod.rs
@@ -1,6 +1,6 @@
 cfg_if::cfg_if! {
     if #[cfg(any(
-        all(target_os = "windows", not(target_vendor = "win7")),
+        all(target_os = "windows", not(any(target_vendor = "win7", target_vendor = "rust9x"))),
         target_os = "linux",
         target_os = "android",
         all(target_arch = "wasm32", target_feature = "atomics"),
@@ -22,6 +22,12 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_vendor = "win7")] {
         mod windows7;
         pub use windows7::Parker;
+    } else if #[cfg(target_vendor = "rust9x")] {
+        mod futex;
+        mod windowsxp;
+        mod generic;
+        mod rust9x;
+        pub use rust9x::Parker;
     } else if #[cfg(all(target_vendor = "apple", not(miri)))] {
         // Doesn't work in Miri, see <https://github.com/rust-lang/miri/issues/2589>.
         mod darwin;
diff --git a/library/std/src/sys/sync/thread_parking/rust9x.rs b/library/std/src/sys/sync/thread_parking/rust9x.rs
new file mode 100644
index 0000000000000..68b66f664cb8d
--- /dev/null
+++ b/library/std/src/sys/sync/thread_parking/rust9x.rs
@@ -0,0 +1,83 @@
+use crate::mem::ManuallyDrop;
+use crate::pin::Pin;
+use crate::sys::compat::thread_parking::{ThreadParkingImpl, thread_parking_impl};
+use crate::time::Duration;
+
+pub union Parker {
+    futex: ManuallyDrop<super::futex::Parker>,
+    keyed_event: ManuallyDrop<super::windowsxp::Parker>,
+    generic: ManuallyDrop<super::generic::Parker>,
+}
+
+impl Parker {
+    pub unsafe fn new_in_place(parker: *mut Parker) {
+        let impl_ = thread_parking_impl();
+
+        match impl_ {
+            ThreadParkingImpl::Futex => unsafe {
+                super::futex::Parker::new_in_place(&raw mut (*(*parker).futex))
+            },
+            ThreadParkingImpl::KeyedEvent => unsafe {
+                super::windowsxp::Parker::new_in_place(&raw mut (*(*parker).keyed_event))
+            },
+            ThreadParkingImpl::Generic => unsafe {
+                super::generic::Parker::new_in_place(&raw mut (*(*parker).generic))
+            },
+        }
+    }
+
+    pub unsafe fn park(self: Pin<&Self>) {
+        let impl_ = thread_parking_impl();
+
+        match impl_ {
+            ThreadParkingImpl::Futex => unsafe { self.map_unchecked(|p| &*p.futex).park() },
+            ThreadParkingImpl::KeyedEvent => unsafe {
+                self.map_unchecked(|p| &*p.keyed_event).park()
+            },
+            ThreadParkingImpl::Generic => unsafe { self.map_unchecked(|p| &*p.generic).park() },
+        }
+    }
+
+    pub unsafe fn park_timeout(self: Pin<&Self>, timeout: Duration) {
+        let impl_ = thread_parking_impl();
+
+        match impl_ {
+            ThreadParkingImpl::Futex => unsafe {
+                self.map_unchecked(|p| &*p.futex).park_timeout(timeout)
+            },
+            ThreadParkingImpl::KeyedEvent => unsafe {
+                self.map_unchecked(|p| &*p.keyed_event).park_timeout(timeout)
+            },
+            ThreadParkingImpl::Generic => unsafe {
+                self.map_unchecked(|p| &*p.generic).park_timeout(timeout)
+            },
+        }
+    }
+
+    pub fn unpark(self: Pin<&Self>) {
+        let impl_ = thread_parking_impl();
+
+        match impl_ {
+            ThreadParkingImpl::Futex => unsafe {
+                self.map_unchecked(|p| &*p.futex).unpark();
+            },
+            ThreadParkingImpl::KeyedEvent => unsafe {
+                self.map_unchecked(|p| &*p.keyed_event).unpark()
+            },
+            ThreadParkingImpl::Generic => unsafe { self.map_unchecked(|p| &*p.generic).unpark() },
+        }
+    }
+}
+
+impl Drop for Parker {
+    fn drop(&mut self) {
+        let impl_ = thread_parking_impl();
+
+        match impl_ {
+            ThreadParkingImpl::Futex | ThreadParkingImpl::KeyedEvent => {
+                // these don't require any cleanup
+            }
+            ThreadParkingImpl::Generic => unsafe { ManuallyDrop::drop(&mut self.generic) },
+        }
+    }
+}
diff --git a/library/std/src/sys/sync/thread_parking/windowsxp.rs b/library/std/src/sys/sync/thread_parking/windowsxp.rs
new file mode 100644
index 0000000000000..267e89d765945
--- /dev/null
+++ b/library/std/src/sys/sync/thread_parking/windowsxp.rs
@@ -0,0 +1,133 @@
+// Just the Windows XP+ implementation yoinked from the Windows 7 implementation, without the
+// Win8+/futex implementation around it, see super::windows7 for more info.
+
+use core::pin::Pin;
+use core::ptr;
+use core::sync::atomic::Ordering::{Acquire, Relaxed, Release};
+use core::sync::atomic::{AtomicI8, AtomicPtr};
+use core::time::Duration;
+
+use crate::ffi::c_void;
+use crate::sys::c;
+
+pub struct Parker {
+    state: AtomicI8,
+}
+
+const PARKED: i8 = -1;
+const EMPTY: i8 = 0;
+const NOTIFIED: i8 = 1;
+
+impl Parker {
+    pub unsafe fn new_in_place(parker: *mut Parker) {
+        parker.write(Self { state: AtomicI8::new(EMPTY) });
+    }
+
+    pub unsafe fn park(self: Pin<&Self>) {
+        // Change NOTIFIED=>EMPTY or EMPTY=>PARKED, and directly return in the
+        // first case.
+        if self.state.fetch_sub(1, Acquire) == NOTIFIED {
+            return;
+        }
+
+        // Wait for unpark() to produce this event.
+        c::NtWaitForKeyedEvent(keyed_event_handle(), self.ptr(), 0, ptr::null_mut());
+        // Set the state back to EMPTY (from either PARKED or NOTIFIED).
+        // Note that we don't just write EMPTY, but use swap() to also
+        // include an acquire-ordered read to synchronize with unpark()'s
+        // release-ordered write.
+        self.state.swap(EMPTY, Acquire);
+        return;
+    }
+
+    pub unsafe fn park_timeout(self: Pin<&Self>, timeout: Duration) {
+        // Change NOTIFIED=>EMPTY or EMPTY=>PARKED, and directly return in the
+        // first case.
+        if self.state.fetch_sub(1, Acquire) == NOTIFIED {
+            return;
+        }
+
+        // Need to wait for unpark() using NtWaitForKeyedEvent.
+        let handle = keyed_event_handle();
+
+        // NtWaitForKeyedEvent uses a unit of 100ns, and uses negative
+        // values to indicate a relative time on the monotonic clock.
+        // This is documented here for the underlying KeWaitForSingleObject function:
+        // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-kewaitforsingleobject
+        let mut timeout = match i64::try_from((timeout.as_nanos() + 99) / 100) {
+            Ok(t) => -t,
+            Err(_) => i64::MIN,
+        };
+
+        // Wait for unpark() to produce this event.
+        let unparked =
+            c::NtWaitForKeyedEvent(handle, self.ptr(), 0, &mut timeout) == c::STATUS_SUCCESS;
+
+        // Set the state back to EMPTY (from either PARKED or NOTIFIED).
+        let prev_state = self.state.swap(EMPTY, Acquire);
+
+        if !unparked && prev_state == NOTIFIED {
+            // We were awoken by a timeout, not by unpark(), but the state
+            // was set to NOTIFIED, which means we *just* missed an
+            // unpark(), which is now blocked on us to wait for it.
+            // Wait for it to consume the event and unblock that thread.
+            c::NtWaitForKeyedEvent(handle, self.ptr(), 0, ptr::null_mut());
+        }
+    }
+
+    pub unsafe fn unpark(self: Pin<&Self>) {
+        // Change PARKED=>NOTIFIED, EMPTY=>NOTIFIED, or NOTIFIED=>NOTIFIED, and
+        // wake the thread in the first case.
+        //
+        // Note that even NOTIFIED=>NOTIFIED results in a write. This is on
+        // purpose, to make sure every unpark() has a release-acquire ordering
+        // with park().
+        if self.state.swap(NOTIFIED, Release) == PARKED {
+            // If we run NtReleaseKeyedEvent before the waiting thread runs
+            // NtWaitForKeyedEvent, this (shortly) blocks until we can wake it up.
+            // If the waiting thread wakes up before we run NtReleaseKeyedEvent
+            // (e.g. due to a timeout), this blocks until we do wake up a thread.
+            // To prevent this thread from blocking indefinitely in that case,
+            // park_impl() will, after seeing the state set to NOTIFIED after
+            // waking up, call NtWaitForKeyedEvent again to unblock us.
+            c::NtReleaseKeyedEvent(keyed_event_handle(), self.ptr(), 0, ptr::null_mut());
+        }
+    }
+
+    fn ptr(&self) -> *const c_void {
+        (&raw const self.state).cast::<c_void>()
+    }
+}
+
+fn keyed_event_handle() -> c::HANDLE {
+    const INVALID: c::HANDLE = ptr::without_provenance_mut(!0);
+    static HANDLE: AtomicPtr<crate::ffi::c_void> = AtomicPtr::new(INVALID);
+    match HANDLE.load(Relaxed) {
+        INVALID => {
+            let mut handle = c::INVALID_HANDLE_VALUE;
+            unsafe {
+                match c::NtCreateKeyedEvent(
+                    &mut handle,
+                    c::GENERIC_READ | c::GENERIC_WRITE,
+                    ptr::null_mut(),
+                    0,
+                ) {
+                    c::STATUS_SUCCESS => {}
+                    r => panic!("Unable to create keyed event handle: error {r}"),
+                }
+            }
+            match HANDLE.compare_exchange(INVALID, handle, Relaxed, Relaxed) {
+                Ok(_) => handle,
+                Err(h) => {
+                    // Lost the race to another thread initializing HANDLE before we did.
+                    // Closing our handle and using theirs instead.
+                    unsafe {
+                        c::CloseHandle(handle);
+                    }
+                    h
+                }
+            }
+        }
+        handle => handle,
+    }
+}
diff --git a/library/windows_targets/Cargo.toml b/library/windows_targets/Cargo.toml
index 94d7c8210647c..e560df52311d6 100644
--- a/library/windows_targets/Cargo.toml
+++ b/library/windows_targets/Cargo.toml
@@ -8,3 +8,8 @@ edition = "2021"
 # Enable using raw-dylib for Windows imports.
 # This will eventually be the default.
 windows_raw_dylib = []
+
+[lints.rust]
+unexpected_cfgs = { level = "warn", check-cfg = [
+    'cfg(target_vendor, values("rust9x"))',
+] }
diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs
index 395cd6a4bab55..a0ef530adff9c 100644
--- a/library/windows_targets/src/lib.rs
+++ b/library/windows_targets/src/lib.rs
@@ -34,9 +34,9 @@ pub macro link {
 }
 
 #[cfg(not(feature = "windows_raw_dylib"))]
-#[link(name = "advapi32")]
-#[link(name = "ntdll")]
-#[link(name = "userenv")]
+#[cfg_attr(not(target_vendor = "rust9x"), link(name = "advapi32"))]
+#[cfg_attr(not(target_vendor = "rust9x"), link(name = "ntdll"))]
+#[cfg_attr(not(target_vendor = "rust9x"), link(name = "userenv"))]
 #[link(name = "ws2_32")]
 #[link(name = "dbghelp")] // required for backtrace-rs symbolization
 extern "C" {}
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index c9697e670b777..b10ea346d6f9f 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -84,9 +84,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.2.0"
+version = "1.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8"
+checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
 dependencies = [
  "shlex",
 ]
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index d8775a67e1939..68e0591c6b7b7 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -36,7 +36,9 @@ test = false
 # Most of the time updating these dependencies requires modifications to the
 # bootstrap codebase(e.g., https://github.com/rust-lang/rust/issues/124565);
 # otherwise, some targets will fail. That's why these dependencies are explicitly pinned.
-cc = "=1.2.0"
+#
+# Do not upgrade this crate unless https://github.com/rust-lang/cc-rs/issues/1317 is fixed.
+cc = "=1.1.22"
 cmake = "=0.1.48"
 
 build_helper = { path = "../build_helper" }
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 89415afbe3bc4..535bdecb092dd 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1264,6 +1264,11 @@ def bootstrap(args):
         config_toml = ""
 
     profile = RustBuild.get_toml_static(config_toml, "profile")
+    is_non_git_source = not os.path.exists(os.path.join(rust_root, ".git"))
+
+    if profile is None and is_non_git_source:
+        profile = "dist"
+
     if profile is not None:
         # Allows creating alias for profile names, allowing
         # profiles to be renamed while maintaining back compatibility
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index ca337aa9f4c32..eeb5b18fdbc4b 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1790,7 +1790,13 @@ impl Step for Assemble {
                     // When using `download-ci-llvm`, some of the tools
                     // may not exist, so skip trying to copy them.
                     if src_path.exists() {
-                        builder.copy_link(&src_path, &libdir_bin.join(&tool_exe));
+                        // There is a chance that these tools are being installed from an external LLVM.
+                        // Use `Builder::resolve_symlink_and_copy` instead of `Builder::copy_link` to ensure
+                        // we are copying the original file not the symlinked path, which causes issues for
+                        // tarball distribution.
+                        //
+                        // See https://github.com/rust-lang/rust/issues/135554.
+                        builder.resolve_symlink_and_copy(&src_path, &libdir_bin.join(&tool_exe));
                     }
                 }
             }
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 8bfa9cc94b341..34e6a1e1d35fb 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -995,7 +995,18 @@ impl Step for PlainSourceTarball {
         ];
         let src_dirs = ["src", "compiler", "library", "tests"];
 
-        copy_src_dirs(builder, &builder.src, &src_dirs, &[], plain_dst_src);
+        copy_src_dirs(
+            builder,
+            &builder.src,
+            &src_dirs,
+            &[
+                // We don't currently use the GCC source code for building any official components,
+                // it is very big, and has unclear licensing implications due to being GPL licensed.
+                // We thus exclude it from the source tarball from now.
+                "src/gcc",
+            ],
+            plain_dst_src,
+        );
 
         // Copy the files normally
         for item in &src_files {
@@ -1592,15 +1603,9 @@ impl Step for Extended {
             prepare("cargo");
             prepare("rust-std");
             prepare("rust-analysis");
-
-            for tool in &[
-                "clippy",
-                "rustfmt",
-                "rust-analyzer",
-                "rust-docs",
-                "miri",
-                "rustc-codegen-cranelift",
-            ] {
+            prepare("clippy");
+            prepare("rust-analyzer");
+            for tool in &["rust-docs", "miri", "rustc-codegen-cranelift"] {
                 if built_tools.contains(tool) {
                     prepare(tool);
                 }
@@ -1640,8 +1645,6 @@ impl Step for Extended {
                     "rust-analyzer-preview".to_string()
                 } else if name == "clippy" {
                     "clippy-preview".to_string()
-                } else if name == "rustfmt" {
-                    "rustfmt-preview".to_string()
                 } else if name == "miri" {
                     "miri-preview".to_string()
                 } else if name == "rustc-codegen-cranelift" {
@@ -1661,7 +1664,7 @@ impl Step for Extended {
             prepare("cargo");
             prepare("rust-analysis");
             prepare("rust-std");
-            for tool in &["clippy", "rustfmt", "rust-analyzer", "rust-docs", "miri"] {
+            for tool in &["clippy", "rust-analyzer", "rust-docs", "miri"] {
                 if built_tools.contains(tool) {
                     prepare(tool);
                 }
@@ -1779,24 +1782,6 @@ impl Step for Extended {
                     .arg(etc.join("msi/remove-duplicates.xsl"))
                     .run(builder);
             }
-            if built_tools.contains("rustfmt") {
-                command(&heat)
-                    .current_dir(&exe)
-                    .arg("dir")
-                    .arg("rustfmt")
-                    .args(heat_flags)
-                    .arg("-cg")
-                    .arg("RustFmtGroup")
-                    .arg("-dr")
-                    .arg("RustFmt")
-                    .arg("-var")
-                    .arg("var.RustFmtDir")
-                    .arg("-out")
-                    .arg(exe.join("RustFmtGroup.wxs"))
-                    .arg("-t")
-                    .arg(etc.join("msi/remove-duplicates.xsl"))
-                    .run(builder);
-            }
             if built_tools.contains("miri") {
                 command(&heat)
                     .current_dir(&exe)
@@ -1868,9 +1853,6 @@ impl Step for Extended {
                 if built_tools.contains("clippy") {
                     cmd.arg("-dClippyDir=clippy");
                 }
-                if built_tools.contains("rustfmt") {
-                    cmd.arg("-dRustFmtDir=rustfmt");
-                }
                 if built_tools.contains("rust-docs") {
                     cmd.arg("-dDocsDir=rust-docs");
                 }
@@ -1897,9 +1879,6 @@ impl Step for Extended {
             if built_tools.contains("clippy") {
                 candle("ClippyGroup.wxs".as_ref());
             }
-            if built_tools.contains("rustfmt") {
-                candle("RustFmtGroup.wxs".as_ref());
-            }
             if built_tools.contains("miri") {
                 candle("MiriGroup.wxs".as_ref());
             }
@@ -1938,9 +1917,6 @@ impl Step for Extended {
             if built_tools.contains("clippy") {
                 cmd.arg("ClippyGroup.wixobj");
             }
-            if built_tools.contains("rustfmt") {
-                cmd.arg("RustFmtGroup.wixobj");
-            }
             if built_tools.contains("miri") {
                 cmd.arg("MiriGroup.wixobj");
             }
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index d0058eeb43d3c..9ae03ac7fe075 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -334,7 +334,11 @@ macro_rules! bootstrap_tool {
 }
 
 bootstrap_tool!(
-    Rustbook, "src/tools/rustbook", "rustbook", submodules = SUBMODULES_FOR_RUSTBOOK;
+    // This is marked as an external tool because it includes dependencies
+    // from submodules. Trying to keep the lints in sync between all the repos
+    // is a bit of a pain. Unfortunately it means the rustbook source itself
+    // doesn't deny warnings, but it is a relatively small piece of code.
+    Rustbook, "src/tools/rustbook", "rustbook", is_external_tool = true, submodules = SUBMODULES_FOR_RUSTBOOK;
     UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen";
     Tidy, "src/tools/tidy", "tidy";
     Linkchecker, "src/tools/linkchecker", "linkchecker";
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index dd2f11ad4690a..053330d7417c6 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -2668,7 +2668,7 @@ impl Config {
     /// used instead to provide a nice error to the user if the submodule is
     /// missing.
     pub(crate) fn update_submodule(&self, relative_path: &str) {
-        if !self.submodules() {
+        if self.rust_info.is_from_tarball() || !self.submodules() {
             return;
         }
 
@@ -2863,21 +2863,26 @@ impl Config {
             allowed_paths.push(":!library");
         }
 
-        // Look for a version to compare to based on the current commit.
-        // Only commits merged by bors will have CI artifacts.
-        let commit = match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged)
-        {
-            Some(commit) => commit,
-            None => {
-                if if_unchanged {
-                    return None;
+        let commit = if self.rust_info.is_managed_git_subrepository() {
+            // Look for a version to compare to based on the current commit.
+            // Only commits merged by bors will have CI artifacts.
+            match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged) {
+                Some(commit) => commit,
+                None => {
+                    if if_unchanged {
+                        return None;
+                    }
+                    println!("ERROR: could not find commit hash for downloading rustc");
+                    println!("HELP: maybe your repository history is too shallow?");
+                    println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
+                    println!("HELP: or fetch enough history to include one upstream commit");
+                    crate::exit!(1);
                 }
-                println!("ERROR: could not find commit hash for downloading rustc");
-                println!("HELP: maybe your repository history is too shallow?");
-                println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
-                println!("HELP: or fetch enough history to include one upstream commit");
-                crate::exit!(1);
             }
+        } else {
+            channel::read_commit_info_file(&self.src)
+                .map(|info| info.sha.trim().to_owned())
+                .expect("git-commit-info is missing in the project root")
         };
 
         if CiEnv::is_ci() && {
@@ -2914,10 +2919,8 @@ impl Config {
         let if_unchanged = || {
             if self.rust_info.is_from_tarball() {
                 // Git is needed for running "if-unchanged" logic.
-                println!(
-                    "WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
-                );
-                return false;
+                println!("ERROR: 'if-unchanged' is only compatible with Git managed sources.");
+                crate::exit!(1);
             }
 
             // Fetching the LLVM submodule is unnecessary for self-tests.
@@ -2959,6 +2962,11 @@ impl Config {
         option_name: &str,
         if_unchanged: bool,
     ) -> Option<String> {
+        assert!(
+            self.rust_info.is_managed_git_subrepository(),
+            "Can't run `Config::last_modified_commit` on a non-git source."
+        );
+
         // Look for a version to compare to based on the current commit.
         // Only commits merged by bors will have CI artifacts.
         let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap();
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index ed0155622c226..5784fa6e300e6 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -34,6 +34,9 @@ pub struct Finder {
 // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
 const STAGE0_MISSING_TARGETS: &[&str] = &[
     // just a dummy comment so the list doesn't get onelined
+    "i586-rust9x-windows-msvc",
+    "i686-rust9x-windows-msvc",
+    "x86_64-rust9x-windows-msvc",
 ];
 
 /// Minimum version threshold for libstdc++ required when using prebuilt LLVM
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 8405c22aff08f..e5d2fc790fbec 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -471,6 +471,10 @@ impl Build {
     /// The given `err_hint` will be shown to the user if the submodule is not
     /// checked out and submodule management is disabled.
     pub fn require_submodule(&self, submodule: &str, err_hint: Option<&str>) {
+        if self.rust_info().is_from_tarball() {
+            return;
+        }
+
         // When testing bootstrap itself, it is much faster to ignore
         // submodules. Almost all Steps work fine without their submodules.
         if cfg!(test) && !self.config.submodules() {
@@ -1657,6 +1661,14 @@ Executed at: {executed_at}"#,
         paths
     }
 
+    /// Copies a file from `src` to `dst`.
+    ///
+    /// If `src` is a symlink, `src` will be resolved to the actual path
+    /// and copied to `dst` instead of the symlink itself.
+    pub fn resolve_symlink_and_copy(&self, src: &Path, dst: &Path) {
+        self.copy_link_internal(src, dst, true);
+    }
+
     /// Links a file from `src` to `dst`.
     /// Attempts to use hard links if possible, falling back to copying.
     /// You can neither rely on this being a copy nor it being a link,
diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs
index 4aec554b4321a..4ec8283942c6d 100644
--- a/src/bootstrap/src/utils/cc_detect.rs
+++ b/src/bootstrap/src/utils/cc_detect.rs
@@ -72,13 +72,16 @@ fn cc2ar(cc: &Path, target: TargetSelection) -> Option<PathBuf> {
 
 fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build {
     let mut cfg = cc::Build::new();
+
+    let triple = target.triple.to_owned().replace("rust9x", "pc");
+
     cfg.cargo_metadata(false)
         .opt_level(2)
         .warnings(false)
         .debug(false)
         // Compress debuginfo
         .flag_if_supported("-gz")
-        .target(&target.triple)
+        .target(&triple)
         .host(&build.build.triple);
     match build.crt_static(target) {
         Some(a) => {
diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs
index 2aad5650fa898..1e28d552fe66c 100644
--- a/src/build_helper/src/git.rs
+++ b/src/build_helper/src/git.rs
@@ -1,8 +1,6 @@
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 
-use crate::ci::CiEnv;
-
 pub struct GitConfig<'a> {
     pub git_repository: &'a str,
     pub nightly_branch: &'a str,
@@ -116,8 +114,8 @@ fn git_upstream_merge_base(
 
 /// Searches for the nearest merge commit in the repository that also exists upstream.
 ///
-/// It looks for the most recent commit made by the merge bot by matching the author's email
-/// address with the merge bot's email.
+/// If it fails to find the upstream remote, it then looks for the most recent commit made
+/// by the merge bot by matching the author's email address with the merge bot's email.
 pub fn get_closest_merge_commit(
     git_dir: Option<&Path>,
     config: &GitConfig<'_>,
@@ -129,15 +127,7 @@ pub fn get_closest_merge_commit(
         git.current_dir(git_dir);
     }
 
-    let merge_base = {
-        if CiEnv::is_ci() {
-            git_upstream_merge_base(config, git_dir).unwrap()
-        } else {
-            // For non-CI environments, ignore rust-lang/rust upstream as it usually gets
-            // outdated very quickly.
-            "HEAD".to_string()
-        }
-    };
+    let merge_base = git_upstream_merge_base(config, git_dir).unwrap_or_else(|_| "HEAD".into());
 
     git.args([
         "rev-list",
diff --git a/src/ci/channel b/src/ci/channel
index bf867e0ae5b6c..2bf5ad0447d33 100644
--- a/src/ci/channel
+++ b/src/ci/channel
@@ -1 +1 @@
-nightly
+stable
diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh
index ece8e6c15c0cb..9878bec6fbe8c 100644
--- a/src/ci/docker/scripts/musl.sh
+++ b/src/ci/docker/scripts/musl.sh
@@ -30,6 +30,47 @@ MUSL=musl-1.2.3
 # may have been downloaded in a previous run
 if [ ! -d $MUSL ]; then
   curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
+
+  # Apply patches for CVE-2025-26519. At the time of adding these patches no release containing them
+  # has been published by the musl project, so we just apply them directly on top of the version we
+  # were distributing already. The patches should be removed once we upgrade to musl >= 1.2.6.
+  #
+  # Advisory: https://www.openwall.com/lists/musl/2025/02/13/1
+  #
+  # Patches applied:
+  # - https://www.openwall.com/lists/musl/2025/02/13/1/1
+  # - https://www.openwall.com/lists/musl/2025/02/13/1/2
+  #
+  # ignore-tidy-tab
+  # ignore-tidy-linelength
+  patch -p1 -d $MUSL <<EOF
+--- a/src/locale/iconv.c
++++ b/src/locale/iconv.c
+@@ -502,7 +502,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
+ 			if (c >= 93 || d >= 94) {
+ 				c += (0xa1-0x81);
+ 				d += 0xa1;
+-				if (c >= 93 || c>=0xc6-0x81 && d>0x52)
++				if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52)
+ 					goto ilseq;
+ 				if (d-'A'<26) d = d-'A';
+ 				else if (d-'a'<26) d = d-'a'+26;
+EOF
+  patch -p1 -d $MUSL <<EOF
+--- a/src/locale/iconv.c
++++ b/src/locale/iconv.c
+@@ -545,6 +545,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
+ 				if (*outb < k) goto toobig;
+ 				memcpy(*out, tmp, k);
+ 			} else k = wctomb_utf8(*out, c);
++			/* This failure condition should be unreachable, but
++			 * is included to prevent decoder bugs from translating
++			 * into advancement outside the output buffer range. */
++			if (k>4) goto ilseq;
+ 			*out += k;
+ 			*outb -= k;
+ 			break;
+EOF
 fi
 
 cd $MUSL
diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh
index 8776e0f0be901..dbd0eff2079b6 100755
--- a/src/ci/docker/scripts/rfl-build.sh
+++ b/src/ci/docker/scripts/rfl-build.sh
@@ -8,16 +8,10 @@ LINUX_VERSION=v6.13-rc1
 ../x.py build --stage 2 library rustdoc clippy rustfmt
 ../x.py build --stage 0 cargo
 
-# Install rustup so that we can use the built toolchain easily, and also
-# install bindgen in an easy way.
-curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs
-sh rustup.sh -y --default-toolchain none
+BUILD_DIR=$(realpath ./build/x86_64-unknown-linux-gnu)
 
-source /cargo/env
-
-BUILD_DIR=$(realpath ./build)
-rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage2
-rustup default local
+# Provide path to rustc, rustdoc, clippy-driver and rustfmt to RfL
+export PATH=${PATH}:${BUILD_DIR}/stage2/bin
 
 mkdir -p rfl
 cd rfl
@@ -33,10 +27,14 @@ git -C linux fetch --depth 1 origin ${LINUX_VERSION}
 git -C linux checkout FETCH_HEAD
 
 # Install bindgen
-"${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage0/bin/cargo install \
+"${BUILD_DIR}"/stage0/bin/cargo install \
   --version $(linux/scripts/min-tool-version.sh bindgen) \
+  --root ${BUILD_DIR}/bindgen \
   bindgen-cli
 
+# Provide path to bindgen to RfL
+export PATH=${PATH}:${BUILD_DIR}/bindgen/bin
+
 # Configure Rust for Linux
 cat <<EOF > linux/kernel/configs/rfl-for-rust-ci.config
 # CONFIG_WERROR is not set
diff --git a/src/ci/scripts/setup-upstream-remote.sh b/src/ci/scripts/setup-upstream-remote.sh
deleted file mode 100755
index 52b4c98a89016..0000000000000
--- a/src/ci/scripts/setup-upstream-remote.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-# In CI environments, bootstrap is forced to use the remote upstream based
-# on "git_repository" and "nightly_branch" values from src/stage0 file.
-# This script configures the remote as it may not exist by default.
-
-set -euo pipefail
-IFS=$'\n\t'
-
-ci_dir=$(cd $(dirname $0) && pwd)/..
-source "$ci_dir/shared.sh"
-
-git_repository=$(parse_stage0_file_by_key "git_repository")
-nightly_branch=$(parse_stage0_file_by_key "nightly_branch")
-
-# Configure "rust-lang/rust" upstream remote only when it's not origin.
-if [ -z "$(git config remote.origin.url | grep $git_repository)" ]; then
-    echo "Configuring https://github.com/$git_repository remote as upstream."
-    git remote add upstream "https://github.com/$git_repository"
-    REMOTE_NAME="upstream"
-else
-    REMOTE_NAME="origin"
-fi
-
-git fetch $REMOTE_NAME $nightly_branch
diff --git a/src/ci/shared.sh b/src/ci/shared.sh
index 9fce68947f429..76464add75d32 100644
--- a/src/ci/shared.sh
+++ b/src/ci/shared.sh
@@ -137,15 +137,3 @@ function releaseChannel {
         echo $RUST_CI_OVERRIDE_RELEASE_CHANNEL
     fi
 }
-
-# Parse values from src/stage0 file by key
-function parse_stage0_file_by_key {
-    local key="$1"
-    local file="$ci_dir/../stage0"
-    local value=$(awk -F= '{a[$1]=$2} END {print(a["'$key'"])}' $file)
-    if [ -z "$value" ]; then
-        echo "ERROR: Key '$key' not found in '$file'."
-        exit 1
-    fi
-    echo "$value"
-}
diff --git a/src/doc/book b/src/doc/book
index 04d06dfe54160..82a4a49789bc9 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit 04d06dfe541607e6419f3d028c3f9b245f3be4d9
+Subproject commit 82a4a49789bc96db1a1b2a210b4c5ed7c9ef0c0d
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
index d56e0f3a0656b..888950147385f 160000
--- a/src/doc/edition-guide
+++ b/src/doc/edition-guide
@@ -1 +1 @@
-Subproject commit d56e0f3a0656b7702ca466d4b191e16c28262b82
+Subproject commit 888950147385fb48076c492a2202e6c1a19d1228
diff --git a/src/doc/reference b/src/doc/reference
index acd6794e712d5..b05d56e8dfab6 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit acd6794e712d5e2ef6f5c84fb95688d32a69b816
+Subproject commit b05d56e8dfab65ac842b898ccdac5cd61c163556
diff --git a/src/doc/rustc/src/check-cfg.md b/src/doc/rustc/src/check-cfg.md
index f7e831dc8bd85..c62ca9fd9ad6b 100644
--- a/src/doc/rustc/src/check-cfg.md
+++ b/src/doc/rustc/src/check-cfg.md
@@ -134,7 +134,7 @@ As of `2025-01-02T`, the list of known names is as follows:
  - `unix`
  - `windows`
 
-> Starting with CURRENT_RUSTC_VERSION, the `test` cfg is consider to be a "userspace" config
+> Starting with 1.85.0, the `test` cfg is consider to be a "userspace" config
 > despite being also set by `rustc` and should be managed by the build-system it-self.
 
 Like with `values(any())`, well known names checking can be disabled by passing `cfg(any())`
diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md
index b9a89c20cee40..19e62c4867c99 100644
--- a/src/doc/style-guide/src/editions.md
+++ b/src/doc/style-guide/src/editions.md
@@ -36,10 +36,6 @@ For a full history of changes in the Rust 2024 style edition, see the git
 history of the style guide. Notable changes in the Rust 2024 style edition
 include:
 
-- [#114764](https://github.com/rust-lang/rust/pull/114764) As the last member
-  of a delimited expression, delimited expressions are generally combinable,
-  regardless of the number of members. Previously only applied with exactly
-  one member (except for closures with explicit blocks).
 - Miscellaneous `rustfmt` bugfixes.
 - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order).
 - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase".
diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md
index 171a24cd89d73..12037b5992ec0 100644
--- a/src/doc/style-guide/src/expressions.md
+++ b/src/doc/style-guide/src/expressions.md
@@ -818,11 +818,11 @@ E.g., `&&Some(foo)` matches, `Foo(4, Bar)` does not.
 
 ## Combinable expressions
 
-When the last argument in a function call is formatted across
-multiple-lines, format the outer call as if it were a single-line call,
+Where a function call has a single argument, and that argument is formatted
+across multiple-lines, format the outer call as if it were a single-line call,
 if the result fits. Apply the same combining behaviour to any similar
 expressions which have multi-line, block-indented lists of sub-expressions
-delimited by parentheses, brackets, or braces. E.g.,
+delimited by parentheses (e.g., macros or tuple struct literals). E.g.,
 
 ```rust
 foo(bar(
@@ -848,61 +848,20 @@ let arr = [combinable(
     an_expr,
     another_expr,
 )];
-
-let x = Thing(an_expr, another_expr, match cond {
-    A => 1,
-    B => 2,
-});
-
-let x = format!("Stuff: {}", [
-    an_expr,
-    another_expr,
-]);
-
-let x = func(an_expr, another_expr, SomeStruct {
-    field: this_is_long,
-    another_field: 123,
-});
 ```
 
 Apply this behavior recursively.
 
-If the last argument is a multi-line closure with an explicit block,
-only apply the combining behavior if there are no other closure arguments.
+For a function with multiple arguments, if the last argument is a multi-line
+closure with an explicit block, there are no other closure arguments, and all
+the arguments and the first line of the closure fit on the first line, use the
+same combining behavior:
 
 ```rust
-// Combinable
 foo(first_arg, x, |param| {
     action();
     foo(param)
 })
-// Not combinable, because the closure is not the last argument
-foo(
-    first_arg,
-    |param| {
-        action();
-        foo(param)
-    },
-    whatever,
-)
-// Not combinable, because the first line of the closure does not fit
-foo(
-    first_arg,
-    x,
-    move |very_long_param_causing_line_to_overflow| -> Bar {
-        action();
-        foo(param)
-    },
-)
-// Not combinable, because there is more than one closure argument
-foo(
-    first_arg,
-    |x| x.bar(),
-    |param| {
-        action();
-        foo(param)
-    },
-)
 ```
 
 ## Ranges
diff --git a/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md
new file mode 100644
index 0000000000000..b20c30ec8f1c8
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/extended-varargs-abi-support.md
@@ -0,0 +1,10 @@
+# `extended_varargs_abi_support`
+
+The tracking issue for this feature is: [#100189]
+
+[#100189]: https://github.com/rust-lang/rust/issues/100189
+
+------------------------
+
+This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling
+conventions on functions with varargs.
diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs
index 2d155bf0b1019..f29e1e4d27a27 100644
--- a/src/etc/installer/msi/rust.wxs
+++ b/src/etc/installer/msi/rust.wxs
@@ -172,11 +172,6 @@
                     <!-- tool-rust-docs-end -->
                     <Directory Id="Cargo" Name="." />
                     <Directory Id="Std" Name="." />
-                    <Directory Id="RustFmt" Name="." />
-                    <Directory Id="RustAnalyzer" Name="." />
-                    <Directory Id="Miri" Name="." />
-                    <Directory Id="Analysis" Name="." />
-                    <Directory Id="Clippy" Name="." />
                 </Directory>
             </Directory>
 
@@ -284,41 +279,7 @@
                  <ComponentRef Id="PathEnvPerMachine" />
                  <ComponentRef Id="PathEnvPerUser" />
         </Feature>
-        <Feature Id="RustFmt"
-                 Title="Formatter for rust"
-                 Display="7"
-                 Level="1"
-                 AllowAdvertise="no">
-                 <ComponentGroupRef Id="RustFmtGroup" />
-        </Feature>
-        <Feature Id="Clippy"
-                 Title="Formatter and checker for rust"
-                 Display="8"
-                 Level="1"
-                 AllowAdvertise="no">
-                 <ComponentGroupRef Id="ClippyGroup" />
-        </Feature>
-        <Feature Id="Miri"
-                 Title="Soundness checker for rust"
-                 Display="9"
-                 Level="1"
-                 AllowAdvertise="no">
-                 <ComponentGroupRef Id="MiriGroup" />
-        </Feature>
-        <Feature Id="RustAnalyzer"
-                 Title="Analyzer for rust"
-                 Display="10"
-                 Level="1"
-                 AllowAdvertise="no">
-                 <ComponentGroupRef Id="RustAnalyzerGroup" />
-        </Feature>
-        <Feature Id="Analysis"
-                 Title="Analysis for rust"
-                 Display="11"
-                 Level="1"
-                 AllowAdvertise="no">
-                 <ComponentGroupRef Id="AnalysisGroup" />
-        </Feature>
+
         <UIRef Id="RustUI" />
     </Product>
 </Wix>
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 009e9662933ae..881d0b6dcbe2a 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -95,7 +95,7 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) ->
         .map_err(|error| format!("failed to create args file: {error:?}"))?;
 
     // We now put the common arguments into the file we created.
-    let mut content = vec!["--crate-type=bin".to_string()];
+    let mut content = vec![];
 
     for cfg in &options.cfgs {
         content.push(format!("--cfg={cfg}"));
@@ -488,12 +488,18 @@ pub(crate) struct RunnableDocTest {
     line: usize,
     edition: Edition,
     no_run: bool,
-    is_multiple_tests: bool,
+    merged_test_code: Option<String>,
 }
 
 impl RunnableDocTest {
-    fn path_for_merged_doctest(&self) -> PathBuf {
-        self.test_opts.outdir.path().join(format!("doctest_{}.rs", self.edition))
+    fn path_for_merged_doctest_bundle(&self) -> PathBuf {
+        self.test_opts.outdir.path().join(format!("doctest_bundle_{}.rs", self.edition))
+    }
+    fn path_for_merged_doctest_runner(&self) -> PathBuf {
+        self.test_opts.outdir.path().join(format!("doctest_runner_{}.rs", self.edition))
+    }
+    fn is_multiple_tests(&self) -> bool {
+        self.merged_test_code.is_some()
     }
 }
 
@@ -512,91 +518,108 @@ fn run_test(
     let rust_out = add_exe_suffix("rust_out".to_owned(), &rustdoc_options.target);
     let output_file = doctest.test_opts.outdir.path().join(rust_out);
 
-    let rustc_binary = rustdoc_options
-        .test_builder
-        .as_deref()
-        .unwrap_or_else(|| rustc_interface::util::rustc_path().expect("found rustc"));
-    let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
+    // Common arguments used for compiling the doctest runner.
+    // On merged doctests, the compiler is invoked twice: once for the test code itself,
+    // and once for the runner wrapper (which needs to use `#![feature]` on stable).
+    let mut compiler_args = vec![];
 
-    compiler.arg(format!("@{}", doctest.global_opts.args_file.display()));
+    compiler_args.push(format!("@{}", doctest.global_opts.args_file.display()));
 
     if let Some(sysroot) = &rustdoc_options.maybe_sysroot {
-        compiler.arg(format!("--sysroot={}", sysroot.display()));
+        compiler_args.push(format!("--sysroot={}", sysroot.display()));
     }
 
-    compiler.arg("--edition").arg(doctest.edition.to_string());
-    if !doctest.is_multiple_tests {
-        // Setting these environment variables is unneeded if this is a merged doctest.
-        compiler.env("UNSTABLE_RUSTDOC_TEST_PATH", &doctest.test_opts.path);
-        compiler.env(
-            "UNSTABLE_RUSTDOC_TEST_LINE",
-            format!("{}", doctest.line as isize - doctest.full_test_line_offset as isize),
-        );
-    }
-    compiler.arg("-o").arg(&output_file);
+    compiler_args.extend_from_slice(&["--edition".to_owned(), doctest.edition.to_string()]);
     if langstr.test_harness {
-        compiler.arg("--test");
+        compiler_args.push("--test".to_owned());
     }
     if rustdoc_options.json_unused_externs.is_enabled() && !langstr.compile_fail {
-        compiler.arg("--error-format=json");
-        compiler.arg("--json").arg("unused-externs");
-        compiler.arg("-W").arg("unused_crate_dependencies");
-        compiler.arg("-Z").arg("unstable-options");
+        compiler_args.push("--error-format=json".to_owned());
+        compiler_args.extend_from_slice(&["--json".to_owned(), "unused-externs".to_owned()]);
+        compiler_args.extend_from_slice(&["-W".to_owned(), "unused_crate_dependencies".to_owned()]);
+        compiler_args.extend_from_slice(&["-Z".to_owned(), "unstable-options".to_owned()]);
     }
 
     if doctest.no_run && !langstr.compile_fail && rustdoc_options.persist_doctests.is_none() {
         // FIXME: why does this code check if it *shouldn't* persist doctests
         //        -- shouldn't it be the negation?
-        compiler.arg("--emit=metadata");
+        compiler_args.push("--emit=metadata".to_owned());
     }
-    compiler.arg("--target").arg(match &rustdoc_options.target {
-        TargetTuple::TargetTuple(s) => s,
-        TargetTuple::TargetJson { path_for_rustdoc, .. } => {
-            path_for_rustdoc.to_str().expect("target path must be valid unicode")
-        }
-    });
+    compiler_args.extend_from_slice(&[
+        "--target".to_owned(),
+        match &rustdoc_options.target {
+            TargetTuple::TargetTuple(s) => s.clone(),
+            TargetTuple::TargetJson { path_for_rustdoc, .. } => {
+                path_for_rustdoc.to_str().expect("target path must be valid unicode").to_owned()
+            }
+        },
+    ]);
     if let ErrorOutputType::HumanReadable(kind, color_config) = rustdoc_options.error_format {
         let short = kind.short();
         let unicode = kind == HumanReadableErrorType::Unicode;
 
         if short {
-            compiler.arg("--error-format").arg("short");
+            compiler_args.extend_from_slice(&["--error-format".to_owned(), "short".to_owned()]);
         }
         if unicode {
-            compiler.arg("--error-format").arg("human-unicode");
+            compiler_args
+                .extend_from_slice(&["--error-format".to_owned(), "human-unicode".to_owned()]);
         }
 
         match color_config {
             ColorConfig::Never => {
-                compiler.arg("--color").arg("never");
+                compiler_args.extend_from_slice(&["--color".to_owned(), "never".to_owned()]);
             }
             ColorConfig::Always => {
-                compiler.arg("--color").arg("always");
+                compiler_args.extend_from_slice(&["--color".to_owned(), "always".to_owned()]);
             }
             ColorConfig::Auto => {
-                compiler.arg("--color").arg(if supports_color { "always" } else { "never" });
+                compiler_args.extend_from_slice(&[
+                    "--color".to_owned(),
+                    if supports_color { "always" } else { "never" }.to_owned(),
+                ]);
             }
         }
     }
 
+    let rustc_binary = rustdoc_options
+        .test_builder
+        .as_deref()
+        .unwrap_or_else(|| rustc_interface::util::rustc_path().expect("found rustc"));
+    let mut compiler = wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
+
+    compiler.args(&compiler_args);
+
     // If this is a merged doctest, we need to write it into a file instead of using stdin
     // because if the size of the merged doctests is too big, it'll simply break stdin.
-    if doctest.is_multiple_tests {
+    if doctest.is_multiple_tests() {
         // It makes the compilation failure much faster if it is for a combined doctest.
         compiler.arg("--error-format=short");
-        let input_file = doctest.path_for_merged_doctest();
+        let input_file = doctest.path_for_merged_doctest_bundle();
         if std::fs::write(&input_file, &doctest.full_test_code).is_err() {
             // If we cannot write this file for any reason, we leave. All combined tests will be
             // tested as standalone tests.
             return Err(TestFailure::CompileError);
         }
-        compiler.arg(input_file);
         if !rustdoc_options.nocapture {
             // If `nocapture` is disabled, then we don't display rustc's output when compiling
             // the merged doctests.
             compiler.stderr(Stdio::null());
         }
+        // bundled tests are an rlib, loaded by a separate runner executable
+        compiler
+            .arg("--crate-type=lib")
+            .arg("--out-dir")
+            .arg(doctest.test_opts.outdir.path())
+            .arg(input_file);
     } else {
+        compiler.arg("--crate-type=bin").arg("-o").arg(&output_file);
+        // Setting these environment variables is unneeded if this is a merged doctest.
+        compiler.env("UNSTABLE_RUSTDOC_TEST_PATH", &doctest.test_opts.path);
+        compiler.env(
+            "UNSTABLE_RUSTDOC_TEST_LINE",
+            format!("{}", doctest.line as isize - doctest.full_test_line_offset as isize),
+        );
         compiler.arg("-");
         compiler.stdin(Stdio::piped());
         compiler.stderr(Stdio::piped());
@@ -605,8 +628,65 @@ fn run_test(
     debug!("compiler invocation for doctest: {compiler:?}");
 
     let mut child = compiler.spawn().expect("Failed to spawn rustc process");
-    let output = if doctest.is_multiple_tests {
+    let output = if let Some(merged_test_code) = &doctest.merged_test_code {
+        // compile-fail tests never get merged, so this should always pass
         let status = child.wait().expect("Failed to wait");
+
+        // the actual test runner is a separate component, built with nightly-only features;
+        // build it now
+        let runner_input_file = doctest.path_for_merged_doctest_runner();
+
+        let mut runner_compiler =
+            wrapped_rustc_command(&rustdoc_options.test_builder_wrappers, rustc_binary);
+        // the test runner does not contain any user-written code, so this doesn't allow
+        // the user to exploit nightly-only features on stable
+        runner_compiler.env("RUSTC_BOOTSTRAP", "1");
+        runner_compiler.args(compiler_args);
+        runner_compiler.args(&["--crate-type=bin", "-o"]).arg(&output_file);
+        let mut extern_path = std::ffi::OsString::from(format!(
+            "--extern=doctest_bundle_{edition}=",
+            edition = doctest.edition
+        ));
+        for extern_str in &rustdoc_options.extern_strs {
+            if let Some((_cratename, path)) = extern_str.split_once('=') {
+                // Direct dependencies of the tests themselves are
+                // indirect dependencies of the test runner.
+                // They need to be in the library search path.
+                let dir = Path::new(path)
+                    .parent()
+                    .filter(|x| x.components().count() > 0)
+                    .unwrap_or(Path::new("."));
+                runner_compiler.arg("-L").arg(dir);
+            }
+        }
+        let output_bundle_file = doctest
+            .test_opts
+            .outdir
+            .path()
+            .join(format!("libdoctest_bundle_{edition}.rlib", edition = doctest.edition));
+        extern_path.push(&output_bundle_file);
+        runner_compiler.arg(extern_path);
+        runner_compiler.arg(&runner_input_file);
+        if std::fs::write(&runner_input_file, &merged_test_code).is_err() {
+            // If we cannot write this file for any reason, we leave. All combined tests will be
+            // tested as standalone tests.
+            return Err(TestFailure::CompileError);
+        }
+        if !rustdoc_options.nocapture {
+            // If `nocapture` is disabled, then we don't display rustc's output when compiling
+            // the merged doctests.
+            runner_compiler.stderr(Stdio::null());
+        }
+        runner_compiler.arg("--error-format=short");
+        debug!("compiler invocation for doctest runner: {runner_compiler:?}");
+
+        let status = if !status.success() {
+            status
+        } else {
+            let mut child_runner = runner_compiler.spawn().expect("Failed to spawn rustc process");
+            child_runner.wait().expect("Failed to wait")
+        };
+
         process::Output { status, stdout: Vec::new(), stderr: Vec::new() }
     } else {
         let stdin = child.stdin.as_mut().expect("Failed to open stdin");
@@ -683,7 +763,7 @@ fn run_test(
         cmd.arg(&output_file);
     } else {
         cmd = Command::new(&output_file);
-        if doctest.is_multiple_tests {
+        if doctest.is_multiple_tests() {
             cmd.env("RUSTDOC_DOCTEST_BIN_PATH", &output_file);
         }
     }
@@ -691,7 +771,7 @@ fn run_test(
         cmd.current_dir(run_directory);
     }
 
-    let result = if doctest.is_multiple_tests || rustdoc_options.nocapture {
+    let result = if doctest.is_multiple_tests() || rustdoc_options.nocapture {
         cmd.status().map(|status| process::Output {
             status,
             stdout: Vec::new(),
@@ -977,7 +1057,7 @@ fn doctest_run_fn(
         line: scraped_test.line,
         edition: scraped_test.edition(&rustdoc_options),
         no_run: scraped_test.no_run(&rustdoc_options),
-        is_multiple_tests: false,
+        merged_test_code: None,
     };
     let res =
         run_test(runnable_test, &rustdoc_options, doctest.supports_color, report_unused_externs);
diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs
index 234f40c6c1ab2..58efa35711a0e 100644
--- a/src/librustdoc/doctest/runner.rs
+++ b/src/librustdoc/doctest/runner.rs
@@ -14,6 +14,7 @@ pub(crate) struct DocTestRunner {
     crate_attrs: FxIndexSet<String>,
     ids: String,
     output: String,
+    output_merged_tests: String,
     supports_color: bool,
     nb_tests: usize,
 }
@@ -24,6 +25,7 @@ impl DocTestRunner {
             crate_attrs: FxIndexSet::default(),
             ids: String::new(),
             output: String::new(),
+            output_merged_tests: String::new(),
             supports_color: true,
             nb_tests: 0,
         }
@@ -55,7 +57,8 @@ impl DocTestRunner {
                 scraped_test,
                 ignore,
                 self.nb_tests,
-                &mut self.output
+                &mut self.output,
+                &mut self.output_merged_tests,
             ),
         ));
         self.supports_color &= doctest.supports_color;
@@ -78,9 +81,11 @@ impl DocTestRunner {
 "
         .to_string();
 
+        let mut code_prefix = String::new();
+
         for crate_attr in &self.crate_attrs {
-            code.push_str(crate_attr);
-            code.push('\n');
+            code_prefix.push_str(crate_attr);
+            code_prefix.push('\n');
         }
 
         if opts.attrs.is_empty() {
@@ -88,15 +93,16 @@ impl DocTestRunner {
             // lints that are commonly triggered in doctests. The crate-level test attributes are
             // commonly used to make tests fail in case they trigger warnings, so having this there in
             // that case may cause some tests to pass when they shouldn't have.
-            code.push_str("#![allow(unused)]\n");
+            code_prefix.push_str("#![allow(unused)]\n");
         }
 
         // Next, any attributes that came from the crate root via #![doc(test(attr(...)))].
         for attr in &opts.attrs {
-            code.push_str(&format!("#![{attr}]\n"));
+            code_prefix.push_str(&format!("#![{attr}]\n"));
         }
 
         code.push_str("extern crate test;\n");
+        writeln!(code, "extern crate doctest_bundle_{edition} as doctest_bundle;").unwrap();
 
         let test_args = test_args.iter().fold(String::new(), |mut x, arg| {
             write!(x, "{arg:?}.to_string(),").unwrap();
@@ -161,12 +167,12 @@ the same process\");
 std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None))
 }}",
             nb_tests = self.nb_tests,
-            output = self.output,
+            output = self.output_merged_tests,
             ids = self.ids,
         )
         .expect("failed to generate test code");
         let runnable_test = RunnableDocTest {
-            full_test_code: code,
+            full_test_code: format!("{code_prefix}{code}", code = self.output),
             full_test_line_offset: 0,
             test_opts: test_options,
             global_opts: opts.clone(),
@@ -174,7 +180,7 @@ std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), N
             line: 0,
             edition,
             no_run: false,
-            is_multiple_tests: true,
+            merged_test_code: Some(code),
         };
         let ret =
             run_test(runnable_test, rustdoc_options, self.supports_color, |_: UnusedExterns| {});
@@ -189,14 +195,15 @@ fn generate_mergeable_doctest(
     ignore: bool,
     id: usize,
     output: &mut String,
+    output_merged_tests: &mut String,
 ) -> String {
     let test_id = format!("__doctest_{id}");
 
     if ignore {
         // We generate nothing else.
-        writeln!(output, "mod {test_id} {{\n").unwrap();
+        writeln!(output, "pub mod {test_id} {{}}\n").unwrap();
     } else {
-        writeln!(output, "mod {test_id} {{\n{}{}", doctest.crates, doctest.maybe_crate_attrs)
+        writeln!(output, "pub mod {test_id} {{\n{}{}", doctest.crates, doctest.maybe_crate_attrs)
             .unwrap();
         if doctest.has_main_fn {
             output.push_str(&doctest.everything_else);
@@ -216,11 +223,17 @@ fn main() {returns_result} {{
             )
             .unwrap();
         }
+        writeln!(
+            output,
+            "\npub fn __main_fn() -> impl std::process::Termination {{ main() }} \n}}\n"
+        )
+        .unwrap();
     }
     let not_running = ignore || scraped_test.langstr.no_run;
     writeln!(
-        output,
+        output_merged_tests,
         "
+mod {test_id} {{
 pub const TEST: test::TestDescAndFn = test::TestDescAndFn::new_doctest(
 {test_name:?}, {ignore}, {file:?}, {line}, {no_run}, {should_panic},
 test::StaticTestFn(
@@ -242,7 +255,7 @@ test::StaticTestFn(
 if let Some(bin_path) = crate::__doctest_mod::doctest_path() {{
     test::assert_test_result(crate::__doctest_mod::doctest_runner(bin_path, {id}))
 }} else {{
-    test::assert_test_result(self::main())
+    test::assert_test_result(doctest_bundle::{test_id}::__main_fn())
 }}
 ",
             )
diff --git a/src/llvm-project b/src/llvm-project
index 59512b0027382..7e8c93c87c611 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 59512b00273829823da74050d373b8d46dbca558
+Subproject commit 7e8c93c87c611f21d9bd95100563392f4c18bfe7
diff --git a/src/stage0 b/src/stage0
index 23ee3304b4226..f21e6fb9d4892 100644
--- a/src/stage0
+++ b/src/stage0
@@ -14,456 +14,354 @@ nightly_branch=master
 # All changes below this comment will be overridden the next time the
 # tool is executed.
             
-compiler_date=2024-11-27
-compiler_version=beta
-rustfmt_date=2024-11-27
-rustfmt_version=nightly
+compiler_date=2025-01-09
+compiler_version=1.84.0
 
-dist/2024-11-27/rustc-beta-aarch64-apple-darwin.tar.gz=58e2ba5f6a388a5bc9ecfa1c7ec4ba3efd9662e1875ea5fba484c75c5f930227
-dist/2024-11-27/rustc-beta-aarch64-apple-darwin.tar.xz=95f3ed14a6e3093cdee83f80227c7966783fffcc0ff0be6ef095df0dc744b9f8
-dist/2024-11-27/rustc-beta-aarch64-pc-windows-msvc.tar.gz=687b58e25baa685be9357048cc1e0c469c25dc6530db55e0179234615ff4d289
-dist/2024-11-27/rustc-beta-aarch64-pc-windows-msvc.tar.xz=694e2405efb25c53575599ad6573d8c4646a168e5d4bde922ef5e7d43f3e530c
-dist/2024-11-27/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=4b42d00e701f90c1fff9a692f1bc1da957fcadbd1813c3066dc1f1990bceadcc
-dist/2024-11-27/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=4f83a8cced878c03aea2d6cec7e1d588c2b6590850664f28f3b49a3be3a8b827
-dist/2024-11-27/rustc-beta-aarch64-unknown-linux-musl.tar.gz=bae97ca3778fbaa40f6db4da4f6da0b2bb870e9880165fc3126363f55a1fb23a
-dist/2024-11-27/rustc-beta-aarch64-unknown-linux-musl.tar.xz=3e617e866a8c03fef243dede8c086d085a6564aeeb5570bada62db5a16e95f2a
-dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=96d2f23814db8286de9ffce7bab033aa4dc656f83aa39418c8f877a5befbb100
-dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=0433a866c4d8a434990746216232759345d3ef556b0b92358b231fc1e727962e
-dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=6a776c6eb2b7b4992eed6a127d11b8845695cdc5d23938ced2267f88f8d97033
-dist/2024-11-27/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=2649e0f522755dcd511a6459258c3c3a24808fc49d3513f3d9098b17bd0f2c79
-dist/2024-11-27/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=02a65e970ee930b46c2d10e1eb3d2e6f2420e08bbef039f10a8311baf57f274f
-dist/2024-11-27/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=3843610c7ecf98948a5f78a364c223d520a084bc8c49ec0c3c8ec48bad6c0bf8
-dist/2024-11-27/rustc-beta-i686-pc-windows-gnu.tar.gz=75288ca1e65157b8902195ec2fff31015017c90d3b8f51890f2f851529b200cb
-dist/2024-11-27/rustc-beta-i686-pc-windows-gnu.tar.xz=5c694e50b41cd6f2c7b59b891eda3e728a1a2c56617b96c9da001b35885637b4
-dist/2024-11-27/rustc-beta-i686-pc-windows-msvc.tar.gz=6d1a66c090322ccf272a425c779f9165398e6bd9e0c7e5d0a5f262086d43ed88
-dist/2024-11-27/rustc-beta-i686-pc-windows-msvc.tar.xz=e826fe8be287f8969d11f620da9d01ea0d913eba145fb79ae86bc78674f1b919
-dist/2024-11-27/rustc-beta-i686-unknown-linux-gnu.tar.gz=31e0d9a1ff97d92c391cc913fd865a0c8afd614279654350d469bdf881a1b1a3
-dist/2024-11-27/rustc-beta-i686-unknown-linux-gnu.tar.xz=3b11a6be4863cb6ad420b66558b7745431834d1fac5dbda899a384dc30b526cf
-dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=59d96cd092a56d12ea796b65225479803edadbdcb483effdfa36e191f73483f1
-dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=0714a469cbd7d96118e9260f80fedf34b21234776904e9c8ec5b71c9493dd36a
-dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=25113ca9719a036ae581f68df4dda74f1446b49ababe7bb194510fbd1b296e7a
-dist/2024-11-27/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=25bd910ea722fe2d4a1e66089352c92f97759ec7212af2b9a04431b469ed8e12
-dist/2024-11-27/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=7a83c9f63d88849c4d691ad1d7fbe7ab5924b5a7d76378ddff5024269be95310
-dist/2024-11-27/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=fbbb11b4c986186d94b0e00ebc70400d0071efc2ba3b802abdd877d86b8cacdd
-dist/2024-11-27/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=6223dff24490e3e8506dfbe2b12620155d7c05fce92191cb01f3b28e269bf1be
-dist/2024-11-27/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=6fb1edea73bcb76d9cb6061d1aba15ee4655a212c1bf96328a225c7c05df3462
-dist/2024-11-27/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=0b7bc9ec0c40a6203fb62eb71fb6eeab43a4f64a2f7d0d51a1e0d041a216adb1
-dist/2024-11-27/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=d77a49acbf26b8c9a2a5f79fdc640feb1c81b9fa38f442b81f69127f49c7cde7
-dist/2024-11-27/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=bdf45a37fad10df4822690ea73840b38ee3e1048878982e625efbad3b2054f28
-dist/2024-11-27/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=ad6a2f03b2e27711e1ec4eb75502782c4bc0200cfaca2b5246e0bd5b86bf29ad
-dist/2024-11-27/rustc-beta-s390x-unknown-linux-gnu.tar.gz=b0cc3024a717d33775dbea63e83f317f8826e564ceb4ecb7a6cf23676f66ccdc
-dist/2024-11-27/rustc-beta-s390x-unknown-linux-gnu.tar.xz=9d5b44a82803d5de5355ffced6ec1dcb9860950910bba6dc54878ad4da7ff444
-dist/2024-11-27/rustc-beta-x86_64-apple-darwin.tar.gz=c7174c35b530453182f5f0b15c6684c030a2ff2770f4cc1a4a4ba75695e53b99
-dist/2024-11-27/rustc-beta-x86_64-apple-darwin.tar.xz=c68c26159a3fb4d4380fb25488aa78223989893d7786b8ec947d82ce0cc905bc
-dist/2024-11-27/rustc-beta-x86_64-pc-windows-gnu.tar.gz=c97caf7877097d78fe2191e715e3a45d827d28c27b4dabf0747f8ca522ee43f5
-dist/2024-11-27/rustc-beta-x86_64-pc-windows-gnu.tar.xz=b7794ecabc42698cb77c1c90d66676a8b1b3632108ab95954ee496ee7d6e5708
-dist/2024-11-27/rustc-beta-x86_64-pc-windows-msvc.tar.gz=28068a6e050abe21933920dba3ead2261f7d0c09687d5a86a5db51cca6e72ea9
-dist/2024-11-27/rustc-beta-x86_64-pc-windows-msvc.tar.xz=3860d7ec8564019c79551727a3a54c66453a7d654fbb89b8feeae75d9021fa77
-dist/2024-11-27/rustc-beta-x86_64-unknown-freebsd.tar.gz=6c2a918f8d40ba01e648565c98ea120d32562dd93820e8f2e33abb2aef08e1da
-dist/2024-11-27/rustc-beta-x86_64-unknown-freebsd.tar.xz=5d1edcc6c4be49849c3c2d1c3c173d4a127db3cfb615093e5ee396e0d0c77366
-dist/2024-11-27/rustc-beta-x86_64-unknown-illumos.tar.gz=a64c30d82dca58d09bfa38e72bbe1457b48b101157193a3ee33dd85922bbfe9d
-dist/2024-11-27/rustc-beta-x86_64-unknown-illumos.tar.xz=87d14b146386fe1f9e24fedc25e1bf9682913bbd7537047b0baef0d74cad5473
-dist/2024-11-27/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=3f186913535ac59446e249f4d3e35e3d93a3f8207b31ee31b3f70af8344856bc
-dist/2024-11-27/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=0c17a60ebac74a9cdfc2ec69fd71a21e370ff178f4c83be6020642b55b6d78ab
-dist/2024-11-27/rustc-beta-x86_64-unknown-linux-musl.tar.gz=327973698dd0ffe9b2d56b3b5929f82ec552f2002b4113fc9a738e27b0005ac0
-dist/2024-11-27/rustc-beta-x86_64-unknown-linux-musl.tar.xz=d7e2f768922ae36a9eb302667398ee308c13f829c03235682529fce90253813d
-dist/2024-11-27/rustc-beta-x86_64-unknown-netbsd.tar.gz=13f327974170a0423ea6e7241cd3a454ab8c39b657a707c08f2e306a7a657b45
-dist/2024-11-27/rustc-beta-x86_64-unknown-netbsd.tar.xz=5c75388802c0ddcfa51336883f4039b6f7963e0efbe47c209bb455c12951990b
-dist/2024-11-27/rust-std-beta-aarch64-apple-darwin.tar.gz=84c4c02fdecc669c5d26c49120fdece5899133c098f5ef791ea19aba33936dea
-dist/2024-11-27/rust-std-beta-aarch64-apple-darwin.tar.xz=7ea047840073e6ad3123a61ca799bc56c951edbb71cb8495ecbc2029759a0190
-dist/2024-11-27/rust-std-beta-aarch64-apple-ios.tar.gz=dfb8207b4b3bc13a9704fd1d212d92a22a0e7a57293f24f28bcaa846ad4c08b6
-dist/2024-11-27/rust-std-beta-aarch64-apple-ios.tar.xz=96940a84d95b4cfdde84a501758c9dd83f5d6cb5afce9142917d5cb3dd75c040
-dist/2024-11-27/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=4ed66daf59e9a8b61d66caef4b2248be72049282518d7526be771301bee2b905
-dist/2024-11-27/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=013d59e32097917b269c45a837bff380a41c4f6401b0c145264cca5a1bbd91c3
-dist/2024-11-27/rust-std-beta-aarch64-apple-ios-sim.tar.gz=270a0322dd3c2342745faa8797f4f64da8c0028b322385d209ff65cf04965a47
-dist/2024-11-27/rust-std-beta-aarch64-apple-ios-sim.tar.xz=9d54f7f51c99f17ba9cfe7cbe005ddbfe598f8af6df1dfccc9ef37029cc08b41
-dist/2024-11-27/rust-std-beta-aarch64-linux-android.tar.gz=9ae4c1d6044b2c3586791f127108e308e0a381e8e14ecc20b3830ae5258a03c2
-dist/2024-11-27/rust-std-beta-aarch64-linux-android.tar.xz=689225ea098a88a88e8e2269ef53f964405a6c31b3ee2bda0fef98da4ed9178e
-dist/2024-11-27/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=f1d9c996cbe468ca93b15c76b84c544930d7452f1eff2968a298c885203f14cb
-dist/2024-11-27/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=f3f8c088d74c81b2457ddff57008cb908cc86e16d0fac60d10969e45210d88d6
-dist/2024-11-27/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=fb4e5d66911a47bd63429686885cd5c7f0a6310b25622f36bb43a754300526be
-dist/2024-11-27/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=ab6c7d346bfd72f06fbbc198743bda35fcb7fd1e131c05c54935b6ceff282f17
-dist/2024-11-27/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=32b2e0d5161f7d8354d846c91e5cb25530e78351dfcff4ebf0a6fba669e2c483
-dist/2024-11-27/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=656fc4a8af570b28b3f83cd59d4e5226f15d11b5d8c26b58ca2c1b2a4e18c4df
-dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=13c98efcde78c1e187f728509f2950a0a407ba32e730877cb9ca4cbb4ba01469
-dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=6372891715046375fd0a04e80c95bf79080db2d136e187b02ea96647e9281407
-dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=db156e0d5db6f04621e625e92323a04091c049a8b5e2b4f7e0fb2e50b81ab2ec
-dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=b610214bb59b8f58be96b84b0f13e5f50473e21039f6e827fa16c446d0e9ccba
-dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=99f96b0bda31bf21853c96b3618408587f275f46ea9bd7d1fc741e58343a5625
-dist/2024-11-27/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=dfa1f209f546b457aa6ef742a645f00f55c70fde86522c737f7a560494170157
-dist/2024-11-27/rust-std-beta-aarch64-unknown-none.tar.gz=4735b29991a2337a7e2016c5a827635e17ac149372efafc0442a86b0dc0759fb
-dist/2024-11-27/rust-std-beta-aarch64-unknown-none.tar.xz=fead0635c572aa4f5e5564e497f1b7e892217ebe52fea54aedacbefb32f6343d
-dist/2024-11-27/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=bbb9b6fedb874a61d99d22b4cdb2d20d8b9e6c69924922312692aa526851b960
-dist/2024-11-27/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=9e0d48236676dc9947565daf0c2605316c5b4abc06bdb1c343559c46b9c4e304
-dist/2024-11-27/rust-std-beta-aarch64-unknown-uefi.tar.gz=e230ffa3d46dbe5330416cdf8b7235b8dc2cf119ef8990b422eeebd017ebd17f
-dist/2024-11-27/rust-std-beta-aarch64-unknown-uefi.tar.xz=38a5560575740f92cb8664d204924cf7a2972e0f2f396852d8a22befd2cdd848
-dist/2024-11-27/rust-std-beta-arm-linux-androideabi.tar.gz=0b0a9f95d10484207c52fcd8ab1bd56903b53f18ce46fe263d5b7bb085044246
-dist/2024-11-27/rust-std-beta-arm-linux-androideabi.tar.xz=91f7655ab2bce397a0821edc0f523dbf2bac0af39a50ead106eb1de637ec5c44
-dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=e8210f03bc18661954f147dedd0b4af721d005866c0c4fea1e91594cd6c9bc2b
-dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=56a623817e6a600e802727d59d4cd653e84cb628695e39ecb23ae99065113115
-dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=310a408bde58335d8011af480d4f8c38745865772d71631596cef1a79f9f4fc2
-dist/2024-11-27/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=fd6766ea9e828adc2e43ff1654a459785eed05ad00c7f6804c742ff8ae8f6b8a
-dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=e663e30526d85d89f41456a3d5bcd411397cb69e7cb9508aa1472b015963fd18
-dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=0361504ada464a7d21e7ac66fdf9e1e820695f3a8ca4854695e78a748c5c7a18
-dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=c375be97e626900d809390c61bf6f2d689c9fca8e58c85e4e02b694bed4c5ce0
-dist/2024-11-27/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=c33e3b4f9098860f75fcc9a8f86c7e7173692ad4c19cbb2c0de068961f87c192
-dist/2024-11-27/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=3f50d9afd9df4db85958e4575429dd4c80b6702a8d91c3f1d9327345aaadefe0
-dist/2024-11-27/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=0016d3a6ec8351ee9fac2eeae358a0854a3c2b360822bb3ba670255e8f27f57e
-dist/2024-11-27/rust-std-beta-armebv7r-none-eabi.tar.gz=f23117b972ccd21c0a6f4db4b544401045c9f157595a297fb56d7e864cf190fe
-dist/2024-11-27/rust-std-beta-armebv7r-none-eabi.tar.xz=ab9be4bb25b1575af276cbec7fb1a1f8c683741b0f137bca7b4b61ab13575645
-dist/2024-11-27/rust-std-beta-armebv7r-none-eabihf.tar.gz=673561456e26bc992cb6a888c34c0b6b13e1bd0d3e0764360a785a6c3369f0d0
-dist/2024-11-27/rust-std-beta-armebv7r-none-eabihf.tar.xz=29c6f01c636bcd901b88e92c60874c454369efd41f690d74b1fa2adf3450166a
-dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=c214d4439676a19c057324dc736d63aa0328ac74c0eb9ced8d782d8bc89757ae
-dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=4baf85ac632750c35d007bcae8f23720208c5197f4a1d49b0a85b2b0e137f603
-dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=a7e81c0e80f2508c81ba9d8e658dabeb19af2de6f7365f6e377d39e99d8449e7
-dist/2024-11-27/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=3f37f746aaa03107573a3a2b201c15bf86777ec405dc03640e7d3f24f718f67f
-dist/2024-11-27/rust-std-beta-armv7-linux-androideabi.tar.gz=fe7c7ecb8a8e612caf0e7ecf04d18ccaed31d8b93911ded6b3cba0c78fcbbddc
-dist/2024-11-27/rust-std-beta-armv7-linux-androideabi.tar.xz=d571b714821de4b7d2accad221b5e043e7f9aead8dbc06586f4f7ff3f3f3e38e
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=663396f0e4c45bfc041b1a502b64627620f499ca6343664633761c3fb1c2229e
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=4d8c47d74958e3b1058ab721e9c6635774afad0252f251b0c9fe4f0895d0c81e
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=3cba82809bc1204b6e8f62877c5e9f9a08f111da7d439032cc30d55be0e88fd7
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=d525a4dde496e72fd18c6f2a525756d652ced436007f513267e9201d8b1c0a40
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=ec0311a0722f205b117160817b2137e9a73f0f4e540930d61c831ceba1265f0d
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=c63c4a28225dfca26baab129f06d8537fae5710083046f203a2fb73c50b48671
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=52eae1bdf37366bf406cff95e5e7979d0651979ae5ad4c036e8badddc8ec8b82
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=542791fb5cd80fe5515ab0812c9fd8671f083151d4262fc76d26f7723ba961e1
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=91697f75c762bdb51f19348953768a45bc37c389c2e904a56f4f092604ed2d1c
-dist/2024-11-27/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=a79a7a5974b365f70598c413da3db8262d14414e3b4d48dde45f529bca4c6ef8
-dist/2024-11-27/rust-std-beta-armv7a-none-eabi.tar.gz=6eec497ec2aaf6c5beb8e6dfbeaf32190b6f7206aebffb7499b5fdd7e5e7643a
-dist/2024-11-27/rust-std-beta-armv7a-none-eabi.tar.xz=234924a6746fed2efa112b0b805d0ca56252b6cde82e6422774871e9c009fed6
-dist/2024-11-27/rust-std-beta-armv7r-none-eabi.tar.gz=1b0cd107412fae22266267bd8eccd2b39a36afa8936da3888d0bd0d2f4cfdb1c
-dist/2024-11-27/rust-std-beta-armv7r-none-eabi.tar.xz=0d0d1ee48f9032df88ea7b3f73f06300686f4d5b9fc16f1d4554caf8356cfd74
-dist/2024-11-27/rust-std-beta-armv7r-none-eabihf.tar.gz=72f0549de44925bd08286e092261164dac47826124123e3fe707411a3dfa756c
-dist/2024-11-27/rust-std-beta-armv7r-none-eabihf.tar.xz=eb45acd55dd70be3670de83c8cbef5b6ef05827b3f97b7c71679a19c88f8f3e6
-dist/2024-11-27/rust-std-beta-i586-pc-windows-msvc.tar.gz=edd8dadbba618f2a786dfcc68e4a5c7f2b7cf1528d1c16ca6ddbc52622df95c6
-dist/2024-11-27/rust-std-beta-i586-pc-windows-msvc.tar.xz=ae59c5d77b31aeac30c22104abc0abda6b7f725419e9f86db6cae634ededf262
-dist/2024-11-27/rust-std-beta-i586-unknown-linux-gnu.tar.gz=8996c94269e4c60270d253ea75bddb9482facc441ee2314a387888924bea1d92
-dist/2024-11-27/rust-std-beta-i586-unknown-linux-gnu.tar.xz=f6b59e3d6e7f0e458c048ad4aad9a2da23f3b54aeac20a905d2e00379da1bd6a
-dist/2024-11-27/rust-std-beta-i586-unknown-linux-musl.tar.gz=85f22b148be72691214dee620eac582405dc3b8937d2ef7c480c9070b963af3a
-dist/2024-11-27/rust-std-beta-i586-unknown-linux-musl.tar.xz=4b48538541dd20fad8569cb3f0994d5ce6aceaacdd8b319d00b0234cefc5c267
-dist/2024-11-27/rust-std-beta-i686-linux-android.tar.gz=6e5ce19fc4cd8cf4dbaca8b31f4032b08ee413ce20f354186e4945efd4e8b6af
-dist/2024-11-27/rust-std-beta-i686-linux-android.tar.xz=5e78b98abdf2b7348381863052c109beec025a5f68285ce72e6f6e9245c22ce3
-dist/2024-11-27/rust-std-beta-i686-pc-windows-gnu.tar.gz=50057f990d1127e7d693b1c5b9539b19262a478130bed51dbc2837d61d2db6da
-dist/2024-11-27/rust-std-beta-i686-pc-windows-gnu.tar.xz=ea524b276e42a1cb918625df12b8d3397ada5ecd43bb9ad5c676747e1f916c8b
-dist/2024-11-27/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=c7c9093e277187590b86ea02fcd940071c8bce93a894396d73953276ec58eb1d
-dist/2024-11-27/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=a67879ff0dcc591d30a155fd972149953eaac3b139bec9aca3a383dc277ddbc6
-dist/2024-11-27/rust-std-beta-i686-pc-windows-msvc.tar.gz=a086c8272f9c7c0db3d5de37b027478dfc22fc577c613254a821700c645df3c9
-dist/2024-11-27/rust-std-beta-i686-pc-windows-msvc.tar.xz=8ac4b938e0b643e47d6d0ba6e5283887fcc73cb1a825fc065c35879b085d9c28
-dist/2024-11-27/rust-std-beta-i686-unknown-freebsd.tar.gz=3614b95b54ca24c598e3ed6e14aaa86f7048c2a5be2b3e9f97d9ca00f3d890ce
-dist/2024-11-27/rust-std-beta-i686-unknown-freebsd.tar.xz=6d36127f5c113b01300fa0d54062bc1137b51d2514346c8d84bafb9f2c56a972
-dist/2024-11-27/rust-std-beta-i686-unknown-linux-gnu.tar.gz=a6d33a96eeb667f3f4649ea6ccdd6212a183bce85f095ff7db5036c3a50d35a6
-dist/2024-11-27/rust-std-beta-i686-unknown-linux-gnu.tar.xz=bab1dada484d61bb96e2834da5fc6ed5d4d788e6636849e9802f9fb6bff45d55
-dist/2024-11-27/rust-std-beta-i686-unknown-linux-musl.tar.gz=0ac331a1c9e384430a5f316809bffdf01bae3ae9cc1f807f07142ffde7388602
-dist/2024-11-27/rust-std-beta-i686-unknown-linux-musl.tar.xz=136341bbf4c820dfc98e96cee41fa0e9fcbc7d81d2772407efaf1d4be6d10f7f
-dist/2024-11-27/rust-std-beta-i686-unknown-uefi.tar.gz=32f06ca3b2752a8687e2f282a59823671fcec672bffc0775a9fb27da50b6bb11
-dist/2024-11-27/rust-std-beta-i686-unknown-uefi.tar.xz=b2f376089b39a34f3308833ce9bf65200f9665e5c55bbda3e5b7e9c5096b7e67
-dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=a2ca950893c93be71c7db707230b98674a29c013546e27d95bdf8c3c6eebf9a7
-dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=c70b58f4583578347e9f0fa20d17bd5fc51d88717095e05d73091209f2a363be
-dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=ed284c40b6253c022e39718dc2af2e4100ca7e805d35d86aca04937586f26ece
-dist/2024-11-27/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=3efcabf46e0d02505ebf0926c6c14e0c70838f9b510f2328ccd98dd0fa977794
-dist/2024-11-27/rust-std-beta-loongarch64-unknown-none.tar.gz=9b9f8418fdf64fef652f15b28a1a1f2f8c63c18da8b323994f10f921010721ab
-dist/2024-11-27/rust-std-beta-loongarch64-unknown-none.tar.xz=fdc673e4b250424c6dafc18a165ffb592aecd7b897e483af8ca54aa145a0e6a9
-dist/2024-11-27/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=802d22c1c364a58402f9313c6ba2f58b79f3cf3163842a608b78680fa2b3d476
-dist/2024-11-27/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=dc4932d91d8a2887d309dbd6317d6c41afd083043f44742138ca7c97f60b931c
-dist/2024-11-27/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=636b19ca036fc7ddcf358062c98f6bcf31e8c2cd035cbb9dc0a6b96c81217f7c
-dist/2024-11-27/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=31f80fc50be95bf665d21fe52b714532ff34ebfcdc0c975bb68f7d2f2cebd0e0
-dist/2024-11-27/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=f2c83275df652bc5b387525e77a1aa30bac31fb301b304ddd7e6bf402e140c34
-dist/2024-11-27/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=41358bdb20fe3a97a95fd7b656b1ed03d5b8012354d8cfad2437bc9ef6c7aeb6
-dist/2024-11-27/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=49b8f286b4abb3b34bd38c92ea3e15efbd1f623d5efa7bcff10711b595363579
-dist/2024-11-27/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=283f065701c77fa47a2d5413d20fa40989fbbcc75bc938889de6c4f9b6b9e53e
-dist/2024-11-27/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=d0ee5ba5dd6f94dc6ca981be0d55f2e3f51c2af25877131a7a74e0ab9848dc3d
-dist/2024-11-27/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=79c78bb31022ec8e7a3fad9823c5d22ac553d389104844110473d1877d8c8302
-dist/2024-11-27/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=b953686e3034f2b51033a2630328c8eb5f59fdf8ef4e26189bddb8efb4c482cf
-dist/2024-11-27/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=fb25ac2e68594d379f915f0555b3ded2b1a7b5a67144e12eb62949f540b0d957
-dist/2024-11-27/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=fbf5a16a57de3a7e846389aebe18bc7871f43e67eff39fc9b4744b5a445b2639
-dist/2024-11-27/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=55a92aa5770924a21b706724c15f58d66ef2ca5b630f7025f6ba1416152ef350
-dist/2024-11-27/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=b880b7209ea604761ad2a46832925d32fc547737b879645fd3cf99ec235e7b39
-dist/2024-11-27/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=c48cc6a6fda06fab014c0b8fef49006dd32fb71f8e981ba44a0c25d47fbfe034
-dist/2024-11-27/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=7d133b6c8d0e8b8ec8b65a74ed8d64a22e2fa5e4f6d4a1e36f9e0ebb8826f40e
-dist/2024-11-27/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=1c507e003c38115bfffe8701df1ff7aed6ad16ef5ac4b383f84bd2d6aa0216bd
-dist/2024-11-27/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=111a909b3d1a04b328ca1c1f247ee4eaaa84349eeaa8df77f7901bbc0efc94c1
-dist/2024-11-27/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=d29f92ed071c60259feaa8005eb5392da549f8e2069fecb1b77e112f89cf1bbc
-dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=241b1ec9ef6a89277944c9d8021f521284dc28822c5f80513b6cd94d2bdd1d64
-dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=9f5b02be846fa2084becc5616f024094d47beca102442ac7a0e3588e0f12ee7e
-dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=7272eae1625415c0f57bf541dd62c14e02b9946ca1de04615827a1f5218c2181
-dist/2024-11-27/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=d4bcd0068d3c9e7351565fec57ca68d36c9ddbfe59249a6bd2c56930ebad2257
-dist/2024-11-27/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=758ccc47004398add2e3cfef52e4839e14dc4d132a215658e576e590401a28ca
-dist/2024-11-27/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=6902fee1027b0136f8dc5179e69e24ed9e34366e9409129b9ba223043ddadea1
-dist/2024-11-27/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=3024570f3e382a57fce0e832c52d080a83d42206d8412b724361bd1f0087ec4d
-dist/2024-11-27/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=20eaa72b6fa32b9884b43030a0bee554bafa9de3f3b51c5768ba0ff47ec492c1
-dist/2024-11-27/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=a3eae70be3fa5b0a56cc88cc6433cdb7c42b3b974caf0d879d21a5219f4f826e
-dist/2024-11-27/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=1da88d1882d4dd1f15ca97e016f392a01b56951882ae75929023e83fa557d796
-dist/2024-11-27/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=387cc8ccaeed6f9c6a8c9d21004e45ac97a9739643a63448eb893e13ed4df22d
-dist/2024-11-27/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=1b9afe3631fb7847b2a8a8f483fc00ca203ccc18ae298339801dab1c7b06b3b3
-dist/2024-11-27/rust-std-beta-sparcv9-sun-solaris.tar.gz=f9a4d2115d6fce06e0da7a9f579b197d383034c218573e145b3c7dae0aad21d4
-dist/2024-11-27/rust-std-beta-sparcv9-sun-solaris.tar.xz=c352bc631e538d4e68eaaccdfb9dca1c9dc8ff0ef4a75d8ee91016aada39d717
-dist/2024-11-27/rust-std-beta-thumbv6m-none-eabi.tar.gz=d97851ca9193d98192a55aeaf695973ac706e6ba3e198643c200cf410817b424
-dist/2024-11-27/rust-std-beta-thumbv6m-none-eabi.tar.xz=89a6524a3743e5a769a583b4a6bf8a76ef5b45c67b7e39da7ae24b687bed4943
-dist/2024-11-27/rust-std-beta-thumbv7em-none-eabi.tar.gz=6fe614db166618a8f2ccb5807e02884daa8bd8dfded2164f88d79fc688047020
-dist/2024-11-27/rust-std-beta-thumbv7em-none-eabi.tar.xz=91c5e4f4575ab004119797988679077e5057881ad9a7f6790b673dd062a8b7ee
-dist/2024-11-27/rust-std-beta-thumbv7em-none-eabihf.tar.gz=d0e05467fb1562ed7d6687a50b7fafa14ba0c2aad328f0e7c19eaca1ee366475
-dist/2024-11-27/rust-std-beta-thumbv7em-none-eabihf.tar.xz=0473372df5fece49e58efcd3b2a702bb93e47ec149b38fd5244ad667804e7c63
-dist/2024-11-27/rust-std-beta-thumbv7m-none-eabi.tar.gz=e6b6130a1a571325cc1bda8ddba6b2672104c2feeed5c93c6022bfcc8ba4b247
-dist/2024-11-27/rust-std-beta-thumbv7m-none-eabi.tar.xz=d4c739c42104e04aba55b96a3ad434e11b013ba44649dd3a648cfbb15de83eb9
-dist/2024-11-27/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=e427d5d6a53abfb53b436df96457d58eedc648198fce6b1d976b50de18cbc31a
-dist/2024-11-27/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=11142018c11849c21adaa7096abf50d0c923f3b8f07d67eb96d6860d428e9b27
-dist/2024-11-27/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=46596d8f2271dd5a6f0f84387ac19d0e81976adfc6050b6aab6cc554102fe469
-dist/2024-11-27/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=f3d0c9db1c50a018540278433fed2e0ae4bc798aa0dac87cf0f55ad1808618a1
-dist/2024-11-27/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=c46fc4bf174fc54f5565fa04e80efff4e853642e3e5f0bf5b696a2bd6e7ae817
-dist/2024-11-27/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=706c10ef22cc16b3d4cab8fc09d8783384313b9f774229470b8ae1dd292850b2
-dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=b9cec80ed374f7b5f22f1446e3f2e0dacfaa0e2d4d6c631ad66cc42a23e156f7
-dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=41c67ee95e72a3d10bdf739c4841bd937c4e0b19c33451724c1f603b4bd2a318
-dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=5ad8603f98cff0d5d015c72f3a55730d75d59680a867c067928bf4586c00d805
-dist/2024-11-27/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=61a75701f7e000f86f318a04dc6746f029fb933e0ea94944d76c7eefca1f24b2
-dist/2024-11-27/rust-std-beta-wasm32-unknown-emscripten.tar.gz=89bfbfea23974ed75a53ff134386992e9c257d3e51a55eb49847aec9c5ba6b13
-dist/2024-11-27/rust-std-beta-wasm32-unknown-emscripten.tar.xz=e34d1586bc6767b4b244f98754badda706645fdec7168ddc0a409b9f95f2b18d
-dist/2024-11-27/rust-std-beta-wasm32-unknown-unknown.tar.gz=8a88bb923e138d0015c8f46bc1c3d5f2f5f75f40dddfca72a49eed42c080d1db
-dist/2024-11-27/rust-std-beta-wasm32-unknown-unknown.tar.xz=79a980f2b999c3e3b04d7e327bd2b548007039b45da705847c6da2bfec3ffc04
-dist/2024-11-27/rust-std-beta-wasm32-wasip1.tar.gz=454e2c4b46b4684e591c6e4c0f1ce8e3c44623a29d561be3a481ae008072dbd5
-dist/2024-11-27/rust-std-beta-wasm32-wasip1.tar.xz=4dcf652ab51fe03c4691de46365218dc483cf1f7c2f5a552a38509685a0ca873
-dist/2024-11-27/rust-std-beta-wasm32-wasip1-threads.tar.gz=c2c34d9b3998633cfa145dc2a5568a99d1fe26b91c5be55a08870a1d27db4af7
-dist/2024-11-27/rust-std-beta-wasm32-wasip1-threads.tar.xz=4d5b25e4b5fb71d879f15f320f7513eec1ad078d3ca6f525ebf56b9620bdb5ad
-dist/2024-11-27/rust-std-beta-wasm32-wasip2.tar.gz=e1385a340d3d9a4003cc456156bfbb1435a5255b2bdae3a40b6d7339768bdc81
-dist/2024-11-27/rust-std-beta-wasm32-wasip2.tar.xz=245e7914174d213ddbb550b09fff200f419bcd632de98548a470013891666410
-dist/2024-11-27/rust-std-beta-wasm32v1-none.tar.gz=d5d924ea001f914bf87df8765b013db6e838a930a4865e95f8d35bfaa86bc81e
-dist/2024-11-27/rust-std-beta-wasm32v1-none.tar.xz=bb98d0d55f38f2308bf99d4e5f11842683452571075eefa5b4e1f18f2bd553bf
-dist/2024-11-27/rust-std-beta-x86_64-apple-darwin.tar.gz=edd5e7ea230a13be750dd74c5f7a7dee20db8683f7978aeb352307a0ce110b9d
-dist/2024-11-27/rust-std-beta-x86_64-apple-darwin.tar.xz=c6cec9a501d9873e3c7abdefd5b9418f7250c8cb915be8b816cb48dedf1f201e
-dist/2024-11-27/rust-std-beta-x86_64-apple-ios.tar.gz=e970c2a4ebfb69219dc66e4c7541cf22c52da5f94983c7c914df1f93beda3d31
-dist/2024-11-27/rust-std-beta-x86_64-apple-ios.tar.xz=594ae9bf5f1501322d986dc91249a48a61c22371513b872fd63e134097ac55ca
-dist/2024-11-27/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=d57bf579b4629417dbe1c02506db4a4ba4428871a2684141d21303e6c99551f5
-dist/2024-11-27/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=714db83e7563a5f286fb37bc629b64834a9ed981bb9a05931122072f95e39bf8
-dist/2024-11-27/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=feafcba9c46ba3e5fa0bd9b5bedc05ef3423c9962dc4d25a7b2367e3e1caa679
-dist/2024-11-27/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=78fbc8f45df64dca21da7223b5d081111922f2268fcc4f1f83595d159d310bce
-dist/2024-11-27/rust-std-beta-x86_64-linux-android.tar.gz=74fb57da7f2907afbaa2a7a73847273ef81e2d6902a326f1ae87767677a864d3
-dist/2024-11-27/rust-std-beta-x86_64-linux-android.tar.xz=3216eb73d9c9effcd2a2de7f63d78055c3d7e50fb8141e2910a45a36ce744ffb
-dist/2024-11-27/rust-std-beta-x86_64-pc-solaris.tar.gz=3df431c8941ac28906c3a6568d3debe478d9349d868ea8bd3ad79e65792c20e8
-dist/2024-11-27/rust-std-beta-x86_64-pc-solaris.tar.xz=548c2a6104148bf0da21bf5e009b80522fd15539077a62021a64f16282815a5e
-dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=235228431d67feb4c8e6aad44e20bf68574f335e8f948808b597ae98d827171d
-dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=5a2d4ed70aed26f902cf45e1dcabc5f25884cf6e9aaff775405ba9c1f0a5cacd
-dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=818131158e8be6af4b762750f7927c4a799346c94059a6073230da79b4408720
-dist/2024-11-27/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=fc08b39833e2c9319dcb55cef5c6d1f0110aea794c9a6f163ca39749a22a94b9
-dist/2024-11-27/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=6164c3ade38c03113193301b815c52df0ee84a4ca1c8ef21e1a56d386e28df00
-dist/2024-11-27/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=0846126e6c4cf2b5184979b6025fbb7bddb5c22905bc7ba31fff69f6b1459280
-dist/2024-11-27/rust-std-beta-x86_64-unknown-freebsd.tar.gz=ae308e29be13a176b26c142347a81facf8c11ef1a28e67d5898f4f2a0d3344ca
-dist/2024-11-27/rust-std-beta-x86_64-unknown-freebsd.tar.xz=e80bcba8b011a4dd3f7b2a2cea69b5a95ae2cde9b2d9078ac8fdd492ac162139
-dist/2024-11-27/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=b25f0d605b7f4a2a93adb746e32f59bfc26af569a4169e9fb203cb33751d1575
-dist/2024-11-27/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=010f35236062a651b1b54d7c928068efca8dc486856b84b04e98f4f97583bf32
-dist/2024-11-27/rust-std-beta-x86_64-unknown-illumos.tar.gz=db3d258c2caea73b469feb9c11fbd3bcc29d22c3969c406321d11f05c24974ed
-dist/2024-11-27/rust-std-beta-x86_64-unknown-illumos.tar.xz=a952b0c2bbed9085525c041c957f00b6b1020e031149dba70c09a1a0d40db3ad
-dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=817d3d3a931eba2255bd5721435cba7604fe37a72c18a179c1fd5f06dc3b97a1
-dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=170a54aa50f161576d4b0d103f2ab6dcbbb81ee57a5a47f7fbd181128f6c17ff
-dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=ea991dce55415ed7462abbeb1ac1c70795cb628b0460e14230e8cecd41117fca
-dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=a8f620c3a641f8f4c29d88e4cc54d7637aeb18cf8eaed8571ce558835f742601
-dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=875e2e3309b1deccc1a4476e4847a2849df32e0e2a394e4ddf3b4abd1feca534
-dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=23f21ac664b3341771109ac69d094518a512391b86219ffec50725dc68a08504
-dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=680f5b2c63f58643bd34f9921e2c1699a549410ab06bfd04ce991907e8fd7d8f
-dist/2024-11-27/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=dd10f6f3ce39489b6e3f3f638573e850c36518e3b2e8ffad0c50c3143e3a8124
-dist/2024-11-27/rust-std-beta-x86_64-unknown-netbsd.tar.gz=fd31ba490f0bfc53530e34e6e5ab35a52eebee616efc8ed18d473065ea885230
-dist/2024-11-27/rust-std-beta-x86_64-unknown-netbsd.tar.xz=daffc01050f5cf0b5ece91717d7a4c42cd4a148c4c11f641b494d9c375df5177
-dist/2024-11-27/rust-std-beta-x86_64-unknown-none.tar.gz=376d571641a9f1f75fadf951da91bb73ba94a5495d7d33389f5f914ccbec57bb
-dist/2024-11-27/rust-std-beta-x86_64-unknown-none.tar.xz=ffd9e826537dc94c6d8e767ef5a61d1fcf0385b8ccbe508ff9177de0fe772939
-dist/2024-11-27/rust-std-beta-x86_64-unknown-redox.tar.gz=447e434b5e40f7882d7adb6d0346629e0e3e92d0f339c7781e5a437898a84b4a
-dist/2024-11-27/rust-std-beta-x86_64-unknown-redox.tar.xz=bc21caabcb492ca648e19a8f3b9dc1a1bf7792135a202831deb554ec3ea11077
-dist/2024-11-27/rust-std-beta-x86_64-unknown-uefi.tar.gz=40ca7d9ebcf6610c26f2921c0560729e708f5661bf6167266e9d8cb3987ad0b3
-dist/2024-11-27/rust-std-beta-x86_64-unknown-uefi.tar.xz=06966d5901f5d9accadb47c4d1e561f3f95bd050f3f8e78f30000389f39e9b6c
-dist/2024-11-27/cargo-beta-aarch64-apple-darwin.tar.gz=e1a24f081ddd93b483c0f1c196bae676163db50fef0a994bc47c2a7c98c9dfa7
-dist/2024-11-27/cargo-beta-aarch64-apple-darwin.tar.xz=d51a5f0669906eceeee4e09b079828e2ebf3404aaedf1fb20745339205270ee0
-dist/2024-11-27/cargo-beta-aarch64-pc-windows-msvc.tar.gz=e135a5f0f83432b58d9e093c6d560b021a133707e39e1ded90a28a9967105e0f
-dist/2024-11-27/cargo-beta-aarch64-pc-windows-msvc.tar.xz=1fbe65015cb8c7ab0b863ffc6f7aa72d3bf52f7830957ede8915c61a22e5b993
-dist/2024-11-27/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=9d4e830e9ba582302865fcefe31883cef4a471e77d46e70838e549ca11a0fbce
-dist/2024-11-27/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=233f6347a36e806dcf27ecad4906c90bb3353051f440a819989efcf091cb78b8
-dist/2024-11-27/cargo-beta-aarch64-unknown-linux-musl.tar.gz=6cd719a7255a0eb1f11592b9a92d0aa4986363f624ee0d6077fcc253acab66a8
-dist/2024-11-27/cargo-beta-aarch64-unknown-linux-musl.tar.xz=b874ca8285ad1936adc70a9323cf80f06322b1e6d5925f54b58500129830f0ca
-dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=ec7200319224ccabe814cb051e51d147f1ae8c763413002fd03c9263a02c2320
-dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=86e96c80a91862e59123272c80f1cfabdca56bfddcd66af4a5e840af7421c4e1
-dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=3f7cfdcb28fe8c3f0dde58c24a0c424652b40d00a24fc50891351fa5bff5c15e
-dist/2024-11-27/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=2d5a184b0103ac943ec4f6756fbc7126773e739e0d120acea7b3244c7cd19b1b
-dist/2024-11-27/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=9a77540943f28584d90b4bcae4e234cc9d833eb732f65d7fbd680a0f4e915da4
-dist/2024-11-27/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=7696a065951b7d7179b30ff2fd16a05675b6bd4250f293666b98ec05299113a5
-dist/2024-11-27/cargo-beta-i686-pc-windows-gnu.tar.gz=eaff75076ad71a4291af5465dedf0fb0998dc171e35ab8f707ac63b43e89c38a
-dist/2024-11-27/cargo-beta-i686-pc-windows-gnu.tar.xz=205d3d19726a1a87a1533d94f77b73ed9de8181906acb48088dca22835aa7a83
-dist/2024-11-27/cargo-beta-i686-pc-windows-msvc.tar.gz=58da319889533ff7be5c9142c2abdd1ade79de10eb83d7ef82ebd93b75607f8b
-dist/2024-11-27/cargo-beta-i686-pc-windows-msvc.tar.xz=5ae699d0f6b9e210a988af5b8f2f0c4d62fb1695ed6fa55718fdf05298039b9c
-dist/2024-11-27/cargo-beta-i686-unknown-linux-gnu.tar.gz=362f6338ea929ceb632307031e049dee1b3ed998f5cf160654c327c5e0e7ed39
-dist/2024-11-27/cargo-beta-i686-unknown-linux-gnu.tar.xz=88f14ca7b5c8af006f3c54749b61747485f7e93fde4c65b5969e73503d12c5c2
-dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=9ee8f29e3e715cd7c85e679fd01ca724a27503a50edb0e6f8912f289630bc7a5
-dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=4c643f0d18ba101c2b248e1df32ec3ddba82efc0d5f9b47945d484fd3d462794
-dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=f70952c63e2eebd05acc326cfa667595535fc36db34bc0262fda4ba100ff2145
-dist/2024-11-27/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=0546a908cc12884801c35b461f98db01e87a7f92d276ca6cb6b89eb76c596e2c
-dist/2024-11-27/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=3534e839b34603e4e2b32fb8ecc76163ea3b9cd9907c1a22fde4165860d1fb56
-dist/2024-11-27/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=b402a2e73debd81dc5cbc866f00c2ca82f676e2f923193674969af0ab34ad311
-dist/2024-11-27/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=fa69011557fdde5af1f78f33f9ba75a1d6f4488b9d8edd2958582593dba347fe
-dist/2024-11-27/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=679be0bf62c7371b92f1824c8718662672ac3ef2d79e8af5c752fe34effbe333
-dist/2024-11-27/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=ecc2ba0da5c1057136eb105ec0727e55396e414d75efe0c2b96bef0477961574
-dist/2024-11-27/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=a89ad44842df861c69c6633ba79bf4ecefc38419d5669b6f22a265dd7be836f2
-dist/2024-11-27/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=051437ff7d177bdeb7a5a0eb947d27b8cf352c8e809b9311a1cc21b785a5a8b5
-dist/2024-11-27/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=1a4f50972104a95c404e778279a4acd42176cae45f58d316d601e7f38dc7bbc0
-dist/2024-11-27/cargo-beta-s390x-unknown-linux-gnu.tar.gz=bbe9812fe890b900e71aa4714dabd2f3e67bdc610fe0bbd5aea645ee807dd0ff
-dist/2024-11-27/cargo-beta-s390x-unknown-linux-gnu.tar.xz=eebac7e8555f44ea9094750b61bd11d758197a72d4d436e1713e4bca42fa8080
-dist/2024-11-27/cargo-beta-x86_64-apple-darwin.tar.gz=6773b94f012a3d3589e2bca28f35dd23208fb245f107e4a17b8b3e7f893c038a
-dist/2024-11-27/cargo-beta-x86_64-apple-darwin.tar.xz=d3a20dbd60545b0162dc06499317e342bea077cff369e053eb89e85e2b640188
-dist/2024-11-27/cargo-beta-x86_64-pc-windows-gnu.tar.gz=39e16c97c0b22533dfa674d6e8f5bf5df256e2b426d02dca5ed33e246f18d05b
-dist/2024-11-27/cargo-beta-x86_64-pc-windows-gnu.tar.xz=ffd939f901c64a17c3f24fc69744cd2af1c176a45d8e5fa8209067ada403db7d
-dist/2024-11-27/cargo-beta-x86_64-pc-windows-msvc.tar.gz=8addc12e74a983f3166b89d1d53ce87c92f38c7c3a62ec7c66580aa424d20516
-dist/2024-11-27/cargo-beta-x86_64-pc-windows-msvc.tar.xz=8e5622917395ff50e53b237e7322f1faf2b64f0446c41ccaa0096e57a3e7de69
-dist/2024-11-27/cargo-beta-x86_64-unknown-freebsd.tar.gz=2734d099aa1ada79346213aec8cc7ebe40312df1dfb40a32d09ccd3b6622e025
-dist/2024-11-27/cargo-beta-x86_64-unknown-freebsd.tar.xz=642edcaf16dd74c0935d28ce9b37cf1c5ecb9c03bec30f6ff0e7476760ae7ca2
-dist/2024-11-27/cargo-beta-x86_64-unknown-illumos.tar.gz=4f28de38005de48db7126dcb698b748063341de41dc71175605301837a3f7336
-dist/2024-11-27/cargo-beta-x86_64-unknown-illumos.tar.xz=ce18692f99780ec09d01816277ee4e71785bdfbd7abb4375ba8d87c1b6905ffa
-dist/2024-11-27/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=f1d692c3a1c280f34de167ef26af3c13a6d0a3b5ae4fb86b0a9f2178c3287a94
-dist/2024-11-27/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=21f477af2b49ec8809bf8bc7b4c4919c7d2ac57782b829f5a0d9ef1967c5d71a
-dist/2024-11-27/cargo-beta-x86_64-unknown-linux-musl.tar.gz=4bed61be221c1347b1649f54222b27e2a3577b84816ce1099c9f0f461c6e9e5a
-dist/2024-11-27/cargo-beta-x86_64-unknown-linux-musl.tar.xz=33f463209d50ca6b04a8953c87d2177a84d1729d635de9a7c9b1a711ccb5d751
-dist/2024-11-27/cargo-beta-x86_64-unknown-netbsd.tar.gz=ce46b5b2d767cc0d790d8fd21052ecfb787dffb4218a238a339fe5f1afd26d6f
-dist/2024-11-27/cargo-beta-x86_64-unknown-netbsd.tar.xz=0afd0489cb4231edc5bc1ef24a43c3f1918f681f08c1207d184fefdb46416509
-dist/2024-11-27/clippy-beta-aarch64-apple-darwin.tar.gz=6e5f1a85dad2b899567369aceac0102943ab807dad7e218c273b7b4d6393dba7
-dist/2024-11-27/clippy-beta-aarch64-apple-darwin.tar.xz=f784ac4a6ab180675396adf8256ac2bf2d1e823bef106d1c6c59911a8360692c
-dist/2024-11-27/clippy-beta-aarch64-pc-windows-msvc.tar.gz=22f1e9299a24aebaf9a32471ddc6cdbf856b455d059ca077170aecf5989f8772
-dist/2024-11-27/clippy-beta-aarch64-pc-windows-msvc.tar.xz=7f3fd047ed5aa85ea6ca2b0d6103f7530d7d070c93b0f212c9d1a6491f160cbc
-dist/2024-11-27/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=f383ecb5cd654268f00be1f577572993c38e7386a1e1d18b864338e87c7b2b42
-dist/2024-11-27/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=b2043facf587f98a8f10a92ae129b7f608297709f4ac61d683b7c813cc65e41e
-dist/2024-11-27/clippy-beta-aarch64-unknown-linux-musl.tar.gz=6678d45195bd2a7b27ed2d4bad3790e6b63e376da71d112b9333760ea375c40f
-dist/2024-11-27/clippy-beta-aarch64-unknown-linux-musl.tar.xz=f6c77e80c9ea4e312fc2715a9f66ea9a2e6344e3f04ab96cc572e4c0e8c915db
-dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=be8c0dfde3f09bf476d6600b530aa498b01415015665429bebed8814c7568b73
-dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=4315f7623dcf0a278cccb6c8b397a29f83f70ecb9b03588f61e383e5ebaa697d
-dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=c31ff694c68f28e0f462133e783a5d732cf9c539737fc8dbbfd01a53e9a456c3
-dist/2024-11-27/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=2553ae5596b8273d8a61ec66d2e20d0c9733c9f791ca5c56217c60884f0ccf9a
-dist/2024-11-27/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=1842cf2c26ab474df47e74720c56997e270b37609f840ac50ab0b05064cb38fb
-dist/2024-11-27/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=e882b1cc2814e3c97c33991fa0a80de62556ce8f4f88307f6338a90be32b045b
-dist/2024-11-27/clippy-beta-i686-pc-windows-gnu.tar.gz=7c6e08b841f21e3b8953e51a6a9fd9df0c719e8defd7b1ab0660d8920fe72185
-dist/2024-11-27/clippy-beta-i686-pc-windows-gnu.tar.xz=137aec194877446fec994a233427db419bb4f2910151c456c3ec80d9329628e7
-dist/2024-11-27/clippy-beta-i686-pc-windows-msvc.tar.gz=52ba38277ac3f80d124fdc8dd1709b8c1115cecfc53fae4731da8615a63f78cb
-dist/2024-11-27/clippy-beta-i686-pc-windows-msvc.tar.xz=548d3eb599334ab98791b8ba27decff8b0de98dfcffadc994ad38aad6255cff5
-dist/2024-11-27/clippy-beta-i686-unknown-linux-gnu.tar.gz=448071394d5e647e8da8f64cfbf85e8305d85ff9357dd24737523c95eb339ab3
-dist/2024-11-27/clippy-beta-i686-unknown-linux-gnu.tar.xz=e25daa6264cf5e0a7cbcfd827e27a8e276c29c88c86cc15977c1a1650d0303f9
-dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=9f080cc937e7209ad83fdb8bf4b2cd7b080af83dbd9061229f154785e273bfec
-dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=7d537f66195c581ff51ce8f53c4687a762daf225c7f0ce76393953ab04b804e1
-dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=2bd38261a9ef33ad687b3edcd33f283c32a493a80b56dbefc822c1116edb1f2f
-dist/2024-11-27/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=7e63dff1d8abe517aefeb4b1976932d23a9a7ed5e4db2398d8ba2659301f639c
-dist/2024-11-27/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=1495b2a49cfce014da72beb691e6c477d189ef34080acb1761b588d11b75d27a
-dist/2024-11-27/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=75da94f1ade2ef48674b77ded595c69ee715f62f9d9dd96e72039e27807b7314
-dist/2024-11-27/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=2d6b826fb4d3d9b61ecd3aaffdd1334f766dd5a5fb0d8279e0de26d381c5cbdc
-dist/2024-11-27/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=f5ceaca2651d6002f232f71809458ad912bb5f00030790e907ff7b0e12c9e0c1
-dist/2024-11-27/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=1a62f307197c6fd08fbeabef89f58842cfd59c6d62f530850592fe55852d61f7
-dist/2024-11-27/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=4c65fd6a5d74527391fbc7c242a2313e5290209f5a15763d74eeaa6cba0a0ed0
-dist/2024-11-27/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=8ab9f735a98de1949e65d51c3050b29ceba3ddc28167ba0180353253dc726392
-dist/2024-11-27/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=0367eb23a9349ebd829d59fe0a2638557c8e57205e48f66a701b238461385bf2
-dist/2024-11-27/clippy-beta-s390x-unknown-linux-gnu.tar.gz=ffe9100ec6b81b081d5f9d840bdf01c658790d7e6bc0674e5ebb6b28f79c2f7f
-dist/2024-11-27/clippy-beta-s390x-unknown-linux-gnu.tar.xz=b19b1b28bb7ddf8cf977f102acb623f65d5117c44ab8b62cf197f2d3d33c15de
-dist/2024-11-27/clippy-beta-x86_64-apple-darwin.tar.gz=d986de5c01bde3469693dea7cb4248155ee9791550aa179d601066d27e45afb1
-dist/2024-11-27/clippy-beta-x86_64-apple-darwin.tar.xz=8000e46ccc2598fdb770c69c68aeb18d94db9b2847d0509f7a9c51ef28714ba7
-dist/2024-11-27/clippy-beta-x86_64-pc-windows-gnu.tar.gz=c701581f28d885889ae5c845a7b34beebb04a4631c2740e9333b69390cfaf499
-dist/2024-11-27/clippy-beta-x86_64-pc-windows-gnu.tar.xz=fc285792e6f626e133edede613a9a9a90ee12191765e2f0beac642a3b3c9ca12
-dist/2024-11-27/clippy-beta-x86_64-pc-windows-msvc.tar.gz=91afdb71bdd54e5c04fc7c933dac06d5e769627e886e20eb712524e852a01966
-dist/2024-11-27/clippy-beta-x86_64-pc-windows-msvc.tar.xz=2ef7018c7319e3a299c5eddf36748d9d293ae43eaf54662d9855fd211eb4658c
-dist/2024-11-27/clippy-beta-x86_64-unknown-freebsd.tar.gz=02234d4c47478112e01d51bc7dd48cd467293e1eeba55bd383d08bc7376c471d
-dist/2024-11-27/clippy-beta-x86_64-unknown-freebsd.tar.xz=a3e6a0c7f31278866d97816c5ed434b1987e0bc5a89b24283e836402803c1388
-dist/2024-11-27/clippy-beta-x86_64-unknown-illumos.tar.gz=b238ab536ac963929884da4dc9bab43679e6fa9aba4251c73ab7e5cbe5d8eeb9
-dist/2024-11-27/clippy-beta-x86_64-unknown-illumos.tar.xz=797ea7a7643a8302e45347f21c4dc6bdee617c2a9d9ccef74ed525c7d2e9dd91
-dist/2024-11-27/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=d630a6b25a08af85d3d426e73d3231e018e0ab7176a5934572786147fbbf3823
-dist/2024-11-27/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=d0259a0112f452ee49b8c9bebd760ab8945e5bc3a0d57b1cdc2b8e24accd35c7
-dist/2024-11-27/clippy-beta-x86_64-unknown-linux-musl.tar.gz=5febe478e5040f0f74a14c23e78eed21b080900d875d6b447354945c07677a6f
-dist/2024-11-27/clippy-beta-x86_64-unknown-linux-musl.tar.xz=552c35bbe76a83439e66cf9ccd522d97e43a8fe4f6aadbabd1f02c4b2c1814dd
-dist/2024-11-27/clippy-beta-x86_64-unknown-netbsd.tar.gz=ff6db2d7b84e1b01c81e494de15ccd07f60fef6dc60fa46d47e128ebaba4022c
-dist/2024-11-27/clippy-beta-x86_64-unknown-netbsd.tar.xz=b27f89b175bee3769dab1c2d0c54f17ff3efba2038f3b600f4077435c7fd21d3
-dist/2024-11-27/rustfmt-nightly-aarch64-apple-darwin.tar.gz=5b5015483d0a98e9dc715c3cc8c23598c02fc14ea6e5878790ae68f2f1c8ef46
-dist/2024-11-27/rustfmt-nightly-aarch64-apple-darwin.tar.xz=ce5706f0397a1b2fd9e17dbf34ccfbc3e8c87cc81c92b54b81fd33accc2b7c06
-dist/2024-11-27/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=3f5077c8743b5c4f233da7d0aa0aa13fc488ef0fa9da24b002bfa413d52dc845
-dist/2024-11-27/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=087eb30f24ba7d8ee42e28bce2a6cd75e5fb7ef5dca8a738ef23fac82ad59566
-dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=28a716ef9c5318543559ab4c0c2d062b0deeab1ecec80d5d83ad5effb574f209
-dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=99cf9ec4b7bea4281f64a613784350a8ac34e9b0387fed7eb26d6f8c21c83735
-dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=a23c3de89603bd4d1035a267e6ee456c6de12efa4029d76ded3edf7c69285a15
-dist/2024-11-27/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=462dfd28b631b5a6d8277920cfa8037d8583cbf6a2e5c9159c492161013e820a
-dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=44af5b13726cab40865580df8bc05182a2359eae64e41a92f84790ef55ca6bdb
-dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=0a7c0b207e745d01194d96f0fbe2402273d630d4f1aa05001a5f5371c9585a2c
-dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=66e2fc688b8f746d15c0dce042f2a94e06c5b652d5e0b6534d9e992eec186784
-dist/2024-11-27/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=15a2e087f7b482fa8c027fe6e6fbaf846d784c8e917fed375048a297d5e13c45
-dist/2024-11-27/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=71788ea2544f8349ec548a2f150dca2afe80a49deb91c00c46484a5e3039742d
-dist/2024-11-27/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d9fa7b780b9d8b93549abf0a3f0e6f31cc8e1e991ddf682adf3b616fe2a1f0c8
-dist/2024-11-27/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=30924bad51ffa62f762d4c000f86ea3457b590f6397d65755c711ff7f77ac129
-dist/2024-11-27/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=14fff13942e6a65927776c49013249b2e75aa3a630667ecf49c9ba721e47bcb4
-dist/2024-11-27/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=02d82688bdf3bd3c261a4a6d4acfb07835e29ce262cdc3165ba849a6a8490bcc
-dist/2024-11-27/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=2a19b55bb609542ec49dea87e3b67532e5d18df8be43d0ad775bb34f4f9f96a0
-dist/2024-11-27/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=d07ca0ddfb0dd89a9cc935b2b9662379bcc9503cb28a28d68c5165f787a7d762
-dist/2024-11-27/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=de8106801b1e49dfd8a4fffbfc2a4f949218eaa011ca2085953ebf2a5ea9b141
-dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=309024f86e80a4568721b5bb61aa936e027accc251fa97acd5043b513b325576
-dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=55bf234aa2ec7fd4c6a7179f779d790e7f62969967519bacfeae84db5cd29abe
-dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=4bf9571182e7ef40e76c7e5905fab8ac35269ace390f5007480b4951f80cfa3b
-dist/2024-11-27/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=2a2cde80fcbf68768ba7a99cb059a0cdc9313ad0c934383dde9598d6147ef756
-dist/2024-11-27/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=b747fb16b15cff3f9368ce1a1f5cad0d2930bde5a609547a3afa2679d7ab8a1a
-dist/2024-11-27/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=b861f8361ee806d83f38afbbbf312e0e5e4d8851e7048444c409de1a83484446
-dist/2024-11-27/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=ebe56700ad0948e4dcd9930730f7df8e01a5eefca1d1157fe12160d782e2a5c0
-dist/2024-11-27/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=5081c9b8677314464d8a3a50220809def18badb2269d2cd8b7106f3547b0e25a
-dist/2024-11-27/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=2ed9094b538b6450371311b742f2d309a1f40b2b4c84deb9867059336b76d1b0
-dist/2024-11-27/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=d9d52d9b9f4da7a457d05dd4645885d092f170bd2f751a49b4ab3b88395a5248
-dist/2024-11-27/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=a2e51d381645c6bf18502ca72fe9f10ffd309281dae87ec16c5627f232f77e50
-dist/2024-11-27/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=c526efc054c33a08626b882eebadf887a9aaf8fd60a4adf6a146659a7c1ec8d7
-dist/2024-11-27/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=04e5b7c97b57ff7d967abb4f98374f0833108c04f6edf482b8b3fefbde340956
-dist/2024-11-27/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=1829afdebce1c3fe249f81958de68c765db18b431927e54fc42be37ea4ab8226
-dist/2024-11-27/rustfmt-nightly-x86_64-apple-darwin.tar.gz=d6cf138d02e50168f8ee4a89abb2a4a39e19458d060d7b46cf227bba1fd4c0d8
-dist/2024-11-27/rustfmt-nightly-x86_64-apple-darwin.tar.xz=e8185262c82c064c4bb9ae6f1d3072819410de9cfca943b77605012a546c254e
-dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=64d78f9f05a978b95b9e22a63bbb31dcf98152df5638f498a361a96d9d2b0c04
-dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=c07041ab84364ace58a357c18b5c4dca037852e1159edabb02f4579ac6853b4a
-dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=7ef0122ccd3a0c77c917bd75e93358eb95d7e87d78a165c724e3f0cd90f8209c
-dist/2024-11-27/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=d0d0566a0a50e1e9e7f4251cf207bde82d96c27016f0a0acc364754561ab4881
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=e4854528c31316894339bfa97b07ec607e8956877c285778e555885ce9c8a068
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=d79c9b352ed7b2f132f06dcdf360527502b2153beb09cca968a5ced521edcd39
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=df76cbeae0a61506a29db22e8743d16fcd97ef2da216ea15bf4d6cd709814017
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=103cbb30bbe92da6666d84fab53dd7fe8105c2ebe62eeab5f6609488e62a481b
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=5f3c61663a319d6162240192f387e10ab87e2a972062198082158a243b667d7f
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=221b45c3928b1c45fedbeea987ad80750d3f55fbc564cf3ccf910a68447ad725
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=18eb24fd665ce1cc4ce66b37b19c22397bff9369963b127137780870c179228d
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=bcd09587a21ea10953a14521e9e0ba7b5100e8e15b6a10cc4e7bd359200d5279
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=db712c5e1d21231770e12dc95f6bcbe2f1d04b9cde61bc7adf8b529b41773adf
-dist/2024-11-27/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=43303e426752dcd15964416822cdce0e5f3012366a9b77f3d68e6011c7bacd0f
-dist/2024-11-27/rustc-nightly-aarch64-apple-darwin.tar.gz=95d543a835b11cb5ccbf0578df1ce4e1846e4915622d23a36cc6e18e44e17f29
-dist/2024-11-27/rustc-nightly-aarch64-apple-darwin.tar.xz=db9e0c51c35c81c2ec8be0838f3231f7374917215792ffee159e3d7ffed855d8
-dist/2024-11-27/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=bf9b83d6418bf97caf2df70a8e8298cd8fecb7b950cdaaa2cecbec243ed57c74
-dist/2024-11-27/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=bb520da5b522fffb5a20eed4390990c2ab9d22eb4f77196535a84ae7a434c9f5
-dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=4072d9ca2d617d09d394139c0b8608bb8b2b8b2b4fa450f13c41975a16a791c7
-dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=3d75a8a534e86bb55b63f5b5b2df66ae47862cb7f3ecd1591a829435031d7279
-dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=3cf05e90bc1f95e92cca4769f74055245234037009cf464df3062238c88bc2b6
-dist/2024-11-27/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=245ebb7886cfba64d667630ca8bd672520cfece0ccec3b916e3de0f26aeada52
-dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=dadff4abd2f169f9aa1910d4ea247b7d1f767fca74238ad31485b73399ab6dda
-dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=ff97e1201e9a305673e8a9b740b7696cc4cb5e86bfaa3e137cd8e3e28cffd7a6
-dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=0c411e0824140323f51600d387d52bd01f601f5539d6457815e950224a6d29a4
-dist/2024-11-27/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=dc5731a70c393f69555433d522cde8a52893bfb88beec519c1bbb03b2a0e060c
-dist/2024-11-27/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=01ef2f07f1222fbf3e0cfc5b957c287fb886fd0bd08cbf18f90dc37fb0b63541
-dist/2024-11-27/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d45042b3ea0c0ce6befea7bfdd731e890dbd1f47d1992fe8718a1363f9f18779
-dist/2024-11-27/rustc-nightly-i686-pc-windows-gnu.tar.gz=5437da4c0b73d203789829512d856a66c1697d95afb1ffeaa6347ad0f7c04672
-dist/2024-11-27/rustc-nightly-i686-pc-windows-gnu.tar.xz=a7cb4cb627d75de1ade9211d8ea489ada9ac76ed38909751861ef0cb729dcbcd
-dist/2024-11-27/rustc-nightly-i686-pc-windows-msvc.tar.gz=fd6ee6fc171459092e5e8a012d9cfb7491313e021d1c38965605836b5b101b0a
-dist/2024-11-27/rustc-nightly-i686-pc-windows-msvc.tar.xz=314c7cd558a3654db85d75b3ed71da7cfec3614e4a5f2c449dbc6663b64c7e3d
-dist/2024-11-27/rustc-nightly-i686-unknown-linux-gnu.tar.gz=7a1118011b11befb7df2df57e4450c7611bb3503b3b3cfece9c9c7d4a304391d
-dist/2024-11-27/rustc-nightly-i686-unknown-linux-gnu.tar.xz=2cb95208e77546bcce56d8d5646c3fb5e49ed711894926cb50903ba10431a36e
-dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=4a76c4493e5ba19aaf14947a6c2e28ebfc7f2da530f1441a9fdfa328e15ea4cf
-dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=9b361904c691e17fbf44d80c7f7789511db1d8f251d65ba9cf6fda7f06fd495f
-dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=e89dc76ab061ae23081aee1619fcbf4a94e3acefef6b9b149231f3e1c22f9ec1
-dist/2024-11-27/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=11266d557e6d1d9155e6f04f65e4815cfbfd9f8e1aaa47221030e3ff11b22f78
-dist/2024-11-27/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=30f2eae1b8694607a04c836f750b4b7c204e1e14e52ec37885b9a821c2c9646e
-dist/2024-11-27/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=495316e70b26140c66b074e9d7f714ab949f422c2635cab784a5e133538e4bb9
-dist/2024-11-27/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=ca560c4fe28051573d54f512652ac9740a2d1111aeb8e36b004a6ff9c325925c
-dist/2024-11-27/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=1191f15bb6da98b01b43f0e9d7f51c5c45d38e3c5be2b4ae5f7c0c8fd25e9a90
-dist/2024-11-27/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=5f85829aaab919fa4b2fa5ac843b87358e8da4797adbb6eeaed5be02666ce964
-dist/2024-11-27/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=7c671d366fec561f0b568bfb4b6a08a6071303077a60f76da1307453e51ebc36
-dist/2024-11-27/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=300307ab6cf88afc4312edaa510769e901598492deec4834176c6fc9f3eef6cb
-dist/2024-11-27/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=6fcf91c8679f4963f7d510cc8afbc24a1070b25ea6d20d5d31ad78ea659da194
-dist/2024-11-27/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=ab905f6f3119648c83a2f37ebe1a55b7899a5ac6d10070e4dbbfb89762a369af
-dist/2024-11-27/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=13688b6857c8b10f7fb497f07c969d406cb6b76869957b5138f4b20fcc5d7c5a
-dist/2024-11-27/rustc-nightly-x86_64-apple-darwin.tar.gz=e6bb782014e34fafdc5dcf3aeb407eb636d822d346c5a8c6227cc45bc645561a
-dist/2024-11-27/rustc-nightly-x86_64-apple-darwin.tar.xz=6016ae620deddc42d1d6b6134b0164dab45a204089754b73db41ec837aa88a84
-dist/2024-11-27/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=ed3a381858612e25cacfd89c08496e9d06378d593ccedea4217ad4fa1ab326d4
-dist/2024-11-27/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=4819bb9c25aa743de7ab7e93b10b30336a87f1f75e5122d578df2c83fbc59850
-dist/2024-11-27/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=404aac87c77871c80f83cd7c59390af9af704ee468f40eba68d224d23e2c84e9
-dist/2024-11-27/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=0e1e0d2454ad24fe1da2cce2dce425bc1167bbca68832da2476c7996c00ba612
-dist/2024-11-27/rustc-nightly-x86_64-unknown-freebsd.tar.gz=946d5bcc3ac0b83fd0b53b60290a6361b179f16ba2aa6a2467789ad520278792
-dist/2024-11-27/rustc-nightly-x86_64-unknown-freebsd.tar.xz=f3bd1a053399ec89dccaa7456da41d54a8e91deb5c628e4c502fdcf34c5fe780
-dist/2024-11-27/rustc-nightly-x86_64-unknown-illumos.tar.gz=c353588a38705b7ae050d4b9868b6c4d3527295edbfb25c115b22cda4912be1f
-dist/2024-11-27/rustc-nightly-x86_64-unknown-illumos.tar.xz=a71d8b2b42f6cd522da237f99492ed59cd34ea8c86fc1e73c8854c8234e1c980
-dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=5116b949572fd6c7b11a079d9453b15a4c48562bce22b26d82b7050da772789b
-dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=3635df40363273d44c6f8182f5f6a3a099ed55897bb764cab2565363cd31c1f4
-dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=5233af0b907fb7b176d2b5fee07c486e92dcbbbab1d54a60d814a827befaa984
-dist/2024-11-27/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=c908cad6d28657f1fdcbe9d84ecb86f247c75134803dd5273ca24c6c68a58f37
-dist/2024-11-27/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c799165c319218a2fb4cdc0ac8db87fc9e2992a8e402d984ea27938a5ad1c5af
-dist/2024-11-27/rustc-nightly-x86_64-unknown-netbsd.tar.xz=ec12763fa5d4cc150f663361cd245c30835e05e3b1928898b1b7300de559468c
\ No newline at end of file
+dist/2025-01-09/rustc-1.84.0-aarch64-apple-darwin.tar.gz=0b8a2d1856a95cc11b1ba4100aafec0fa5d07d2fbf4dd43461bd746633ba521c
+dist/2025-01-09/rustc-1.84.0-aarch64-apple-darwin.tar.xz=7e2a1594c1e174f28b84adab25e96699feb8d0455dabe8dac1b2850945b400b1
+dist/2025-01-09/rustc-1.84.0-aarch64-pc-windows-msvc.tar.gz=d7e2f6e583cbce17786fecd921c932d218ec8df081336fcb6b447f0e742759dc
+dist/2025-01-09/rustc-1.84.0-aarch64-pc-windows-msvc.tar.xz=6097716d4a7be64ed92b3cfbeeffc7fd52d057e7ae3f25c38d613bf758c05d63
+dist/2025-01-09/rustc-1.84.0-aarch64-unknown-linux-gnu.tar.gz=bef86eeb44effaf1a7b149a7df1c7a0c89b118c10948c74aa87e16ccbeba9b6c
+dist/2025-01-09/rustc-1.84.0-aarch64-unknown-linux-gnu.tar.xz=9f5650aece53e083b933a57e5a8e0e2db4479f52ec897d5b6d0f77be6cd50498
+dist/2025-01-09/rustc-1.84.0-aarch64-unknown-linux-musl.tar.gz=f354ef3686b1a04933a56e8ae738c114101519c7ee10276ecbb34b9d9a757609
+dist/2025-01-09/rustc-1.84.0-aarch64-unknown-linux-musl.tar.xz=f0f78ea5f9a42c0a1d341f0a1eeb23f796d39e3c85da4658764a20a1e3efb2ab
+dist/2025-01-09/rustc-1.84.0-arm-unknown-linux-gnueabi.tar.gz=23d5bc4ec00f3edc480d87f65eaba0938cd24cbeb0a783f1a4ef50ecdac9910b
+dist/2025-01-09/rustc-1.84.0-arm-unknown-linux-gnueabi.tar.xz=358d0ada79241855ab252908bf63381aaf35f569c3d0c918e124d71e1aa1c9f6
+dist/2025-01-09/rustc-1.84.0-arm-unknown-linux-gnueabihf.tar.gz=09c9b25221838cfad6ce9d18435267a9faa7ff4bea76eea8bb01d8c7775c02ea
+dist/2025-01-09/rustc-1.84.0-arm-unknown-linux-gnueabihf.tar.xz=1b10d12ab6b31b699d7e169a907d8b8e4e4abe465f4b50e9fccfcd56b504362d
+dist/2025-01-09/rustc-1.84.0-armv7-unknown-linux-gnueabihf.tar.gz=05b24531b0c523c52223ce8d146d1f31ebd9501660c2d426ec25f2225d64d840
+dist/2025-01-09/rustc-1.84.0-armv7-unknown-linux-gnueabihf.tar.xz=f5a5d93677e57c3d859ebf534a4925727486c05dc4e9152a90ce83708450bb5a
+dist/2025-01-09/rustc-1.84.0-i686-pc-windows-gnu.tar.gz=0a131f597693e8c51e468c64d6722bbdc6c10d95b8e47fdefa2eba4a19be318c
+dist/2025-01-09/rustc-1.84.0-i686-pc-windows-gnu.tar.xz=2d3f854cf48aa3d9fbf072460a4a54b64b7e9956e360f145c24122d1d7ab49bc
+dist/2025-01-09/rustc-1.84.0-i686-pc-windows-msvc.tar.gz=d4f5139a091eba3fb778ded8a86aad3215a6a8a706d137646628609b9df72c45
+dist/2025-01-09/rustc-1.84.0-i686-pc-windows-msvc.tar.xz=c6fe31d182f7990689af49ae0a000f928e2b77783d77c826c6ab1112f43ff7cf
+dist/2025-01-09/rustc-1.84.0-i686-unknown-linux-gnu.tar.gz=049590d403153414d032e479839faaf7bf8d9dad05b8e63a684f9965e4b464a8
+dist/2025-01-09/rustc-1.84.0-i686-unknown-linux-gnu.tar.xz=f0bc277e8e8c072d20ee91784f919c08b34a65ab56b67bcd2bb98a009cdcf97c
+dist/2025-01-09/rustc-1.84.0-loongarch64-unknown-linux-gnu.tar.gz=50cf987bc861ef3afac359c925a55d72f8d9bbbdb90e2dc816b2d87aad306e20
+dist/2025-01-09/rustc-1.84.0-loongarch64-unknown-linux-gnu.tar.xz=33ecfb62afce6e30864f07b4e3b76ac6d9f603a3626e5228ad0d59a7ee263cc1
+dist/2025-01-09/rustc-1.84.0-loongarch64-unknown-linux-musl.tar.gz=e5995903925207b1d6bc4e5ecf96d75d7b01c17d10c45b88966f8a4b9f8f9b62
+dist/2025-01-09/rustc-1.84.0-loongarch64-unknown-linux-musl.tar.xz=f1dd0e669a2c1ee9504137e0b2277b9075ab17262101d2ffc9282db1d0d04a2c
+dist/2025-01-09/rustc-1.84.0-powerpc-unknown-linux-gnu.tar.gz=6280fe1350006504d8b89b5e40dcd8437a5a2cb68d5e8f304bbea6d01338b345
+dist/2025-01-09/rustc-1.84.0-powerpc-unknown-linux-gnu.tar.xz=ac99e907c9819b61de94a6c12b64256661e5d76c53f3ed25246b46741d1dc973
+dist/2025-01-09/rustc-1.84.0-powerpc64-unknown-linux-gnu.tar.gz=cc40afcf9d3c3cbcd3fc0353a2ac8a24fe71525fce0b968f28513f6495e4d8e2
+dist/2025-01-09/rustc-1.84.0-powerpc64-unknown-linux-gnu.tar.xz=1f5ff831c9fd97d7d306eb7d99186b9e49f35527144aaabd43f67f04449cd732
+dist/2025-01-09/rustc-1.84.0-powerpc64le-unknown-linux-gnu.tar.gz=2fef9d2de5898bbbae0cb001ac5ba29d6859d2a19fa1827a380c9e3b04f54863
+dist/2025-01-09/rustc-1.84.0-powerpc64le-unknown-linux-gnu.tar.xz=1f6aa28f848b24d4589277b04535ad0258e72b5fa78a4a85ba6d18db95636d69
+dist/2025-01-09/rustc-1.84.0-riscv64gc-unknown-linux-gnu.tar.gz=87b2f4fb753ef6fcef528b9512b3655d4d52e99515936731f995fd135438d5fc
+dist/2025-01-09/rustc-1.84.0-riscv64gc-unknown-linux-gnu.tar.xz=c0eaf824c7789c94901f895792333595fe131e43f097bcf5987301cc1b14c3f0
+dist/2025-01-09/rustc-1.84.0-s390x-unknown-linux-gnu.tar.gz=421fa65b67a6c9fd7cd35aec44908e924855f64e201e98bce4de21cf496d2e23
+dist/2025-01-09/rustc-1.84.0-s390x-unknown-linux-gnu.tar.xz=7dbc2fc2c04e820f636bfc74093396c55df0296f7ee4f0547bb849d9a9f05fe0
+dist/2025-01-09/rustc-1.84.0-x86_64-apple-darwin.tar.gz=8dd224e3b21a92e017c057c8e2c1d13de366896b3d876f8d64ebac6415a15928
+dist/2025-01-09/rustc-1.84.0-x86_64-apple-darwin.tar.xz=2976d8c061069f8589587fd3e867aa61e13e80cd5d08cd37392cff67d7978263
+dist/2025-01-09/rustc-1.84.0-x86_64-pc-windows-gnu.tar.gz=b4b77ee44b226eb0248e919f099bf5d8e30e44540c86b0c80a80b6e02a15dbc3
+dist/2025-01-09/rustc-1.84.0-x86_64-pc-windows-gnu.tar.xz=4e137e1e076aa33825a919c2491aead5b1beb92aaa7be1a2168158f39039fc5f
+dist/2025-01-09/rustc-1.84.0-x86_64-pc-windows-msvc.tar.gz=2d3618054aa0d44656662f6d45954858efcf0b1ec2bbe215456b9c1e874ea2cc
+dist/2025-01-09/rustc-1.84.0-x86_64-pc-windows-msvc.tar.xz=c576530b47054eee263f5fc547574004e2c2ebda521440a5784e85fe3f6570ba
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-freebsd.tar.gz=2945585bf13dc4ae11b90f8d939c415f1989cd3f93f880e13239d95c6888951d
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-freebsd.tar.xz=c6f5286267a5e5585a9bdb3a215c8b8d698ab1f4015b9ea6a366b1498320487c
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-illumos.tar.gz=38c1366c86099bd9c1f2c299fc9a170356aa375a63806e237f89ac0d0e3fed6f
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-illumos.tar.xz=f654a8cf9749375318995487f269415ac4777758f36fc916275833e169cf1bf9
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-linux-gnu.tar.gz=e8349a7da9d63500431196fb3abdf79b0c8c76e0bfada815fb3f6669ecb5de3e
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-linux-gnu.tar.xz=a1737d86f80b31a6d48a6726726275dc068ecb930c9635b13aa59999486de837
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-linux-musl.tar.gz=1446a53ba814bd6da595e394dd9f53e9cb2744055c39e034d8c49211850064c0
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-linux-musl.tar.xz=bb96af675e34195588ab322ddaeabadd8bf4da08869aef3c91b7e7bbaf9a74b1
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-netbsd.tar.gz=426f69aa691599cdadd42298057f5e4651d6e7ecb10a409965953ad4ff3d030c
+dist/2025-01-09/rustc-1.84.0-x86_64-unknown-netbsd.tar.xz=5da41e062f92595365813e721a674230f67b7f4312342d565e5f7d7c901ba562
+dist/2025-01-09/rust-std-1.84.0-aarch64-apple-darwin.tar.gz=0a0626661ac576a67da46af73e2e74d6e42d79cb2f54321b08ab81a86eab94a0
+dist/2025-01-09/rust-std-1.84.0-aarch64-apple-darwin.tar.xz=c3ec73225e0f0228e4a8a9c650195b3f9e63f839954e65509d47ea58316f8f5d
+dist/2025-01-09/rust-std-1.84.0-aarch64-apple-ios.tar.gz=97187cb3ce3ccee2befc68e40423606b041e72c5b11f251a028075ac7e33e065
+dist/2025-01-09/rust-std-1.84.0-aarch64-apple-ios.tar.xz=a39a417e44c371dafae78421621758a003c3edfc7ebab6cbc8e67fca871ab40e
+dist/2025-01-09/rust-std-1.84.0-aarch64-apple-ios-macabi.tar.gz=ccb00290c7ea6c78d44a45bfadce3c94868b09b6c0ee58024289b2019a952178
+dist/2025-01-09/rust-std-1.84.0-aarch64-apple-ios-macabi.tar.xz=68c9f82327ed7b7b782da3593555490dd07a5467d81271d31924fa6b66fcd93f
+dist/2025-01-09/rust-std-1.84.0-aarch64-apple-ios-sim.tar.gz=326ec821c7967797a2173a84353e1423a1b3071f52facd988af05b1e5824faea
+dist/2025-01-09/rust-std-1.84.0-aarch64-apple-ios-sim.tar.xz=6ae53a53b21bd35b728515d4f92b16b8d24624991689622c40c39e4ec36b5443
+dist/2025-01-09/rust-std-1.84.0-aarch64-linux-android.tar.gz=210576203cc79ecf17e987673060aa0fb5df85b31d54f1bac0e51f591a26a4d1
+dist/2025-01-09/rust-std-1.84.0-aarch64-linux-android.tar.xz=c21e0583954aa5968f7acacd4d7c8e9c832679ba6a0060df6373996b1fa9b7f6
+dist/2025-01-09/rust-std-1.84.0-aarch64-pc-windows-gnullvm.tar.gz=7c45d37a0e0883b7f40a6398ed5e547c749f8261d7f7475e438384d055a134f9
+dist/2025-01-09/rust-std-1.84.0-aarch64-pc-windows-gnullvm.tar.xz=6c1d2974bed255b54129ecc3a4d45bfb60592078dd012238fba4844e30c089dd
+dist/2025-01-09/rust-std-1.84.0-aarch64-pc-windows-msvc.tar.gz=4a44d1d4f5024e8479d06aca32e628a82aee02f94d54222e2d5e6b6219d97f1e
+dist/2025-01-09/rust-std-1.84.0-aarch64-pc-windows-msvc.tar.xz=acb867650ea342ace3d0cf8ac481b801c522fc142a499ceccf6ba02421af5c20
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-fuchsia.tar.gz=bbb84f1dedb70c094580355bc6ae7b49b151ca5f6c888d4fb5620c4077268e35
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-fuchsia.tar.xz=aef76494a2c8a377e947c2ef1b2ce6115833c554b2d6e08cb4b49987b693337a
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-linux-gnu.tar.gz=11a698df87efacfb472b32e91fc39df0261b9b7acda48ea01a7f296424cf5f5d
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-linux-gnu.tar.xz=023f0b6153b23ac0e9686c2ab95bc393ee3e295b166bb36de3b4dfb53e3913e0
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-linux-musl.tar.gz=31bbac8bbe4d733f72f96290630676cb3297035b11bd618616dfd64a93a13f2d
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-linux-musl.tar.xz=2fcc03bf72c6759d6a1778b6592062a2e69349239f7ba9f21a62a7529e4fdf8b
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-linux-ohos.tar.gz=b302c530f35a3391b8e01c198e09512f22f3087ceac944bc73e7980fc4ddba35
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-linux-ohos.tar.xz=99dba7bb7ed4565095fd4df4f9687c4f3ef5ada5d30331a0eb2360ee325f31b5
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-none.tar.gz=9e2368fb1207c3b429db693fd0099ae250ff6e9c391dec6200b286a7acf166e7
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-none.tar.xz=f3e4e15b6c9298fe2351bf1819551b166bf7d19378d028f2db061f65ba86cf40
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-none-softfloat.tar.gz=ac9ccded250ad6f757d19ca07d492d43f417dbbf6229c5ee6a2940fc92d47dc8
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-none-softfloat.tar.xz=3bb72a272d11d80423814717f1166c678ccdbe282a67b0c8bdb089cb46a77a27
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-uefi.tar.gz=14bb9f716560a5eec0e8fb09e4446bc127af8d33a430cd71f861dd83cbbc6207
+dist/2025-01-09/rust-std-1.84.0-aarch64-unknown-uefi.tar.xz=f0ddab14976547c3d96fc26908e1888d2cfc9f36db3e608fc255b6ae3a1a8416
+dist/2025-01-09/rust-std-1.84.0-arm-linux-androideabi.tar.gz=ab4f38c1b440bf444eea502ae6e5ba297ecc55dc8e2585adfdd7ac3970f15e0a
+dist/2025-01-09/rust-std-1.84.0-arm-linux-androideabi.tar.xz=119362290da9ac4b1ec405f3f65ee06dbbb438182577360d039ebea448d1e28a
+dist/2025-01-09/rust-std-1.84.0-arm-unknown-linux-gnueabi.tar.gz=7cd501d1ee2f10fa048e0aa0825085251009eb0e546b19499987d5b17b6aea86
+dist/2025-01-09/rust-std-1.84.0-arm-unknown-linux-gnueabi.tar.xz=5ad4a321ca84fa18811923765031d31d037bbe2e86debda7922d820313ae3926
+dist/2025-01-09/rust-std-1.84.0-arm-unknown-linux-gnueabihf.tar.gz=02e88bfe926d25bfbba357fc017b2e6e03587d2863e5c1639b48c125f2903157
+dist/2025-01-09/rust-std-1.84.0-arm-unknown-linux-gnueabihf.tar.xz=b2a92aa3b5116e2f48cd1a854da5dc308cffad989bb68b9d12e983ed72dcc7a7
+dist/2025-01-09/rust-std-1.84.0-arm-unknown-linux-musleabi.tar.gz=a023c77dce5f3b9758a85babef759ccfb4a862bad80da1e10f69d00902de36ba
+dist/2025-01-09/rust-std-1.84.0-arm-unknown-linux-musleabi.tar.xz=469fec94070e8efd38663e1ae6b51a2639e2885e6cc4a7b3c48c2907ccd083fa
+dist/2025-01-09/rust-std-1.84.0-arm-unknown-linux-musleabihf.tar.gz=65e2072d49aaf24a12cff5d31f5321eaf38fe92c3bc08e471c892635c2e33063
+dist/2025-01-09/rust-std-1.84.0-arm-unknown-linux-musleabihf.tar.xz=0fadfac3379bc1acfb44ba6d52ea6269449560b883802b2567005fd351606360
+dist/2025-01-09/rust-std-1.84.0-arm64ec-pc-windows-msvc.tar.gz=43c5acebd828b3445720b728673ff0d6c46c9fd7a82f89295825f4d24f08ed40
+dist/2025-01-09/rust-std-1.84.0-arm64ec-pc-windows-msvc.tar.xz=c7a93600d0f70a83bd16c61a40a9b68887bef1b28bb052498c0ddee161848ef0
+dist/2025-01-09/rust-std-1.84.0-armebv7r-none-eabi.tar.gz=f5f53d8ca2d392286361b2e516fd9d74b650b60694a3a6c0fc72d8c7f7e5a689
+dist/2025-01-09/rust-std-1.84.0-armebv7r-none-eabi.tar.xz=737ec0076cf329b60ca4be145129722a24fcde50dd6a3c75f4e66facadac2f52
+dist/2025-01-09/rust-std-1.84.0-armebv7r-none-eabihf.tar.gz=1bc841bcca521905e4c55dcbd42c96a88830697e9ae77252fbb4bbc173bf19e8
+dist/2025-01-09/rust-std-1.84.0-armebv7r-none-eabihf.tar.xz=4803a0f825ad6b5a972bac7666f0df66817ad15a7ec7a259fe24a8fc16ff2d7f
+dist/2025-01-09/rust-std-1.84.0-armv5te-unknown-linux-gnueabi.tar.gz=e2919a98419d7ea7763b198501378c1e4bcaeb7b8a7a41d5d46117f3adbc71b5
+dist/2025-01-09/rust-std-1.84.0-armv5te-unknown-linux-gnueabi.tar.xz=e9c6e1b5f91ee78f052cb1d6017c33a33d0f3fa9481e1906d9ef2d674f957be7
+dist/2025-01-09/rust-std-1.84.0-armv5te-unknown-linux-musleabi.tar.gz=54c588181d8a38f1ced59eaea076aaae8cb76a672c2538c186b879f26283da56
+dist/2025-01-09/rust-std-1.84.0-armv5te-unknown-linux-musleabi.tar.xz=7ae93ecec3da72d7053bb3fa8e6c7cd89f9869efd2934be5e29a4381db4cc682
+dist/2025-01-09/rust-std-1.84.0-armv7-linux-androideabi.tar.gz=b6e1947d55d09e15cd1504641e6c340e7415e6a59a11739c7d6c8f5890465025
+dist/2025-01-09/rust-std-1.84.0-armv7-linux-androideabi.tar.xz=bd15abd7c5d6abddca8001e5d8f25c3c957050dec689c4fc807596733103c818
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-gnueabi.tar.gz=5375124e7a90dc6d64997dd5da52a7d88eb6fae1a950bc125d8b4fb260ac0f53
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-gnueabi.tar.xz=dd80b1d9982d8339ae72d2f985e81d7d528ecf60f7a2eeecd9b6dfdd5431d480
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-gnueabihf.tar.gz=44a93e9c8ce63dc9cfe4417ae015b9de3aa6538689e37ef1b4a513957b09d536
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-gnueabihf.tar.xz=5b1bc0298dae734ca1d3a66b457cb1ef5c3265dcd0cfd586790c4d45d9826d5f
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-musleabi.tar.gz=6c8fd72175959e4321179baea08315d4d5b32a5d92ecc07b23aa1e3bec6587eb
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-musleabi.tar.xz=00fc66cc41c2352f6ea3c36ae97d4c96b92f9a038a101176c3b709f409ce9f2f
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-musleabihf.tar.gz=db1eb3bbb54438acc263faf40ac21ccdfef124683132c1842ab9f027a4677fad
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-musleabihf.tar.xz=e5caef0eae65f66e15fc16c26a86efa6d177a56ed28ef2285de0e4bbb9d4c904
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-ohos.tar.gz=17c8f5ed01836a83c5b80cd8c6f65f40a0e540d2d8ca7bcf9f6bc649110cbdd3
+dist/2025-01-09/rust-std-1.84.0-armv7-unknown-linux-ohos.tar.xz=b53ec73910a18f2e3afe44f4e0386245cc4f93c6bd2cee4d27525afb1e0f8cae
+dist/2025-01-09/rust-std-1.84.0-armv7a-none-eabi.tar.gz=34d02cfb66a60f4550395e6655c853f9ea6cdd169b5148bc0e273acd5081dcfd
+dist/2025-01-09/rust-std-1.84.0-armv7a-none-eabi.tar.xz=c523b528b60e2b646726098baeac3cc622c194671d1a18e26057ccadf72ec4b3
+dist/2025-01-09/rust-std-1.84.0-armv7r-none-eabi.tar.gz=6a81015a0ddae96ad271ce95df7c13c19deb25db3898f01071bdbe596addc3e8
+dist/2025-01-09/rust-std-1.84.0-armv7r-none-eabi.tar.xz=0c727320fa4de24a462aa44aea073cc19f9af817af785f1c3b2f0500de2bd5b3
+dist/2025-01-09/rust-std-1.84.0-armv7r-none-eabihf.tar.gz=2e66baeb2c81f258ab9db191810e38538a3674fb7c84a9722bbe973d92cf7a03
+dist/2025-01-09/rust-std-1.84.0-armv7r-none-eabihf.tar.xz=fa63619cd2f486dfecbd0e04162b8994e65833bc503bd0f2deafeae3996d6a2c
+dist/2025-01-09/rust-std-1.84.0-i586-pc-windows-msvc.tar.gz=76d7e7802a6183a95c5224d9a9ccb2f5ca5251c74db6949768fe5582bbd2aaf1
+dist/2025-01-09/rust-std-1.84.0-i586-pc-windows-msvc.tar.xz=3a21f048dc2d19fc897c22f1402503e2b670394ae75dd0e0abc66f83c4906991
+dist/2025-01-09/rust-std-1.84.0-i586-unknown-linux-gnu.tar.gz=b1ab3d8c46c2b776ec86594ea88f4699f4540fda87c07fbe5ea653490851ffcf
+dist/2025-01-09/rust-std-1.84.0-i586-unknown-linux-gnu.tar.xz=a877622fbbfa58304c34372d369e95db106cc35758ca59053144bf7d86fbf3fc
+dist/2025-01-09/rust-std-1.84.0-i586-unknown-linux-musl.tar.gz=d541de5d00e420d38fb6f10b84de50db73bb845e6e7115dfb99e41efcb23f3ba
+dist/2025-01-09/rust-std-1.84.0-i586-unknown-linux-musl.tar.xz=f0f911935c3915ca53f3e2eb51007bbafa1863cda69cb35077bfed38871b83be
+dist/2025-01-09/rust-std-1.84.0-i686-linux-android.tar.gz=1c608948a1be6356a4763e732474e3ebc27e4d786fb7d1ad407b6d36ff31b741
+dist/2025-01-09/rust-std-1.84.0-i686-linux-android.tar.xz=5a2e0941076924fb7edfffb3b07604c38a6133f9bc1d5e1de266a7292b7adb5c
+dist/2025-01-09/rust-std-1.84.0-i686-pc-windows-gnu.tar.gz=368913ba0cbfe273ed2347ca8a5ced2b93a95405e379f868f63a4c228eb2f2ea
+dist/2025-01-09/rust-std-1.84.0-i686-pc-windows-gnu.tar.xz=b2d2cf170aa499e8660bd6c8cda844cd6047a201715fa95d296553e91e480935
+dist/2025-01-09/rust-std-1.84.0-i686-pc-windows-gnullvm.tar.gz=46a57c89d5741994600849be29bb5f944e9def258a7b9ad970812d21e3da6411
+dist/2025-01-09/rust-std-1.84.0-i686-pc-windows-gnullvm.tar.xz=071fc172c3d32e9bac804d341af0199e8cbfb425cdf17c87fce542f0108d9500
+dist/2025-01-09/rust-std-1.84.0-i686-pc-windows-msvc.tar.gz=3af23f34bfd68d8c9e2bd32f40a88cf2b76b98a6ec331dd0161b9dc48eb65773
+dist/2025-01-09/rust-std-1.84.0-i686-pc-windows-msvc.tar.xz=1c41cceeb8a175565cf9599ec558f1042cdb7baa746066847568bb0a31f4cdec
+dist/2025-01-09/rust-std-1.84.0-i686-unknown-freebsd.tar.gz=f4ca55b89f39d05ab852de45b8bc62f4bec8b7b257c7392f23690145a95642e9
+dist/2025-01-09/rust-std-1.84.0-i686-unknown-freebsd.tar.xz=f9e0aa7c33e140a394adcff2d44168e3fcd7f54f0bedcda9bdb0f960a299e9e6
+dist/2025-01-09/rust-std-1.84.0-i686-unknown-linux-gnu.tar.gz=81fb46f365f0dca15ef3ac7f8d18ed78a292e5e51c19de21a19294daf1c4f32b
+dist/2025-01-09/rust-std-1.84.0-i686-unknown-linux-gnu.tar.xz=e710100be26e742733d445722a37227381f1ec2010664ece85489bc598d70456
+dist/2025-01-09/rust-std-1.84.0-i686-unknown-linux-musl.tar.gz=725199040c50c7db7a840228f64e9e4f5b4117aa2ed62e2af0be9d0c02fa5671
+dist/2025-01-09/rust-std-1.84.0-i686-unknown-linux-musl.tar.xz=1c8f12e789b64fade8a449ec12039656aa9f5cbc2bc60b720562f1286fbea4fa
+dist/2025-01-09/rust-std-1.84.0-i686-unknown-uefi.tar.gz=48b5461d01d9c38d49310c8bf170eaa132dde2b749576f344d407b7008145445
+dist/2025-01-09/rust-std-1.84.0-i686-unknown-uefi.tar.xz=f260bd07420bf0a9f2e4ae9e3698a29903e66e78d2db05f911b93a38dc554160
+dist/2025-01-09/rust-std-1.84.0-loongarch64-unknown-linux-gnu.tar.gz=a212a96ebf70f9a56162196c5bcc553fcb1a236553c424fd11c0335c5376f000
+dist/2025-01-09/rust-std-1.84.0-loongarch64-unknown-linux-gnu.tar.xz=763b93ca08028a1e63a8a3754ac6118b2659022538e5e33675f2d7620488cd57
+dist/2025-01-09/rust-std-1.84.0-loongarch64-unknown-linux-musl.tar.gz=721c7533238f3c4d30b5f70dfbe0a544af95b7ac2de45f1e813e04fed4d7e20a
+dist/2025-01-09/rust-std-1.84.0-loongarch64-unknown-linux-musl.tar.xz=054be22ac25d16629d219480ff372d27f00c8fa3a7334ab6d1d5d20650136a38
+dist/2025-01-09/rust-std-1.84.0-loongarch64-unknown-none.tar.gz=ef5789315d2c89c63d947221e5a3d5d2eb0b6c1ff2d5464122fe3c378b263e0c
+dist/2025-01-09/rust-std-1.84.0-loongarch64-unknown-none.tar.xz=ec67d141ccfd891e4fd2daa6cf7a1650de46ffc69d9b9023ff582ce07ca533bb
+dist/2025-01-09/rust-std-1.84.0-loongarch64-unknown-none-softfloat.tar.gz=b5670cbbc2f6257f0b78abf0ab81a6752e11293c22c1442fc240ba1f5639c092
+dist/2025-01-09/rust-std-1.84.0-loongarch64-unknown-none-softfloat.tar.xz=fd5fc2a854a88c3320df703b762c6551eda0043849b7ad5b74261c50ae41cb23
+dist/2025-01-09/rust-std-1.84.0-nvptx64-nvidia-cuda.tar.gz=d407d2c4e7fad3212787ed32740575971e6d8fce81d11a598c8e999a76ff388c
+dist/2025-01-09/rust-std-1.84.0-nvptx64-nvidia-cuda.tar.xz=9f23e499613ddc2fe7ee9769acea82cf544470ec1c6c03b36c7df387d67616c1
+dist/2025-01-09/rust-std-1.84.0-powerpc-unknown-linux-gnu.tar.gz=3f91b82e8e78dbbbb3b61e39428c151afd887bdabc595344475563f43b1bf04e
+dist/2025-01-09/rust-std-1.84.0-powerpc-unknown-linux-gnu.tar.xz=fdbb75060e59ad59273a8ef11fc2ad61837539686df0e8dfe46107e1b15ab90a
+dist/2025-01-09/rust-std-1.84.0-powerpc64-unknown-linux-gnu.tar.gz=5a48ffbd7270cef21555641dc932f997543d34b026828a3231603518e34a669f
+dist/2025-01-09/rust-std-1.84.0-powerpc64-unknown-linux-gnu.tar.xz=f2819f8ce1ae41c2c2bcf40fc90d6b1a5d340d3e9558267d464730a797122bf5
+dist/2025-01-09/rust-std-1.84.0-powerpc64le-unknown-linux-gnu.tar.gz=d1dacba52577c23210b417dafd7c41bc36e9ba1b83702c6c7b851e9f06f5ac07
+dist/2025-01-09/rust-std-1.84.0-powerpc64le-unknown-linux-gnu.tar.xz=db731e894cce9973ab2b41109c9097d0fc6a49c0d45a0d333bd1547d2c7485a1
+dist/2025-01-09/rust-std-1.84.0-riscv32i-unknown-none-elf.tar.gz=6118fc5f11a16ba380a90c6ffc4c0326d6dbdf30490b923e277dee1174099e7f
+dist/2025-01-09/rust-std-1.84.0-riscv32i-unknown-none-elf.tar.xz=e5c1b12bf60e6019194d28cca5062d0853b896f4daace646d3d327495214a9e6
+dist/2025-01-09/rust-std-1.84.0-riscv32im-unknown-none-elf.tar.gz=c6179c399020f4eac03f20624c27aff749f2a9d451b6b954cf3e864478687f3c
+dist/2025-01-09/rust-std-1.84.0-riscv32im-unknown-none-elf.tar.xz=3d08ab2b4446d7e2659effd4ab975c6c37a7a0bd28553e2f48f21b0b7e1addb4
+dist/2025-01-09/rust-std-1.84.0-riscv32imac-unknown-none-elf.tar.gz=81d6ec63779b7d4370d7a48e5cf44ae0e6b515cdd49158ba8da1c837c98386e3
+dist/2025-01-09/rust-std-1.84.0-riscv32imac-unknown-none-elf.tar.xz=c654f54db21b6e857fab6028b3ab31a9413f44d0ee9aa383af2ac6c7ba8220d3
+dist/2025-01-09/rust-std-1.84.0-riscv32imafc-unknown-none-elf.tar.gz=9cb91f1baebbe1be86f9359e2247998f37a7a5674c4aa8f60f83f8e04e30dd47
+dist/2025-01-09/rust-std-1.84.0-riscv32imafc-unknown-none-elf.tar.xz=bfabfd354aada0ce4c768b9a5780cfff5989d924b96a1768ebd07980c98997f5
+dist/2025-01-09/rust-std-1.84.0-riscv32imc-unknown-none-elf.tar.gz=8202c761abb1650a2cc69520d919a58a4f86b0ecf054c95d27f3102e4132699e
+dist/2025-01-09/rust-std-1.84.0-riscv32imc-unknown-none-elf.tar.xz=cb32559189150b885df625eac5aa7adf066a80695c4a11d9d8e85341c1dba39a
+dist/2025-01-09/rust-std-1.84.0-riscv64gc-unknown-linux-gnu.tar.gz=8bffde598c149881bb03883469a442f95ecc58e3a05e4b6dd2cdf973fb0a5f9e
+dist/2025-01-09/rust-std-1.84.0-riscv64gc-unknown-linux-gnu.tar.xz=451580f9cdc47eef4efb0986b1960a8f9c4fb0959f81b77eb6292e6bcff9fc64
+dist/2025-01-09/rust-std-1.84.0-riscv64gc-unknown-linux-musl.tar.gz=45dfb7bd6e62a0053d1f1b2a582a1213ebaa8bad3d9c8ca058cd6b9c9ce3a6ca
+dist/2025-01-09/rust-std-1.84.0-riscv64gc-unknown-linux-musl.tar.xz=c6811e042fcd2f62c66f07ad95b207769b12f15ea310469778d5aeb97ac452e2
+dist/2025-01-09/rust-std-1.84.0-riscv64gc-unknown-none-elf.tar.gz=37a24186a8ff0ba8d06727562aaff220a593c2a8242410e2dd6dd2f82c73ad5a
+dist/2025-01-09/rust-std-1.84.0-riscv64gc-unknown-none-elf.tar.xz=78ecec401eec65856cc3794076fddf07e2aa8947b7ab113b756ffaadf6b73973
+dist/2025-01-09/rust-std-1.84.0-riscv64imac-unknown-none-elf.tar.gz=4dcc04f0b05beb546f74ed076c63283b121699338bfa3d27782f1e7122eed14f
+dist/2025-01-09/rust-std-1.84.0-riscv64imac-unknown-none-elf.tar.xz=bc6ca8ed83e4caa3894a254cbf8c36ab4a1c87efec9fc14a0664d1bbf56a6d84
+dist/2025-01-09/rust-std-1.84.0-s390x-unknown-linux-gnu.tar.gz=5d0420ad2685a90fc83f46cb075d72a2eca9603ce92da5282558e2a32fa192f1
+dist/2025-01-09/rust-std-1.84.0-s390x-unknown-linux-gnu.tar.xz=5208f45cec5f3600f2cbc11d1796bc217f09e9c922689c8e4f0cc3f2b83ebb74
+dist/2025-01-09/rust-std-1.84.0-sparc64-unknown-linux-gnu.tar.gz=fdbd4028e5fdf43acb3761ba402e6d9e0ed3f872222481db60e374545e08a74a
+dist/2025-01-09/rust-std-1.84.0-sparc64-unknown-linux-gnu.tar.xz=ecd1662d6cbbb62984ab31ae787442f1ab32caf6bc17260d407b3a94b434ad32
+dist/2025-01-09/rust-std-1.84.0-sparcv9-sun-solaris.tar.gz=92cff117ef26b6d44f918223de4dc0a16bc90f7cb68a12afcba8dd98b1f0343d
+dist/2025-01-09/rust-std-1.84.0-sparcv9-sun-solaris.tar.xz=2e9e65ea1ca5b69b46a97a7940e036ba3f49df139e064fdaf4996480171c0ebb
+dist/2025-01-09/rust-std-1.84.0-thumbv6m-none-eabi.tar.gz=4e13683d108b9d50ba44ab64a8e323231756088fab1c1f96f93d771c40f73b8d
+dist/2025-01-09/rust-std-1.84.0-thumbv6m-none-eabi.tar.xz=f3735b16fc98707ee087d9e04fd891dc2a99b577d1f6e72677cb71717a78ebc4
+dist/2025-01-09/rust-std-1.84.0-thumbv7em-none-eabi.tar.gz=8add5a38a287294a282db0de480dab914bb328663dcc24cbd8975d41d5963a8c
+dist/2025-01-09/rust-std-1.84.0-thumbv7em-none-eabi.tar.xz=8e8e084b44f3ead6dfacb6150299ece975866422840af8f8e17990c61e74a4cc
+dist/2025-01-09/rust-std-1.84.0-thumbv7em-none-eabihf.tar.gz=4b11b6a973a77c2dad9f8aa34a1dbc99b59acaff3ed481d6cc11fb239193fdc1
+dist/2025-01-09/rust-std-1.84.0-thumbv7em-none-eabihf.tar.xz=49b455932534db2b7c5a469b9a2f132e9642ef9509c9bdbda5e7e90481ac0949
+dist/2025-01-09/rust-std-1.84.0-thumbv7m-none-eabi.tar.gz=7820cd9f7c691527feb68088582a5fb8200983a18edd9015b2a580199d0ec807
+dist/2025-01-09/rust-std-1.84.0-thumbv7m-none-eabi.tar.xz=920bb11cd06547b092c7cbe65e0811139daca52e08baf2b2956295d9cd3aff80
+dist/2025-01-09/rust-std-1.84.0-thumbv7neon-linux-androideabi.tar.gz=fb44a1dca4ce8c8674ccca8d5b89618bb159e8ecba0eb7cb9ee80df0ea1029ae
+dist/2025-01-09/rust-std-1.84.0-thumbv7neon-linux-androideabi.tar.xz=991713332f143578fbb7d79bb79ee6a780367d69377c39afb4964639e7601b1f
+dist/2025-01-09/rust-std-1.84.0-thumbv7neon-unknown-linux-gnueabihf.tar.gz=b66f640db796302c28732d56a505dd6ae6effa27fb0d125ef28d254f189a3e5f
+dist/2025-01-09/rust-std-1.84.0-thumbv7neon-unknown-linux-gnueabihf.tar.xz=1a6e2ebe680c1e683faa17390c5a02736f38acc89ed97c7b0d8a874c9fc781cc
+dist/2025-01-09/rust-std-1.84.0-thumbv8m.base-none-eabi.tar.gz=bfa6573cbb2624c76985ba18e82c98b673cb9f382ee05a012b85d1dfc8ed3c8b
+dist/2025-01-09/rust-std-1.84.0-thumbv8m.base-none-eabi.tar.xz=aa1ec332f539fab30d556e395a9258c3f98c3a853f43148219adb364be8e7aa2
+dist/2025-01-09/rust-std-1.84.0-thumbv8m.main-none-eabi.tar.gz=be4170d0346dd715274048a47720c19cf3bafbf013b4ffa435ae9fc556840326
+dist/2025-01-09/rust-std-1.84.0-thumbv8m.main-none-eabi.tar.xz=01d5e635ee27d521dc339d1fd41bfa04e9b996f5f0894949a2724b7a68219c51
+dist/2025-01-09/rust-std-1.84.0-thumbv8m.main-none-eabihf.tar.gz=e611edf2f24615eb856a0d606cc5fc5410705086d2082295a3dcc1dcfef96fa6
+dist/2025-01-09/rust-std-1.84.0-thumbv8m.main-none-eabihf.tar.xz=57ce874bca3cf31f9749d107a5613bbd4c1ddc26ba4fcf88fa7422546d1f056a
+dist/2025-01-09/rust-std-1.84.0-wasm32-unknown-emscripten.tar.gz=767d06523ae6a0aa2cb8627eb890202c6e43434e01be9a1fad5c8613edeb8e26
+dist/2025-01-09/rust-std-1.84.0-wasm32-unknown-emscripten.tar.xz=bb85a24c6576ce39da3876b44fd00088ec175915423ee4adf06003cba3df4720
+dist/2025-01-09/rust-std-1.84.0-wasm32-unknown-unknown.tar.gz=76e74b68fa4561f94434b37e16d06e3167d5524870515e62d52a7d3c93d0dc14
+dist/2025-01-09/rust-std-1.84.0-wasm32-unknown-unknown.tar.xz=7003bdae2aab2ddb6991e3dc8a62f45964ee1ed021cff47f47fd58b2ef91aef8
+dist/2025-01-09/rust-std-1.84.0-wasm32-wasip1.tar.gz=6e42a2d39b77da376a5afe73c9739682e41154850da5c71f89ddbf953680b21e
+dist/2025-01-09/rust-std-1.84.0-wasm32-wasip1.tar.xz=338951e39f3e69aa37b3c5020919ffcaf230e86773def2d1a51a87ab87b9f20c
+dist/2025-01-09/rust-std-1.84.0-wasm32-wasip1-threads.tar.gz=7e78ce32a9eab43bb16d738d498365fdd983399c58ce4b33080ceabbda0354c4
+dist/2025-01-09/rust-std-1.84.0-wasm32-wasip1-threads.tar.xz=0e884ba748708ceeb9f144ea6074ffab0df1e4b74708e35aca5e58dacee25dbb
+dist/2025-01-09/rust-std-1.84.0-wasm32-wasip2.tar.gz=fd41b37cfd3cabaa1c0379c07af62cd2afbda2ecdf6857fbf7ac82466b71dc6d
+dist/2025-01-09/rust-std-1.84.0-wasm32-wasip2.tar.xz=56926904562bcd0fc0e4ff1ec062677cecb2e8107a7210cb9faf82f1b69bedd4
+dist/2025-01-09/rust-std-1.84.0-wasm32v1-none.tar.gz=53012308522d9a6448fbaed72c212c79a6888e2ff0f93c32d3fcb2676a96d3e4
+dist/2025-01-09/rust-std-1.84.0-wasm32v1-none.tar.xz=d1325f56e2569eafd41dad50bda514e12d067b07bf34b953ddd7b71ba4236320
+dist/2025-01-09/rust-std-1.84.0-x86_64-apple-darwin.tar.gz=a77b82c6c6b0c32808cc812e100b1274cffc81818d25754b92d197409e5c12b9
+dist/2025-01-09/rust-std-1.84.0-x86_64-apple-darwin.tar.xz=81d503a3dc54c760ecb5088fe61f8808f4b498c24c397aad00d93bc9dc8963c9
+dist/2025-01-09/rust-std-1.84.0-x86_64-apple-ios.tar.gz=3cfa1b7774289b94f398a4b273606f420bb584da8a1210f48603adb0904fef6f
+dist/2025-01-09/rust-std-1.84.0-x86_64-apple-ios.tar.xz=8dfc3c4f754be7f2b41e52b257c80d6a77f8a124cb9f055919701d24b55e8ff3
+dist/2025-01-09/rust-std-1.84.0-x86_64-apple-ios-macabi.tar.gz=7acbfa9ce4a59f3ae9532898fdb4b487c0e0e15eb39ff91e8081506783a9d473
+dist/2025-01-09/rust-std-1.84.0-x86_64-apple-ios-macabi.tar.xz=015e465c9cdcf2974137e0d889636cc9e78bf3f8ddebb9d4cdd86206b2284408
+dist/2025-01-09/rust-std-1.84.0-x86_64-fortanix-unknown-sgx.tar.gz=bde7d1a4b6c67a67be6f7863530466c5d5051d4fbf719c3ed83ba2a659f193f8
+dist/2025-01-09/rust-std-1.84.0-x86_64-fortanix-unknown-sgx.tar.xz=f2691106f5970bd08b2873a047591d556aba4b714c56f82b14cfa97d233be91c
+dist/2025-01-09/rust-std-1.84.0-x86_64-linux-android.tar.gz=c979d55799eb0e709b8278a861f19279b5ff4de96f92b398f86032c907523e6c
+dist/2025-01-09/rust-std-1.84.0-x86_64-linux-android.tar.xz=bb676ef61e3a417a8518d24408dc322ddb44c1eba739bcb807976211168d61ed
+dist/2025-01-09/rust-std-1.84.0-x86_64-pc-solaris.tar.gz=3b491848310e30a3623d27eb38aa698258db809e81a79994227b30774bec007f
+dist/2025-01-09/rust-std-1.84.0-x86_64-pc-solaris.tar.xz=7845c5d470b11d85b934a364fa5c4ec0fb7e5aa76c4b8b15c820ac39f5fd8b52
+dist/2025-01-09/rust-std-1.84.0-x86_64-pc-windows-gnu.tar.gz=c3e62fc054b1d4b30f5daf70820365def8b5cf489ae158cdbe6412ca28df5d65
+dist/2025-01-09/rust-std-1.84.0-x86_64-pc-windows-gnu.tar.xz=89cb1489267db4a11455aa64012716e103585a47eb13e8471f15e3409a818a42
+dist/2025-01-09/rust-std-1.84.0-x86_64-pc-windows-gnullvm.tar.gz=c5c62253a0e80cda2f56a314fbfe79a158e9233949c14dea462ec54809a23765
+dist/2025-01-09/rust-std-1.84.0-x86_64-pc-windows-gnullvm.tar.xz=991d1b8462c90c86cae3ae67dde165ee286566b8db54ec4f86dcb0b8dcb0eaa3
+dist/2025-01-09/rust-std-1.84.0-x86_64-pc-windows-msvc.tar.gz=d61cd761c4531dbb4f21e50e4d27ba7816c834bc5fe1d802998d9797619d61aa
+dist/2025-01-09/rust-std-1.84.0-x86_64-pc-windows-msvc.tar.xz=1d9c772f87202c962da5c7c697077fb3751308087445278422328eb244cfe262
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-freebsd.tar.gz=c506c6b50cac025268e1ee4536cf6149c3efb81898ddca51c68c52e9fbd68938
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-freebsd.tar.xz=10b57f3d2fa998586f5be01d1dcc93a33afe154c63c09d1d35b8cb7326c13b55
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-fuchsia.tar.gz=2b1635e37c504598209152e01fef4b55a0735fc85fd806ce6a6efd90abb606ff
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-fuchsia.tar.xz=91a896dc41c24886da69619bf65fb73ed4261c711270c06747a135d2d57459ae
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-illumos.tar.gz=ab68afbf5469678cd4e8e8a1e6e6a418e140b867da69c3b07a7c57f31fcefde7
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-illumos.tar.xz=8316f75aab299394028d4f49f297f2c235ecdd265517a776681632d173330663
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-linux-gnu.tar.gz=b3050a3b63da621f27517bd1252e976fd69ca45adf24e307627d4ca8b3efd7d7
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-linux-gnu.tar.xz=770237080b9310d126350c3bd70820bd91064c2e96c29ab5f2e002b31b5bd067
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-linux-gnux32.tar.gz=4ec178dba32f3f93ccb2b8493fe12538fe410a70a58cead607f26ed633fb6e71
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-linux-gnux32.tar.xz=cf7f4186d89c37ddc655dd01e515fffd85d4485da06876be34601cba5342301d
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-linux-musl.tar.gz=9c226ea54ceb03d97a70068ec2b9606a2741df6938fe5916d741ccbc099712f7
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-linux-musl.tar.xz=5f976818603468384bd78fde6c4e12f2b0a996d55f4985a33a68b5af54974ac0
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-linux-ohos.tar.gz=a6f34f90982271b7101ecfce278d4e5e2288028048fa30140fd7021451c58c3f
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-linux-ohos.tar.xz=3e5316404d207fbcae402d007291d2c781ad9a3a2c1a54c8b29e39151d223eec
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-netbsd.tar.gz=3613adadfacd038d0e38ebac81e1986903b5e9982ae521cb8828b4c9d8b814db
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-netbsd.tar.xz=344a3adfeda4af316483800bc7d5be584e536779801083e34c66f297aff7562f
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-none.tar.gz=a404fbb75cb6e6ff0c30f9643788353886044b4fa47d71e587e0856f865366d7
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-none.tar.xz=0e0a43435b7b2beada02e6ae6e3b8bb9bbbd3313623dbbaaa50792884ec0a7ae
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-redox.tar.gz=3bc885a374b7ae76ff0024d90f13f1ccf6813cc73c50bc2106170920398824d6
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-redox.tar.xz=50a228ea53f693085e490985b8e4c587504a52b6fa4facfc46966b092c48204d
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-uefi.tar.gz=ee310ac0b2c4ad259fcff30d13ca368cab0755f7597afdeb744a70c3ce6536d5
+dist/2025-01-09/rust-std-1.84.0-x86_64-unknown-uefi.tar.xz=9de92f9a25be99f944b06c225d188b07041b8dbcb1d5d511d8c4ebc45de2e508
+dist/2025-01-09/cargo-1.84.0-aarch64-apple-darwin.tar.gz=1dd13231219728dfb4c3eba59949362ff01a3d139a5f028242d2f5004137f08c
+dist/2025-01-09/cargo-1.84.0-aarch64-apple-darwin.tar.xz=0dc1cf2510c692f0d2ac254bf8474b3f96a719eeb5062b16dceb30361c0d235e
+dist/2025-01-09/cargo-1.84.0-aarch64-pc-windows-msvc.tar.gz=0eabe919a4ebff9f061dd4d7b062407253def98a664be3f5e2b2aa3a4e28823f
+dist/2025-01-09/cargo-1.84.0-aarch64-pc-windows-msvc.tar.xz=d0f7bf5f3ac922e98acf150349cf49b20c189318ca98f2db1ef9fb0f6e897dd0
+dist/2025-01-09/cargo-1.84.0-aarch64-unknown-linux-gnu.tar.gz=8acd371fa7e0cb85b274acdf2281f461d67c25a95a11c78db6be83b9b71989e3
+dist/2025-01-09/cargo-1.84.0-aarch64-unknown-linux-gnu.tar.xz=68d4ad239b6d1e810e7b8591636dc408cb2c1e89661329fed906febf9c0a9d98
+dist/2025-01-09/cargo-1.84.0-aarch64-unknown-linux-musl.tar.gz=fd6beeca96a35d8ce2c1965d2b721086d10e3e591efb1c7656fe06c637c61385
+dist/2025-01-09/cargo-1.84.0-aarch64-unknown-linux-musl.tar.xz=d2cf082baf2736f48bf06e33996814991629088d35cbaa5a6f69d477c22f916f
+dist/2025-01-09/cargo-1.84.0-arm-unknown-linux-gnueabi.tar.gz=36996c95ce04d4e6c1374a6655ef5c3b4eeef161145b51d41d02be9aec10b384
+dist/2025-01-09/cargo-1.84.0-arm-unknown-linux-gnueabi.tar.xz=ee28bfaf610ceca1fd14b8d35ff913c73636e4019ba5973427f577c292bc82dd
+dist/2025-01-09/cargo-1.84.0-arm-unknown-linux-gnueabihf.tar.gz=e33834d9bdcd358771c34c759e54d23c872dfb957d2514e982fc86e79824c449
+dist/2025-01-09/cargo-1.84.0-arm-unknown-linux-gnueabihf.tar.xz=48228ae35953bb6261b1a8dbc36b1cf2f41ffd052d62d494fffdb760c68c0b61
+dist/2025-01-09/cargo-1.84.0-armv7-unknown-linux-gnueabihf.tar.gz=2920f0fd23f1772a1d05697c43a14fa525fa9ed4359ba6af947967c5732af4c6
+dist/2025-01-09/cargo-1.84.0-armv7-unknown-linux-gnueabihf.tar.xz=5284dda073112bc9ff25f374cb50f0fda26247d367880e2c5f29e2ea9554e8c6
+dist/2025-01-09/cargo-1.84.0-i686-pc-windows-gnu.tar.gz=8c2c9d886380cfa1cd26e1615f38cb6f91204510898f848e896afc92c8774446
+dist/2025-01-09/cargo-1.84.0-i686-pc-windows-gnu.tar.xz=bef27b550c8634fb2000b262f455ec854222e5b5d124da36ff66e1d0adfd0d66
+dist/2025-01-09/cargo-1.84.0-i686-pc-windows-msvc.tar.gz=701507cb6b83c361b97c1f70307e1e635e60dac14999353868fa504d544d4eae
+dist/2025-01-09/cargo-1.84.0-i686-pc-windows-msvc.tar.xz=db1865910517dec655f64ac8d1ebe9dc7345c83608e33d3efe361fb70ffae7cc
+dist/2025-01-09/cargo-1.84.0-i686-unknown-linux-gnu.tar.gz=1f614bfbf3bef306c75dcf26607d8a52a104fe19f19a6216544558b7a8ed087d
+dist/2025-01-09/cargo-1.84.0-i686-unknown-linux-gnu.tar.xz=3a20231475b75f2f6ad0f7c5de283c5706403b41e941d3f1ca6cccfbced214c6
+dist/2025-01-09/cargo-1.84.0-loongarch64-unknown-linux-gnu.tar.gz=3a035f36f0f105a238c48495bf83ac036411de2c670b1aadf66d11ac1f3add89
+dist/2025-01-09/cargo-1.84.0-loongarch64-unknown-linux-gnu.tar.xz=1531b9f3d09983c43f54d7e5ced6b452044e82b24609532e8cee345656e5d8a4
+dist/2025-01-09/cargo-1.84.0-loongarch64-unknown-linux-musl.tar.gz=732b974554e0d724748007b74518a2e65e5a10b9980536ea863b23405d7c5e9d
+dist/2025-01-09/cargo-1.84.0-loongarch64-unknown-linux-musl.tar.xz=656329bd047a1e419d0b30d1c59c095c767bd0ae84b18c59652f9be09ffc0ea8
+dist/2025-01-09/cargo-1.84.0-powerpc-unknown-linux-gnu.tar.gz=7cdca593f020fc0ef2fe2ca4873be1e4ab98607ae6f7247892384b711058645d
+dist/2025-01-09/cargo-1.84.0-powerpc-unknown-linux-gnu.tar.xz=dedcb36320cfa924e2d21552057f88ee8a30c0424802015494c2f6237150ec55
+dist/2025-01-09/cargo-1.84.0-powerpc64-unknown-linux-gnu.tar.gz=5c791f7b83ca685284401f84b22bc2816ce08c3cd39e6be9cda21822fcb27802
+dist/2025-01-09/cargo-1.84.0-powerpc64-unknown-linux-gnu.tar.xz=09d9954bf817404c08a8ac952afe1e086ad11fe20d07522a4bde5f26bf7fb5d2
+dist/2025-01-09/cargo-1.84.0-powerpc64le-unknown-linux-gnu.tar.gz=078f53f18363e3190dc8b533969a7133779e954335bc07f290875bf59bd6ed9e
+dist/2025-01-09/cargo-1.84.0-powerpc64le-unknown-linux-gnu.tar.xz=7dc351327de2567cce2a3387f110cce1db20c68fc529353c5cdef2eada5dbfd8
+dist/2025-01-09/cargo-1.84.0-riscv64gc-unknown-linux-gnu.tar.gz=942f47b356133193ce5fd2e75634642c4360a1532c205ecaf79a1fd0fac624ca
+dist/2025-01-09/cargo-1.84.0-riscv64gc-unknown-linux-gnu.tar.xz=3a850b74bdf2c3a5912e9f1ea32aaf1c9ac7c5f89c1c0bcf421b961195833992
+dist/2025-01-09/cargo-1.84.0-s390x-unknown-linux-gnu.tar.gz=dee6a36611d622adc332c7943e17bb38517187060c46ab22e337eba8c30dbf81
+dist/2025-01-09/cargo-1.84.0-s390x-unknown-linux-gnu.tar.xz=bdf944ff5c0b97e8b64093fff8d1f63926df86b5e98f91d30c7bd844c6efa20f
+dist/2025-01-09/cargo-1.84.0-x86_64-apple-darwin.tar.gz=dfec6952d8ecfac1d8760a0b3dec0540f6fdbe9e1489df9aef5a172fc6415ecc
+dist/2025-01-09/cargo-1.84.0-x86_64-apple-darwin.tar.xz=712f5807ce7553ea8903105f27345f3628ec3c15c8a6f62e87bb5429d10545f2
+dist/2025-01-09/cargo-1.84.0-x86_64-pc-windows-gnu.tar.gz=801c4f2a1b7bb261ea6c7fe7bd0771063b4b7ed474df3ceec0b9037d1337be4c
+dist/2025-01-09/cargo-1.84.0-x86_64-pc-windows-gnu.tar.xz=5abeb0580b569877bd0d43fe7330829d7dd8d4472e675cd5ef6ac5e6553f33fb
+dist/2025-01-09/cargo-1.84.0-x86_64-pc-windows-msvc.tar.gz=dca700cc849c95c198403998c422179599be5858d9c61fe4d317bb71f38d345e
+dist/2025-01-09/cargo-1.84.0-x86_64-pc-windows-msvc.tar.xz=635610db1ed6ceea00a746a83b15402bab608b149d15bef0cb1573c6a441da12
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-freebsd.tar.gz=dd630edc84951c9bc84a72741c84fe0f4fce560fe87cb67c3a9587e2b5576fa5
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-freebsd.tar.xz=e428d2866be9fb48852bc6ea25551c77fbdeb0b97856742cf8841c9ca7f71977
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-illumos.tar.gz=86f29478b538a6c0f079e4be8973d40d62d00261534763d70362097f9193082a
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-illumos.tar.xz=7e3b47a6ece0c4d7f534d11764d07d9b685365b5fd82cb533fe63a243039557a
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-linux-gnu.tar.gz=0d63b2f736326127a387b5f9c62ee146eac661e54f4795a07b9f7ad09be16c23
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-linux-gnu.tar.xz=6c2371488db92a09cd50a1b4045c022f3cf2c643285b3b21105ab5f9b64fd6b6
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-linux-musl.tar.gz=efbc3075f517cc12c52133c02590b2faa234fabceceb98f3363a27737a7ff51d
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-linux-musl.tar.xz=0356fa019a7ee60fe6eec2f94c7d68e01b1a7710437bb6cf3422b42c2870d822
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-netbsd.tar.gz=671d40ab0d8ff9e12f14ecd5d67003bb6135a2faf0d070c1ad158c2ecbc7efc0
+dist/2025-01-09/cargo-1.84.0-x86_64-unknown-netbsd.tar.xz=9abba67db92554e7f5aa6c3eb1220e377de3635f62b0d629dad913a9c4edd2b1
+dist/2025-01-09/clippy-1.84.0-aarch64-apple-darwin.tar.gz=0b86ee90f846603f3459e6a3cfe302fde5254de23f5bacd4ced2c588ff41f4b3
+dist/2025-01-09/clippy-1.84.0-aarch64-apple-darwin.tar.xz=5317d98dc9d6994f8d087aabecc16627d1a202500acd09f752d722f5462587df
+dist/2025-01-09/clippy-1.84.0-aarch64-pc-windows-msvc.tar.gz=5eb7de0d9d319346787528a842b720243813bba3b7f43258a407476b26fae656
+dist/2025-01-09/clippy-1.84.0-aarch64-pc-windows-msvc.tar.xz=d1a7ef58a6f6ca103f900453293faa022b10fce53b0a25e36429b272bb79f740
+dist/2025-01-09/clippy-1.84.0-aarch64-unknown-linux-gnu.tar.gz=252a85c2a7e519b6fcc4625b85dc299d81a7d0eb90ef4160dcd86517acf4cd3a
+dist/2025-01-09/clippy-1.84.0-aarch64-unknown-linux-gnu.tar.xz=6022245416a988b9952f36bf20f62de0c2f3337bd150e34439ea6651592ac8ca
+dist/2025-01-09/clippy-1.84.0-aarch64-unknown-linux-musl.tar.gz=40caea642121254cf9c0e7b5c9ed28b12cec6444b961166f7c150a7ca604e6ec
+dist/2025-01-09/clippy-1.84.0-aarch64-unknown-linux-musl.tar.xz=13b87f271557b5160c6872be84e0ef5b2e56d5e79677c1499e64877e084b68d4
+dist/2025-01-09/clippy-1.84.0-arm-unknown-linux-gnueabi.tar.gz=4b90734e9792bcad7914dabd2963621085bf7c6d85a66962f9008e04ef0ba998
+dist/2025-01-09/clippy-1.84.0-arm-unknown-linux-gnueabi.tar.xz=4a99c74586e2b82c57db39f42f6f610d9619bdd206cc3615d6050f2db2971983
+dist/2025-01-09/clippy-1.84.0-arm-unknown-linux-gnueabihf.tar.gz=4f3fd887a55b02515c8fdfdeccfcf9ebd376a02cc232b3dc396a5b68f63feb83
+dist/2025-01-09/clippy-1.84.0-arm-unknown-linux-gnueabihf.tar.xz=a46ff178460420314b10cc814a631e72fa6cdcfc74808a260d9c037087884cd7
+dist/2025-01-09/clippy-1.84.0-armv7-unknown-linux-gnueabihf.tar.gz=d3855f76433c1a1b3d5fb755323e17a2800238b2e0e707981ecec5e0ff284730
+dist/2025-01-09/clippy-1.84.0-armv7-unknown-linux-gnueabihf.tar.xz=e62da2e5c7e384374b96c75f76d3200e48c1f1d4f524740f9521178de72e6308
+dist/2025-01-09/clippy-1.84.0-i686-pc-windows-gnu.tar.gz=dc792b80e7742b4b4229296937629a16686926504de8b89b221a67116faae10e
+dist/2025-01-09/clippy-1.84.0-i686-pc-windows-gnu.tar.xz=51af56af22d6e71d6cb60b47f44cb1ed85cbd63ac137335c877511c13008d60f
+dist/2025-01-09/clippy-1.84.0-i686-pc-windows-msvc.tar.gz=21180404245ec9eb97e5c8c9eaccbf5e6d175a122150c5724bb3eefc81f7e542
+dist/2025-01-09/clippy-1.84.0-i686-pc-windows-msvc.tar.xz=d1a3ae5a4e32015d4b67331cb04ef242b822ec0ee3857bba1a6b6840315a8377
+dist/2025-01-09/clippy-1.84.0-i686-unknown-linux-gnu.tar.gz=5a7039740aff06a9e077492b15f41feaa3d47e67b16187824d0090ac38224b64
+dist/2025-01-09/clippy-1.84.0-i686-unknown-linux-gnu.tar.xz=8b5bdd84b9128abc6d61bc1acb60e55eab90e063c7057371b4e6f79aaa1acb9b
+dist/2025-01-09/clippy-1.84.0-loongarch64-unknown-linux-gnu.tar.gz=27caee490f25656ad0db77fb66a046e7ea6bd423fbb19d23667fd44db2be1043
+dist/2025-01-09/clippy-1.84.0-loongarch64-unknown-linux-gnu.tar.xz=80719f10010eaf6a26ba7b2f8c5c7bce3a78fd838cbbe17c00a4e3e7cd45fe5e
+dist/2025-01-09/clippy-1.84.0-loongarch64-unknown-linux-musl.tar.gz=6f5bcd9a76c462dbaf6d0296537e539948715e49268fa263790395522ca6879f
+dist/2025-01-09/clippy-1.84.0-loongarch64-unknown-linux-musl.tar.xz=c358dc9e6bac4e3d7777d6e26ded2ef7c92721989891794763915f8d5dcbc61a
+dist/2025-01-09/clippy-1.84.0-powerpc-unknown-linux-gnu.tar.gz=498ab2941346920ee1505b5dcb95e48055ca86ddc2906a2c509b5d98b31a3816
+dist/2025-01-09/clippy-1.84.0-powerpc-unknown-linux-gnu.tar.xz=de2413ae321d2bccf77c77acb1e9775b63eca1993ee1450e65e388f029565a51
+dist/2025-01-09/clippy-1.84.0-powerpc64-unknown-linux-gnu.tar.gz=086c05eebe6024332ac6d9aa4008231a87d529842ccfcd6b442bf8a74547eeda
+dist/2025-01-09/clippy-1.84.0-powerpc64-unknown-linux-gnu.tar.xz=a34cde35f254210cbb212c3fa85411efaa8e70d600d2c2404b7b319eae9b5be6
+dist/2025-01-09/clippy-1.84.0-powerpc64le-unknown-linux-gnu.tar.gz=6080fec4cfc0155220d3378e78c45b09caf4ef288879e5178a4b9b0ca0ab4d64
+dist/2025-01-09/clippy-1.84.0-powerpc64le-unknown-linux-gnu.tar.xz=b53cb58c719b84044de62851b6214db8d504f57ad71e81b373d7dea0393146d8
+dist/2025-01-09/clippy-1.84.0-riscv64gc-unknown-linux-gnu.tar.gz=87a2e92fe92590834f60cfca943bcec2f4120c2631dc7c1fcf7b790893219e65
+dist/2025-01-09/clippy-1.84.0-riscv64gc-unknown-linux-gnu.tar.xz=fb8c9d489e10a961f9faa550980069738b5f0f68740e34d7b3ee46a262b53af7
+dist/2025-01-09/clippy-1.84.0-s390x-unknown-linux-gnu.tar.gz=36661fc401318d5b74bfd4db14106f04bbe194e4b3321e3209aabef4cc3c4aaa
+dist/2025-01-09/clippy-1.84.0-s390x-unknown-linux-gnu.tar.xz=b02a586369e6edebb0f0608e396472d1867419213fd01ba32f3c847e4c5a3c07
+dist/2025-01-09/clippy-1.84.0-x86_64-apple-darwin.tar.gz=0bbc95842a1c861855af5181a10e1fb850d38610ad52501f2729bad66337a8a8
+dist/2025-01-09/clippy-1.84.0-x86_64-apple-darwin.tar.xz=101b935f94849a03ceed9908f2ced5fd9f70abd03b4e53008c077a55f0f7ff8e
+dist/2025-01-09/clippy-1.84.0-x86_64-pc-windows-gnu.tar.gz=be9d310b739bade62ea777b31d351871e2177d304dba1b652c2247c5e0ded6ce
+dist/2025-01-09/clippy-1.84.0-x86_64-pc-windows-gnu.tar.xz=5965d477148cdd49f896a214f789a07d36248116cb37f83e42fea93d627f3c8a
+dist/2025-01-09/clippy-1.84.0-x86_64-pc-windows-msvc.tar.gz=891088cb4a69fe2d5b7c4c2ee860b0bfc964ef8aa0a0926d128bdc17378209b3
+dist/2025-01-09/clippy-1.84.0-x86_64-pc-windows-msvc.tar.xz=680cb002a3c0847ffe29dfc675a3aabfba104604fcc6795c1d0c6d35bd9261b2
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-freebsd.tar.gz=c0a385fb58b979cfc430a0dfe2b6dd16620698670f7e5c6bb1291f06e561d0de
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-freebsd.tar.xz=8b98e2a50ab10b8b71482460db1a7400d884c96e87e6201d1689e4066a80a10b
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-illumos.tar.gz=3f89f479b1aadab2fbfcc0ceac4af6435dc6f8166eefcec9b105adb7419ceff0
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-illumos.tar.xz=8f65f53e6f51cbbc1770b84b1e49f6e3b596ab7c12f04f7e5b6c0852969ad25d
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-linux-gnu.tar.gz=7e0aeac429cf32fed5c10145c638fcf0af78d369ec45d476efe77807900780b6
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-linux-gnu.tar.xz=1db0212c08e126bf6ee28a0d363c5d6859fe357aa9e91d0247059397dbe7e1fd
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-linux-musl.tar.gz=f0844ed876bc70972745adedb69294637c65d099a2eb4e7aeb80eff36089d172
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-linux-musl.tar.xz=e3cf9dd84c61fc37f5d834026d1f0aeb14b75df561b762436d435e2ea0308b1a
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-netbsd.tar.gz=89fcfc0059ffaed872a31e1aa14917e20d7229e20e5d1bdce299c3cb35bb97d8
+dist/2025-01-09/clippy-1.84.0-x86_64-unknown-netbsd.tar.xz=a87cca2556a99787a102c6c6508d7bb2f139cbd7d07d9b90575bb22a1f401bec
\ No newline at end of file
diff --git a/src/tools/clippy/clippy_lints/src/literal_string_with_formatting_args.rs b/src/tools/clippy/clippy_lints/src/literal_string_with_formatting_args.rs
index 49353a1b76bec..2d8c1e492fb65 100644
--- a/src/tools/clippy/clippy_lints/src/literal_string_with_formatting_args.rs
+++ b/src/tools/clippy/clippy_lints/src/literal_string_with_formatting_args.rs
@@ -31,7 +31,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.83.0"]
     pub LITERAL_STRING_WITH_FORMATTING_ARGS,
-    suspicious,
+    nursery,
     "Checks if string literals have formatting arguments"
 }
 
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 428b40c5771c8..104ae154e3695 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
@@ -109,7 +109,7 @@ fn check_rvalue<'tcx>(
 ) -> McfResult {
     match rvalue {
         Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())),
-        Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
+        Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
             check_place(tcx, *place, span, body, msrv)
         },
         Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index 15dd6aba311fc..e3041cd91fe5f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -94,7 +94,7 @@ impl FunctionData {
             .map(Box::new);
         let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists();
         if flags.contains(FnFlags::HAS_UNSAFE_KW)
-            && !crate_graph[krate].edition.at_least_2024()
+            // && !crate_graph[krate].edition.at_least_2024()
             && attrs.by_key(&sym::rustc_deprecated_safe_2024).exists()
         {
             flags.remove(FnFlags::HAS_UNSAFE_KW);
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
index b23f2749ab285..42c030dfc6c1c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
@@ -226,8 +226,8 @@ impl<'a> TyLoweringContext<'a> {
         self
     }
 
-    pub fn push_diagnostic(&mut self, type_ref: TypeRefId, kind: TyLoweringDiagnosticKind) {
-        let source = match self.types_source_map {
+    pub fn push_diagnostic(&mut self, type_ref: TypeRefId, _kind: TyLoweringDiagnosticKind) {
+        let _source = match self.types_source_map {
             Some(source_map) => {
                 let Ok(source) = source_map.type_syntax(type_ref) else {
                     stdx::never!("error in synthetic type");
@@ -237,7 +237,7 @@ impl<'a> TyLoweringContext<'a> {
             }
             None => Either::Left(type_ref),
         };
-        self.diagnostics.push(TyLoweringDiagnostic { source, kind });
+        // self.diagnostics.push(TyLoweringDiagnostic { source, kind });
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
index 85833dab1b092..c8d9e6cc2990d 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs
@@ -175,7 +175,7 @@ fn expand_id(
             });
         let res = match thread {
             Ok(handle) => handle.join(),
-            Err(e) => std::panic::resume_unwind(Box::new(e)),
+            Err(e) => return Err(e.to_string()),
         };
 
         match res {
@@ -223,7 +223,7 @@ fn expand_ra_span(
             });
         let res = match thread {
             Ok(handle) => handle.join(),
-            Err(e) => std::panic::resume_unwind(Box::new(e)),
+            Err(e) => return Err(e.to_string()),
         };
 
         match res {
diff --git a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs
index 8530521d9157b..6e43676354c25 100644
--- a/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ra-salsa/src/lib.rs
@@ -610,11 +610,9 @@ where
 #[non_exhaustive]
 pub enum Cancelled {
     /// The query was operating on revision R, but there is a pending write to move to revision R+1.
-    #[non_exhaustive]
     PendingWrite,
 
     /// The query was blocked on another thread, and that thread panicked.
-    #[non_exhaustive]
     PropagatedPanic,
 }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs
index 2aa4ffbe1dc11..148a8194cdaa0 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs
@@ -5,6 +5,7 @@ use std::{
 };
 
 use ide::Cancelled;
+use ide_db::base_db::ra_salsa::Cycle;
 use lsp_server::{ExtractError, Response, ResponseError};
 use serde::{de::DeserializeOwned, Serialize};
 use stdx::thread::ThreadIntent;
@@ -328,7 +329,13 @@ where
             if let Some(panic_message) = panic_message {
                 message.push_str(": ");
                 message.push_str(panic_message)
-            };
+            } else if let Some(cycle) = panic.downcast_ref::<Cycle>() {
+                tracing::error!("Cycle propagated out of salsa! This is a bug: {cycle:?}");
+                return Err(Cancelled::PropagatedPanic);
+            } else if let Ok(cancelled) = panic.downcast::<Cancelled>() {
+                tracing::error!("Cancellation propagated out of salsa! This is a bug");
+                return Err(*cancelled);
+            }
 
             Ok(lsp_server::Response::new_err(
                 id,
diff --git a/src/tools/rustfmt/src/bin/main.rs b/src/tools/rustfmt/src/bin/main.rs
index 4078484ff10fe..28df49b9304c5 100644
--- a/src/tools/rustfmt/src/bin/main.rs
+++ b/src/tools/rustfmt/src/bin/main.rs
@@ -161,6 +161,12 @@ fn make_opts() -> Options {
         "Set options from command line. These settings take priority over .rustfmt.toml",
         "[key1=val1,key2=val2...]",
     );
+    opts.optopt(
+        "",
+        "style-edition",
+        "The edition of the Style Guide.",
+        "[2015|2018|2021|2024]",
+    );
 
     if is_nightly {
         opts.optflag(
@@ -186,12 +192,6 @@ fn make_opts() -> Options {
             "skip-children",
             "Don't reformat child modules (unstable).",
         );
-        opts.optopt(
-            "",
-            "style-edition",
-            "The edition of the Style Guide (unstable).",
-            "[2015|2018|2021|2024]",
-        );
     }
 
     opts.optflag("v", "verbose", "Print verbose output");
@@ -817,7 +817,6 @@ mod test {
         options.inline_config = HashMap::from([("version".to_owned(), "Two".to_owned())]);
         let config = get_config(None, Some(options));
         assert_eq!(config.style_edition(), StyleEdition::Edition2024);
-        assert_eq!(config.overflow_delimited_expr(), true);
     }
 
     #[nightly_only_test]
@@ -827,7 +826,6 @@ mod test {
         let config_file = Some(Path::new("tests/config/style-edition/just-version"));
         let config = get_config(config_file, Some(options));
         assert_eq!(config.style_edition(), StyleEdition::Edition2024);
-        assert_eq!(config.overflow_delimited_expr(), true);
     }
 
     #[nightly_only_test]
@@ -872,7 +870,6 @@ mod test {
         ]);
         let config = get_config(None, Some(options));
         assert_eq!(config.style_edition(), StyleEdition::Edition2024);
-        assert_eq!(config.overflow_delimited_expr(), true);
     }
 
     #[nightly_only_test]
@@ -938,7 +935,6 @@ mod test {
         options.style_edition = Some(StyleEdition::Edition2024);
         let config = get_config(None, Some(options));
         assert_eq!(config.style_edition(), StyleEdition::Edition2024);
-        assert_eq!(config.overflow_delimited_expr(), true);
     }
 
     #[nightly_only_test]
@@ -948,6 +944,8 @@ mod test {
         let config_file = Some(Path::new("tests/config/style-edition/overrides"));
         let config = get_config(config_file, Some(options));
         assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+        // FIXME: this test doesn't really exercise anything, since
+        // `overflow_delimited_expr` is disabled by default in edition 2024.
         assert_eq!(config.overflow_delimited_expr(), false);
     }
 
@@ -959,7 +957,8 @@ mod test {
         options.inline_config =
             HashMap::from([("overflow_delimited_expr".to_owned(), "false".to_owned())]);
         let config = get_config(config_file, Some(options));
-        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+        // FIXME: this test doesn't really exercise anything, since
+        // `overflow_delimited_expr` is disabled by default in edition 2024.
         assert_eq!(config.overflow_delimited_expr(), false);
     }
 }
diff --git a/src/tools/rustfmt/src/config/mod.rs b/src/tools/rustfmt/src/config/mod.rs
index 7355adc9f9df1..6b63108c037eb 100644
--- a/src/tools/rustfmt/src/config/mod.rs
+++ b/src/tools/rustfmt/src/config/mod.rs
@@ -848,7 +848,7 @@ binop_separator = "Front"
 remove_nested_parens = true
 combine_control_expr = true
 short_array_element_width_threshold = 10
-overflow_delimited_expr = true
+overflow_delimited_expr = false
 struct_field_align_threshold = 0
 enum_discrim_align_threshold = 0
 match_arm_blocks = true
diff --git a/src/tools/rustfmt/src/config/options.rs b/src/tools/rustfmt/src/config/options.rs
index bbc99a2dced2b..71865ec75ce6e 100644
--- a/src/tools/rustfmt/src/config/options.rs
+++ b/src/tools/rustfmt/src/config/options.rs
@@ -627,7 +627,7 @@ config_option_with_style_edition_default!(
     RemoveNestedParens, bool, _ => true;
     CombineControlExpr, bool, _ => true;
     ShortArrayElementWidthThreshold, usize, _ => 10;
-    OverflowDelimitedExpr, bool, Edition2024 => true, _ => false;
+    OverflowDelimitedExpr, bool, _ => false;
     StructFieldAlignThreshold, usize, _ => 0;
     EnumDiscrimAlignThreshold, usize, _ => 0;
     MatchArmBlocks, bool, _ => true;
@@ -644,7 +644,7 @@ config_option_with_style_edition_default!(
     BlankLinesLowerBound, usize, _ => 0;
     EditionConfig, Edition, _ => Edition::Edition2015;
     StyleEditionConfig, StyleEdition,
-        Edition2024 =>  StyleEdition::Edition2024, _ => StyleEdition::Edition2015;
+        Edition2024 => StyleEdition::Edition2024, _ => StyleEdition::Edition2015;
     VersionConfig, Version, Edition2024 => Version::Two, _ => Version::One;
     InlineAttributeWidth, usize, _ => 0;
     FormatGeneratedFiles, bool, _ => true;
diff --git a/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs b/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs
index ecd2e8ca79708..1b2d12ce32019 100644
--- a/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs
+++ b/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs
@@ -25,10 +25,13 @@ fn combine_blocklike() {
         y: value2,
     });
 
-    do_thing(x, Bar {
-        x: value,
-        y: value2,
-    });
+    do_thing(
+        x,
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
 
     do_thing(
         x,
@@ -46,12 +49,15 @@ fn combine_blocklike() {
         value4_with_longer_name,
     ]);
 
-    do_thing(x, &[
-        value_with_longer_name,
-        value2_with_longer_name,
-        value3_with_longer_name,
-        value4_with_longer_name,
-    ]);
+    do_thing(
+        x,
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
 
     do_thing(
         x,
@@ -71,12 +77,15 @@ fn combine_blocklike() {
         value4_with_longer_name,
     ]);
 
-    do_thing(x, vec![
-        value_with_longer_name,
-        value2_with_longer_name,
-        value3_with_longer_name,
-        value4_with_longer_name,
-    ]);
+    do_thing(
+        x,
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
 
     do_thing(
         x,
@@ -99,22 +108,28 @@ fn combine_blocklike() {
 }
 
 fn combine_struct_sample() {
-    let identity = verify(&ctx, VerifyLogin {
-        type_: LoginType::Username,
-        username: args.username.clone(),
-        password: Some(args.password.clone()),
-        domain: None,
-    })?;
+    let identity = verify(
+        &ctx,
+        VerifyLogin {
+            type_: LoginType::Username,
+            username: args.username.clone(),
+            password: Some(args.password.clone()),
+            domain: None,
+        },
+    )?;
 }
 
 fn combine_macro_sample() {
     rocket::ignite()
-        .mount("/", routes![
-            http::auth::login,
-            http::auth::logout,
-            http::cors::options,
-            http::action::dance,
-            http::action::sleep,
-        ])
+        .mount(
+            "/",
+            routes![
+                http::auth::login,
+                http::auth::logout,
+                http::cors::options,
+                http::action::dance,
+                http::action::sleep,
+            ],
+        )
         .launch();
 }
diff --git a/src/version b/src/version
index f288d11142d11..8510ffad03679 100644
--- a/src/version
+++ b/src/version
@@ -1 +1 @@
-1.85.0
+1.85.1
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
index 8d9176ef301ff..a467987e88612 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
@@ -7,7 +7,8 @@ fn main() -> () {
     let mut _5: u32;
     let mut _6: *mut usize;
     let _7: usize;
-    let mut _8: bool;
+    let mut _8: usize;
+    let mut _9: bool;
     scope 1 {
         debug x => _1;
         let mut _2: usize;
@@ -40,8 +41,9 @@ fn main() -> () {
         StorageDead(_6);
         StorageLive(_7);
         _7 = copy _2;
-        _8 = Lt(copy _7, const 3_usize);
-        assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind unreachable];
+        _8 = Len(_1);
+        _9 = Lt(copy _7, copy _8);
+        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
     }
 
     bb2: {
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
index e1df0e3e2a3b2..bd7365543bdce 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
@@ -7,7 +7,8 @@ fn main() -> () {
     let mut _5: u32;
     let mut _6: *mut usize;
     let _7: usize;
-    let mut _8: bool;
+    let mut _8: usize;
+    let mut _9: bool;
     scope 1 {
         debug x => _1;
         let mut _2: usize;
@@ -40,8 +41,9 @@ fn main() -> () {
         StorageDead(_6);
         StorageLive(_7);
         _7 = copy _2;
-        _8 = Lt(copy _7, const 3_usize);
-        assert(move _8, "index out of bounds: the length is {} but the index is {}", const 3_usize, copy _7) -> [success: bb2, unwind continue];
+        _8 = Len(_1);
+        _9 = Lt(copy _7, copy _8);
+        assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
     }
 
     bb2: {
diff --git a/tests/mir-opt/building/custom/arrays.arrays.built.after.mir b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir
new file mode 100644
index 0000000000000..30d11e31e4d4e
--- /dev/null
+++ b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir
@@ -0,0 +1,14 @@
+// MIR for `arrays` after built
+
+fn arrays() -> usize {
+    let mut _0: usize;
+    let mut _1: [i32; C];
+    let mut _2: usize;
+
+    bb0: {
+        _1 = [const 5_i32; C];
+        _2 = Len(_1);
+        _0 = copy _2;
+        return;
+    }
+}
diff --git a/tests/mir-opt/building/custom/arrays.rs b/tests/mir-opt/building/custom/arrays.rs
new file mode 100644
index 0000000000000..4bd6f93e11340
--- /dev/null
+++ b/tests/mir-opt/building/custom/arrays.rs
@@ -0,0 +1,22 @@
+// skip-filecheck
+#![feature(custom_mir, core_intrinsics)]
+
+extern crate core;
+use core::intrinsics::mir::*;
+
+// EMIT_MIR arrays.arrays.built.after.mir
+#[custom_mir(dialect = "built")]
+fn arrays<const C: usize>() -> usize {
+    mir! {
+        {
+            let x = [5_i32; C];
+            let c = Len(x);
+            RET = c;
+            Return()
+        }
+    }
+}
+
+fn main() {
+    assert_eq!(arrays::<20>(), 20);
+}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir
deleted file mode 100644
index d28a2031013f3..0000000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_array.built.after.mir
+++ /dev/null
@@ -1,31 +0,0 @@
-// MIR for `index_array` after built
-
-fn index_array(_1: &[i32; 7], _2: usize) -> &i32 {
-    debug array => _1;
-    debug index => _2;
-    let mut _0: &i32;
-    let _3: &i32;
-    let _4: usize;
-    let mut _5: bool;
-
-    bb0: {
-        StorageLive(_3);
-        StorageLive(_4);
-        _4 = copy _2;
-        FakeRead(ForIndex, (*_1));
-        _5 = Lt(copy _4, const 7_usize);
-        assert(move _5, "index out of bounds: the length is {} but the index is {}", const 7_usize, copy _4) -> [success: bb1, unwind: bb2];
-    }
-
-    bb1: {
-        _3 = &(*_1)[_4];
-        _0 = &(*_3);
-        StorageDead(_4);
-        StorageDead(_3);
-        return;
-    }
-
-    bb2 (cleanup): {
-        resume;
-    }
-}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir
deleted file mode 100644
index e9627532c3828..0000000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_const_generic_array.built.after.mir
+++ /dev/null
@@ -1,31 +0,0 @@
-// MIR for `index_const_generic_array` after built
-
-fn index_const_generic_array(_1: &[i32; N], _2: usize) -> &i32 {
-    debug array => _1;
-    debug index => _2;
-    let mut _0: &i32;
-    let _3: &i32;
-    let _4: usize;
-    let mut _5: bool;
-
-    bb0: {
-        StorageLive(_3);
-        StorageLive(_4);
-        _4 = copy _2;
-        FakeRead(ForIndex, (*_1));
-        _5 = Lt(copy _4, const N);
-        assert(move _5, "index out of bounds: the length is {} but the index is {}", const N, copy _4) -> [success: bb1, unwind: bb2];
-    }
-
-    bb1: {
-        _3 = &(*_1)[_4];
-        _0 = &(*_3);
-        StorageDead(_4);
-        StorageDead(_3);
-        return;
-    }
-
-    bb2 (cleanup): {
-        resume;
-    }
-}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir
deleted file mode 100644
index 00f2b7e07d551..0000000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_custom.built.after.mir
+++ /dev/null
@@ -1,34 +0,0 @@
-// MIR for `index_custom` after built
-
-fn index_custom(_1: &WithSliceTail, _2: usize) -> &i32 {
-    debug custom => _1;
-    debug index => _2;
-    let mut _0: &i32;
-    let _3: &i32;
-    let _4: usize;
-    let mut _5: *const [i32];
-    let mut _6: usize;
-    let mut _7: bool;
-
-    bb0: {
-        StorageLive(_3);
-        StorageLive(_4);
-        _4 = copy _2;
-        _5 = &raw const ((*_1).1: [i32]);
-        _6 = PtrMetadata(move _5);
-        _7 = Lt(copy _4, copy _6);
-        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];
-    }
-
-    bb1: {
-        _3 = &((*_1).1: [i32])[_4];
-        _0 = &(*_3);
-        StorageDead(_4);
-        StorageDead(_3);
-        return;
-    }
-
-    bb2 (cleanup): {
-        resume;
-    }
-}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir
deleted file mode 100644
index cb0b2f600c81a..0000000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_mut_slice.built.after.mir
+++ /dev/null
@@ -1,34 +0,0 @@
-// MIR for `index_mut_slice` after built
-
-fn index_mut_slice(_1: &mut [i32], _2: usize) -> &i32 {
-    debug slice => _1;
-    debug index => _2;
-    let mut _0: &i32;
-    let _3: &i32;
-    let _4: usize;
-    let mut _5: *const [i32];
-    let mut _6: usize;
-    let mut _7: bool;
-
-    bb0: {
-        StorageLive(_3);
-        StorageLive(_4);
-        _4 = copy _2;
-        _5 = &raw const (*_1);
-        _6 = PtrMetadata(move _5);
-        _7 = Lt(copy _4, copy _6);
-        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb2];
-    }
-
-    bb1: {
-        _3 = &(*_1)[_4];
-        _0 = &(*_3);
-        StorageDead(_4);
-        StorageDead(_3);
-        return;
-    }
-
-    bb2 (cleanup): {
-        resume;
-    }
-}
diff --git a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir b/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir
deleted file mode 100644
index 0911df590497c..0000000000000
--- a/tests/mir-opt/building/index_array_and_slice.index_slice.built.after.mir
+++ /dev/null
@@ -1,32 +0,0 @@
-// MIR for `index_slice` after built
-
-fn index_slice(_1: &[i32], _2: usize) -> &i32 {
-    debug slice => _1;
-    debug index => _2;
-    let mut _0: &i32;
-    let _3: &i32;
-    let _4: usize;
-    let mut _5: usize;
-    let mut _6: bool;
-
-    bb0: {
-        StorageLive(_3);
-        StorageLive(_4);
-        _4 = copy _2;
-        _5 = PtrMetadata(copy _1);
-        _6 = Lt(copy _4, copy _5);
-        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb2];
-    }
-
-    bb1: {
-        _3 = &(*_1)[_4];
-        _0 = &(*_3);
-        StorageDead(_4);
-        StorageDead(_3);
-        return;
-    }
-
-    bb2 (cleanup): {
-        resume;
-    }
-}
diff --git a/tests/mir-opt/building/index_array_and_slice.rs b/tests/mir-opt/building/index_array_and_slice.rs
deleted file mode 100644
index 16d0b983132df..0000000000000
--- a/tests/mir-opt/building/index_array_and_slice.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-//@ compile-flags: -C opt-level=0
-
-// EMIT_MIR index_array_and_slice.index_array.built.after.mir
-fn index_array(array: &[i32; 7], index: usize) -> &i32 {
-    // CHECK: bb0:
-    // CHECK: [[LT:_.+]] = Lt(copy _2, const 7_usize);
-    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const 7_usize, copy _2) -> [success: bb1, unwind
-
-    // CHECK: bb1:
-    // CHECK: _0 = &(*_1)[_2];
-    &array[index]
-}
-
-// EMIT_MIR index_array_and_slice.index_const_generic_array.built.after.mir
-fn index_const_generic_array<const N: usize>(array: &[i32; N], index: usize) -> &i32 {
-    // CHECK: bb0:
-    // CHECK: [[LT:_.+]] = Lt(copy _2, const N);
-    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", const N, copy _2) -> [success: bb1, unwind
-
-    // CHECK: bb1:
-    // CHECK: _0 = &(*_1)[_2];
-    &array[index]
-}
-
-// EMIT_MIR index_array_and_slice.index_slice.built.after.mir
-fn index_slice(slice: &[i32], index: usize) -> &i32 {
-    // CHECK: bb0:
-    // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
-    // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
-    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
-
-    // CHECK: bb1:
-    // CHECK: _0 = &(*_1)[_2];
-    &slice[index]
-}
-
-// EMIT_MIR index_array_and_slice.index_mut_slice.built.after.mir
-fn index_mut_slice(slice: &mut [i32], index: usize) -> &i32 {
-    // While the filecheck here is identical to the above test, the emitted MIR is different.
-    // This cannot `copy _1` in the *built* MIR, only in the *runtime* MIR.
-
-    // CHECK: bb0:
-    // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
-    // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
-    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
-
-    // CHECK: bb1:
-    // CHECK: _0 = &(*_1)[_2];
-    &slice[index]
-}
-
-struct WithSliceTail(f64, [i32]);
-
-// EMIT_MIR index_array_and_slice.index_custom.built.after.mir
-fn index_custom(custom: &WithSliceTail, index: usize) -> &i32 {
-    // CHECK: bb0:
-    // CHECK: [[PTR:_.+]] = &raw const ((*_1).1: [i32]);
-    // CHECK: [[LEN:_.+]] = PtrMetadata(move [[PTR]]);
-    // CHECK: [[LT:_.+]] = Lt(copy _2, copy [[LEN]]);
-    // CHECK: assert(move [[LT]], "index out of bounds{{.+}}", move [[LEN]], copy _2) -> [success: bb1,
-
-    // CHECK: bb1:
-    // CHECK: _0 = &((*_1).1: [i32])[_2];
-    &custom.1[index]
-}
-
-fn main() {
-    index_array(&[1, 2, 3, 4, 5, 6, 7], 3);
-    index_slice(&[1, 2, 3, 4, 5, 6, 7][..], 3);
-    _ = index_custom;
-}
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff
index 3a5a8d0099128..e754af95ce399 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-abort.diff
@@ -6,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 4_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const 4_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff
index 62d6e6007e5c9..e15a35c7fe945 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.32bit.panic-unwind.diff
@@ -6,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 4_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _4 = const 4_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff
index 3a5a8d0099128..e754af95ce399 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-abort.diff
@@ -6,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 4_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const 4_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff
index 62d6e6007e5c9..e15a35c7fe945 100644
--- a/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/array_index.main.GVN.64bit.panic-unwind.diff
@@ -6,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 4_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _4 = const 4_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
index be42c4d60c807..15d3014036713 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
@@ -30,22 +30,19 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
--         StorageLive(_6);
-+         nop;
+          StorageLive(_6);
           _6 = const 3_usize;
--         _7 = PtrMetadata(copy _1);
+          _7 = Len((*_1));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const false;
-+         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
++         _8 = Lt(const 3_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
--         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-+         nop;
+          StorageDead(_6);
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
index b51d0c0845f38..dd411d84f9fbe 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
@@ -30,22 +30,19 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
--         StorageLive(_6);
-+         nop;
+          StorageLive(_6);
           _6 = const 3_usize;
--         _7 = PtrMetadata(copy _1);
+          _7 = Len((*_1));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const false;
-+         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
++         _8 = Lt(const 3_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
--         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-+         nop;
+          StorageDead(_6);
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
index be42c4d60c807..15d3014036713 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
@@ -30,22 +30,19 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
--         StorageLive(_6);
-+         nop;
+          StorageLive(_6);
           _6 = const 3_usize;
--         _7 = PtrMetadata(copy _1);
+          _7 = Len((*_1));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const false;
-+         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind unreachable];
++         _8 = Lt(const 3_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
--         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-+         nop;
+          StorageDead(_6);
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
index b51d0c0845f38..dd411d84f9fbe 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
@@ -30,22 +30,19 @@
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_5);
--         StorageLive(_6);
-+         nop;
+          StorageLive(_6);
           _6 = const 3_usize;
--         _7 = PtrMetadata(copy _1);
+          _7 = Len((*_1));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const false;
-+         assert(const false, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 3_usize) -> [success: bb1, unwind continue];
++         _8 = Lt(const 3_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
 -         _5 = copy (*_1)[_6];
--         StorageDead(_6);
 +         _5 = copy (*_1)[3 of 4];
-+         nop;
+          StorageDead(_6);
           _0 = const ();
           StorageDead(_5);
           StorageDead(_1);
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff
index 3569998b13fa5..49ea51deed69d 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-abort.diff
@@ -6,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 5000_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const 5000_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff
index 50b31c9ac136c..103bfbcaf6426 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.32bit.panic-unwind.diff
@@ -6,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 5000_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _4 = const 5000_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff
index 3569998b13fa5..49ea51deed69d 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-abort.diff
@@ -6,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 5000_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const 5000_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff
index 50b31c9ac136c..103bfbcaf6426 100644
--- a/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/large_array_index.main.GVN.64bit.panic-unwind.diff
@@ -6,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 5000_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _4 = const 5000_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff
index a41668b6fa36a..f7c1c2da01fc1 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-abort.diff
@@ -7,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Lt(copy _4, const 8_usize);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const true;
+-         _5 = Len(_3);
+-         _6 = Lt(copy _4, copy _5);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const 8_usize;
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff
index 2313084b49e6f..436773c855636 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.32bit.panic-unwind.diff
@@ -7,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Lt(copy _4, const 8_usize);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const true;
+-         _5 = Len(_3);
+-         _6 = Lt(copy _4, copy _5);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
++         _5 = const 8_usize;
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff
index a41668b6fa36a..f7c1c2da01fc1 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-abort.diff
@@ -7,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Lt(copy _4, const 8_usize);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const true;
+-         _5 = Len(_3);
+-         _6 = Lt(copy _4, copy _5);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const 8_usize;
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff
index 2313084b49e6f..436773c855636 100644
--- a/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/repeat.main.GVN.64bit.panic-unwind.diff
@@ -7,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Lt(copy _4, const 8_usize);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const true;
+-         _5 = Len(_3);
+-         _6 = Lt(copy _4, copy _5);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
++         _5 = const 8_usize;
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
index 0798b30392956..8a8ea5b7e200b 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-abort.diff
@@ -30,12 +30,11 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = PtrMetadata(copy _2);
+          _7 = Len((*_2));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
++         _8 = Lt(const 1_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
index c0b3d4d321902..f0c844884f670 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.32bit.panic-unwind.diff
@@ -30,12 +30,11 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = PtrMetadata(copy _2);
+          _7 = Len((*_2));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
++         _8 = Lt(const 1_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
index 0798b30392956..8a8ea5b7e200b 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-abort.diff
@@ -30,12 +30,11 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = PtrMetadata(copy _2);
+          _7 = Len((*_2));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
++         _8 = Lt(const 1_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
index c0b3d4d321902..f0c844884f670 100644
--- a/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/slice_len.main.GVN.64bit.panic-unwind.diff
@@ -30,12 +30,11 @@
           StorageDead(_3);
           StorageLive(_6);
           _6 = const 1_usize;
--         _7 = PtrMetadata(copy _2);
+          _7 = Len((*_2));
 -         _8 = Lt(copy _6, copy _7);
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
-+         _7 = const 3_usize;
-+         _8 = const true;
-+         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
++         _8 = Lt(const 1_usize, copy _7);
++         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 1_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
index 689083dfc1d3a..6d967257df1f5 100644
--- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
+++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-abort.diff
@@ -18,7 +18,8 @@
       let mut _15: !;
       let mut _17: i32;
       let _18: usize;
-      let mut _19: bool;
+      let mut _19: usize;
+      let mut _20: bool;
       scope 1 {
           debug sum => _1;
           let _2: [i32; 4];
@@ -91,10 +92,11 @@
           StorageLive(_17);
 -         StorageLive(_18);
 -         _18 = copy _16;
--         _19 = Lt(copy _18, const 4_usize);
--         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind unreachable];
-+         _19 = Lt(copy _16, const 4_usize);
-+         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind unreachable];
+          _19 = Len(_2);
+-         _20 = Lt(copy _18, copy _19);
+-         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind unreachable];
++         _20 = Lt(copy _16, copy _19);
++         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind unreachable];
       }
   
       bb7: {
diff --git a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
index 7f768a9f834d9..3580c87c46995 100644
--- a/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/issue_107511.main.CopyProp.panic-unwind.diff
@@ -18,7 +18,8 @@
       let mut _15: !;
       let mut _17: i32;
       let _18: usize;
-      let mut _19: bool;
+      let mut _19: usize;
+      let mut _20: bool;
       scope 1 {
           debug sum => _1;
           let _2: [i32; 4];
@@ -91,10 +92,11 @@
           StorageLive(_17);
 -         StorageLive(_18);
 -         _18 = copy _16;
--         _19 = Lt(copy _18, const 4_usize);
--         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _18) -> [success: bb8, unwind continue];
-+         _19 = Lt(copy _16, const 4_usize);
-+         assert(move _19, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _16) -> [success: bb8, unwind continue];
+          _19 = Len(_2);
+-         _20 = Lt(copy _18, copy _19);
+-         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _18) -> [success: bb8, unwind continue];
++         _20 = Lt(copy _16, copy _19);
++         assert(move _20, "index out of bounds: the length is {} but the index is {}", move _19, copy _16) -> [success: bb8, unwind continue];
       }
   
       bb7: {
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff
index 0275d7e8a0d4d..a46daef435f3b 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-abort.diff
@@ -6,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 4_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const 4_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff
index 490ed4b55a1da..1a4e15b45faad 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -6,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 4_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _4 = const 4_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff
index 0275d7e8a0d4d..a46daef435f3b 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-abort.diff
@@ -6,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 4_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const 4_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff
index 490ed4b55a1da..1a4e15b45faad 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/array_index.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -6,7 +6,8 @@
       let _1: u32;
       let mut _2: [u32; 4];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 4_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 4_usize, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _4 = const 4_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 4_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/array_index.rs b/tests/mir-opt/dataflow-const-prop/array_index.rs
index 1aa8dcd28f4eb..e442ef99f79e6 100644
--- a/tests/mir-opt/dataflow-const-prop/array_index.rs
+++ b/tests/mir-opt/dataflow-const-prop/array_index.rs
@@ -11,10 +11,9 @@ fn main() {
 
     // CHECK:       [[array_lit]] = [const 0_u32, const 1_u32, const 2_u32, const 3_u32];
     // CHECK-NOT:   {{_.*}} = Len(
-    // CHECK-NOT:   {{_.*}} = PtrMetadata(
     // CHECK-NOT:   {{_.*}} = Lt(
     // CHECK-NOT:   assert(move _
-    // CHECK:       {{_.*}} = const 2_usize;
+    // CHECK:       {{_.*}} = const 4_usize;
     // CHECK:       {{_.*}} = const true;
     // CHECK:       assert(const true
     // CHECK:       [[x]] = copy [[array_lit]][2 of 3];
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff
index f0d59ef5923fb..b7ff0b671f7bf 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-abort.diff
@@ -6,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 5000_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const 5000_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff
index 959c3e75214fb..af6e3626142fc 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -6,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 5000_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _4 = const 5000_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff
index f0d59ef5923fb..b7ff0b671f7bf 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-abort.diff
@@ -6,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 5000_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind unreachable];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
++         _4 = const 5000_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff
index 959c3e75214fb..af6e3626142fc 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -6,7 +6,8 @@
       let _1: u8;
       let mut _2: [u8; 5000];
       let _3: usize;
-      let mut _4: bool;
+      let mut _4: usize;
+      let mut _5: bool;
       scope 1 {
           debug x => _1;
       }
@@ -17,9 +18,11 @@
           _2 = [const 0_u8; 5000];
           StorageLive(_3);
           _3 = const 2_usize;
--         _4 = Lt(copy _3, const 5000_usize);
--         assert(move _4, "index out of bounds: the length is {} but the index is {}", const 5000_usize, copy _3) -> [success: bb1, unwind continue];
-+         _4 = const true;
+-         _4 = Len(_2);
+-         _5 = Lt(copy _3, copy _4);
+-         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
++         _4 = const 5000_usize;
++         _5 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 5000_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/large_array_index.rs b/tests/mir-opt/dataflow-const-prop/large_array_index.rs
index e490cfde24726..e9f2fa2badf95 100644
--- a/tests/mir-opt/dataflow-const-prop/large_array_index.rs
+++ b/tests/mir-opt/dataflow-const-prop/large_array_index.rs
@@ -10,7 +10,7 @@ fn main() {
 
     // CHECK: debug x => [[x:_.*]];
     // CHECK: [[array_lit:_.*]] = [const 0_u8; 5000];
-    // CHECK: {{_.*}} = const 2_usize;
+    // CHECK: {{_.*}} = const 5000_usize;
     // CHECK: {{_.*}} = const true;
     // CHECK: assert(const true
     // CHECK: [[x]] = copy [[array_lit]][2 of 3];
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff
index 618121ea6326c..dfa541b1200d5 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-abort.diff
@@ -7,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Lt(copy _4, const 8_usize);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const true;
+-         _5 = Len(_3);
+-         _6 = Lt(copy _4, copy _5);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const 8_usize;
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff
index 1788f58432b8e..9ede3c5f7ac21 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -7,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Lt(copy _4, const 8_usize);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const true;
+-         _5 = Len(_3);
+-         _6 = Lt(copy _4, copy _5);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
++         _5 = const 8_usize;
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff
index 618121ea6326c..dfa541b1200d5 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-abort.diff
@@ -7,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Lt(copy _4, const 8_usize);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind unreachable];
-+         _5 = const true;
+-         _5 = Len(_3);
+-         _6 = Lt(copy _4, copy _5);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind unreachable];
++         _5 = const 8_usize;
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind unreachable];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff
index 1788f58432b8e..9ede3c5f7ac21 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/repeat.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -7,7 +7,8 @@
       let mut _2: u32;
       let mut _3: [u32; 8];
       let _4: usize;
-      let mut _5: bool;
+      let mut _5: usize;
+      let mut _6: bool;
       scope 1 {
           debug x => _1;
       }
@@ -19,9 +20,11 @@
           _3 = [const 42_u32; 8];
           StorageLive(_4);
           _4 = const 2_usize;
--         _5 = Lt(copy _4, const 8_usize);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", const 8_usize, copy _4) -> [success: bb1, unwind continue];
-+         _5 = const true;
+-         _5 = Len(_3);
+-         _6 = Lt(copy _4, copy _5);
+-         assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind continue];
++         _5 = const 8_usize;
++         _6 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 8_usize, const 2_usize) -> [success: bb1, unwind continue];
       }
   
diff --git a/tests/mir-opt/dataflow-const-prop/repeat.rs b/tests/mir-opt/dataflow-const-prop/repeat.rs
index 1bc2cb82a6068..2067aa3d709e2 100644
--- a/tests/mir-opt/dataflow-const-prop/repeat.rs
+++ b/tests/mir-opt/dataflow-const-prop/repeat.rs
@@ -9,9 +9,8 @@ fn main() {
 
     // CHECK: [[array_lit:_.*]] = [const 42_u32; 8];
     // CHECK-NOT: {{_.*}} = Len(
-    // CHECK-NOT: {{_.*}} = PtrMetadata(
     // CHECK-NOT: {{_.*}} = Lt(
-    // CHECK: {{_.*}} = const 2_usize;
+    // CHECK: {{_.*}} = const 8_usize;
     // CHECK: {{_.*}} = const true;
     // CHECK: assert(const true
 
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff
new file mode 100644
index 0000000000000..e71992316dcf4
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff
@@ -0,0 +1,77 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: u32;
+      let mut _2: &[u32];
+      let mut _3: &[u32; 3];
+      let _4: &[u32; 3];
+      let _5: [u32; 3];
+      let _6: usize;
+      let mut _7: usize;
+      let mut _8: bool;
+      let mut _10: &[u32];
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+      let mut _14: &[u32; 3];
+      scope 1 {
+          debug local => _1;
+          let _9: u32;
+          scope 2 {
+              debug constant => _9;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _14 = const main::promoted[0];
+          _4 = copy _14;
+          _3 = copy _4;
+          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
+          StorageDead(_3);
+          StorageLive(_6);
+          _6 = const 1_usize;
+-         _7 = Len((*_2));
+-         _8 = Lt(copy _6, copy _7);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+-         _1 = copy (*_2)[_6];
++         _1 = copy (*_2)[1 of 2];
+          StorageDead(_6);
+          StorageDead(_4);
+          StorageDead(_2);
+          StorageLive(_9);
+          StorageLive(_10);
+          _10 = const main::SLICE;
+          StorageLive(_11);
+          _11 = const 1_usize;
+-         _12 = Len((*_10));
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable];
++         _12 = const 3_usize;
++         _13 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+-         _9 = copy (*_10)[_11];
++         _9 = copy (*_10)[1 of 2];
+          StorageDead(_11);
+          StorageDead(_10);
+          _0 = const ();
+          StorageDead(_9);
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff
new file mode 100644
index 0000000000000..26de859576896
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -0,0 +1,77 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: u32;
+      let mut _2: &[u32];
+      let mut _3: &[u32; 3];
+      let _4: &[u32; 3];
+      let _5: [u32; 3];
+      let _6: usize;
+      let mut _7: usize;
+      let mut _8: bool;
+      let mut _10: &[u32];
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+      let mut _14: &[u32; 3];
+      scope 1 {
+          debug local => _1;
+          let _9: u32;
+          scope 2 {
+              debug constant => _9;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _14 = const main::promoted[0];
+          _4 = copy _14;
+          _3 = copy _4;
+          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
+          StorageDead(_3);
+          StorageLive(_6);
+          _6 = const 1_usize;
+-         _7 = Len((*_2));
+-         _8 = Lt(copy _6, copy _7);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
+      }
+  
+      bb1: {
+-         _1 = copy (*_2)[_6];
++         _1 = copy (*_2)[1 of 2];
+          StorageDead(_6);
+          StorageDead(_4);
+          StorageDead(_2);
+          StorageLive(_9);
+          StorageLive(_10);
+          _10 = const main::SLICE;
+          StorageLive(_11);
+          _11 = const 1_usize;
+-         _12 = Len((*_10));
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue];
++         _12 = const 3_usize;
++         _13 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue];
+      }
+  
+      bb2: {
+-         _9 = copy (*_10)[_11];
++         _9 = copy (*_10)[1 of 2];
+          StorageDead(_11);
+          StorageDead(_10);
+          _0 = const ();
+          StorageDead(_9);
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff
new file mode 100644
index 0000000000000..e71992316dcf4
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff
@@ -0,0 +1,77 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: u32;
+      let mut _2: &[u32];
+      let mut _3: &[u32; 3];
+      let _4: &[u32; 3];
+      let _5: [u32; 3];
+      let _6: usize;
+      let mut _7: usize;
+      let mut _8: bool;
+      let mut _10: &[u32];
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+      let mut _14: &[u32; 3];
+      scope 1 {
+          debug local => _1;
+          let _9: u32;
+          scope 2 {
+              debug constant => _9;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _14 = const main::promoted[0];
+          _4 = copy _14;
+          _3 = copy _4;
+          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
+          StorageDead(_3);
+          StorageLive(_6);
+          _6 = const 1_usize;
+-         _7 = Len((*_2));
+-         _8 = Lt(copy _6, copy _7);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+-         _1 = copy (*_2)[_6];
++         _1 = copy (*_2)[1 of 2];
+          StorageDead(_6);
+          StorageDead(_4);
+          StorageDead(_2);
+          StorageLive(_9);
+          StorageLive(_10);
+          _10 = const main::SLICE;
+          StorageLive(_11);
+          _11 = const 1_usize;
+-         _12 = Len((*_10));
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable];
++         _12 = const 3_usize;
++         _13 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+-         _9 = copy (*_10)[_11];
++         _9 = copy (*_10)[1 of 2];
+          StorageDead(_11);
+          StorageDead(_10);
+          _0 = const ();
+          StorageDead(_9);
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff
new file mode 100644
index 0000000000000..26de859576896
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -0,0 +1,77 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: u32;
+      let mut _2: &[u32];
+      let mut _3: &[u32; 3];
+      let _4: &[u32; 3];
+      let _5: [u32; 3];
+      let _6: usize;
+      let mut _7: usize;
+      let mut _8: bool;
+      let mut _10: &[u32];
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
+      let mut _14: &[u32; 3];
+      scope 1 {
+          debug local => _1;
+          let _9: u32;
+          scope 2 {
+              debug constant => _9;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          _14 = const main::promoted[0];
+          _4 = copy _14;
+          _3 = copy _4;
+          _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast));
+          StorageDead(_3);
+          StorageLive(_6);
+          _6 = const 1_usize;
+-         _7 = Len((*_2));
+-         _8 = Lt(copy _6, copy _7);
+-         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue];
++         _7 = const 3_usize;
++         _8 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue];
+      }
+  
+      bb1: {
+-         _1 = copy (*_2)[_6];
++         _1 = copy (*_2)[1 of 2];
+          StorageDead(_6);
+          StorageDead(_4);
+          StorageDead(_2);
+          StorageLive(_9);
+          StorageLive(_10);
+          _10 = const main::SLICE;
+          StorageLive(_11);
+          _11 = const 1_usize;
+-         _12 = Len((*_10));
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue];
++         _12 = const 3_usize;
++         _13 = const true;
++         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue];
+      }
+  
+      bb2: {
+-         _9 = copy (*_10)[_11];
++         _9 = copy (*_10)[1 of 2];
+          StorageDead(_11);
+          StorageDead(_10);
+          _0 = const ();
+          StorageDead(_9);
+          StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.rs b/tests/mir-opt/dataflow-const-prop/slice_len.rs
new file mode 100644
index 0000000000000..e0e68f9fde54a
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/slice_len.rs
@@ -0,0 +1,34 @@
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+//@ test-mir-pass: DataflowConstProp
+//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
+// EMIT_MIR slice_len.main.DataflowConstProp.diff
+
+// CHECK-LABEL: fn main(
+fn main() {
+    // CHECK: debug local => [[local:_.*]];
+    // CHECK: debug constant => [[constant:_.*]];
+
+    // CHECK-NOT: {{_.*}} = Len(
+    // CHECK-NOT: {{_.*}} = Lt(
+    // CHECK-NOT: assert(move _
+    // CHECK: {{_.*}} = const 3_usize;
+    // CHECK: {{_.*}} = const true;
+    // CHECK: assert(const true,
+
+    // CHECK: [[local]] = copy (*{{_.*}})[1 of 2];
+    let local = (&[1u32, 2, 3] as &[u32])[1];
+
+    // CHECK-NOT: {{_.*}} = Len(
+    // CHECK-NOT: {{_.*}} = Lt(
+    // CHECK-NOT: assert(move _
+    const SLICE: &[u32] = &[1, 2, 3];
+    // CHECK: {{_.*}} = const 3_usize;
+    // CHECK: {{_.*}} = const true;
+    // CHECK: assert(const true,
+
+    // CHECK-NOT: [[constant]] = {{copy|move}} (*{{_.*}})[_
+    // CHECK: [[constant]] = copy (*{{_.*}})[1 of 2];
+    let constant = SLICE[1];
+}
diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff
index b4197c09ac94b..60742ef0e9a90 100644
--- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff
+++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff
@@ -22,14 +22,14 @@
   
       bb1: {
           StorageDead(_3);
-          _4 = PtrMetadata(copy _2);
+          _4 = Len((*_2));
           _5 = const 4_usize;
           _6 = Ge(move _4, move _5);
           switchInt(move _6) -> [0: bb2, otherwise: bb3];
       }
   
       bb2: {
-          _7 = PtrMetadata(copy _2);
+          _7 = Len((*_2));
           _8 = const 3_usize;
           _9 = Ge(move _7, move _8);
 -         switchInt(move _9) -> [0: bb7, otherwise: bb8];
diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
index 4bcb13ca49c12..7337a32f525f9 100644
--- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
+++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff
@@ -22,14 +22,14 @@
   
       bb1: {
           StorageDead(_3);
-          _4 = PtrMetadata(copy _2);
+          _4 = Len((*_2));
           _5 = const 4_usize;
           _6 = Ge(move _4, move _5);
           switchInt(move _6) -> [0: bb2, otherwise: bb3];
       }
   
       bb2: {
-          _7 = PtrMetadata(copy _2);
+          _7 = Len((*_2));
           _8 = const 3_usize;
           _9 = Ge(move _7, move _8);
 -         switchInt(move _9) -> [0: bb7, otherwise: bb8];
diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
index 183b4d2599f53..3f052ee19fdfe 100644
--- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-abort.diff
@@ -53,7 +53,7 @@
           StorageLive(_8);
 -         _8 = copy _2;
 +         _8 = const usize::MAX;
-          _9 = PtrMetadata(copy _1);
+          _9 = Len((*_1));
 -         _10 = Lt(copy _8, copy _9);
 -         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
 +         _10 = Lt(const usize::MAX, copy _9);
@@ -72,7 +72,7 @@
           StorageDead(_5);
           StorageLive(_11);
           _11 = const 0_usize;
-          _12 = PtrMetadata(copy _1);
+          _12 = Len((*_1));
 -         _13 = Lt(copy _11, copy _12);
 -         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable];
 +         _13 = Lt(const 0_usize, copy _12);
diff --git a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
index 03e8aa3bd9b98..84b738c7804e0 100644
--- a/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.constant_index_overflow.GVN.panic-unwind.diff
@@ -53,7 +53,7 @@
           StorageLive(_8);
 -         _8 = copy _2;
 +         _8 = const usize::MAX;
-          _9 = PtrMetadata(copy _1);
+          _9 = Len((*_1));
 -         _10 = Lt(copy _8, copy _9);
 -         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
 +         _10 = Lt(const usize::MAX, copy _9);
@@ -72,7 +72,7 @@
           StorageDead(_5);
           StorageLive(_11);
           _11 = const 0_usize;
-          _12 = PtrMetadata(copy _1);
+          _12 = Len((*_1));
 -         _13 = Lt(copy _11, copy _12);
 -         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue];
 +         _13 = Lt(const 0_usize, copy _12);
diff --git a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff
deleted file mode 100644
index 4b077f580f100..0000000000000
--- a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-abort.diff
+++ /dev/null
@@ -1,72 +0,0 @@
-- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN
-+ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN
-  
-  fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] {
-      debug x => _1;
-      let mut _0: [i32; 3];
-      let mut _2: i32;
-      let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
-      let mut _6: i32;
-      let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let mut _10: i32;
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-  
-      bb0: {
-          StorageLive(_2);
-          StorageLive(_3);
-          _3 = const 42_usize;
-          _4 = PtrMetadata(copy _1);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
-+         _5 = Lt(const 42_usize, copy _4);
-+         assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind unreachable];
-      }
-  
-      bb1: {
--         _2 = copy (*_1)[_3];
-+         _2 = copy (*_1)[42 of 43];
-          StorageLive(_6);
-          StorageLive(_7);
-          _7 = const 13_usize;
--         _8 = PtrMetadata(copy _1);
--         _9 = Lt(copy _7, copy _8);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
-+         _8 = copy _4;
-+         _9 = Lt(const 13_usize, copy _4);
-+         assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind unreachable];
-      }
-  
-      bb2: {
--         _6 = copy (*_1)[_7];
-+         _6 = copy (*_1)[13 of 14];
-          StorageLive(_10);
-          StorageLive(_11);
-          _11 = const 7_usize;
--         _12 = PtrMetadata(copy _1);
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind unreachable];
-+         _12 = copy _4;
-+         _13 = Lt(const 7_usize, copy _4);
-+         assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind unreachable];
-      }
-  
-      bb3: {
--         _10 = copy (*_1)[_11];
-+         _10 = copy (*_1)[7 of 8];
-          _0 = [move _2, move _6, move _10];
-          StorageDead(_10);
-          StorageDead(_6);
-          StorageDead(_2);
-          StorageDead(_11);
-          StorageDead(_7);
-          StorageDead(_3);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff
deleted file mode 100644
index 87e69d440069e..0000000000000
--- a/tests/mir-opt/gvn.dedup_multiple_bounds_checks_lengths.GVN.panic-unwind.diff
+++ /dev/null
@@ -1,72 +0,0 @@
-- // MIR for `dedup_multiple_bounds_checks_lengths` before GVN
-+ // MIR for `dedup_multiple_bounds_checks_lengths` after GVN
-  
-  fn dedup_multiple_bounds_checks_lengths(_1: &[i32]) -> [i32; 3] {
-      debug x => _1;
-      let mut _0: [i32; 3];
-      let mut _2: i32;
-      let _3: usize;
-      let mut _4: usize;
-      let mut _5: bool;
-      let mut _6: i32;
-      let _7: usize;
-      let mut _8: usize;
-      let mut _9: bool;
-      let mut _10: i32;
-      let _11: usize;
-      let mut _12: usize;
-      let mut _13: bool;
-  
-      bb0: {
-          StorageLive(_2);
-          StorageLive(_3);
-          _3 = const 42_usize;
-          _4 = PtrMetadata(copy _1);
--         _5 = Lt(copy _3, copy _4);
--         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
-+         _5 = Lt(const 42_usize, copy _4);
-+         assert(move _5, "index out of bounds: the length is {} but the index is {}", copy _4, const 42_usize) -> [success: bb1, unwind continue];
-      }
-  
-      bb1: {
--         _2 = copy (*_1)[_3];
-+         _2 = copy (*_1)[42 of 43];
-          StorageLive(_6);
-          StorageLive(_7);
-          _7 = const 13_usize;
--         _8 = PtrMetadata(copy _1);
--         _9 = Lt(copy _7, copy _8);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
-+         _8 = copy _4;
-+         _9 = Lt(const 13_usize, copy _4);
-+         assert(move _9, "index out of bounds: the length is {} but the index is {}", copy _4, const 13_usize) -> [success: bb2, unwind continue];
-      }
-  
-      bb2: {
--         _6 = copy (*_1)[_7];
-+         _6 = copy (*_1)[13 of 14];
-          StorageLive(_10);
-          StorageLive(_11);
-          _11 = const 7_usize;
--         _12 = PtrMetadata(copy _1);
--         _13 = Lt(copy _11, copy _12);
--         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb3, unwind continue];
-+         _12 = copy _4;
-+         _13 = Lt(const 7_usize, copy _4);
-+         assert(move _13, "index out of bounds: the length is {} but the index is {}", copy _4, const 7_usize) -> [success: bb3, unwind continue];
-      }
-  
-      bb3: {
--         _10 = copy (*_1)[_11];
-+         _10 = copy (*_1)[7 of 8];
-          _0 = [move _2, move _6, move _10];
-          StorageDead(_10);
-          StorageDead(_6);
-          StorageDead(_2);
-          StorageDead(_11);
-          StorageDead(_7);
-          StorageDead(_3);
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
index 7f44176b75683..d4b22d05f6c78 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
@@ -10,11 +10,13 @@
       let _5: ();
       let mut _6: T;
       let _7: usize;
-      let mut _8: bool;
-      let _9: ();
-      let mut _10: T;
-      let _11: usize;
-      let mut _12: bool;
+      let mut _8: usize;
+      let mut _9: bool;
+      let _10: ();
+      let mut _11: T;
+      let _12: usize;
+      let mut _13: usize;
+      let mut _14: bool;
       scope 1 {
           debug a => _3;
       }
@@ -30,10 +32,12 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = const 0_usize;
--         _8 = Lt(copy _7, const N);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind unreachable];
-+         _8 = Lt(const 0_usize, const N);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable];
+-         _8 = Len(_3);
+-         _9 = Lt(copy _7, copy _8);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind unreachable];
++         _8 = const N;
++         _9 = Lt(const 0_usize, const N);
++         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind unreachable];
       }
   
       bb1: {
@@ -47,27 +51,29 @@
           StorageDead(_6);
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_9);
           StorageLive(_10);
           StorageLive(_11);
-          _11 = copy _2;
--         _12 = Lt(copy _11, const N);
--         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind unreachable];
-+         _12 = Lt(copy _2, const N);
-+         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable];
+          StorageLive(_12);
+          _12 = copy _2;
+-         _13 = Len(_3);
+-         _14 = Lt(copy _12, copy _13);
+-         assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind unreachable];
++         _13 = const N;
++         _14 = Lt(copy _2, const N);
++         assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind unreachable];
       }
   
       bb3: {
--         _10 = copy _3[_11];
--         _9 = opaque::<T>(move _10) -> [return: bb4, unwind unreachable];
-+         _10 = copy _1;
-+         _9 = opaque::<T>(copy _1) -> [return: bb4, unwind unreachable];
+-         _11 = copy _3[_12];
+-         _10 = opaque::<T>(move _11) -> [return: bb4, unwind unreachable];
++         _11 = copy _1;
++         _10 = opaque::<T>(copy _1) -> [return: bb4, unwind unreachable];
       }
   
       bb4: {
-          StorageDead(_10);
           StorageDead(_11);
-          StorageDead(_9);
+          StorageDead(_12);
+          StorageDead(_10);
           _0 = const ();
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
index d34882d725f49..708c0f92e542e 100644
--- a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
@@ -10,11 +10,13 @@
       let _5: ();
       let mut _6: T;
       let _7: usize;
-      let mut _8: bool;
-      let _9: ();
-      let mut _10: T;
-      let _11: usize;
-      let mut _12: bool;
+      let mut _8: usize;
+      let mut _9: bool;
+      let _10: ();
+      let mut _11: T;
+      let _12: usize;
+      let mut _13: usize;
+      let mut _14: bool;
       scope 1 {
           debug a => _3;
       }
@@ -30,10 +32,12 @@
           StorageLive(_6);
           StorageLive(_7);
           _7 = const 0_usize;
--         _8 = Lt(copy _7, const N);
--         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, copy _7) -> [success: bb1, unwind continue];
-+         _8 = Lt(const 0_usize, const N);
-+         assert(move _8, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue];
+-         _8 = Len(_3);
+-         _9 = Lt(copy _7, copy _8);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb1, unwind continue];
++         _8 = const N;
++         _9 = Lt(const 0_usize, const N);
++         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb1, unwind continue];
       }
   
       bb1: {
@@ -47,27 +51,29 @@
           StorageDead(_6);
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_9);
           StorageLive(_10);
           StorageLive(_11);
-          _11 = copy _2;
--         _12 = Lt(copy _11, const N);
--         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _11) -> [success: bb3, unwind continue];
-+         _12 = Lt(copy _2, const N);
-+         assert(move _12, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue];
+          StorageLive(_12);
+          _12 = copy _2;
+-         _13 = Len(_3);
+-         _14 = Lt(copy _12, copy _13);
+-         assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, copy _12) -> [success: bb3, unwind continue];
++         _13 = const N;
++         _14 = Lt(copy _2, const N);
++         assert(move _14, "index out of bounds: the length is {} but the index is {}", const N, copy _2) -> [success: bb3, unwind continue];
       }
   
       bb3: {
--         _10 = copy _3[_11];
--         _9 = opaque::<T>(move _10) -> [return: bb4, unwind continue];
-+         _10 = copy _1;
-+         _9 = opaque::<T>(copy _1) -> [return: bb4, unwind continue];
+-         _11 = copy _3[_12];
+-         _10 = opaque::<T>(move _11) -> [return: bb4, unwind continue];
++         _11 = copy _1;
++         _10 = opaque::<T>(copy _1) -> [return: bb4, unwind continue];
       }
   
       bb4: {
-          StorageDead(_10);
           StorageDead(_11);
-          StorageDead(_9);
+          StorageDead(_12);
+          StorageDead(_10);
           _0 = const ();
           StorageDead(_3);
           return;
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
index 19b58a917f87c..97513248e23c6 100644
--- a/tests/mir-opt/gvn.rs
+++ b/tests/mir-opt/gvn.rs
@@ -835,25 +835,6 @@ fn array_len(x: &mut [i32; 42]) -> usize {
     std::intrinsics::ptr_metadata(x)
 }
 
-// Check that we only load the length once, rather than all 3 times.
-fn dedup_multiple_bounds_checks_lengths(x: &[i32]) -> [i32; 3] {
-    // CHECK-LABEL: fn dedup_multiple_bounds_checks_lengths
-    // CHECK: [[LEN:_.+]] = PtrMetadata(copy _1);
-    // CHECK: Lt(const 42_usize, copy [[LEN]]);
-    // CHECK: assert{{.+}}copy [[LEN]]
-    // CHECK: [[A:_.+]] = copy (*_1)[42 of 43];
-    // CHECK-NOT: PtrMetadata
-    // CHECK: Lt(const 13_usize, copy [[LEN]]);
-    // CHECK: assert{{.+}}copy [[LEN]]
-    // CHECK: [[B:_.+]] = copy (*_1)[13 of 14];
-    // CHECK-NOT: PtrMetadata
-    // CHECK: Lt(const 7_usize, copy [[LEN]]);
-    // CHECK: assert{{.+}}copy [[LEN]]
-    // CHECK: [[C:_.+]] = copy (*_1)[7 of 8];
-    // CHECK: _0 = [move [[A]], move [[B]], move [[C]]]
-    [x[42], x[13], x[7]]
-}
-
 #[custom_mir(dialect = "runtime")]
 fn generic_cast_metadata<T, A: ?Sized, B: ?Sized>(ps: *const [T], pa: *const A, pb: *const B) {
     // CHECK-LABEL: fn generic_cast_metadata
@@ -1031,7 +1012,6 @@ fn identity<T>(x: T) -> T {
 // EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff
 // EMIT_MIR gvn.manual_slice_mut_len.GVN.diff
 // EMIT_MIR gvn.array_len.GVN.diff
-// EMIT_MIR gvn.dedup_multiple_bounds_checks_lengths.GVN.diff
 // EMIT_MIR gvn.generic_cast_metadata.GVN.diff
 // EMIT_MIR gvn.cast_pointer_eq.GVN.diff
 // EMIT_MIR gvn.cast_pointer_then_transmute.GVN.diff
diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff
index 1b305e746f5ee..6b6152c1117e3 100644
--- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-abort.diff
@@ -10,60 +10,62 @@
       let mut _6: &i32;
       let _7: &i32;
       let _8: usize;
-      let mut _9: bool;
-      let mut _11: *const dyn std::marker::Send;
-      let _12: &dyn std::marker::Send;
-      let mut _13: &i32;
-      let _14: &i32;
-      let _15: usize;
-      let mut _16: bool;
-      let _17: ();
+      let mut _9: usize;
+      let mut _10: bool;
+      let mut _12: *const dyn std::marker::Send;
+      let _13: &dyn std::marker::Send;
+      let mut _14: &i32;
+      let _15: &i32;
+      let _16: usize;
+      let mut _17: usize;
       let mut _18: bool;
-      let mut _19: *const dyn std::marker::Send;
-      let mut _20: *const dyn std::marker::Send;
+      let _19: ();
+      let mut _20: bool;
       let mut _21: *const dyn std::marker::Send;
-      let _22: ();
-      let mut _23: bool;
-      let mut _24: *const dyn std::marker::Send;
-      let mut _25: *const dyn std::marker::Send;
+      let mut _22: *const dyn std::marker::Send;
+      let mut _23: *const dyn std::marker::Send;
+      let _24: ();
+      let mut _25: bool;
       let mut _26: *const dyn std::marker::Send;
-      let _27: ();
-      let mut _28: bool;
-      let mut _29: *const dyn std::marker::Send;
-      let mut _30: *const dyn std::marker::Send;
+      let mut _27: *const dyn std::marker::Send;
+      let mut _28: *const dyn std::marker::Send;
+      let _29: ();
+      let mut _30: bool;
       let mut _31: *const dyn std::marker::Send;
-      let _32: ();
-      let mut _33: bool;
-      let mut _34: *const dyn std::marker::Send;
-      let mut _35: *const dyn std::marker::Send;
+      let mut _32: *const dyn std::marker::Send;
+      let mut _33: *const dyn std::marker::Send;
+      let _34: ();
+      let mut _35: bool;
       let mut _36: *const dyn std::marker::Send;
-      let _37: ();
-      let mut _38: bool;
-      let mut _39: *const dyn std::marker::Send;
-      let mut _40: *const dyn std::marker::Send;
+      let mut _37: *const dyn std::marker::Send;
+      let mut _38: *const dyn std::marker::Send;
+      let _39: ();
+      let mut _40: bool;
       let mut _41: *const dyn std::marker::Send;
-      let _42: ();
-      let mut _43: bool;
-      let mut _44: *const dyn std::marker::Send;
-      let mut _45: *const dyn std::marker::Send;
+      let mut _42: *const dyn std::marker::Send;
+      let mut _43: *const dyn std::marker::Send;
+      let _44: ();
+      let mut _45: bool;
       let mut _46: *const dyn std::marker::Send;
-      let mut _47: &[i32; 2];
+      let mut _47: *const dyn std::marker::Send;
+      let mut _48: *const dyn std::marker::Send;
+      let mut _49: &[i32; 2];
       scope 1 {
           debug slice => _1;
           let _3: *const dyn std::marker::Send;
           scope 2 {
               debug a => _3;
-              let _10: *const dyn std::marker::Send;
+              let _11: *const dyn std::marker::Send;
               scope 3 {
-                  debug b => _10;
+                  debug b => _11;
               }
           }
       }
   
       bb0: {
           StorageLive(_1);
-          _47 = const wide_ptr_same_provenance::promoted[0];
-          _1 = &(*_47);
+          _49 = const wide_ptr_same_provenance::promoted[0];
+          _1 = &(*_49);
           StorageLive(_3);
 -         StorageLive(_4);
 +         nop;
@@ -72,9 +74,11 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = const 0_usize;
--         _9 = Lt(copy _8, const 2_usize);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind unreachable];
-+         _9 = const true;
+-         _9 = Len((*_1));
+-         _10 = Lt(copy _8, copy _9);
+-         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind unreachable];
++         _9 = const 2_usize;
++         _10 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind unreachable];
       }
   
@@ -91,168 +95,170 @@
 +         nop;
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_10);
--         StorageLive(_11);
+          StorageLive(_11);
+-         StorageLive(_12);
 +         nop;
-          StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
           StorageLive(_15);
-          _15 = const 1_usize;
--         _16 = Lt(copy _15, const 2_usize);
--         assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind unreachable];
-+         _16 = const true;
+          StorageLive(_16);
+          _16 = const 1_usize;
+-         _17 = Len((*_1));
+-         _18 = Lt(copy _16, copy _17);
+-         assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind unreachable];
++         _17 = const 2_usize;
++         _18 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind unreachable];
       }
   
       bb2: {
--         _14 = &(*_1)[_15];
-+         _14 = &(*_1)[1 of 2];
-          _13 = &(*_14);
-          _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
-          StorageDead(_13);
-          _11 = &raw const (*_12);
--         _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
--         StorageDead(_11);
-+         _10 = copy _11;
-+         nop;
+-         _15 = &(*_1)[_16];
++         _15 = &(*_1)[1 of 2];
+          _14 = &(*_15);
+          _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
           StorageDead(_14);
-          StorageDead(_12);
-          StorageLive(_17);
-          StorageLive(_18);
+          _12 = &raw const (*_13);
+-         _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+-         StorageDead(_12);
++         _11 = copy _12;
++         nop;
+          StorageDead(_15);
+          StorageDead(_13);
           StorageLive(_19);
--         _19 = copy _3;
-+         _19 = copy _4;
           StorageLive(_20);
           StorageLive(_21);
--         _21 = copy _10;
--         _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _21 = copy _11;
-+         _20 = copy _11;
+-         _21 = copy _3;
++         _21 = copy _4;
+          StorageLive(_22);
+          StorageLive(_23);
+-         _23 = copy _11;
+-         _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _23 = copy _12;
++         _22 = copy _12;
+          StorageDead(_23);
+-         _20 = Eq(move _21, move _22);
++         _20 = Eq(copy _4, copy _12);
+          StorageDead(_22);
           StorageDead(_21);
--         _18 = Eq(move _19, move _20);
-+         _18 = Eq(copy _4, copy _11);
-          StorageDead(_20);
-          StorageDead(_19);
-          _17 = opaque::<bool>(move _18) -> [return: bb3, unwind unreachable];
+          _19 = opaque::<bool>(move _20) -> [return: bb3, unwind unreachable];
       }
   
       bb3: {
-          StorageDead(_18);
-          StorageDead(_17);
-          StorageLive(_22);
-          StorageLive(_23);
+          StorageDead(_20);
+          StorageDead(_19);
           StorageLive(_24);
--         _24 = copy _3;
-+         _24 = copy _4;
           StorageLive(_25);
           StorageLive(_26);
--         _26 = copy _10;
--         _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _26 = copy _11;
-+         _25 = copy _11;
+-         _26 = copy _3;
++         _26 = copy _4;
+          StorageLive(_27);
+          StorageLive(_28);
+-         _28 = copy _11;
+-         _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _28 = copy _12;
++         _27 = copy _12;
+          StorageDead(_28);
+-         _25 = Ne(move _26, move _27);
++         _25 = Ne(copy _4, copy _12);
+          StorageDead(_27);
           StorageDead(_26);
--         _23 = Ne(move _24, move _25);
-+         _23 = Ne(copy _4, copy _11);
-          StorageDead(_25);
-          StorageDead(_24);
-          _22 = opaque::<bool>(move _23) -> [return: bb4, unwind unreachable];
+          _24 = opaque::<bool>(move _25) -> [return: bb4, unwind unreachable];
       }
   
       bb4: {
-          StorageDead(_23);
-          StorageDead(_22);
-          StorageLive(_27);
-          StorageLive(_28);
+          StorageDead(_25);
+          StorageDead(_24);
           StorageLive(_29);
--         _29 = copy _3;
-+         _29 = copy _4;
           StorageLive(_30);
           StorageLive(_31);
--         _31 = copy _10;
--         _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _31 = copy _11;
-+         _30 = copy _11;
+-         _31 = copy _3;
++         _31 = copy _4;
+          StorageLive(_32);
+          StorageLive(_33);
+-         _33 = copy _11;
+-         _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _33 = copy _12;
++         _32 = copy _12;
+          StorageDead(_33);
+-         _30 = Lt(move _31, move _32);
++         _30 = Lt(copy _4, copy _12);
+          StorageDead(_32);
           StorageDead(_31);
--         _28 = Lt(move _29, move _30);
-+         _28 = Lt(copy _4, copy _11);
-          StorageDead(_30);
-          StorageDead(_29);
-          _27 = opaque::<bool>(move _28) -> [return: bb5, unwind unreachable];
+          _29 = opaque::<bool>(move _30) -> [return: bb5, unwind unreachable];
       }
   
       bb5: {
-          StorageDead(_28);
-          StorageDead(_27);
-          StorageLive(_32);
-          StorageLive(_33);
+          StorageDead(_30);
+          StorageDead(_29);
           StorageLive(_34);
--         _34 = copy _3;
-+         _34 = copy _4;
           StorageLive(_35);
           StorageLive(_36);
--         _36 = copy _10;
--         _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _36 = copy _11;
-+         _35 = copy _11;
+-         _36 = copy _3;
++         _36 = copy _4;
+          StorageLive(_37);
+          StorageLive(_38);
+-         _38 = copy _11;
+-         _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _38 = copy _12;
++         _37 = copy _12;
+          StorageDead(_38);
+-         _35 = Le(move _36, move _37);
++         _35 = Le(copy _4, copy _12);
+          StorageDead(_37);
           StorageDead(_36);
--         _33 = Le(move _34, move _35);
-+         _33 = Le(copy _4, copy _11);
-          StorageDead(_35);
-          StorageDead(_34);
-          _32 = opaque::<bool>(move _33) -> [return: bb6, unwind unreachable];
+          _34 = opaque::<bool>(move _35) -> [return: bb6, unwind unreachable];
       }
   
       bb6: {
-          StorageDead(_33);
-          StorageDead(_32);
-          StorageLive(_37);
-          StorageLive(_38);
+          StorageDead(_35);
+          StorageDead(_34);
           StorageLive(_39);
--         _39 = copy _3;
-+         _39 = copy _4;
           StorageLive(_40);
           StorageLive(_41);
--         _41 = copy _10;
--         _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _41 = copy _11;
-+         _40 = copy _11;
+-         _41 = copy _3;
++         _41 = copy _4;
+          StorageLive(_42);
+          StorageLive(_43);
+-         _43 = copy _11;
+-         _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _43 = copy _12;
++         _42 = copy _12;
+          StorageDead(_43);
+-         _40 = Gt(move _41, move _42);
++         _40 = Gt(copy _4, copy _12);
+          StorageDead(_42);
           StorageDead(_41);
--         _38 = Gt(move _39, move _40);
-+         _38 = Gt(copy _4, copy _11);
-          StorageDead(_40);
-          StorageDead(_39);
-          _37 = opaque::<bool>(move _38) -> [return: bb7, unwind unreachable];
+          _39 = opaque::<bool>(move _40) -> [return: bb7, unwind unreachable];
       }
   
       bb7: {
-          StorageDead(_38);
-          StorageDead(_37);
-          StorageLive(_42);
-          StorageLive(_43);
+          StorageDead(_40);
+          StorageDead(_39);
           StorageLive(_44);
--         _44 = copy _3;
-+         _44 = copy _4;
           StorageLive(_45);
           StorageLive(_46);
--         _46 = copy _10;
--         _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _46 = copy _11;
-+         _45 = copy _11;
+-         _46 = copy _3;
++         _46 = copy _4;
+          StorageLive(_47);
+          StorageLive(_48);
+-         _48 = copy _11;
+-         _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _48 = copy _12;
++         _47 = copy _12;
+          StorageDead(_48);
+-         _45 = Ge(move _46, move _47);
++         _45 = Ge(copy _4, copy _12);
+          StorageDead(_47);
           StorageDead(_46);
--         _43 = Ge(move _44, move _45);
-+         _43 = Ge(copy _4, copy _11);
-          StorageDead(_45);
-          StorageDead(_44);
-          _42 = opaque::<bool>(move _43) -> [return: bb8, unwind unreachable];
+          _44 = opaque::<bool>(move _45) -> [return: bb8, unwind unreachable];
       }
   
       bb8: {
-          StorageDead(_43);
-          StorageDead(_42);
+          StorageDead(_45);
+          StorageDead(_44);
           _0 = const ();
-          StorageDead(_15);
-          StorageDead(_10);
+          StorageDead(_16);
+          StorageDead(_11);
           StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
diff --git a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff
index e418ecf25bd4f..093c1ec6ce379 100644
--- a/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.wide_ptr_same_provenance.GVN.panic-unwind.diff
@@ -10,60 +10,62 @@
       let mut _6: &i32;
       let _7: &i32;
       let _8: usize;
-      let mut _9: bool;
-      let mut _11: *const dyn std::marker::Send;
-      let _12: &dyn std::marker::Send;
-      let mut _13: &i32;
-      let _14: &i32;
-      let _15: usize;
-      let mut _16: bool;
-      let _17: ();
+      let mut _9: usize;
+      let mut _10: bool;
+      let mut _12: *const dyn std::marker::Send;
+      let _13: &dyn std::marker::Send;
+      let mut _14: &i32;
+      let _15: &i32;
+      let _16: usize;
+      let mut _17: usize;
       let mut _18: bool;
-      let mut _19: *const dyn std::marker::Send;
-      let mut _20: *const dyn std::marker::Send;
+      let _19: ();
+      let mut _20: bool;
       let mut _21: *const dyn std::marker::Send;
-      let _22: ();
-      let mut _23: bool;
-      let mut _24: *const dyn std::marker::Send;
-      let mut _25: *const dyn std::marker::Send;
+      let mut _22: *const dyn std::marker::Send;
+      let mut _23: *const dyn std::marker::Send;
+      let _24: ();
+      let mut _25: bool;
       let mut _26: *const dyn std::marker::Send;
-      let _27: ();
-      let mut _28: bool;
-      let mut _29: *const dyn std::marker::Send;
-      let mut _30: *const dyn std::marker::Send;
+      let mut _27: *const dyn std::marker::Send;
+      let mut _28: *const dyn std::marker::Send;
+      let _29: ();
+      let mut _30: bool;
       let mut _31: *const dyn std::marker::Send;
-      let _32: ();
-      let mut _33: bool;
-      let mut _34: *const dyn std::marker::Send;
-      let mut _35: *const dyn std::marker::Send;
+      let mut _32: *const dyn std::marker::Send;
+      let mut _33: *const dyn std::marker::Send;
+      let _34: ();
+      let mut _35: bool;
       let mut _36: *const dyn std::marker::Send;
-      let _37: ();
-      let mut _38: bool;
-      let mut _39: *const dyn std::marker::Send;
-      let mut _40: *const dyn std::marker::Send;
+      let mut _37: *const dyn std::marker::Send;
+      let mut _38: *const dyn std::marker::Send;
+      let _39: ();
+      let mut _40: bool;
       let mut _41: *const dyn std::marker::Send;
-      let _42: ();
-      let mut _43: bool;
-      let mut _44: *const dyn std::marker::Send;
-      let mut _45: *const dyn std::marker::Send;
+      let mut _42: *const dyn std::marker::Send;
+      let mut _43: *const dyn std::marker::Send;
+      let _44: ();
+      let mut _45: bool;
       let mut _46: *const dyn std::marker::Send;
-      let mut _47: &[i32; 2];
+      let mut _47: *const dyn std::marker::Send;
+      let mut _48: *const dyn std::marker::Send;
+      let mut _49: &[i32; 2];
       scope 1 {
           debug slice => _1;
           let _3: *const dyn std::marker::Send;
           scope 2 {
               debug a => _3;
-              let _10: *const dyn std::marker::Send;
+              let _11: *const dyn std::marker::Send;
               scope 3 {
-                  debug b => _10;
+                  debug b => _11;
               }
           }
       }
   
       bb0: {
           StorageLive(_1);
-          _47 = const wide_ptr_same_provenance::promoted[0];
-          _1 = &(*_47);
+          _49 = const wide_ptr_same_provenance::promoted[0];
+          _1 = &(*_49);
           StorageLive(_3);
 -         StorageLive(_4);
 +         nop;
@@ -72,9 +74,11 @@
           StorageLive(_7);
           StorageLive(_8);
           _8 = const 0_usize;
--         _9 = Lt(copy _8, const 2_usize);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _8) -> [success: bb1, unwind continue];
-+         _9 = const true;
+-         _9 = Len((*_1));
+-         _10 = Lt(copy _8, copy _9);
+-         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb1, unwind continue];
++         _9 = const 2_usize;
++         _10 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 0_usize) -> [success: bb1, unwind continue];
       }
   
@@ -91,168 +95,170 @@
 +         nop;
           StorageDead(_7);
           StorageDead(_5);
-          StorageLive(_10);
--         StorageLive(_11);
+          StorageLive(_11);
+-         StorageLive(_12);
 +         nop;
-          StorageLive(_12);
           StorageLive(_13);
           StorageLive(_14);
           StorageLive(_15);
-          _15 = const 1_usize;
--         _16 = Lt(copy _15, const 2_usize);
--         assert(move _16, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _15) -> [success: bb2, unwind continue];
-+         _16 = const true;
+          StorageLive(_16);
+          _16 = const 1_usize;
+-         _17 = Len((*_1));
+-         _18 = Lt(copy _16, copy _17);
+-         assert(move _18, "index out of bounds: the length is {} but the index is {}", move _17, copy _16) -> [success: bb2, unwind continue];
++         _17 = const 2_usize;
++         _18 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 2_usize, const 1_usize) -> [success: bb2, unwind continue];
       }
   
       bb2: {
--         _14 = &(*_1)[_15];
-+         _14 = &(*_1)[1 of 2];
-          _13 = &(*_14);
-          _12 = move _13 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
-          StorageDead(_13);
-          _11 = &raw const (*_12);
--         _10 = move _11 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
--         StorageDead(_11);
-+         _10 = copy _11;
-+         nop;
+-         _15 = &(*_1)[_16];
++         _15 = &(*_1)[1 of 2];
+          _14 = &(*_15);
+          _13 = move _14 as &dyn std::marker::Send (PointerCoercion(Unsize, AsCast));
           StorageDead(_14);
-          StorageDead(_12);
-          StorageLive(_17);
-          StorageLive(_18);
+          _12 = &raw const (*_13);
+-         _11 = move _12 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
+-         StorageDead(_12);
++         _11 = copy _12;
++         nop;
+          StorageDead(_15);
+          StorageDead(_13);
           StorageLive(_19);
--         _19 = copy _3;
-+         _19 = copy _4;
           StorageLive(_20);
           StorageLive(_21);
--         _21 = copy _10;
--         _20 = move _21 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _21 = copy _11;
-+         _20 = copy _11;
+-         _21 = copy _3;
++         _21 = copy _4;
+          StorageLive(_22);
+          StorageLive(_23);
+-         _23 = copy _11;
+-         _22 = move _23 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _23 = copy _12;
++         _22 = copy _12;
+          StorageDead(_23);
+-         _20 = Eq(move _21, move _22);
++         _20 = Eq(copy _4, copy _12);
+          StorageDead(_22);
           StorageDead(_21);
--         _18 = Eq(move _19, move _20);
-+         _18 = Eq(copy _4, copy _11);
-          StorageDead(_20);
-          StorageDead(_19);
-          _17 = opaque::<bool>(move _18) -> [return: bb3, unwind continue];
+          _19 = opaque::<bool>(move _20) -> [return: bb3, unwind continue];
       }
   
       bb3: {
-          StorageDead(_18);
-          StorageDead(_17);
-          StorageLive(_22);
-          StorageLive(_23);
+          StorageDead(_20);
+          StorageDead(_19);
           StorageLive(_24);
--         _24 = copy _3;
-+         _24 = copy _4;
           StorageLive(_25);
           StorageLive(_26);
--         _26 = copy _10;
--         _25 = move _26 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _26 = copy _11;
-+         _25 = copy _11;
+-         _26 = copy _3;
++         _26 = copy _4;
+          StorageLive(_27);
+          StorageLive(_28);
+-         _28 = copy _11;
+-         _27 = move _28 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _28 = copy _12;
++         _27 = copy _12;
+          StorageDead(_28);
+-         _25 = Ne(move _26, move _27);
++         _25 = Ne(copy _4, copy _12);
+          StorageDead(_27);
           StorageDead(_26);
--         _23 = Ne(move _24, move _25);
-+         _23 = Ne(copy _4, copy _11);
-          StorageDead(_25);
-          StorageDead(_24);
-          _22 = opaque::<bool>(move _23) -> [return: bb4, unwind continue];
+          _24 = opaque::<bool>(move _25) -> [return: bb4, unwind continue];
       }
   
       bb4: {
-          StorageDead(_23);
-          StorageDead(_22);
-          StorageLive(_27);
-          StorageLive(_28);
+          StorageDead(_25);
+          StorageDead(_24);
           StorageLive(_29);
--         _29 = copy _3;
-+         _29 = copy _4;
           StorageLive(_30);
           StorageLive(_31);
--         _31 = copy _10;
--         _30 = move _31 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _31 = copy _11;
-+         _30 = copy _11;
+-         _31 = copy _3;
++         _31 = copy _4;
+          StorageLive(_32);
+          StorageLive(_33);
+-         _33 = copy _11;
+-         _32 = move _33 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _33 = copy _12;
++         _32 = copy _12;
+          StorageDead(_33);
+-         _30 = Lt(move _31, move _32);
++         _30 = Lt(copy _4, copy _12);
+          StorageDead(_32);
           StorageDead(_31);
--         _28 = Lt(move _29, move _30);
-+         _28 = Lt(copy _4, copy _11);
-          StorageDead(_30);
-          StorageDead(_29);
-          _27 = opaque::<bool>(move _28) -> [return: bb5, unwind continue];
+          _29 = opaque::<bool>(move _30) -> [return: bb5, unwind continue];
       }
   
       bb5: {
-          StorageDead(_28);
-          StorageDead(_27);
-          StorageLive(_32);
-          StorageLive(_33);
+          StorageDead(_30);
+          StorageDead(_29);
           StorageLive(_34);
--         _34 = copy _3;
-+         _34 = copy _4;
           StorageLive(_35);
           StorageLive(_36);
--         _36 = copy _10;
--         _35 = move _36 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _36 = copy _11;
-+         _35 = copy _11;
+-         _36 = copy _3;
++         _36 = copy _4;
+          StorageLive(_37);
+          StorageLive(_38);
+-         _38 = copy _11;
+-         _37 = move _38 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _38 = copy _12;
++         _37 = copy _12;
+          StorageDead(_38);
+-         _35 = Le(move _36, move _37);
++         _35 = Le(copy _4, copy _12);
+          StorageDead(_37);
           StorageDead(_36);
--         _33 = Le(move _34, move _35);
-+         _33 = Le(copy _4, copy _11);
-          StorageDead(_35);
-          StorageDead(_34);
-          _32 = opaque::<bool>(move _33) -> [return: bb6, unwind continue];
+          _34 = opaque::<bool>(move _35) -> [return: bb6, unwind continue];
       }
   
       bb6: {
-          StorageDead(_33);
-          StorageDead(_32);
-          StorageLive(_37);
-          StorageLive(_38);
+          StorageDead(_35);
+          StorageDead(_34);
           StorageLive(_39);
--         _39 = copy _3;
-+         _39 = copy _4;
           StorageLive(_40);
           StorageLive(_41);
--         _41 = copy _10;
--         _40 = move _41 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _41 = copy _11;
-+         _40 = copy _11;
+-         _41 = copy _3;
++         _41 = copy _4;
+          StorageLive(_42);
+          StorageLive(_43);
+-         _43 = copy _11;
+-         _42 = move _43 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _43 = copy _12;
++         _42 = copy _12;
+          StorageDead(_43);
+-         _40 = Gt(move _41, move _42);
++         _40 = Gt(copy _4, copy _12);
+          StorageDead(_42);
           StorageDead(_41);
--         _38 = Gt(move _39, move _40);
-+         _38 = Gt(copy _4, copy _11);
-          StorageDead(_40);
-          StorageDead(_39);
-          _37 = opaque::<bool>(move _38) -> [return: bb7, unwind continue];
+          _39 = opaque::<bool>(move _40) -> [return: bb7, unwind continue];
       }
   
       bb7: {
-          StorageDead(_38);
-          StorageDead(_37);
-          StorageLive(_42);
-          StorageLive(_43);
+          StorageDead(_40);
+          StorageDead(_39);
           StorageLive(_44);
--         _44 = copy _3;
-+         _44 = copy _4;
           StorageLive(_45);
           StorageLive(_46);
--         _46 = copy _10;
--         _45 = move _46 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
-+         _46 = copy _11;
-+         _45 = copy _11;
+-         _46 = copy _3;
++         _46 = copy _4;
+          StorageLive(_47);
+          StorageLive(_48);
+-         _48 = copy _11;
+-         _47 = move _48 as *const dyn std::marker::Send (PointerCoercion(Unsize, Implicit));
++         _48 = copy _12;
++         _47 = copy _12;
+          StorageDead(_48);
+-         _45 = Ge(move _46, move _47);
++         _45 = Ge(copy _4, copy _12);
+          StorageDead(_47);
           StorageDead(_46);
--         _43 = Ge(move _44, move _45);
-+         _43 = Ge(copy _4, copy _11);
-          StorageDead(_45);
-          StorageDead(_44);
-          _42 = opaque::<bool>(move _43) -> [return: bb8, unwind continue];
+          _44 = opaque::<bool>(move _45) -> [return: bb8, unwind continue];
       }
   
       bb8: {
-          StorageDead(_43);
-          StorageDead(_42);
+          StorageDead(_45);
+          StorageDead(_44);
           _0 = const ();
-          StorageDead(_15);
-          StorageDead(_10);
+          StorageDead(_16);
+          StorageDead(_11);
           StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
diff --git a/tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff b/tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff
new file mode 100644
index 0000000000000..2f83f54d2afdb
--- /dev/null
+++ b/tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff
@@ -0,0 +1,12 @@
+- // MIR for `cursed_is_i32` before GVN
++ // MIR for `cursed_is_i32` after GVN
+  
+  fn cursed_is_i32() -> bool {
+      let mut _0: bool;
+  
+      bb0: {
+          _0 = Eq(const cursed_is_i32::<T>::{constant#0}, const cursed_is_i32::<T>::{constant#1});
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn_type_id_polymorphic.rs b/tests/mir-opt/gvn_type_id_polymorphic.rs
new file mode 100644
index 0000000000000..39bc5c24ecc68
--- /dev/null
+++ b/tests/mir-opt/gvn_type_id_polymorphic.rs
@@ -0,0 +1,22 @@
+//@ test-mir-pass: GVN
+//@ compile-flags: -C opt-level=2
+
+#![feature(core_intrinsics)]
+
+fn generic<T>() {}
+
+const fn type_id_of_val<T: 'static>(_: &T) -> u128 {
+    std::intrinsics::type_id::<T>()
+}
+
+// EMIT_MIR gvn_type_id_polymorphic.cursed_is_i32.GVN.diff
+fn cursed_is_i32<T: 'static>() -> bool {
+    // CHECK-LABEL: fn cursed_is_i32(
+    // CHECK: _0 = Eq(const cursed_is_i32::<T>::{constant#0}, const cursed_is_i32::<T>::{constant#1});
+    // CHECK-NEXT: return;
+    (const { type_id_of_val(&generic::<T>) } == const { type_id_of_val(&generic::<i32>) })
+}
+
+fn main() {
+    dbg!(cursed_is_i32::<i32>());
+}
diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff
new file mode 100644
index 0000000000000..f39df7ffca0fb
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff
@@ -0,0 +1,77 @@
+- // MIR for `norm2` before InstSimplify-after-simplifycfg
++ // MIR for `norm2` after InstSimplify-after-simplifycfg
+  
+  fn norm2(_1: [f32; 2]) -> f32 {
+      debug x => _1;
+      let mut _0: f32;
+      let _2: f32;
+      let _3: usize;
+      let mut _4: usize;
+      let mut _5: bool;
+      let _7: usize;
+      let mut _8: usize;
+      let mut _9: bool;
+      let mut _10: f32;
+      let mut _11: f32;
+      let mut _12: f32;
+      let mut _13: f32;
+      let mut _14: f32;
+      let mut _15: f32;
+      scope 1 {
+          debug a => _2;
+          let _6: f32;
+          scope 2 {
+              debug b => _6;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 0_usize;
+-         _4 = Len(_1);
++         _4 = const 2_usize;
+          _5 = Lt(copy _3, copy _4);
+          assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          _2 = copy _1[_3];
+          StorageDead(_3);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+-         _8 = Len(_1);
++         _8 = const 2_usize;
+          _9 = Lt(copy _7, copy _8);
+          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          _6 = copy _1[_7];
+          StorageDead(_7);
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = copy _2;
+          StorageLive(_12);
+          _12 = copy _2;
+          _10 = Mul(move _11, move _12);
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_13);
+          StorageLive(_14);
+          _14 = copy _6;
+          StorageLive(_15);
+          _15 = copy _6;
+          _13 = Mul(move _14, move _15);
+          StorageDead(_15);
+          StorageDead(_14);
+          _0 = Add(move _10, move _13);
+          StorageDead(_13);
+          StorageDead(_10);
+          StorageDead(_6);
+          StorageDead(_2);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff
new file mode 100644
index 0000000000000..0e7d5653c6820
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff
@@ -0,0 +1,77 @@
+- // MIR for `norm2` before InstSimplify-after-simplifycfg
++ // MIR for `norm2` after InstSimplify-after-simplifycfg
+  
+  fn norm2(_1: [f32; 2]) -> f32 {
+      debug x => _1;
+      let mut _0: f32;
+      let _2: f32;
+      let _3: usize;
+      let mut _4: usize;
+      let mut _5: bool;
+      let _7: usize;
+      let mut _8: usize;
+      let mut _9: bool;
+      let mut _10: f32;
+      let mut _11: f32;
+      let mut _12: f32;
+      let mut _13: f32;
+      let mut _14: f32;
+      let mut _15: f32;
+      scope 1 {
+          debug a => _2;
+          let _6: f32;
+          scope 2 {
+              debug b => _6;
+          }
+      }
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = const 0_usize;
+-         _4 = Len(_1);
++         _4 = const 2_usize;
+          _5 = Lt(copy _3, copy _4);
+          assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind continue];
+      }
+  
+      bb1: {
+          _2 = copy _1[_3];
+          StorageDead(_3);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+-         _8 = Len(_1);
++         _8 = const 2_usize;
+          _9 = Lt(copy _7, copy _8);
+          assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb2, unwind continue];
+      }
+  
+      bb2: {
+          _6 = copy _1[_7];
+          StorageDead(_7);
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = copy _2;
+          StorageLive(_12);
+          _12 = copy _2;
+          _10 = Mul(move _11, move _12);
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_13);
+          StorageLive(_14);
+          _14 = copy _6;
+          StorageLive(_15);
+          _15 = copy _6;
+          _13 = Mul(move _14, move _15);
+          StorageDead(_15);
+          StorageDead(_14);
+          _0 = Add(move _10, move _13);
+          StorageDead(_13);
+          StorageDead(_10);
+          StorageDead(_6);
+          StorageDead(_2);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/instsimplify/combine_array_len.rs b/tests/mir-opt/instsimplify/combine_array_len.rs
new file mode 100644
index 0000000000000..91f43f75689de
--- /dev/null
+++ b/tests/mir-opt/instsimplify/combine_array_len.rs
@@ -0,0 +1,15 @@
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+//@ test-mir-pass: InstSimplify-after-simplifycfg
+
+// EMIT_MIR combine_array_len.norm2.InstSimplify-after-simplifycfg.diff
+fn norm2(x: [f32; 2]) -> f32 {
+    // CHECK-LABEL: fn norm2(
+    // CHECK-NOT: Len(
+    let a = x[0];
+    let b = x[1];
+    a * a + b * b
+}
+
+fn main() {
+    assert_eq!(norm2([3.0, 4.0]), 5.0 * 5.0);
+}
diff --git a/tests/mir-opt/issue_72181.foo.built.after.mir b/tests/mir-opt/issue_72181.foo.built.after.mir
index 7593b79543258..314cf8b367f57 100644
--- a/tests/mir-opt/issue_72181.foo.built.after.mir
+++ b/tests/mir-opt/issue_72181.foo.built.after.mir
@@ -4,14 +4,15 @@ fn foo(_1: [(Never, u32); 1]) -> u32 {
     debug xs => _1;
     let mut _0: u32;
     let _2: usize;
-    let mut _3: bool;
+    let mut _3: usize;
+    let mut _4: bool;
 
     bb0: {
         StorageLive(_2);
         _2 = const 0_usize;
-        FakeRead(ForIndex, _1);
-        _3 = Lt(copy _2, const 1_usize);
-        assert(move _3, "index out of bounds: the length is {} but the index is {}", const 1_usize, copy _2) -> [success: bb1, unwind: bb2];
+        _3 = Len(_1);
+        _4 = Lt(copy _2, copy _3);
+        assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind: bb2];
     }
 
     bb1: {
diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir
index 9f3803f5407fe..aade84a6dd2e8 100644
--- a/tests/mir-opt/issue_72181.main.built.after.mir
+++ b/tests/mir-opt/issue_72181.main.built.after.mir
@@ -7,7 +7,8 @@ fn main() -> () {
     let mut _4: Foo;
     let mut _5: u64;
     let _6: usize;
-    let mut _7: bool;
+    let mut _7: usize;
+    let mut _8: bool;
     scope 1 {
         let _2: [Foo; 2];
         scope 2 {
@@ -37,9 +38,9 @@ fn main() -> () {
         StorageLive(_5);
         StorageLive(_6);
         _6 = const 0_usize;
-        FakeRead(ForIndex, _2);
-        _7 = Lt(copy _6, const 2_usize);
-        assert(move _7, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _6) -> [success: bb3, unwind: bb5];
+        _7 = Len(_2);
+        _8 = Lt(copy _6, copy _7);
+        assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb3, unwind: bb5];
     }
 
     bb2: {
diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
index 94ba7082c6612..c02bab3524bca 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff
@@ -7,16 +7,18 @@
       let _2: &[T];
       let _3: &[T; 3];
       let _4: [T; 3];
-      let mut _8: !;
+      let mut _5: usize;
+      let mut _6: bool;
+      let mut _10: !;
       scope 1 {
           debug v => _2;
-          let _5: &T;
-          let _6: &T;
           let _7: &T;
+          let _8: &T;
+          let _9: &T;
           scope 2 {
-              debug v1 => _5;
-              debug v2 => _6;
-              debug v3 => _7;
+              debug v1 => _7;
+              debug v2 => _8;
+              debug v3 => _9;
           }
       }
   
@@ -25,23 +27,25 @@
           _4 = [copy _1, copy _1, copy _1];
           _3 = &_4;
           _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit));
+          nop;
+          nop;
           goto -> bb2;
       }
   
       bb1: {
-          _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable;
+          _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable;
       }
   
       bb2: {
-          StorageLive(_5);
-          _5 = &(*_2)[0 of 3];
-          StorageLive(_6);
-          _6 = &(*_2)[1 of 3];
           StorageLive(_7);
-          _7 = &(*_2)[2 of 3];
+          _7 = &(*_2)[0 of 3];
+          StorageLive(_8);
+          _8 = &(*_2)[1 of 3];
+          StorageLive(_9);
+          _9 = &(*_2)[2 of 3];
+          StorageDead(_9);
+          StorageDead(_8);
           StorageDead(_7);
-          StorageDead(_6);
-          StorageDead(_5);
           StorageDead(_4);
           return;
       }
diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
index 0455b2c326eb8..49be042588cb3 100644
--- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
+++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff
@@ -7,16 +7,18 @@
       let _2: &[T];
       let _3: &[T; 3];
       let _4: [T; 3];
-      let mut _8: !;
+      let mut _5: usize;
+      let mut _6: bool;
+      let mut _10: !;
       scope 1 {
           debug v => _2;
-          let _5: &T;
-          let _6: &T;
           let _7: &T;
+          let _8: &T;
+          let _9: &T;
           scope 2 {
-              debug v1 => _5;
-              debug v2 => _6;
-              debug v3 => _7;
+              debug v1 => _7;
+              debug v2 => _8;
+              debug v3 => _9;
           }
       }
   
@@ -25,23 +27,25 @@
           _4 = [copy _1, copy _1, copy _1];
           _3 = &_4;
           _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit));
+          nop;
+          nop;
           goto -> bb2;
       }
   
       bb1: {
-          _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue;
+          _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue;
       }
   
       bb2: {
-          StorageLive(_5);
-          _5 = &(*_2)[0 of 3];
-          StorageLive(_6);
-          _6 = &(*_2)[1 of 3];
           StorageLive(_7);
-          _7 = &(*_2)[2 of 3];
+          _7 = &(*_2)[0 of 3];
+          StorageLive(_8);
+          _8 = &(*_2)[1 of 3];
+          StorageLive(_9);
+          _9 = &(*_2)[2 of 3];
+          StorageDead(_9);
+          StorageDead(_8);
           StorageDead(_7);
-          StorageDead(_6);
-          StorageDead(_5);
           StorageDead(_4);
           return;
       }
diff --git a/tests/mir-opt/issue_91633.foo.built.after.mir b/tests/mir-opt/issue_91633.foo.built.after.mir
index bf65b5b4a8ccb..50fdf08375a00 100644
--- a/tests/mir-opt/issue_91633.foo.built.after.mir
+++ b/tests/mir-opt/issue_91633.foo.built.after.mir
@@ -6,9 +6,8 @@ fn foo(_1: Box<[T]>) -> T {
     let _2: T;
     let mut _3: &T;
     let _4: usize;
-    let mut _5: *const [T];
-    let mut _6: usize;
-    let mut _7: bool;
+    let mut _5: usize;
+    let mut _6: bool;
     scope 1 {
         debug f => _2;
     }
@@ -18,10 +17,9 @@ fn foo(_1: Box<[T]>) -> T {
         StorageLive(_3);
         StorageLive(_4);
         _4 = const 0_usize;
-        _5 = &raw const (*_1);
-        _6 = PtrMetadata(move _5);
-        _7 = Lt(copy _4, copy _6);
-        assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _4) -> [success: bb1, unwind: bb5];
+        _5 = Len((*_1));
+        _6 = Lt(copy _4, copy _5);
+        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, copy _4) -> [success: bb1, unwind: bb5];
     }
 
     bb1: {
diff --git a/tests/mir-opt/issue_91633.fun.built.after.mir b/tests/mir-opt/issue_91633.fun.built.after.mir
index d2fc438d3e817..5b41b376719b2 100644
--- a/tests/mir-opt/issue_91633.fun.built.after.mir
+++ b/tests/mir-opt/issue_91633.fun.built.after.mir
@@ -15,7 +15,7 @@ fn fun(_1: &[T]) -> &T {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const 0_usize;
-        _4 = PtrMetadata(copy _1);
+        _4 = Len((*_1));
         _5 = Lt(copy _3, copy _4);
         assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb2];
     }
diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff
index 98c5e868046b5..f052c8f63dcaa 100644
--- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-abort.diff
@@ -11,14 +11,16 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: bool;
+      let mut _9: usize;
+      let mut _10: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
-          StorageLive(_5);
+-         StorageLive(_5);
++         nop;
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -38,13 +40,16 @@
       }
   
       bb2: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Lt(copy _8, const N);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable];
-+         _9 = copy _3;
+-         _9 = Len((*_2));
+-         _10 = Lt(copy _8, copy _9);
+-         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
++         _9 = const N;
++         _10 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
       }
   
@@ -56,7 +61,8 @@
       }
   
       bb4: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
diff --git a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff
index 72c7313786996..3299e3004317d 100644
--- a/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound.GVN.panic-unwind.diff
@@ -11,14 +11,16 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: bool;
+      let mut _9: usize;
+      let mut _10: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
-          StorageLive(_5);
+-         StorageLive(_5);
++         nop;
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -38,13 +40,16 @@
       }
   
       bb2: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Lt(copy _8, const N);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue];
-+         _9 = copy _3;
+-         _9 = Len((*_2));
+-         _10 = Lt(copy _8, copy _9);
+-         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
++         _9 = const N;
++         _10 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
       }
   
@@ -56,7 +61,8 @@
       }
   
       bb4: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           _0 = const 42_u8;
           goto -> bb5;
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff
index 9ffaf44c02bd2..329eb80b3c4f5 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-abort.diff
@@ -11,16 +11,19 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: bool;
-      let _10: usize;
-      let mut _11: bool;
+      let mut _9: usize;
+      let mut _10: bool;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
-          StorageLive(_5);
+-         StorageLive(_5);
++         nop;
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -40,13 +43,16 @@
       }
   
       bb2: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Lt(copy _8, const N);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind unreachable];
-+         _9 = copy _3;
+-         _9 = Len((*_2));
+-         _10 = Lt(copy _8, copy _9);
+-         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind unreachable];
++         _9 = const N;
++         _10 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind unreachable];
       }
   
@@ -58,20 +64,23 @@
       }
   
       bb4: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
-          StorageLive(_10);
-          _10 = const 0_usize;
--         _11 = Lt(copy _10, const N);
--         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind unreachable];
-+         _11 = Lt(const 0_usize, const N);
-+         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable];
+          StorageLive(_11);
+          _11 = const 0_usize;
+-         _12 = Len((*_2));
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind unreachable];
++         _12 = const N;
++         _13 = Lt(const 0_usize, const N);
++         assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind unreachable];
       }
   
       bb5: {
--         (*_2)[_10] = const 42_u8;
+-         (*_2)[_11] = const 42_u8;
 +         (*_2)[0 of 1] = const 42_u8;
-          StorageDead(_10);
+          StorageDead(_11);
           _0 = const 42_u8;
           goto -> bb6;
       }
diff --git a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff
index 08008e463357f..ab007e133ecc1 100644
--- a/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_bound_mut.GVN.panic-unwind.diff
@@ -11,16 +11,19 @@
       let mut _6: &[u8];
       let mut _7: &[u8; N];
       let _8: usize;
-      let mut _9: bool;
-      let _10: usize;
-      let mut _11: bool;
+      let mut _9: usize;
+      let mut _10: bool;
+      let _11: usize;
+      let mut _12: usize;
+      let mut _13: bool;
   
       bb0: {
 -         StorageLive(_3);
 +         nop;
           StorageLive(_4);
           _4 = copy _1;
-          StorageLive(_5);
+-         StorageLive(_5);
++         nop;
           StorageLive(_6);
           StorageLive(_7);
           _7 = &(*_2);
@@ -40,13 +43,16 @@
       }
   
       bb2: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
           StorageLive(_8);
           _8 = copy _1;
--         _9 = Lt(copy _8, const N);
--         assert(move _9, "index out of bounds: the length is {} but the index is {}", const N, copy _8) -> [success: bb3, unwind continue];
-+         _9 = copy _3;
+-         _9 = Len((*_2));
+-         _10 = Lt(copy _8, copy _9);
+-         assert(move _10, "index out of bounds: the length is {} but the index is {}", move _9, copy _8) -> [success: bb3, unwind continue];
++         _9 = const N;
++         _10 = copy _3;
 +         assert(copy _3, "index out of bounds: the length is {} but the index is {}", const N, copy _1) -> [success: bb3, unwind continue];
       }
   
@@ -58,20 +64,23 @@
       }
   
       bb4: {
-          StorageDead(_5);
+-         StorageDead(_5);
++         nop;
           StorageDead(_4);
-          StorageLive(_10);
-          _10 = const 0_usize;
--         _11 = Lt(copy _10, const N);
--         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, copy _10) -> [success: bb5, unwind continue];
-+         _11 = Lt(const 0_usize, const N);
-+         assert(move _11, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue];
+          StorageLive(_11);
+          _11 = const 0_usize;
+-         _12 = Len((*_2));
+-         _13 = Lt(copy _11, copy _12);
+-         assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb5, unwind continue];
++         _12 = const N;
++         _13 = Lt(const 0_usize, const N);
++         assert(move _13, "index out of bounds: the length is {} but the index is {}", const N, const 0_usize) -> [success: bb5, unwind continue];
       }
   
       bb5: {
--         (*_2)[_10] = const 42_u8;
+-         (*_2)[_11] = const 42_u8;
 +         (*_2)[0 of 1] = const 42_u8;
-          StorageDead(_10);
+          StorageDead(_11);
           _0 = const 42_u8;
           goto -> bb6;
       }
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
index 4b39e18d16cfc..20001f1248ef5 100644
--- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
+++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-abort.diff
@@ -36,7 +36,7 @@
           StorageDead(_4);
           StorageLive(_7);
           _7 = copy _1;
-          _8 = PtrMetadata(copy _2);
+          _8 = Len((*_2));
           _9 = Lt(copy _7, copy _8);
           assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind unreachable];
       }
diff --git a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
index f0d4afa21ae4b..ca8f92df5de0c 100644
--- a/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
+++ b/tests/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.panic-unwind.diff
@@ -36,7 +36,7 @@
           StorageDead(_4);
           StorageLive(_7);
           _7 = copy _1;
-          _8 = PtrMetadata(copy _2);
+          _8 = Len((*_2));
           _9 = Lt(copy _7, copy _8);
           assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, copy _7) -> [success: bb3, unwind continue];
       }
diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
index 35e44b2314a50..7294302609a24 100644
--- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir
@@ -27,19 +27,20 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: [usize; ValTree(Leaf(0x00000003): usize)];
     let _3: usize;
-    let mut _4: bool;
-    let mut _6: bool;
-    let _7: bool;
-    let mut _8: usize;
-    let _9: bool;
+    let mut _4: usize;
+    let mut _5: bool;
+    let mut _7: bool;
+    let _8: bool;
+    let mut _9: usize;
+    let _10: bool;
     scope 1 {
         debug v => _1;
         let _2: &'?3 usize;
         scope 2 {
             debug p => _2;
-            let _5: &'?4 usize;
+            let _6: &'?4 usize;
             scope 3 {
-                debug q => _5;
+                debug q => _6;
             }
         }
     }
@@ -51,50 +52,50 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const ConstValue(Scalar(0x00000000): usize);
-        FakeRead(ForIndex, _1);
-        _4 = Lt(copy _3, const ConstValue(Scalar(0x00000003): usize));
-        assert(move _4, "index out of bounds: the length is {} but the index is {}", const ConstValue(Scalar(0x00000003): usize), copy _3) -> [success: bb1, unwind: bb7];
+        _4 = Len(_1);
+        _5 = Lt(copy _3, copy _4);
+        assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7];
     }
 
     bb1: {
         _2 = &'?2 _1[_3];
         FakeRead(ForLet(None), _2);
-        StorageLive(_5);
-        _5 = copy _2;
-        FakeRead(ForLet(None), _5);
         StorageLive(_6);
-        _6 = const ConstValue(Scalar(0x01): bool);
-        switchInt(move _6) -> [0: bb4, otherwise: bb2];
+        _6 = copy _2;
+        FakeRead(ForLet(None), _6);
+        StorageLive(_7);
+        _7 = const ConstValue(Scalar(0x01): bool);
+        switchInt(move _7) -> [0: bb4, otherwise: bb2];
     }
 
     bb2: {
-        StorageLive(_7);
         StorageLive(_8);
-        _8 = copy (*_5);
-        _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
+        StorageLive(_9);
+        _9 = copy (*_6);
+        _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
     }
 
     bb3: {
+        StorageDead(_9);
         StorageDead(_8);
-        StorageDead(_7);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb4: {
-        StorageLive(_9);
-        _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
+        StorageLive(_10);
+        _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x00000016): usize)) -> [return: bb5, unwind: bb7];
     }
 
     bb5: {
-        StorageDead(_9);
+        StorageDead(_10);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb6: {
+        StorageDead(_7);
         StorageDead(_6);
-        StorageDead(_5);
         StorageDead(_3);
         StorageDead(_2);
         StorageDead(_1);
diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
index 6d415f42d06f3..85b89a013c4e4 100644
--- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
+++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir
@@ -27,19 +27,20 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: [usize; ValTree(Leaf(0x0000000000000003): usize)];
     let _3: usize;
-    let mut _4: bool;
-    let mut _6: bool;
-    let _7: bool;
-    let mut _8: usize;
-    let _9: bool;
+    let mut _4: usize;
+    let mut _5: bool;
+    let mut _7: bool;
+    let _8: bool;
+    let mut _9: usize;
+    let _10: bool;
     scope 1 {
         debug v => _1;
         let _2: &'?3 usize;
         scope 2 {
             debug p => _2;
-            let _5: &'?4 usize;
+            let _6: &'?4 usize;
             scope 3 {
-                debug q => _5;
+                debug q => _6;
             }
         }
     }
@@ -51,50 +52,50 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const ConstValue(Scalar(0x0000000000000000): usize);
-        FakeRead(ForIndex, _1);
-        _4 = Lt(copy _3, const ConstValue(Scalar(0x0000000000000003): usize));
-        assert(move _4, "index out of bounds: the length is {} but the index is {}", const ConstValue(Scalar(0x0000000000000003): usize), copy _3) -> [success: bb1, unwind: bb7];
+        _4 = Len(_1);
+        _5 = Lt(copy _3, copy _4);
+        assert(move _5, "index out of bounds: the length is {} but the index is {}", move _4, copy _3) -> [success: bb1, unwind: bb7];
     }
 
     bb1: {
         _2 = &'?2 _1[_3];
         FakeRead(ForLet(None), _2);
-        StorageLive(_5);
-        _5 = copy _2;
-        FakeRead(ForLet(None), _5);
         StorageLive(_6);
-        _6 = const ConstValue(Scalar(0x01): bool);
-        switchInt(move _6) -> [0: bb4, otherwise: bb2];
+        _6 = copy _2;
+        FakeRead(ForLet(None), _6);
+        StorageLive(_7);
+        _7 = const ConstValue(Scalar(0x01): bool);
+        switchInt(move _7) -> [0: bb4, otherwise: bb2];
     }
 
     bb2: {
-        StorageLive(_7);
         StorageLive(_8);
-        _8 = copy (*_5);
-        _7 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _8) -> [return: bb3, unwind: bb7];
+        StorageLive(_9);
+        _9 = copy (*_6);
+        _8 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(move _9) -> [return: bb3, unwind: bb7];
     }
 
     bb3: {
+        StorageDead(_9);
         StorageDead(_8);
-        StorageDead(_7);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb4: {
-        StorageLive(_9);
-        _9 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
+        StorageLive(_10);
+        _10 = ConstValue(ZeroSized: fn(usize) -> bool {use_x})(const ConstValue(Scalar(0x0000000000000016): usize)) -> [return: bb5, unwind: bb7];
     }
 
     bb5: {
-        StorageDead(_9);
+        StorageDead(_10);
         _0 = const ConstValue(ZeroSized: ());
         goto -> bb6;
     }
 
     bb6: {
+        StorageDead(_7);
         StorageDead(_6);
-        StorageDead(_5);
         StorageDead(_3);
         StorageDead(_2);
         StorageDead(_1);
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff
index 5b39e45806e33..6575610727b99 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-abort.diff
@@ -7,16 +7,17 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -37,9 +38,10 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
--         _6 = Lt(copy _5, const 6_usize);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
-+         _6 = const true;
+          _6 = const 6_usize;
+-         _7 = Lt(copy _5, copy _6);
+-         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
++         _7 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable];
       }
   
@@ -48,13 +50,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
           StorageLive(_8);
-          _8 = const 42_u32;
--         _7 = copy _8;
-+         _7 = const 42_u32;
+          StorageLive(_9);
+          _9 = const 42_u32;
+-         _8 = copy _9;
++         _8 = const 42_u32;
+          StorageDead(_9);
           StorageDead(_8);
-          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff
index ea2742a6471a1..1a4ed5767fece 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.32bit.panic-unwind.diff
@@ -7,16 +7,17 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -37,9 +38,10 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
--         _6 = Lt(copy _5, const 6_usize);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
-+         _6 = const true;
+          _6 = const 6_usize;
+-         _7 = Lt(copy _5, copy _6);
+-         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
++         _7 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
@@ -48,13 +50,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
           StorageLive(_8);
-          _8 = const 42_u32;
--         _7 = copy _8;
-+         _7 = const 42_u32;
+          StorageLive(_9);
+          _9 = const 42_u32;
+-         _8 = copy _9;
++         _8 = const 42_u32;
+          StorageDead(_9);
           StorageDead(_8);
-          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff
index 5b39e45806e33..6575610727b99 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-abort.diff
@@ -7,16 +7,17 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -37,9 +38,10 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
--         _6 = Lt(copy _5, const 6_usize);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
-+         _6 = const true;
+          _6 = const 6_usize;
+-         _7 = Lt(copy _5, copy _6);
+-         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
++         _7 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind unreachable];
       }
   
@@ -48,13 +50,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
           StorageLive(_8);
-          _8 = const 42_u32;
--         _7 = copy _8;
-+         _7 = const 42_u32;
+          StorageLive(_9);
+          _9 = const 42_u32;
+-         _8 = copy _9;
++         _8 = const 42_u32;
+          StorageDead(_9);
           StorageDead(_8);
-          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff
index ea2742a6471a1..1a4ed5767fece 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.GVN.64bit.panic-unwind.diff
@@ -7,16 +7,17 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -37,9 +38,10 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
--         _6 = Lt(copy _5, const 6_usize);
--         assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
-+         _6 = const true;
+          _6 = const 6_usize;
+-         _7 = Lt(copy _5, copy _6);
+-         assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
++         _7 = const true;
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 6_usize, const 3_usize) -> [success: bb2, unwind continue];
       }
   
@@ -48,13 +50,13 @@
 +         _3 = const 3_i32;
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
           StorageLive(_8);
-          _8 = const 42_u32;
--         _7 = copy _8;
-+         _7 = const 42_u32;
+          StorageLive(_9);
+          _9 = const 42_u32;
+-         _8 = copy _9;
++         _8 = const 42_u32;
+          StorageDead(_9);
           StorageDead(_8);
-          StorageDead(_7);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff
index f7fe08831b97d..e2420a341e0ab 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff
@@ -7,18 +7,19 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: Point;
-+     let mut _9: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: Point;
 +     let mut _10: u32;
++     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -36,30 +37,31 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = Lt(copy _5, const 6_usize);
-          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
+          _6 = const 6_usize;
+          _7 = Lt(copy _5, copy _6);
+          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
--         StorageLive(_8);
--         _8 = Point { x: const 12_u32, y: const 42_u32 };
--         _7 = copy (_8.1: u32);
--         StorageDead(_8);
-+         StorageLive(_9);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = Point { x: const 12_u32, y: const 42_u32 };
+-         _8 = copy (_9.1: u32);
+-         StorageDead(_9);
 +         StorageLive(_10);
++         StorageLive(_11);
 +         nop;
-+         _9 = const 12_u32;
-+         _10 = const 42_u32;
++         _10 = const 12_u32;
++         _11 = const 42_u32;
 +         nop;
-+         _7 = copy _10;
-+         StorageDead(_9);
++         _8 = copy _11;
 +         StorageDead(_10);
++         StorageDead(_11);
 +         nop;
-          StorageDead(_7);
+          StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
index 6e36386bea601..a2fb3b979e622 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff
@@ -7,18 +7,19 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: Point;
-+     let mut _9: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: Point;
 +     let mut _10: u32;
++     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -36,30 +37,31 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = Lt(copy _5, const 6_usize);
-          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
+          _6 = const 6_usize;
+          _7 = Lt(copy _5, copy _6);
+          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
--         StorageLive(_8);
--         _8 = Point { x: const 12_u32, y: const 42_u32 };
--         _7 = copy (_8.1: u32);
--         StorageDead(_8);
-+         StorageLive(_9);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = Point { x: const 12_u32, y: const 42_u32 };
+-         _8 = copy (_9.1: u32);
+-         StorageDead(_9);
 +         StorageLive(_10);
++         StorageLive(_11);
 +         nop;
-+         _9 = const 12_u32;
-+         _10 = const 42_u32;
++         _10 = const 12_u32;
++         _11 = const 42_u32;
 +         nop;
-+         _7 = copy _10;
-+         StorageDead(_9);
++         _8 = copy _11;
 +         StorageDead(_10);
++         StorageDead(_11);
 +         nop;
-          StorageDead(_7);
+          StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff
index f7fe08831b97d..e2420a341e0ab 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff
@@ -7,18 +7,19 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: Point;
-+     let mut _9: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: Point;
 +     let mut _10: u32;
++     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -36,30 +37,31 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = Lt(copy _5, const 6_usize);
-          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind unreachable];
+          _6 = const 6_usize;
+          _7 = Lt(copy _5, copy _6);
+          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind unreachable];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
--         StorageLive(_8);
--         _8 = Point { x: const 12_u32, y: const 42_u32 };
--         _7 = copy (_8.1: u32);
--         StorageDead(_8);
-+         StorageLive(_9);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = Point { x: const 12_u32, y: const 42_u32 };
+-         _8 = copy (_9.1: u32);
+-         StorageDead(_9);
 +         StorageLive(_10);
++         StorageLive(_11);
 +         nop;
-+         _9 = const 12_u32;
-+         _10 = const 42_u32;
++         _10 = const 12_u32;
++         _11 = const 42_u32;
 +         nop;
-+         _7 = copy _10;
-+         StorageDead(_9);
++         _8 = copy _11;
 +         StorageDead(_10);
++         StorageDead(_11);
 +         nop;
-          StorageDead(_7);
+          StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
index 6e36386bea601..a2fb3b979e622 100644
--- a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff
@@ -7,18 +7,19 @@
       let mut _2: (i32, bool);
       let mut _4: [i32; 6];
       let _5: usize;
-      let mut _6: bool;
-      let mut _8: Point;
-+     let mut _9: u32;
+      let mut _6: usize;
+      let mut _7: bool;
+      let mut _9: Point;
 +     let mut _10: u32;
++     let mut _11: u32;
       scope 1 {
           debug x => _1;
           let _3: i32;
           scope 2 {
               debug y => _3;
-              let _7: u32;
+              let _8: u32;
               scope 3 {
-                  debug z => _7;
+                  debug z => _8;
               }
           }
       }
@@ -36,30 +37,31 @@
           _4 = [const 0_i32, const 1_i32, const 2_i32, const 3_i32, const 4_i32, const 5_i32];
           StorageLive(_5);
           _5 = const 3_usize;
-          _6 = Lt(copy _5, const 6_usize);
-          assert(move _6, "index out of bounds: the length is {} but the index is {}", const 6_usize, copy _5) -> [success: bb2, unwind continue];
+          _6 = const 6_usize;
+          _7 = Lt(copy _5, copy _6);
+          assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, copy _5) -> [success: bb2, unwind continue];
       }
   
       bb2: {
           _3 = copy _4[_5];
           StorageDead(_5);
           StorageDead(_4);
-          StorageLive(_7);
--         StorageLive(_8);
--         _8 = Point { x: const 12_u32, y: const 42_u32 };
--         _7 = copy (_8.1: u32);
--         StorageDead(_8);
-+         StorageLive(_9);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = Point { x: const 12_u32, y: const 42_u32 };
+-         _8 = copy (_9.1: u32);
+-         StorageDead(_9);
 +         StorageLive(_10);
++         StorageLive(_11);
 +         nop;
-+         _9 = const 12_u32;
-+         _10 = const 42_u32;
++         _10 = const 12_u32;
++         _11 = const 42_u32;
 +         nop;
-+         _7 = copy _10;
-+         StorageDead(_9);
++         _8 = copy _11;
 +         StorageDead(_10);
++         StorageDead(_11);
 +         nop;
-          StorageDead(_7);
+          StorageDead(_8);
           StorageDead(_3);
           StorageDead(_1);
           return;
diff --git a/tests/mir-opt/pre-codegen/slice_index.rs b/tests/mir-opt/pre-codegen/slice_index.rs
index 5dac535d195ad..574062d6c3569 100644
--- a/tests/mir-opt/pre-codegen/slice_index.rs
+++ b/tests/mir-opt/pre-codegen/slice_index.rs
@@ -9,7 +9,7 @@ use std::ops::Range;
 // EMIT_MIR slice_index.slice_index_usize.PreCodegen.after.mir
 pub fn slice_index_usize(slice: &[u32], index: usize) -> u32 {
     // CHECK-LABEL: slice_index_usize
-    // CHECK: [[LEN:_[0-9]+]] = PtrMetadata(copy _1)
+    // CHECK: [[LEN:_[0-9]+]] = Len((*_1))
     // CHECK: Lt(copy _2, copy [[LEN]])
     // CHECK-NOT: precondition_check
     // CHECK: _0 = copy (*_1)[_2];
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir
index 81e60b8ec2ca7..cc1034229fc39 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir
@@ -8,7 +8,7 @@ fn slice_index_usize(_1: &[u32], _2: usize) -> u32 {
     let mut _4: bool;
 
     bb0: {
-        _3 = PtrMetadata(copy _1);
+        _3 = Len((*_1));
         _4 = Lt(copy _2, copy _3);
         assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind unreachable];
     }
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
index c0fdc839608da..358226fb5294d 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir
@@ -8,7 +8,7 @@ fn slice_index_usize(_1: &[u32], _2: usize) -> u32 {
     let mut _4: bool;
 
     bb0: {
-        _3 = PtrMetadata(copy _1);
+        _3 = Len((*_1));
         _4 = Lt(copy _2, copy _3);
         assert(move _4, "index out of bounds: the length is {} but the index is {}", move _3, copy _2) -> [success: bb1, unwind continue];
     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
index 151783969dd7a..ecac03ad0f9d9 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
@@ -7,19 +7,20 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     let mut _3: usize;
     let mut _4: usize;
     let mut _9: std::option::Option<usize>;
-    let mut _11: bool;
-    let mut _13: &impl Fn(usize, &T);
-    let mut _14: (usize, &T);
-    let _15: ();
+    let mut _11: usize;
+    let mut _12: bool;
+    let mut _14: &impl Fn(usize, &T);
+    let mut _15: (usize, &T);
+    let _16: ();
     scope 1 {
         debug ((iter: std::ops::Range<usize>).0: usize) => _4;
         debug ((iter: std::ops::Range<usize>).1: usize) => _3;
         let _10: usize;
         scope 2 {
             debug i => _10;
-            let _12: &T;
+            let _13: &T;
             scope 3 {
-                debug x => _12;
+                debug x => _13;
             }
         }
         scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
@@ -81,22 +82,23 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         StorageDead(_6);
         StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
-        _11 = Lt(copy _10, copy _3);
-        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind unreachable];
+        _11 = Len((*_1));
+        _12 = Lt(copy _10, copy _11);
+        assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb6, unwind unreachable];
     }
 
     bb6: {
-        _12 = &(*_1)[_10];
-        StorageLive(_13);
-        _13 = &_2;
+        _13 = &(*_1)[_10];
         StorageLive(_14);
-        _14 = (copy _10, copy _12);
-        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind unreachable];
+        _14 = &_2;
+        StorageLive(_15);
+        _15 = (copy _10, copy _13);
+        _16 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _14, move _15) -> [return: bb7, unwind unreachable];
     }
 
     bb7: {
+        StorageDead(_15);
         StorageDead(_14);
-        StorageDead(_13);
         StorageDead(_9);
         goto -> bb1;
     }
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
index 006329dc20dc9..1032473b9b2a2 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
@@ -7,19 +7,20 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     let mut _3: usize;
     let mut _4: usize;
     let mut _9: std::option::Option<usize>;
-    let mut _11: bool;
-    let mut _13: &impl Fn(usize, &T);
-    let mut _14: (usize, &T);
-    let _15: ();
+    let mut _11: usize;
+    let mut _12: bool;
+    let mut _14: &impl Fn(usize, &T);
+    let mut _15: (usize, &T);
+    let _16: ();
     scope 1 {
         debug ((iter: std::ops::Range<usize>).0: usize) => _4;
         debug ((iter: std::ops::Range<usize>).1: usize) => _3;
         let _10: usize;
         scope 2 {
             debug i => _10;
-            let _12: &T;
+            let _13: &T;
             scope 3 {
-                debug x => _12;
+                debug x => _13;
             }
         }
         scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
@@ -81,22 +82,23 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
         StorageDead(_6);
         StorageDead(_7);
         _10 = copy ((_9 as Some).0: usize);
-        _11 = Lt(copy _10, copy _3);
-        assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb6, unwind: bb8];
+        _11 = Len((*_1));
+        _12 = Lt(copy _10, copy _11);
+        assert(move _12, "index out of bounds: the length is {} but the index is {}", move _11, copy _10) -> [success: bb6, unwind: bb8];
     }
 
     bb6: {
-        _12 = &(*_1)[_10];
-        StorageLive(_13);
-        _13 = &_2;
+        _13 = &(*_1)[_10];
         StorageLive(_14);
-        _14 = (copy _10, copy _12);
-        _15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind: bb8];
+        _14 = &_2;
+        StorageLive(_15);
+        _15 = (copy _10, copy _13);
+        _16 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _14, move _15) -> [return: bb7, unwind: bb8];
     }
 
     bb7: {
+        StorageDead(_15);
         StorageDead(_14);
-        StorageDead(_13);
         StorageDead(_9);
         goto -> bb1;
     }
diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
index e9eea69377f37..05ad9dbf3cccf 100644
--- a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff
@@ -92,7 +92,7 @@
           StorageDead(_7);
 -         StorageDead(_6);
 -         StorageLive(_10);
-          StorageLive(_11);
+-         StorageLive(_11);
 -         StorageLive(_12);
           StorageLive(_13);
           _26 = const debuginfo::promoted[0];
@@ -105,8 +105,9 @@
       bb5: {
           StorageDead(_15);
           StorageDead(_13);
-          _11 = &(*_12);
-          _16 = PtrMetadata(copy _11);
+-         _11 = &(*_12);
+-         _16 = Len((*_11));
++         _16 = Len((*_12));
           _17 = const 3_usize;
           _18 = Ge(move _16, move _17);
           switchInt(move _18) -> [0: bb7, otherwise: bb6];
@@ -136,7 +137,7 @@
   
       bb8: {
 -         StorageDead(_12);
-          StorageDead(_11);
+-         StorageDead(_11);
 -         StorageDead(_10);
           StorageLive(_22);
           StorageLive(_23);
diff --git a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir
index e9bbe30bd774f..ee6e16d20fd8d 100644
--- a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir
+++ b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir
@@ -74,6 +74,7 @@ fn method_1(_1: Guard) -> () {
 
     bb7: {
         backward incompatible drop(_2);
+        backward incompatible drop(_4);
         backward incompatible drop(_5);
         goto -> bb21;
     }
diff --git a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir
index e9bbe30bd774f..ee6e16d20fd8d 100644
--- a/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir
+++ b/tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir
@@ -74,6 +74,7 @@ fn method_1(_1: Guard) -> () {
 
     bb7: {
         backward incompatible drop(_2);
+        backward incompatible drop(_4);
         backward incompatible drop(_5);
         goto -> bb21;
     }
diff --git a/tests/run-make/doctests-merge/rmake.rs b/tests/run-make/doctests-merge/rmake.rs
index a25da7403e24b..a88b050c50fa8 100644
--- a/tests/run-make/doctests-merge/rmake.rs
+++ b/tests/run-make/doctests-merge/rmake.rs
@@ -8,7 +8,6 @@ fn test_and_compare(input_file: &str, stdout_file: &str, edition: &str, dep: &Pa
     let output = cmd
         .input(input_file)
         .arg("--test")
-        .arg("-Zunstable-options")
         .edition(edition)
         .arg("--test-args=--test-threads=1")
         .extern_("foo", dep.display().to_string())
diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/main.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/main.rs
new file mode 100644
index 0000000000000..421eb4331b3ff
--- /dev/null
+++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+    other::big_function();
+}
diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/other.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/other.rs
new file mode 100644
index 0000000000000..a3ff578ebe411
--- /dev/null
+++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/other.rs
@@ -0,0 +1 @@
+proc::declare_big_function!();
diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/proc.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/proc.rs
new file mode 100644
index 0000000000000..59d17a9be5933
--- /dev/null
+++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/proc.rs
@@ -0,0 +1,7 @@
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro]
+pub fn declare_big_function(_input: TokenStream) -> TokenStream {
+    include_str!("./generated.rs").parse().unwrap()
+}
diff --git a/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs
new file mode 100644
index 0000000000000..2727effe81883
--- /dev/null
+++ b/tests/run-make/llvm-location-discriminator-limit-dummy-span/rmake.rs
@@ -0,0 +1,65 @@
+//! Regression test for <https://github.com/rust-lang/rust/issues/135332>.
+//!
+//! We can't simply drop debuginfo location spans when LLVM's location discriminator value limit is
+//! reached. Otherwise, with `-Z verify-llvm-ir` and fat LTO, LLVM will report a broken module for
+//!
+//! ```text
+//! inlinable function call in a function with debug info must have a !dbg location
+//! ```
+
+//@ ignore-cross-compile
+//@ needs-dynamic-linking
+//@ only-nightly (requires unstable rustc flag)
+
+#![deny(warnings)]
+
+use run_make_support::{dynamic_lib_name, rfs, rust_lib_name, rustc};
+
+// Synthesize a function that will have a large (`n`) number of functions
+// MIR-inlined into it. When combined with a proc-macro, all of these inline
+// callsites will have the same span, forcing rustc to use the DWARF
+// discriminator to distinguish between them. LLVM's capacity to store that
+// discriminator is not infinite (currently it allocates 12 bits for a
+// maximum value of 4096) so if this function gets big enough rustc's error
+// handling path will be exercised.
+fn generate_program(n: u32) -> String {
+    let mut program = String::from("pub type BigType = Vec<Vec<String>>;\n\n");
+    program.push_str("pub fn big_function() -> BigType {\n");
+    program.push_str("    vec![\n");
+    for i in 1..=n {
+        program.push_str(&format!("vec![\"string{}\".to_owned()],\n", i));
+    }
+    program.push_str("    ]\n");
+    program.push_str("}\n");
+    program
+}
+
+fn main() {
+    // The reported threshold is around 1366 (4096/3), but let's bump it to
+    // around 1500 to be less sensitive.
+    rfs::write("generated.rs", generate_program(1500));
+
+    rustc()
+        .input("proc.rs")
+        .crate_type("proc-macro")
+        .edition("2021")
+        .arg("-Cdebuginfo=line-tables-only")
+        .run();
+    rustc()
+        .extern_("proc", dynamic_lib_name("proc"))
+        .input("other.rs")
+        .crate_type("rlib")
+        .edition("2021")
+        .opt_level("3")
+        .arg("-Cdebuginfo=line-tables-only")
+        .run();
+    rustc()
+        .extern_("other", rust_lib_name("other"))
+        .input("main.rs")
+        .edition("2021")
+        .opt_level("3")
+        .arg("-Cdebuginfo=line-tables-only")
+        .arg("-Clto=fat")
+        .arg("-Zverify-llvm-ir")
+        .run();
+}
diff --git a/tests/run-make/strip/hello.rs b/tests/run-make/strip/hello.rs
new file mode 100644
index 0000000000000..2dc0376650bfe
--- /dev/null
+++ b/tests/run-make/strip/hello.rs
@@ -0,0 +1,8 @@
+fn main() {
+    hey_i_get_compiled();
+}
+
+#[inline(never)]
+fn hey_i_get_compiled() {
+    println!("Hi! Do or do not strip me, your choice.");
+}
diff --git a/tests/run-make/strip/rmake.rs b/tests/run-make/strip/rmake.rs
new file mode 100644
index 0000000000000..ef1acc26b4556
--- /dev/null
+++ b/tests/run-make/strip/rmake.rs
@@ -0,0 +1,42 @@
+//@ ignore-windows Windows does not actually strip
+
+// Test that -Cstrip correctly strips/preserves debuginfo and symbols.
+
+use run_make_support::{bin_name, is_darwin, llvm_dwarfdump, llvm_nm, rustc};
+
+fn main() {
+    // We use DW_ (the start of any DWARF name) to check that some debuginfo is present.
+    let dwarf_indicator = "DW_";
+
+    let test_symbol = "hey_i_get_compiled";
+    let binary = &bin_name("hello");
+
+    // Avoid checking debuginfo on darwin, because it is not actually affected by strip.
+    // Darwin *never* puts debuginfo in the main binary (-Csplit-debuginfo=off just removes it),
+    // so we never actually have any debuginfo in there, so we can't check that it's present.
+    let do_debuginfo_check = !is_darwin();
+
+    // Additionally, use -Cdebuginfo=2 to make the test independent of the amount of debuginfo
+    // for std.
+
+    // -Cstrip=none should preserve symbols and debuginfo.
+    rustc().arg("hello.rs").arg("-Cdebuginfo=2").arg("-Cstrip=none").run();
+    llvm_nm().input(binary).run().assert_stdout_contains(test_symbol);
+    if do_debuginfo_check {
+        llvm_dwarfdump().input(binary).run().assert_stdout_contains(dwarf_indicator);
+    }
+
+    // -Cstrip=debuginfo should preserve symbols and strip debuginfo.
+    rustc().arg("hello.rs").arg("-Cdebuginfo=2").arg("-Cstrip=debuginfo").run();
+    llvm_nm().input(binary).run().assert_stdout_contains(test_symbol);
+    if do_debuginfo_check {
+        llvm_dwarfdump().input(binary).run().assert_stdout_not_contains(dwarf_indicator);
+    }
+
+    // -Cstrip=symbols should strip symbols and strip debuginfo.
+    rustc().arg("hello.rs").arg("-Cdebuginfo=2").arg("-Cstrip=symbols").run();
+    llvm_nm().input(binary).run().assert_stderr_not_contains(test_symbol);
+    if do_debuginfo_check {
+        llvm_dwarfdump().input(binary).run().assert_stdout_not_contains(dwarf_indicator);
+    }
+}
diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs
index fb4ab06800019..04bd1813b4c81 100644
--- a/tests/rustdoc-ui/doctest/doctest-output.rs
+++ b/tests/rustdoc-ui/doctest/doctest-output.rs
@@ -2,7 +2,7 @@
 //@[edition2015]edition:2015
 //@[edition2015]aux-build:extern_macros.rs
 //@[edition2015]compile-flags:--test --test-args=--test-threads=1
-//@[edition2024]edition:2015
+//@[edition2024]edition:2024
 //@[edition2024]aux-build:extern_macros.rs
 //@[edition2024]compile-flags:--test --test-args=--test-threads=1
 //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout
new file mode 100644
index 0000000000000..5bbf3ebfab6cc
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2015.stdout
@@ -0,0 +1,28 @@
+
+running 1 test
+test $DIR/failed-doctest-test-crate.rs - m (line 14) ... FAILED
+
+failures:
+
+---- $DIR/failed-doctest-test-crate.rs - m (line 14) stdout ----
+error[E0432]: unresolved import `test`
+  --> $DIR/failed-doctest-test-crate.rs:15:5
+   |
+LL | use test::*;
+   |     ^^^^ you might be missing crate `test`
+   |
+help: consider importing the `test` crate
+   |
+LL + extern crate test;
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0432`.
+Couldn't compile the test.
+
+failures:
+    $DIR/failed-doctest-test-crate.rs - m (line 14)
+
+test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout
new file mode 100644
index 0000000000000..463b0fa95361b
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.edition2024.stdout
@@ -0,0 +1,23 @@
+
+running 1 test
+test $DIR/failed-doctest-test-crate.rs - m (line 14) ... FAILED
+
+failures:
+
+---- $DIR/failed-doctest-test-crate.rs - m (line 14) stdout ----
+error[E0432]: unresolved import `test`
+  --> $DIR/failed-doctest-test-crate.rs:15:5
+   |
+LL | use test::*;
+   |     ^^^^ use of undeclared crate or module `test`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0432`.
+Couldn't compile the test.
+
+failures:
+    $DIR/failed-doctest-test-crate.rs - m (line 14)
+
+test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs
new file mode 100644
index 0000000000000..6966d3df11ce7
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/failed-doctest-test-crate.rs
@@ -0,0 +1,17 @@
+// FIXME: if/when the output of the test harness can be tested on its own, this test should be
+// adapted to use that, and that normalize line can go away
+
+//@ revisions: edition2015 edition2024
+//@[edition2015]edition:2015
+//@[edition2024]edition:2024
+//@ compile-flags:--test
+//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ failure-status: 101
+
+/// <https://github.com/rust-lang/rust/pull/137899#discussion_r1976743383>
+///
+/// ```rust
+/// use test::*;
+/// ```
+pub mod m {}
diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs
new file mode 100644
index 0000000000000..17fa3ccfe3e89
--- /dev/null
+++ b/tests/rustdoc-ui/target-feature-stability.rs
@@ -0,0 +1,28 @@
+//! This is a regression test for <https://github.com/rust-lang/rust/issues/137366>, ensuring
+//! that we can use the `neon` target feature on ARM32 targets in rustdoc despite there
+//! being a "forbidden" feature of the same name for aarch64, and rustdoc merging the
+//! target features of all targets.
+//@ check-pass
+//@ revisions: arm aarch64
+//@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
+//@[arm] needs-llvm-components: arm
+//@[aarch64] compile-flags: --target aarch64-unknown-none-softfloat
+//@[aarch64] needs-llvm-components: aarch64
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items)]
+#![feature(arm_target_feature)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+// `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`.
+#[target_feature(enable = "fp-armv8")]
+pub fn fun1() {}
+
+// This would usually be rejected as it changes the ABI.
+// But we disable that check in rustdoc since we are building "for all targets" and the
+// check can't really handle that.
+#[target_feature(enable = "soft-float")]
+pub fn fun2() {}
diff --git a/tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs b/tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs
new file mode 100644
index 0000000000000..74b5cfcfb04de
--- /dev/null
+++ b/tests/ui/borrowck/array-disjoint-borrows-issue-135671.rs
@@ -0,0 +1,30 @@
+// This is a regression test for issue #135671 where a MIR refactor about arrays and their lengths
+// unexpectedly caused borrowck errors for disjoint borrows of array elements, for which we had no
+// tests. This is a collection of a few code samples from that issue.
+
+//@ check-pass
+
+struct Test {
+    a: i32,
+    b: i32,
+}
+
+fn one() {
+    let inputs: &mut [_] = &mut [Test { a: 0, b: 0 }];
+    let a = &mut inputs[0].a;
+    let b = &mut inputs[0].b;
+
+    *a = 0;
+    *b = 1;
+}
+
+fn two() {
+    let slice = &mut [(0, 0)][..];
+    std::mem::swap(&mut slice[0].0, &mut slice[0].1);
+}
+
+fn three(a: &mut [(i32, i32)], i: usize, j: usize) -> (&mut i32, &mut i32) {
+    (&mut a[i].0, &mut a[j].1)
+}
+
+fn main() {}
diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.rs b/tests/ui/borrowck/borrowck-describe-lvalue.rs
index f3a4b382fa89f..cdcff69d6e529 100644
--- a/tests/ui/borrowck/borrowck-describe-lvalue.rs
+++ b/tests/ui/borrowck/borrowck-describe-lvalue.rs
@@ -231,6 +231,7 @@ fn main() {
         let x = &mut v;
         v[0].y;
         //~^ ERROR cannot use `v[_].y` because it was mutably borrowed
+        //~| ERROR cannot use `*v` because it was mutably borrowed
         drop(x);
     }
     // Field of constant index
diff --git a/tests/ui/borrowck/borrowck-describe-lvalue.stderr b/tests/ui/borrowck/borrowck-describe-lvalue.stderr
index 666a21808d80b..11f2e42d42b7b 100644
--- a/tests/ui/borrowck/borrowck-describe-lvalue.stderr
+++ b/tests/ui/borrowck/borrowck-describe-lvalue.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/borrowck-describe-lvalue.rs:253:13
+  --> $DIR/borrowck-describe-lvalue.rs:254:13
    |
 LL |             let y = &mut x;
    |                     ------ first mutable borrow occurs here
@@ -9,7 +9,7 @@ LL |             *y = 1;
    |             ------ first borrow later used here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time
-  --> $DIR/borrowck-describe-lvalue.rs:263:20
+  --> $DIR/borrowck-describe-lvalue.rs:264:20
    |
 LL |                    let y = &mut x;
    |                            ------ first mutable borrow occurs here
@@ -19,7 +19,7 @@ LL |                    *y = 1;
    |                    ------ first borrow later used here
 
 error: captured variable cannot escape `FnMut` closure body
-  --> $DIR/borrowck-describe-lvalue.rs:261:16
+  --> $DIR/borrowck-describe-lvalue.rs:262:16
    |
 LL |           let mut x = 0;
    |               ----- variable defined here
@@ -300,6 +300,17 @@ LL |             S  { x: F { y: ref x0, .. }, .. } =>
 LL |         drop(x);
    |              - mutable borrow later used here
 
+error[E0503]: cannot use `*v` because it was mutably borrowed
+  --> $DIR/borrowck-describe-lvalue.rs:232:9
+   |
+LL |         let x = &mut v;
+   |                 ------ `v` is borrowed here
+LL |         v[0].y;
+   |         ^^^^ use of borrowed `v`
+...
+LL |         drop(x);
+   |              - borrow later used here
+
 error[E0503]: cannot use `v[_].y` because it was mutably borrowed
   --> $DIR/borrowck-describe-lvalue.rs:232:9
    |
@@ -307,12 +318,12 @@ LL |         let x = &mut v;
    |                 ------ `v` is borrowed here
 LL |         v[0].y;
    |         ^^^^^^ use of borrowed `v`
-LL |
+...
 LL |         drop(x);
    |              - borrow later used here
 
 error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-describe-lvalue.rs:242:24
+  --> $DIR/borrowck-describe-lvalue.rs:243:24
    |
 LL |         let x = &mut v;
    |                 ------ mutable borrow occurs here
@@ -346,7 +357,7 @@ LL |             drop(x);
    |                  - mutable borrow later used here
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/borrowck-describe-lvalue.rs:273:22
+  --> $DIR/borrowck-describe-lvalue.rs:274:22
    |
 LL |                 drop(x);
    |                      - value moved here
@@ -355,7 +366,7 @@ LL |                 drop(x);
    |
    = note: move occurs because `x` has type `Vec<i32>`, which does not implement the `Copy` trait
 
-error: aborting due to 31 previous errors
+error: aborting due to 32 previous errors
 
 Some errors have detailed explanations: E0382, E0499, E0502, E0503.
 For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs
new file mode 100644
index 0000000000000..d47a8e085fd3a
--- /dev/null
+++ b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.rs
@@ -0,0 +1,19 @@
+//@ only-x86_64
+
+fn efiapi(f: extern "efiapi" fn(usize, ...)) {
+    //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+    //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+    f(22, 44);
+}
+fn sysv(f: extern "sysv64" fn(usize, ...)) {
+    //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+    //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+    f(22, 44);
+}
+fn win(f: extern "win64" fn(usize, ...)) {
+    //~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+    //~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+    f(22, 44);
+}
+
+fn main() {}
diff --git a/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr
new file mode 100644
index 0000000000000..41be378424543
--- /dev/null
+++ b/tests/ui/c-variadic/feature-gate-extended_varargs_abi_support.stderr
@@ -0,0 +1,52 @@
+error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
+   |
+LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
+   = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
+   |
+LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
+error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
+   |
+LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
+   = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
+   |
+LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
+error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
+   |
+LL | fn win(f: extern "win64" fn(usize, ...)) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
+   = help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
+  --> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
+   |
+LL | fn win(f: extern "win64" fn(usize, ...)) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0045, E0658.
+For more information about an error, try `rustc --explain E0045`.
diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr
index 7a54d043356a3..194710dfd2187 100644
--- a/tests/ui/c-variadic/variadic-ffi-1.stderr
+++ b/tests/ui/c-variadic/variadic-ffi-1.stderr
@@ -1,4 +1,4 @@
-error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
   --> $DIR/variadic-ffi-1.rs:9:5
    |
 LL |     fn printf(_: *const u8, ...);
diff --git a/tests/ui/c-variadic/variadic-ffi-2-arm.rs b/tests/ui/c-variadic/variadic-ffi-2-arm.rs
index 82f9df5053c19..3b0a71007a0e6 100644
--- a/tests/ui/c-variadic/variadic-ffi-2-arm.rs
+++ b/tests/ui/c-variadic/variadic-ffi-2-arm.rs
@@ -1,5 +1,6 @@
 //@ only-arm
 //@ build-pass
+#![feature(extended_varargs_abi_support)]
 
 fn aapcs(f: extern "aapcs" fn(usize, ...)) {
     f(22, 44);
diff --git a/tests/ui/c-variadic/variadic-ffi-2.rs b/tests/ui/c-variadic/variadic-ffi-2.rs
index 17a1065279f4e..bafb7e2b20cc7 100644
--- a/tests/ui/c-variadic/variadic-ffi-2.rs
+++ b/tests/ui/c-variadic/variadic-ffi-2.rs
@@ -1,4 +1,5 @@
 //@ ignore-arm stdcall isn't supported
+#![feature(extended_varargs_abi_support)]
 
 #[allow(unsupported_fn_ptr_calling_conventions)]
 fn baz(f: extern "stdcall" fn(usize, ...)) {
diff --git a/tests/ui/c-variadic/variadic-ffi-2.stderr b/tests/ui/c-variadic/variadic-ffi-2.stderr
index fbf273b1f1dbf..e52de93a92646 100644
--- a/tests/ui/c-variadic/variadic-ffi-2.stderr
+++ b/tests/ui/c-variadic/variadic-ffi-2.stderr
@@ -1,5 +1,5 @@
 error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
-  --> $DIR/variadic-ffi-2.rs:4:11
+  --> $DIR/variadic-ffi-2.rs:5:11
    |
 LL | fn baz(f: extern "stdcall" fn(usize, ...)) {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
index 2d22c9a856f6b..3abc81e191ebf 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.rs
@@ -12,7 +12,8 @@ fn arrays_1() {
     // c will capture `arr` completely, therefore another index into the
     // array can't be modified here
     arr[1] += 10;
-    //~^ ERROR: cannot use `arr[_]` because it was mutably borrowed
+    //~^ ERROR: cannot use `arr` because it was mutably borrowed
+    //~| ERROR: cannot use `arr[_]` because it was mutably borrowed
     c();
 }
 
@@ -54,7 +55,8 @@ fn arrays_4() {
     // c will capture `arr` completely, therefore we cannot borrow another index
     // into the array.
     println!("{}", arr[3]);
-    //~^ ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
+    //~^ ERROR: cannot use `arr` because it was mutably borrowed
+    //~| ERROR: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
 
     c();
 }
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
index 97ecdfab82059..9e5200ef34b54 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr
@@ -1,3 +1,17 @@
+error[E0503]: cannot use `arr` because it was mutably borrowed
+  --> $DIR/arrays.rs:14:5
+   |
+LL |     let mut c = || {
+   |                 -- `arr` is borrowed here
+LL |         arr[0] += 10;
+   |         --- borrow occurs due to use of `arr` in closure
+...
+LL |     arr[1] += 10;
+   |     ^^^^^^ use of borrowed `arr`
+...
+LL |     c();
+   |     - borrow later used here
+
 error[E0503]: cannot use `arr[_]` because it was mutably borrowed
   --> $DIR/arrays.rs:14:5
    |
@@ -8,12 +22,12 @@ LL |         arr[0] += 10;
 ...
 LL |     arr[1] += 10;
    |     ^^^^^^^^^^^^ use of borrowed `arr`
-LL |
+...
 LL |     c();
    |     - borrow later used here
 
 error[E0506]: cannot assign to `arr[_]` because it is borrowed
-  --> $DIR/arrays.rs:28:5
+  --> $DIR/arrays.rs:29:5
    |
 LL |     let c = || {
    |             -- `arr[_]` is borrowed here
@@ -27,7 +41,7 @@ LL |     c();
    |     - borrow later used here
 
 error[E0506]: cannot assign to `arr[_]` because it is borrowed
-  --> $DIR/arrays.rs:42:5
+  --> $DIR/arrays.rs:43:5
    |
 LL |     let c = || {
    |             -- `arr[_]` is borrowed here
@@ -40,8 +54,22 @@ LL |
 LL |     c();
    |     - borrow later used here
 
+error[E0503]: cannot use `arr` because it was mutably borrowed
+  --> $DIR/arrays.rs:57:20
+   |
+LL |     let mut c = || {
+   |                 -- `arr` is borrowed here
+LL |         arr[1] += 10;
+   |         --- borrow occurs due to use of `arr` in closure
+...
+LL |     println!("{}", arr[3]);
+   |                    ^^^^^^ use of borrowed `arr`
+...
+LL |     c();
+   |     - borrow later used here
+
 error[E0502]: cannot borrow `arr[_]` as immutable because it is also borrowed as mutable
-  --> $DIR/arrays.rs:56:20
+  --> $DIR/arrays.rs:57:20
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -57,7 +85,7 @@ LL |     c();
    = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0502]: cannot borrow `arr` as immutable because it is also borrowed as mutable
-  --> $DIR/arrays.rs:71:24
+  --> $DIR/arrays.rs:73:24
    |
 LL |     let mut c = || {
    |                 -- mutable borrow occurs here
@@ -70,7 +98,7 @@ LL |     println!("{:#?}", &arr[3..2]);
 LL |     c();
    |     - mutable borrow later used here
 
-error: aborting due to 5 previous errors
+error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0502, E0503, E0506.
 For more information about an error, try `rustc --explain E0502`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs
index da1327dace5d4..9e0ffa75c2296 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs
@@ -39,4 +39,4 @@ type WithTransparentTraitObject =
 //~^ ERROR return value of `"C-cmse-nonsecure-call"` function too large to pass via registers [E0798]
 
 type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...);
-//~^ ERROR C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` [E0045]
+//~^ ERROR C-variadic function must have a compatible calling convention, like `C` or `cdecl` [E0045]
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr
index f20e67e3d9438..7cb8e135ea31b 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr
@@ -68,7 +68,7 @@ LL |     extern "C-cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTranspa
    = note: functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers
    = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
 
-error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
   --> $DIR/generics.rs:41:20
    |
 LL | type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...);
diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr
index 466b991471ed9..25f9523f4e455 100644
--- a/tests/ui/coherence/occurs-check/associated-type.next.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr
@@ -1,7 +1,5 @@
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
 error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
   --> $DIR/associated-type.rs:32:1
    |
diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr
index 1e0345f4ec05b..e091ddcacb20a 100644
--- a/tests/ui/coherence/occurs-check/associated-type.old.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr
@@ -1,7 +1,5 @@
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
 error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
   --> $DIR/associated-type.rs:32:1
    |
diff --git a/tests/ui/const-generics/issues/index_array_bad_type.rs b/tests/ui/const-generics/issues/index_array_bad_type.rs
deleted file mode 100644
index 41e4dba026c2e..0000000000000
--- a/tests/ui/const-generics/issues/index_array_bad_type.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ check-fail
-//@ compile-flags: -C opt-level=0
-
-#![crate_type = "lib"]
-
-// This used to fail in the known-panics lint, as the MIR was ill-typed due to
-// the length constant not actually having type usize.
-// https://github.com/rust-lang/rust/issues/134352
-
-pub struct BadStruct<const N: i64>(pub [u8; N]);
-//~^ ERROR: the constant `N` is not of type `usize`
-
-pub fn bad_array_length_type(value: BadStruct<3>) -> u8 {
-    value.0[0]
-}
diff --git a/tests/ui/const-generics/issues/index_array_bad_type.stderr b/tests/ui/const-generics/issues/index_array_bad_type.stderr
deleted file mode 100644
index e4417192150ee..0000000000000
--- a/tests/ui/const-generics/issues/index_array_bad_type.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: the constant `N` is not of type `usize`
-  --> $DIR/index_array_bad_type.rs:10:40
-   |
-LL | pub struct BadStruct<const N: i64>(pub [u8; N]);
-   |                                        ^^^^^^^ expected `usize`, found `i64`
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/consts/issue-65348.rs b/tests/ui/consts/issue-65348.rs
index 0d12da3926cd6..1443fcbe1c1ce 100644
--- a/tests/ui/consts/issue-65348.rs
+++ b/tests/ui/consts/issue-65348.rs
@@ -9,17 +9,15 @@ impl<T> Generic<T> {
 }
 
 pub const fn array<T>() -> &'static T {
-    #[expect(unconditional_panic)]
+    #[allow(unconditional_panic)]
     &Generic::<T>::ARRAY[0]
 }
 
 pub const fn newtype_array<T>() -> &'static T {
-    #[expect(unconditional_panic)]
     &Generic::<T>::NEWTYPE_ARRAY.0[0]
 }
 
 pub const fn array_field<T>() -> &'static T {
-    #[expect(unconditional_panic)]
     &(Generic::<T>::ARRAY_FIELD.0).1[0]
 }
 
diff --git a/tests/ui/drop/lint-tail-expr-drop-order-borrowck.rs b/tests/ui/drop/lint-tail-expr-drop-order-borrowck.rs
new file mode 100644
index 0000000000000..f37707e0bf295
--- /dev/null
+++ b/tests/ui/drop/lint-tail-expr-drop-order-borrowck.rs
@@ -0,0 +1,51 @@
+// Edition 2024 lint for change in drop order at tail expression
+// This lint is to capture potential borrow-checking errors
+// due to implementation of RFC 3606 <https://github.com/rust-lang/rfcs/pull/3606>
+//@ edition: 2021
+
+#![deny(tail_expr_drop_order)] //~ NOTE: the lint level is defined here
+
+fn should_lint_with_potential_borrowck_err() {
+    let _ = { String::new().as_str() }.len();
+    //~^ ERROR: relative drop order changing
+    //~| WARN: this changes meaning in Rust 2024
+    //~| NOTE: this temporary value will be dropped at the end of the block
+    //~| borrow later used here
+    //~| NOTE: for more information, see
+}
+
+fn should_lint_with_unsafe_block() {
+    fn f(_: usize) {}
+    f(unsafe { String::new().as_str() }.len());
+    //~^ ERROR: relative drop order changing
+    //~| WARN: this changes meaning in Rust 2024
+    //~| NOTE: this temporary value will be dropped at the end of the block
+    //~| borrow later used here
+    //~| NOTE: for more information, see
+}
+
+#[rustfmt::skip]
+fn should_lint_with_big_block() {
+    fn f<T>(_: T) {}
+    f({
+        &mut || 0
+        //~^ ERROR: relative drop order changing
+        //~| WARN: this changes meaning in Rust 2024
+        //~| NOTE: this temporary value will be dropped at the end of the block
+        //~| borrow later used here
+        //~| NOTE: for more information, see
+    })
+}
+
+fn another_temp_that_is_copy_in_arg() {
+    fn f() {}
+    fn g(_: &()) {}
+    g({ &f() });
+    //~^ ERROR: relative drop order changing
+    //~| WARN: this changes meaning in Rust 2024
+    //~| NOTE: this temporary value will be dropped at the end of the block
+    //~| borrow later used by call
+    //~| NOTE: for more information, see
+}
+
+fn main() {}
diff --git a/tests/ui/drop/lint-tail-expr-drop-order-borrowck.stderr b/tests/ui/drop/lint-tail-expr-drop-order-borrowck.stderr
new file mode 100644
index 0000000000000..862b01119e8ed
--- /dev/null
+++ b/tests/ui/drop/lint-tail-expr-drop-order-borrowck.stderr
@@ -0,0 +1,54 @@
+error: relative drop order changing in Rust 2024
+  --> $DIR/lint-tail-expr-drop-order-borrowck.rs:9:15
+   |
+LL |     let _ = { String::new().as_str() }.len();
+   |               ^^^^^^^^^^^^^---------
+   |               |
+   |               this temporary value will be dropped at the end of the block
+   |               borrow later used here
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+note: the lint level is defined here
+  --> $DIR/lint-tail-expr-drop-order-borrowck.rs:6:9
+   |
+LL | #![deny(tail_expr_drop_order)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: relative drop order changing in Rust 2024
+  --> $DIR/lint-tail-expr-drop-order-borrowck.rs:19:16
+   |
+LL |     f(unsafe { String::new().as_str() }.len());
+   |                ^^^^^^^^^^^^^---------
+   |                |
+   |                this temporary value will be dropped at the end of the block
+   |                borrow later used here
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+
+error: relative drop order changing in Rust 2024
+  --> $DIR/lint-tail-expr-drop-order-borrowck.rs:31:9
+   |
+LL |         &mut || 0
+   |         ^^^^^^^^^
+   |         |
+   |         this temporary value will be dropped at the end of the block
+   |         borrow later used here
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+
+error: relative drop order changing in Rust 2024
+  --> $DIR/lint-tail-expr-drop-order-borrowck.rs:43:9
+   |
+LL |     g({ &f() });
+   |     -   ^^^^ this temporary value will be dropped at the end of the block
+   |     |
+   |     borrow later used by call
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/drop/lint-tail-expr-drop-order.rs b/tests/ui/drop/lint-tail-expr-drop-order.rs
index b2a5db0d87133..55a2d1d3b7543 100644
--- a/tests/ui/drop/lint-tail-expr-drop-order.rs
+++ b/tests/ui/drop/lint-tail-expr-drop-order.rs
@@ -17,7 +17,6 @@ impl Drop for LoudDropper {
     //~| NOTE: `#1` invokes this custom destructor
     //~| NOTE: `x` invokes this custom destructor
     //~| NOTE: `#1` invokes this custom destructor
-    //~| NOTE: `future` invokes this custom destructor
     //~| NOTE: `_x` invokes this custom destructor
     //~| NOTE: `#1` invokes this custom destructor
     fn drop(&mut self) {
diff --git a/tests/ui/drop/lint-tail-expr-drop-order.stderr b/tests/ui/drop/lint-tail-expr-drop-order.stderr
index 92afae5af6766..6ff9b7c12681d 100644
--- a/tests/ui/drop/lint-tail-expr-drop-order.stderr
+++ b/tests/ui/drop/lint-tail-expr-drop-order.stderr
@@ -1,5 +1,5 @@
 error: relative drop order changing in Rust 2024
-  --> $DIR/lint-tail-expr-drop-order.rs:41:15
+  --> $DIR/lint-tail-expr-drop-order.rs:40:15
    |
 LL |     let x = LoudDropper;
    |         -
@@ -40,7 +40,7 @@ LL | #![deny(tail_expr_drop_order)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: relative drop order changing in Rust 2024
-  --> $DIR/lint-tail-expr-drop-order.rs:66:19
+  --> $DIR/lint-tail-expr-drop-order.rs:65:19
    |
 LL |         let x = LoudDropper;
    |             -
@@ -76,7 +76,7 @@ LL | | }
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
 
 error: relative drop order changing in Rust 2024
-  --> $DIR/lint-tail-expr-drop-order.rs:93:7
+  --> $DIR/lint-tail-expr-drop-order.rs:92:7
    |
 LL |     let x = LoudDropper;
    |         -
@@ -112,7 +112,7 @@ LL | | }
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
 
 error: relative drop order changing in Rust 2024
-  --> $DIR/lint-tail-expr-drop-order.rs:146:5
+  --> $DIR/lint-tail-expr-drop-order.rs:145:5
    |
 LL |     let future = f();
    |         ------
@@ -136,19 +136,12 @@ note: `#1` invokes this custom destructor
    |
 LL | / impl Drop for LoudDropper {
 ...  |
-LL | | }
-   | |_^
-note: `future` invokes this custom destructor
-  --> $DIR/lint-tail-expr-drop-order.rs:10:1
-   |
-LL | / impl Drop for LoudDropper {
-...  |
 LL | | }
    | |_^
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
 
 error: relative drop order changing in Rust 2024
-  --> $DIR/lint-tail-expr-drop-order.rs:163:14
+  --> $DIR/lint-tail-expr-drop-order.rs:162:14
    |
 LL |     let x = T::default();
    |         -
@@ -170,7 +163,7 @@ LL | }
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
 
 error: relative drop order changing in Rust 2024
-  --> $DIR/lint-tail-expr-drop-order.rs:177:5
+  --> $DIR/lint-tail-expr-drop-order.rs:176:5
    |
 LL |     let x: Result<LoudDropper, ()> = Ok(LoudDropper);
    |         -
@@ -206,7 +199,7 @@ LL | | }
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
 
 error: relative drop order changing in Rust 2024
-  --> $DIR/lint-tail-expr-drop-order.rs:221:5
+  --> $DIR/lint-tail-expr-drop-order.rs:220:5
    |
 LL |     let x = LoudDropper2;
    |         -
@@ -226,7 +219,7 @@ LL | }
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
 note: `#1` invokes this custom destructor
-  --> $DIR/lint-tail-expr-drop-order.rs:194:5
+  --> $DIR/lint-tail-expr-drop-order.rs:193:5
    |
 LL | /     impl Drop for LoudDropper3 {
 LL | |
@@ -236,7 +229,7 @@ LL | |         }
 LL | |     }
    | |_____^
 note: `x` invokes this custom destructor
-  --> $DIR/lint-tail-expr-drop-order.rs:206:5
+  --> $DIR/lint-tail-expr-drop-order.rs:205:5
    |
 LL | /     impl Drop for LoudDropper2 {
 LL | |
@@ -248,7 +241,7 @@ LL | |     }
    = note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
 
 error: relative drop order changing in Rust 2024
-  --> $DIR/lint-tail-expr-drop-order.rs:234:13
+  --> $DIR/lint-tail-expr-drop-order.rs:233:13
    |
 LL |             LoudDropper.get()
    |             ^^^^^^^^^^^
diff --git a/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr b/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr
index d98100bc1b04c..b0f971dd5cec6 100644
--- a/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr
+++ b/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr
@@ -4,10 +4,14 @@ error: relative drop order changing in Rust 2024
 LL |         match func().await {
    |               ^^^^^^^-----
    |               |      |
+   |               |      this value will be stored in a temporary; let us call it `#3`
+   |               |      up until Edition 2021 `#3` is dropped last but will be dropped earlier in Edition 2024
    |               |      this value will be stored in a temporary; let us call it `#1`
    |               |      `#1` will be dropped later as of Edition 2024
    |               this value will be stored in a temporary; let us call it `#2`
    |               up until Edition 2021 `#2` is dropped last but will be dropped earlier in Edition 2024
+   |               `__awaitee` calls a custom destructor
+   |               `__awaitee` will be dropped later as of Edition 2024
 ...
 LL |             Err(e) => {}
    |                 -
diff --git a/tests/ui/drop/tail_expr_drop_order-on-recursive-boxed-fut.rs b/tests/ui/drop/tail_expr_drop_order-on-recursive-boxed-fut.rs
new file mode 100644
index 0000000000000..4a72f224d9436
--- /dev/null
+++ b/tests/ui/drop/tail_expr_drop_order-on-recursive-boxed-fut.rs
@@ -0,0 +1,13 @@
+//@ edition: 2021
+//@ check-pass
+
+// Make sure we don't cycle error when normalizing types for tail expr drop order lint.
+
+#![deny(tail_expr_drop_order)]
+
+async fn test() -> Result<(), Box<dyn std::error::Error>> {
+    Box::pin(test()).await?;
+    Ok(())
+}
+
+fn main() {}
diff --git a/tests/ui/drop/tail_expr_drop_order-on-thread-local.rs b/tests/ui/drop/tail_expr_drop_order-on-thread-local.rs
new file mode 100644
index 0000000000000..e38175fd1b653
--- /dev/null
+++ b/tests/ui/drop/tail_expr_drop_order-on-thread-local.rs
@@ -0,0 +1,56 @@
+//@ check-pass
+
+#![feature(thread_local)]
+#![deny(tail_expr_drop_order)]
+
+use std::marker::PhantomData;
+use std::ops::{Deref, DerefMut};
+
+pub struct Global;
+
+#[thread_local]
+static REENTRANCY_STATE: State<Global> = State { marker: PhantomData, controller: Global };
+
+pub struct Token(PhantomData<*mut ()>);
+
+pub fn with_mut<T>(f: impl FnOnce(&mut Token) -> T) -> T {
+    f(&mut REENTRANCY_STATE.borrow_mut())
+}
+
+pub struct State<T: ?Sized = Global> {
+    marker: PhantomData<*mut ()>,
+    controller: T,
+}
+
+impl<T: ?Sized> State<T> {
+    pub fn borrow_mut(&self) -> TokenMut<'_, T> {
+        todo!()
+    }
+}
+
+pub struct TokenMut<'a, T: ?Sized = Global> {
+    state: &'a State<T>,
+    token: Token,
+}
+
+impl<T> Deref for TokenMut<'_, T> {
+    type Target = Token;
+
+    fn deref(&self) -> &Self::Target {
+        todo!()
+    }
+}
+
+impl<T> DerefMut for TokenMut<'_, T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        todo!()
+    }
+}
+
+impl<T: ?Sized> Drop for TokenMut<'_, T> {
+    fn drop(&mut self) {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0045.stderr b/tests/ui/error-codes/E0045.stderr
index b8ee31a40495a..25b2f2654da15 100644
--- a/tests/ui/error-codes/E0045.stderr
+++ b/tests/ui/error-codes/E0045.stderr
@@ -1,4 +1,4 @@
-error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
+error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
   --> $DIR/E0045.rs:1:17
    |
 LL | extern "Rust" { fn foo(x: u8, ...); }
diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs
index 075d7c70ac653..32dc09273175d 100644
--- a/tests/ui/impl-trait/precise-capturing/redundant.rs
+++ b/tests/ui/impl-trait/precise-capturing/redundant.rs
@@ -1,24 +1,24 @@
 //@ edition: 2024
-//@ check-pass
 
 #![feature(precise_capturing_in_traits)]
+#![deny(impl_trait_redundant_captures)]
 
 fn hello<'a>() -> impl Sized + use<'a> {}
-//~^ WARN all possible in-scope parameters are already captured
+//~^ ERROR all possible in-scope parameters are already captured
 
 struct Inherent;
 impl Inherent {
     fn inherent(&self) -> impl Sized + use<'_> {}
-    //~^ WARN all possible in-scope parameters are already captured
+    //~^ ERROR all possible in-scope parameters are already captured
 }
 
 trait Test<'a> {
     fn in_trait() -> impl Sized + use<'a, Self>;
-    //~^ WARN all possible in-scope parameters are already captured
+    //~^ ERROR all possible in-scope parameters are already captured
 }
 impl<'a> Test<'a> for () {
     fn in_trait() -> impl Sized + use<'a> {}
-    //~^ WARN all possible in-scope parameters are already captured
+    //~^ ERROR all possible in-scope parameters are already captured
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/redundant.stderr b/tests/ui/impl-trait/precise-capturing/redundant.stderr
index 274d9d2375f7d..5c8b35c228585 100644
--- a/tests/ui/impl-trait/precise-capturing/redundant.stderr
+++ b/tests/ui/impl-trait/precise-capturing/redundant.stderr
@@ -1,4 +1,4 @@
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
   --> $DIR/redundant.rs:6:19
    |
 LL | fn hello<'a>() -> impl Sized + use<'a> {}
@@ -6,9 +6,13 @@ LL | fn hello<'a>() -> impl Sized + use<'a> {}
    |                                |
    |                                help: remove the `use<...>` syntax
    |
-   = note: `#[warn(impl_trait_redundant_captures)]` on by default
+note: the lint level is defined here
+  --> $DIR/redundant.rs:4:9
+   |
+LL | #![deny(impl_trait_redundant_captures)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
   --> $DIR/redundant.rs:11:27
    |
 LL |     fn inherent(&self) -> impl Sized + use<'_> {}
@@ -16,7 +20,7 @@ LL |     fn inherent(&self) -> impl Sized + use<'_> {}
    |                                        |
    |                                        help: remove the `use<...>` syntax
 
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
   --> $DIR/redundant.rs:16:22
    |
 LL |     fn in_trait() -> impl Sized + use<'a, Self>;
@@ -24,7 +28,7 @@ LL |     fn in_trait() -> impl Sized + use<'a, Self>;
    |                                   |
    |                                   help: remove the `use<...>` syntax
 
-warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
+error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
   --> $DIR/redundant.rs:20:22
    |
 LL |     fn in_trait() -> impl Sized + use<'a> {}
@@ -32,5 +36,5 @@ LL |     fn in_trait() -> impl Sized + use<'a> {}
    |                                   |
    |                                   help: remove the `use<...>` syntax
 
-warning: 4 warnings emitted
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
index e2b2c98761046..0a22e939496e5 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed
@@ -23,22 +23,22 @@ fn main() {
     assert_type_eq(x, &mut 0u8);
 
     let &Foo(mut x) = &Foo(0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &mut Foo(mut x) = &mut Foo(0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
-    let &Foo(ref x) = &Foo(0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    let Foo(x) = &Foo(0);
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
     let &mut Foo(ref x) = &mut Foo(0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
@@ -55,22 +55,22 @@ fn main() {
     assert_type_eq(x, &0u8);
 
     let &Foo(&x) = &Foo(&0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &Foo(&mut x) = &Foo(&mut 0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &mut Foo(&x) = &mut Foo(&0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let &mut Foo(&mut x) = &mut Foo(&mut 0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
@@ -79,25 +79,25 @@ fn main() {
     }
 
     if let &&&&&Some(&x) = &&&&&Some(&0u8) {
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, &mut 0u8);
     }
@@ -109,20 +109,20 @@ fn main() {
     }
 
     let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, &0u32);
     assert_type_eq(b, 0u32);
 
     let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, 0u32);
     assert_type_eq(b, &&0u32);
     assert_type_eq(c, &&0u32);
 
     if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
     {
@@ -135,10 +135,108 @@ fn main() {
         // The two patterns are the same syntactically, but because they're defined in different
         // editions they don't mean the same thing.
         &(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
-            //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+            //~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
             assert_type_eq(x, 0u32);
             assert_type_eq(y, 0u32);
         }
         _ => {}
     }
+
+    let &mut [&mut &[ref a]] = &mut [&mut &[0]];
+    //~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+
+    let &[&(_)] = &[&0];
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+
+    // NB: Most of the following tests are for possible future improvements to migration suggestions
+
+    // Test removing multiple binding modifiers.
+    let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 };
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(c, &0u32);
+
+    // Test that we don't change bindings' modes when removing binding modifiers.
+    let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 };
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, &mut 0u32);
+    assert_type_eq(c, &mut 0u32);
+
+    // Test removing multiple reference patterns of various mutabilities, plus a binding modifier.
+    let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &0u32);
+
+    // Test that we don't change bindings' types when removing reference patterns.
+    let &Foo(&ref a) = &Foo(&0);
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+
+    // Test that we don't change bindings' modes when adding reference paterns (caught early).
+    let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, 0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &0u32);
+    assert_type_eq(d, &0u32);
+    assert_type_eq(e, &0u32);
+
+    // Test that we don't change bindings' modes when adding reference patterns (caught late).
+    let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]);
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, 0u32);
+
+    // Test featuring both additions and removals.
+    let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0]));
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, 0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &0u32);
+
+    // Test that bindings' subpatterns' modes are updated properly.
+    let &[mut a @ ref b] = &[0];
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, 0u32);
+    assert_type_eq(b, &0u32);
+
+    // Test that bindings' subpatterns' modes are checked properly.
+    let &[ref a @ mut b] = &[0];
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, 0u32);
+
+    // Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`.
+    let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2];
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &0u32);
+    assert_type_eq(d, 0u32);
+
+    // Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`.
+    let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &[0u32]);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &[0u32]);
+    assert_type_eq(d, 0u32);
 }
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
index 098540adfa2cf..7a6f2269d44a2 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs
@@ -23,22 +23,22 @@ fn main() {
     assert_type_eq(x, &mut 0u8);
 
     let Foo(mut x) = &Foo(0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(mut x) = &mut Foo(0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(ref x) = &Foo(0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
     let Foo(ref x) = &mut Foo(0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, &0u8);
 
@@ -55,22 +55,22 @@ fn main() {
     assert_type_eq(x, &0u8);
 
     let Foo(&x) = &Foo(&0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(&mut x) = &Foo(&mut 0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(&x) = &mut Foo(&0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
     let Foo(&mut x) = &mut Foo(&mut 0);
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(x, 0u8);
 
@@ -79,25 +79,25 @@ fn main() {
     }
 
     if let Some(&x) = &&&&&Some(&0u8) {
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let Some(&x) = &&&&&mut Some(&0u8) {
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, 0u8);
     }
 
     if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         assert_type_eq(x, &mut 0u8);
     }
@@ -109,20 +109,20 @@ fn main() {
     }
 
     let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, &0u32);
     assert_type_eq(b, 0u32);
 
     let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
-    //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+    //~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
     //~| WARN: this changes meaning in Rust 2024
     assert_type_eq(a, 0u32);
     assert_type_eq(b, &&0u32);
     assert_type_eq(c, &&0u32);
 
     if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
-        //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+        //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
         //~| WARN: this changes meaning in Rust 2024
         &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
     {
@@ -135,10 +135,108 @@ fn main() {
         // The two patterns are the same syntactically, but because they're defined in different
         // editions they don't mean the same thing.
         (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
-            //~^ ERROR: this pattern relies on behavior which may change in edition 2024
+            //~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
             assert_type_eq(x, 0u32);
             assert_type_eq(y, 0u32);
         }
         _ => {}
     }
+
+    let [&mut [ref a]] = &mut [&mut &[0]];
+    //~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+
+    let [&(_)] = &[&0];
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+
+    // NB: Most of the following tests are for possible future improvements to migration suggestions
+
+    // Test removing multiple binding modifiers.
+    let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(c, &0u32);
+
+    // Test that we don't change bindings' modes when removing binding modifiers.
+    let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, &mut 0u32);
+    assert_type_eq(c, &mut 0u32);
+
+    // Test removing multiple reference patterns of various mutabilities, plus a binding modifier.
+    let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &0u32);
+
+    // Test that we don't change bindings' types when removing reference patterns.
+    let Foo(&ref a) = &Foo(&0);
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+
+    // Test that we don't change bindings' modes when adding reference paterns (caught early).
+    let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, 0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &0u32);
+    assert_type_eq(d, &0u32);
+    assert_type_eq(e, &0u32);
+
+    // Test that we don't change bindings' modes when adding reference patterns (caught late).
+    let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, 0u32);
+
+    // Test featuring both additions and removals.
+    let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, 0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &0u32);
+
+    // Test that bindings' subpatterns' modes are updated properly.
+    let [mut a @ b] = &[0];
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, 0u32);
+    assert_type_eq(b, &0u32);
+
+    // Test that bindings' subpatterns' modes are checked properly.
+    let [a @ mut b] = &[0];
+    //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, 0u32);
+
+    // Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`.
+    let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &0u32);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &0u32);
+    assert_type_eq(d, 0u32);
+
+    // Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`.
+    let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
+    //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+    //~| WARN: this changes meaning in Rust 2024
+    assert_type_eq(a, &[0u32]);
+    assert_type_eq(b, &0u32);
+    assert_type_eq(c, &[0u32]);
+    assert_type_eq(d, 0u32);
 }
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
index 83346b9dd4a84..191800df07a2e 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr
@@ -1,11 +1,16 @@
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:25:13
    |
 LL |     let Foo(mut x) = &Foo(0);
-   |             ^^^ requires binding by-value, but the implicit default is by-reference
+   |             ^^^ binding modifier not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:25:9
+   |
+LL |     let Foo(mut x) = &Foo(0);
+   |         ^^^^^^^^^^ this matches on type `&_`
 note: the lint level is defined here
   --> $DIR/migration_lint.rs:7:9
    |
@@ -16,206 +21,546 @@ help: make the implied reference pattern explicit
 LL |     let &Foo(mut x) = &Foo(0);
    |         +
 
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:30:13
    |
 LL |     let Foo(mut x) = &mut Foo(0);
-   |             ^^^ requires binding by-value, but the implicit default is by-reference
+   |             ^^^ binding modifier not allowed under `ref mut` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:30:9
+   |
+LL |     let Foo(mut x) = &mut Foo(0);
+   |         ^^^^^^^^^^ this matches on type `&mut _`
 help: make the implied reference pattern explicit
    |
 LL |     let &mut Foo(mut x) = &mut Foo(0);
    |         ++++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:35:13
    |
 LL |     let Foo(ref x) = &Foo(0);
-   |             ^^^ cannot override to bind by-reference when that is the implicit default
+   |             ^^^ binding modifier not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
-help: make the implied reference pattern explicit
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:35:9
+   |
+LL |     let Foo(ref x) = &Foo(0);
+   |         ^^^^^^^^^^ this matches on type `&_`
+help: remove the unnecessary binding modifier
+   |
+LL -     let Foo(ref x) = &Foo(0);
+LL +     let Foo(x) = &Foo(0);
    |
-LL |     let &Foo(ref x) = &Foo(0);
-   |         +
 
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:40:13
    |
 LL |     let Foo(ref x) = &mut Foo(0);
-   |             ^^^ cannot override to bind by-reference when that is the implicit default
+   |             ^^^ binding modifier not allowed under `ref mut` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:40:9
+   |
+LL |     let Foo(ref x) = &mut Foo(0);
+   |         ^^^^^^^^^^ this matches on type `&mut _`
 help: make the implied reference pattern explicit
    |
 LL |     let &mut Foo(ref x) = &mut Foo(0);
    |         ++++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:57:13
    |
 LL |     let Foo(&x) = &Foo(&0);
-   |             ^ cannot implicitly match against multiple layers of reference
+   |             ^ reference pattern not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:57:9
+   |
+LL |     let Foo(&x) = &Foo(&0);
+   |         ^^^^^^^ this matches on type `&_`
 help: make the implied reference pattern explicit
    |
 LL |     let &Foo(&x) = &Foo(&0);
    |         +
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:62:13
    |
 LL |     let Foo(&mut x) = &Foo(&mut 0);
-   |             ^^^^ cannot implicitly match against multiple layers of reference
+   |             ^^^^ reference pattern not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:62:9
+   |
+LL |     let Foo(&mut x) = &Foo(&mut 0);
+   |         ^^^^^^^^^^^ this matches on type `&_`
 help: make the implied reference pattern explicit
    |
 LL |     let &Foo(&mut x) = &Foo(&mut 0);
    |         +
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:67:13
    |
 LL |     let Foo(&x) = &mut Foo(&0);
-   |             ^ cannot implicitly match against multiple layers of reference
+   |             ^ reference pattern not allowed under `ref mut` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:67:9
+   |
+LL |     let Foo(&x) = &mut Foo(&0);
+   |         ^^^^^^^ this matches on type `&mut _`
 help: make the implied reference pattern explicit
    |
 LL |     let &mut Foo(&x) = &mut Foo(&0);
    |         ++++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:72:13
    |
 LL |     let Foo(&mut x) = &mut Foo(&mut 0);
-   |             ^^^^ cannot implicitly match against multiple layers of reference
+   |             ^^^^ reference pattern not allowed under `ref mut` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:72:9
+   |
+LL |     let Foo(&mut x) = &mut Foo(&mut 0);
+   |         ^^^^^^^^^^^ this matches on type `&mut _`
 help: make the implied reference pattern explicit
    |
 LL |     let &mut Foo(&mut x) = &mut Foo(&mut 0);
    |         ++++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:81:17
    |
 LL |     if let Some(&x) = &&&&&Some(&0u8) {
-   |                 ^ cannot implicitly match against multiple layers of reference
+   |                 ^ reference pattern not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:81:12
+   |
+LL |     if let Some(&x) = &&&&&Some(&0u8) {
+   |            ^^^^^^^^ this matches on type `&_`
 help: make the implied reference patterns explicit
    |
 LL |     if let &&&&&Some(&x) = &&&&&Some(&0u8) {
    |            +++++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:87:17
    |
 LL |     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
-   |                 ^^^^ cannot implicitly match against multiple layers of reference
+   |                 ^^^^ reference pattern not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:87:12
+   |
+LL |     if let Some(&mut x) = &&&&&Some(&mut 0u8) {
+   |            ^^^^^^^^^^^^ this matches on type `&_`
 help: make the implied reference patterns explicit
    |
 LL |     if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
    |            +++++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:93:17
    |
 LL |     if let Some(&x) = &&&&&mut Some(&0u8) {
-   |                 ^ cannot implicitly match against multiple layers of reference
+   |                 ^ reference pattern not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:93:12
+   |
+LL |     if let Some(&x) = &&&&&mut Some(&0u8) {
+   |            ^^^^^^^^ this matches on type `&_`
 help: make the implied reference patterns explicit
    |
 LL |     if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
    |            ++++++++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:99:17
    |
 LL |     if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
-   |                 ^^^^ cannot implicitly match against multiple layers of reference
+   |                 ^^^^ reference pattern not allowed under `ref mut` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:99:12
+   |
+LL |     if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&mut _`
 help: make the implied reference patterns and variable binding mode explicit
    |
 LL |     if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
    |            ++++                ++++      +++++++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:111:21
    |
 LL |     let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
-   |                     ^^^ requires binding by-value, but the implicit default is by-reference
+   |                     ^^^ binding modifier not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:111:9
+   |
+LL |     let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
+   |         ^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
 help: make the implied reference pattern and variable binding modes explicit
    |
 LL |     let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
    |         +         +++           +++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:117:21
    |
 LL |     let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
-   |                     ^      ^^^ cannot override to bind by-reference when that is the implicit default
+   |                     ^      ^^^ binding modifier not allowed under `ref` default binding mode
    |                     |
-   |                     cannot implicitly match against multiple layers of reference
+   |                     reference pattern not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:117:9
+   |
+LL |     let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
 help: make the implied reference pattern and variable binding mode explicit
    |
 LL |     let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
    |         +                +++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
   --> $DIR/migration_lint.rs:124:24
    |
 LL |     if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
-   |                        ^                 ^ cannot implicitly match against multiple layers of reference
+   |                        ^                 ^ reference pattern not allowed under `ref` default binding mode
    |                        |
-   |                        cannot implicitly match against multiple layers of reference
+   |                        reference pattern not allowed under `ref` default binding mode
    |
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:124:12
+   |
+LL |     if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
 help: make the implied reference patterns and variable binding mode explicit
    |
 LL |     if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
    |            +                         +             +     +++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers may only be written when the default binding mode is `move`
   --> $DIR/migration_lint.rs:137:15
    |
 LL |         (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
-   |               ^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ default binding mode is reset within expansion
+   |               ^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion
    |               |
-   |               requires binding by-value, but the implicit default is by-reference
+   |               binding modifier not allowed under `ref` default binding mode
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:137:9
+   |
+LL |         (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
    = note: this error originates in the macro `migration_lint_macros::mixed_edition_pat` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: make the implied reference pattern explicit
    |
 LL |         &(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
    |         +
 
-error: aborting due to 16 previous errors
+error: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:145:10
+   |
+LL |     let [&mut [ref a]] = &mut [&mut &[0]];
+   |          ^^^^  ^^^ binding modifier not allowed under `ref` default binding mode
+   |          |
+   |          reference pattern not allowed under `ref mut` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:145:15
+   |
+LL |     let [&mut [ref a]] = &mut [&mut &[0]];
+   |               ^^^^^^^ this matches on type `&_`
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:145:9
+   |
+LL |     let [&mut [ref a]] = &mut [&mut &[0]];
+   |         ^^^^^^^^^^^^^^ this matches on type `&mut _`
+help: make the implied reference patterns explicit
+   |
+LL |     let &mut [&mut &[ref a]] = &mut [&mut &[0]];
+   |         ++++       +
+
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:150:10
+   |
+LL |     let [&(_)] = &[&0];
+   |          ^ reference pattern not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:150:9
+   |
+LL |     let [&(_)] = &[&0];
+   |         ^^^^^^ this matches on type `&_`
+help: make the implied reference pattern explicit
+   |
+LL |     let &[&(_)] = &[&0];
+   |         +
+
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:157:18
+   |
+LL |     let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
+   |                  ^^^    ^^^ binding modifier not allowed under `ref` default binding mode
+   |                  |
+   |                  binding modifier not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:157:9
+   |
+LL |     let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
+help: remove the unnecessary binding modifiers
+   |
+LL -     let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 };
+LL +     let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 };
+   |
+
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:164:18
+   |
+LL |     let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
+   |                  ^^^    ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
+   |                  |
+   |                  binding modifier not allowed under `ref mut` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:164:9
+   |
+LL |     let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&mut _`
+help: make the implied reference pattern and variable binding mode explicit
+   |
+LL |     let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 };
+   |         ++++                            +++++++
+
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:172:21
+   |
+LL |     let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
+   |                     ^            ^^^^ reference pattern not allowed under `ref` default binding mode
+   |                     |
+   |                     reference pattern not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:172:9
+   |
+LL |     let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
+help: make the implied reference patterns and variable binding modes explicit
+   |
+LL |     let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 };
+   |         ++++++                               + +++      +++
+
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:180:13
+   |
+LL |     let Foo(&ref a) = &Foo(&0);
+   |             ^ reference pattern not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:180:9
+   |
+LL |     let Foo(&ref a) = &Foo(&0);
+   |         ^^^^^^^^^^^ this matches on type `&_`
+help: make the implied reference pattern explicit
+   |
+LL |     let &Foo(&ref a) = &Foo(&0);
+   |         +
+
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:186:10
+   |
+LL |     let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
+   |          ^ reference pattern not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:186:9
+   |
+LL |     let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
+help: make the implied reference patterns and variable binding modes explicit
+   |
+LL |     let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]);
+   |         +     +++    + +++     ++++  ++++  +++    + +++
+
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:196:19
+   |
+LL |     let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
+   |                   ^^^ binding modifier not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:196:9
+   |
+LL |     let (a, [b], [mut c]) = &(0, &mut [0], &[0]);
+   |         ^^^^^^^^^^^^^^^^^ this matches on type `&_`
+help: make the implied reference patterns and variable binding modes explicit
+   |
+LL |     let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]);
+   |         + +++    ++++  +++     +
+
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:204:10
+   |
+LL |     let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
+   |          ^       ^ reference pattern not allowed under `ref` default binding mode
+   |          |
+   |          reference pattern not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:204:9
+   |
+LL |     let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0]));
+   |         ^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
+help: make the implied reference patterns and variable binding mode explicit
+   |
+LL |     let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0]));
+   |         +     ++++  +++
+
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:212:10
+   |
+LL |     let [mut a @ b] = &[0];
+   |          ^^^ binding modifier not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:212:9
+   |
+LL |     let [mut a @ b] = &[0];
+   |         ^^^^^^^^^^^ this matches on type `&_`
+help: make the implied reference pattern and variable binding mode explicit
+   |
+LL |     let &[mut a @ ref b] = &[0];
+   |         +         +++
+
+error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:219:14
+   |
+LL |     let [a @ mut b] = &[0];
+   |              ^^^ binding modifier not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:219:9
+   |
+LL |     let [a @ mut b] = &[0];
+   |         ^^^^^^^^^^^ this matches on type `&_`
+help: make the implied reference pattern and variable binding mode explicit
+   |
+LL |     let &[ref a @ mut b] = &[0];
+   |         + +++
+
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:226:14
+   |
+LL |     let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
+   |              ^                    ^ reference pattern not allowed under `ref` default binding mode
+   |              |
+   |              reference pattern not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:226:31
+   |
+LL |     let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
+   |                               ^^^^^^^^^^^^^^^ this matches on type `&_`
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:226:10
+   |
+LL |     let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2];
+   |          ^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
+help: make the implied reference patterns explicit
+   |
+LL |     let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2];
+   |          +                     +
+
+error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
+  --> $DIR/migration_lint.rs:235:14
+   |
+LL |     let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
+   |              ^                      ^ reference pattern not allowed under `ref` default binding mode
+   |              |
+   |              reference pattern not allowed under `ref` default binding mode
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:235:33
+   |
+LL |     let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
+   |                                 ^^^^^^^^^^^^^^^^^ this matches on type `&_`
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/migration_lint.rs:235:10
+   |
+LL |     let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
+   |          ^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
+help: make the implied reference patterns explicit
+   |
+LL |     let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2];
+   |          +                       +
+
+error: aborting due to 29 previous errors
 
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
index 5ba554fc6e5a4..4dc04d90aaf5e 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs
@@ -21,17 +21,17 @@ macro_rules! test_pat_on_type {
 }
 
 test_pat_on_type![(&x,): &(T,)]; //~ ERROR mismatched types
-test_pat_on_type![(&x,): &(&T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
+test_pat_on_type![(&x,): &(&T,)]; //~ ERROR reference patterns may only be written when the default binding mode is `move`
 test_pat_on_type![(&x,): &(&mut T,)]; //~ ERROR mismatched types
 test_pat_on_type![(&mut x,): &(&T,)]; //~ ERROR mismatched types
-test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
+test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR reference patterns may only be written when the default binding mode is `move`
 test_pat_on_type![(&x,): &&mut &(T,)]; //~ ERROR mismatched types
 test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types
 test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types
-test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR this pattern relies on behavior which may change in edition 2024
-test_pat_on_type![(mut x,): &(T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
-test_pat_on_type![(ref x,): &(T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
-test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR this pattern relies on behavior which may change in edition 2024
+test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR reference patterns may only be written when the default binding mode is `move`
+test_pat_on_type![(mut x,): &(T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move`
+test_pat_on_type![(ref x,): &(T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move`
+test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move`
 
 fn get<X>() -> X {
     unimplemented!()
@@ -40,6 +40,6 @@ fn get<X>() -> X {
 // Make sure this works even when the underlying type is inferred. This test passes on rust stable.
 fn infer<X: Copy>() -> X {
     match &get() {
-        (&x,) => x, //~ ERROR this pattern relies on behavior which may change in edition 2024
+        (&x,) => x, //~ ERROR reference patterns may only be written when the default binding mode is `move`
     }
 }
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
index affdca1d44906..0c6b2ff3a2f09 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr
@@ -99,85 +99,122 @@ LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
 LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo];
    |
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move`
   --> $DIR/min_match_ergonomics_fail.rs:24:20
    |
 LL | test_pat_on_type![(&x,): &(&T,)];
-   |                    ^ cannot implicitly match against multiple layers of reference
+   |                    ^ reference pattern not allowed under `ref` default binding mode
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/min_match_ergonomics_fail.rs:24:19
+   |
+LL | test_pat_on_type![(&x,): &(&T,)];
+   |                   ^^^^^ this matches on type `&_`
 help: make the implied reference pattern explicit
    |
 LL | test_pat_on_type![&(&x,): &(&T,)];
    |                   +
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move`
   --> $DIR/min_match_ergonomics_fail.rs:27:20
    |
 LL | test_pat_on_type![(&mut x,): &(&mut T,)];
-   |                    ^^^^ cannot implicitly match against multiple layers of reference
+   |                    ^^^^ reference pattern not allowed under `ref` default binding mode
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/min_match_ergonomics_fail.rs:27:19
+   |
+LL | test_pat_on_type![(&mut x,): &(&mut T,)];
+   |                   ^^^^^^^^^ this matches on type `&_`
 help: make the implied reference pattern explicit
    |
 LL | test_pat_on_type![&(&mut x,): &(&mut T,)];
    |                   +
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move`
   --> $DIR/min_match_ergonomics_fail.rs:31:28
    |
 LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
-   |                            ^ cannot implicitly match against multiple layers of reference
+   |                            ^ reference pattern not allowed under `ref` default binding mode
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/min_match_ergonomics_fail.rs:31:19
+   |
+LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
+   |                   ^^^^^^^^^^^^^^^^ this matches on type `&_`
 help: make the implied reference pattern explicit
    |
 LL | test_pat_on_type![&Foo { f: &(x,) }: &Foo];
    |                   +
 
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers may only be written when the default binding mode is `move`
   --> $DIR/min_match_ergonomics_fail.rs:32:20
    |
 LL | test_pat_on_type![(mut x,): &(T,)];
-   |                    ^^^ requires binding by-value, but the implicit default is by-reference
+   |                    ^^^ binding modifier not allowed under `ref` default binding mode
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/min_match_ergonomics_fail.rs:32:19
+   |
+LL | test_pat_on_type![(mut x,): &(T,)];
+   |                   ^^^^^^^^ this matches on type `&_`
 help: make the implied reference pattern explicit
    |
 LL | test_pat_on_type![&(mut x,): &(T,)];
    |                   +
 
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers may only be written when the default binding mode is `move`
   --> $DIR/min_match_ergonomics_fail.rs:33:20
    |
 LL | test_pat_on_type![(ref x,): &(T,)];
-   |                    ^^^ cannot override to bind by-reference when that is the implicit default
+   |                    ^^^ binding modifier not allowed under `ref` default binding mode
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
-help: make the implied reference pattern explicit
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/min_match_ergonomics_fail.rs:33:19
+   |
+LL | test_pat_on_type![(ref x,): &(T,)];
+   |                   ^^^^^^^^ this matches on type `&_`
+help: remove the unnecessary binding modifier
+   |
+LL - test_pat_on_type![(ref x,): &(T,)];
+LL + test_pat_on_type![(x,): &(T,)];
    |
-LL | test_pat_on_type![&(ref x,): &(T,)];
-   |                   +
 
-error: this pattern relies on behavior which may change in edition 2024
+error: binding modifiers may only be written when the default binding mode is `move`
   --> $DIR/min_match_ergonomics_fail.rs:34:20
    |
 LL | test_pat_on_type![(ref mut x,): &mut (T,)];
-   |                    ^^^^^^^ cannot override to bind by-reference when that is the implicit default
+   |                    ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
-help: make the implied reference pattern explicit
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/min_match_ergonomics_fail.rs:34:19
+   |
+LL | test_pat_on_type![(ref mut x,): &mut (T,)];
+   |                   ^^^^^^^^^^^^ this matches on type `&mut _`
+help: remove the unnecessary binding modifier
+   |
+LL - test_pat_on_type![(ref mut x,): &mut (T,)];
+LL + test_pat_on_type![(x,): &mut (T,)];
    |
-LL | test_pat_on_type![&mut (ref mut x,): &mut (T,)];
-   |                   ++++
 
-error: this pattern relies on behavior which may change in edition 2024
+error: reference patterns may only be written when the default binding mode is `move`
   --> $DIR/min_match_ergonomics_fail.rs:43:10
    |
 LL |         (&x,) => x,
-   |          ^ cannot implicitly match against multiple layers of reference
+   |          ^ reference pattern not allowed under `ref` default binding mode
    |
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
+note: matching on a reference type with a non-reference pattern changes the default binding mode
+  --> $DIR/min_match_ergonomics_fail.rs:43:9
+   |
+LL |         (&x,) => x,
+   |         ^^^^^ this matches on type `&_`
 help: make the implied reference pattern explicit
    |
 LL |         &(&x,) => x,
diff --git a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs
new file mode 100644
index 0000000000000..17a5bad0e6c0f
--- /dev/null
+++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.rs
@@ -0,0 +1,10 @@
+// Regression test for #135209.
+// We ensure that we don't try to access fields on a non-struct pattern type.
+fn main() {
+    if let <Vec<()> as Iterator>::Item { .. } = 1 {
+        //~^ ERROR E0658
+        //~| ERROR E0071
+        //~| ERROR E0277
+        x //~ ERROR E0425
+    }
+}
diff --git a/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr
new file mode 100644
index 0000000000000..793c2d1e97fc0
--- /dev/null
+++ b/tests/ui/pattern/struct-pattern-on-non-struct-resolve-error.stderr
@@ -0,0 +1,34 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:8:9
+   |
+LL |         x
+   |         ^ not found in this scope
+
+error[E0658]: usage of qualified paths in this context is experimental
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
+   |
+LL |     if let <Vec<()> as Iterator>::Item { .. } = 1 {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
+   = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0071]: expected struct, variant or union type, found inferred type
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
+   |
+LL |     if let <Vec<()> as Iterator>::Item { .. } = 1 {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a struct
+
+error[E0277]: `Vec<()>` is not an iterator
+  --> $DIR/struct-pattern-on-non-struct-resolve-error.rs:4:12
+   |
+LL |     if let <Vec<()> as Iterator>::Item { .. } = 1 {
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Vec<()>` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `Vec<()>`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0071, E0277, E0425, E0658.
+For more information about an error, try `rustc --explain E0071`.
diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs
index 225891e390ff5..39f9f5a2c0208 100644
--- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs
+++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.rs
@@ -3,6 +3,10 @@ struct Website {
     title: Option<String>,
 }
 
+enum Foo {
+    Bar { a: i32 },
+}
+
 fn main() {
     let website = Website {
         url: "http://www.example.com".into(),
@@ -18,4 +22,9 @@ fn main() {
         println!("[{}]({})", title, url); //~ ERROR cannot find value `title` in this scope
         //~^ NOTE not found in this scope
     }
+
+    let x = Foo::Bar { a: 1 };
+    if let Foo::Bar { .. } = x { //~ NOTE this pattern
+        println!("{a}"); //~ ERROR cannot find value `a` in this scope
+    }
 }
diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr
index 80fcd714400d6..b985b771754ee 100644
--- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr
+++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr
@@ -1,5 +1,5 @@
 error: expected `,`
-  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:12:31
+  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:16:31
    |
 LL |     if let Website { url, Some(title) } = website {
    |            -------            ^
@@ -7,13 +7,21 @@ LL |     if let Website { url, Some(title) } = website {
    |            while parsing the fields for this pattern
 
 error[E0425]: cannot find value `title` in this scope
-  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:18:30
+  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:22:30
    |
 LL |     if let Website { url, .. } = website {
    |            ------------------- this pattern doesn't include `title`, which is available in `Website`
 LL |         println!("[{}]({})", title, url);
    |                              ^^^^^ not found in this scope
 
-error: aborting due to 2 previous errors
+error[E0425]: cannot find value `a` in this scope
+  --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:28:20
+   |
+LL |     if let Foo::Bar { .. } = x {
+   |            --------------- this pattern doesn't include `a`, which is available in `Bar`
+LL |         println!("{a}");
+   |                    ^ help: a local variable with a similar name exists: `x`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/stable-mir-print/operands.stdout b/tests/ui/stable-mir-print/operands.stdout
index c3b1151ae24a3..3c27878b3cf0f 100644
--- a/tests/ui/stable-mir-print/operands.stdout
+++ b/tests/ui/stable-mir-print/operands.stdout
@@ -5,183 +5,187 @@ fn operands(_1: u8) -> () {
     let  _2: [u8; 10];
     let  _3: u8;
     let  _4: usize;
-    let mut _5: bool;
-    let  _6: u8;
-    let  _7: usize;
-    let mut _8: (usize, bool);
-    let mut _9: bool;
-    let mut _10: (&u8, &u8);
-    let mut _11: &u8;
-    let mut _12: &u8;
-    let  _13: &u8;
-    let  _14: &u8;
-    let mut _15: bool;
-    let mut _16: u8;
-    let mut _17: u8;
-    let  _18: core::panicking::AssertKind;
-    let  _19: !;
-    let mut _20: Option<Arguments<'_>>;
-    let  _21: &u8;
-    let  _22: u8;
-    let mut _23: (&u8, &u8);
-    let mut _24: &u8;
-    let mut _25: &u8;
-    let  _26: &u8;
-    let  _27: &u8;
-    let mut _28: bool;
-    let mut _29: u8;
-    let mut _30: u8;
-    let  _31: core::panicking::AssertKind;
-    let  _32: !;
-    let mut _33: Option<Arguments<'_>>;
-    let  _34: (u8, u8);
-    let  _35: u8;
-    let  _36: u8;
-    let mut _37: (&u8, &u8);
-    let mut _38: &u8;
-    let mut _39: &u8;
-    let  _40: &u8;
-    let  _41: &u8;
-    let mut _42: bool;
-    let mut _43: u8;
-    let mut _44: u8;
-    let  _45: core::panicking::AssertKind;
-    let  _46: !;
-    let mut _47: Option<Arguments<'_>>;
-    let  _48: usize;
-    let mut _49: &[u8];
-    let mut _50: &[u8; 10];
-    let  _51: usize;
-    let  _52: &usize;
-    let mut _53: (&usize, &usize);
-    let mut _54: &usize;
-    let mut _55: &usize;
-    let  _56: &usize;
-    let  _57: &usize;
-    let mut _58: bool;
-    let mut _59: usize;
-    let mut _60: usize;
-    let  _61: core::panicking::AssertKind;
-    let  _62: !;
-    let mut _63: Option<Arguments<'_>>;
+    let mut _5: usize;
+    let mut _6: bool;
+    let  _7: u8;
+    let  _8: usize;
+    let mut _9: (usize, bool);
+    let mut _10: usize;
+    let mut _11: bool;
+    let mut _12: (&u8, &u8);
+    let mut _13: &u8;
+    let mut _14: &u8;
+    let  _15: &u8;
+    let  _16: &u8;
+    let mut _17: bool;
+    let mut _18: u8;
+    let mut _19: u8;
+    let  _20: core::panicking::AssertKind;
+    let  _21: !;
+    let mut _22: Option<Arguments<'_>>;
+    let  _23: &u8;
+    let  _24: u8;
+    let mut _25: (&u8, &u8);
+    let mut _26: &u8;
+    let mut _27: &u8;
+    let  _28: &u8;
+    let  _29: &u8;
+    let mut _30: bool;
+    let mut _31: u8;
+    let mut _32: u8;
+    let  _33: core::panicking::AssertKind;
+    let  _34: !;
+    let mut _35: Option<Arguments<'_>>;
+    let  _36: (u8, u8);
+    let  _37: u8;
+    let  _38: u8;
+    let mut _39: (&u8, &u8);
+    let mut _40: &u8;
+    let mut _41: &u8;
+    let  _42: &u8;
+    let  _43: &u8;
+    let mut _44: bool;
+    let mut _45: u8;
+    let mut _46: u8;
+    let  _47: core::panicking::AssertKind;
+    let  _48: !;
+    let mut _49: Option<Arguments<'_>>;
+    let  _50: usize;
+    let mut _51: &[u8];
+    let mut _52: &[u8; 10];
+    let  _53: usize;
+    let  _54: &usize;
+    let mut _55: (&usize, &usize);
+    let mut _56: &usize;
+    let mut _57: &usize;
+    let  _58: &usize;
+    let  _59: &usize;
+    let mut _60: bool;
+    let mut _61: usize;
+    let mut _62: usize;
+    let  _63: core::panicking::AssertKind;
+    let  _64: !;
+    let mut _65: Option<Arguments<'_>>;
     debug val => _1;
     debug array => _2;
     debug first => _3;
-    debug last => _6;
-    debug left_val => _13;
-    debug right_val => _14;
-    debug kind => _18;
-    debug reference => _21;
-    debug dereferenced => _22;
-    debug left_val => _26;
-    debug right_val => _27;
-    debug kind => _31;
-    debug tuple => _34;
-    debug first_again => _35;
-    debug first_again_again => _36;
-    debug left_val => _40;
-    debug right_val => _41;
-    debug kind => _45;
-    debug length => _48;
-    debug size_of => _51;
-    debug left_val => _56;
-    debug right_val => _57;
-    debug kind => _61;
+    debug last => _7;
+    debug left_val => _15;
+    debug right_val => _16;
+    debug kind => _20;
+    debug reference => _23;
+    debug dereferenced => _24;
+    debug left_val => _28;
+    debug right_val => _29;
+    debug kind => _33;
+    debug tuple => _36;
+    debug first_again => _37;
+    debug first_again_again => _38;
+    debug left_val => _42;
+    debug right_val => _43;
+    debug kind => _47;
+    debug length => _50;
+    debug size_of => _53;
+    debug left_val => _58;
+    debug right_val => _59;
+    debug kind => _63;
     bb0: {
         _2 = [_1; 10];
         _4 = 0_usize;
-        _5 = Lt(_4, 10_usize);
-        assert(move _5, "index out of bounds: the length is {} but the index is {}", 10_usize, _4) -> [success: bb1, unwind unreachable];
+        _5 = 10_usize;
+        _6 = Lt(_4, _5);
+        assert(move _6, "index out of bounds: the length is {} but the index is {}", move _5, _4) -> [success: bb1, unwind unreachable];
     }
     bb1: {
         _3 = _2[_4];
-        _8 = CheckedSub(10_usize, 1_usize);
-        assert(!move (_8.1: bool), "attempt to compute `{} - {}`, which would overflow", 10_usize, 1_usize) -> [success: bb2, unwind unreachable];
+        _9 = CheckedSub(10_usize, 1_usize);
+        assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", 10_usize, 1_usize) -> [success: bb2, unwind unreachable];
     }
     bb2: {
-        _7 = move (_8.0: usize);
-        _9 = Lt(_7, 10_usize);
-        assert(move _9, "index out of bounds: the length is {} but the index is {}", 10_usize, _7) -> [success: bb3, unwind unreachable];
+        _8 = move (_9.0: usize);
+        _10 = 10_usize;
+        _11 = Lt(_8, _10);
+        assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, _8) -> [success: bb3, unwind unreachable];
     }
     bb3: {
-        _6 = _2[_7];
-        _11 = &_3;
-        _12 = &_6;
-        _10 = (move _11, move _12);
-        _13 = (_10.0: &u8);
-        _14 = (_10.1: &u8);
-        _16 = (*_13);
-        _17 = (*_14);
-        _15 = Eq(move _16, move _17);
-        switchInt(move _15) -> [0: bb5, otherwise: bb4];
+        _7 = _2[_8];
+        _13 = &_3;
+        _14 = &_7;
+        _12 = (move _13, move _14);
+        _15 = (_12.0: &u8);
+        _16 = (_12.1: &u8);
+        _18 = (*_15);
+        _19 = (*_16);
+        _17 = Eq(move _18, move _19);
+        switchInt(move _17) -> [0: bb5, otherwise: bb4];
     }
     bb4: {
-        _21 = &_3;
-        _22 = (*_21);
-        _24 = &_22;
-        _25 = &_3;
-        _23 = (move _24, move _25);
-        _26 = (_23.0: &u8);
-        _27 = (_23.1: &u8);
-        _29 = (*_26);
-        _30 = (*_27);
-        _28 = Eq(move _29, move _30);
-        switchInt(move _28) -> [0: bb7, otherwise: bb6];
+        _23 = &_3;
+        _24 = (*_23);
+        _26 = &_24;
+        _27 = &_3;
+        _25 = (move _26, move _27);
+        _28 = (_25.0: &u8);
+        _29 = (_25.1: &u8);
+        _31 = (*_28);
+        _32 = (*_29);
+        _30 = Eq(move _31, move _32);
+        switchInt(move _30) -> [0: bb7, otherwise: bb6];
     }
     bb5: {
-        _18 = core::panicking::AssertKind::Eq;
-        _20 = std::option::Option::None;
-        _19 = core::panicking::assert_failed::<u8, u8>(move _18, _13, _14, move _20) -> unwind unreachable;
+        _20 = core::panicking::AssertKind::Eq;
+        _22 = std::option::Option::None;
+        _21 = core::panicking::assert_failed::<u8, u8>(move _20, _15, _16, move _22) -> unwind unreachable;
     }
     bb6: {
-        _34 = (_3, _6);
-        _35 = (_34.0: u8);
-        _36 = (_34.0: u8);
-        _38 = &_35;
-        _39 = &_36;
-        _37 = (move _38, move _39);
-        _40 = (_37.0: &u8);
-        _41 = (_37.1: &u8);
-        _43 = (*_40);
-        _44 = (*_41);
-        _42 = Eq(move _43, move _44);
-        switchInt(move _42) -> [0: bb9, otherwise: bb8];
+        _36 = (_3, _7);
+        _37 = (_36.0: u8);
+        _38 = (_36.0: u8);
+        _40 = &_37;
+        _41 = &_38;
+        _39 = (move _40, move _41);
+        _42 = (_39.0: &u8);
+        _43 = (_39.1: &u8);
+        _45 = (*_42);
+        _46 = (*_43);
+        _44 = Eq(move _45, move _46);
+        switchInt(move _44) -> [0: bb9, otherwise: bb8];
     }
     bb7: {
-        _31 = core::panicking::AssertKind::Eq;
-        _33 = std::option::Option::None;
-        _32 = core::panicking::assert_failed::<u8, u8>(move _31, _26, _27, move _33) -> unwind unreachable;
+        _33 = core::panicking::AssertKind::Eq;
+        _35 = std::option::Option::None;
+        _34 = core::panicking::assert_failed::<u8, u8>(move _33, _28, _29, move _35) -> unwind unreachable;
     }
     bb8: {
-        _50 = &_2;
-        _49 = move _50 as &[u8];
-        _48 = PtrMetadata(move _49);
-        _52 = &_48;
-        _51 = std::mem::size_of_val::<usize>(_52) -> [return: bb10, unwind unreachable];
+        _52 = &_2;
+        _51 = move _52 as &[u8];
+        _50 = PtrMetadata(move _51);
+        _54 = &_50;
+        _53 = std::mem::size_of_val::<usize>(_54) -> [return: bb10, unwind unreachable];
     }
     bb9: {
-        _45 = core::panicking::AssertKind::Eq;
-        _47 = std::option::Option::None;
-        _46 = core::panicking::assert_failed::<u8, u8>(move _45, _40, _41, move _47) -> unwind unreachable;
+        _47 = core::panicking::AssertKind::Eq;
+        _49 = std::option::Option::None;
+        _48 = core::panicking::assert_failed::<u8, u8>(move _47, _42, _43, move _49) -> unwind unreachable;
     }
     bb10: {
-        _54 = &_48;
-        _55 = &_51;
-        _53 = (move _54, move _55);
-        _56 = (_53.0: &usize);
-        _57 = (_53.1: &usize);
-        _59 = (*_56);
-        _60 = (*_57);
-        _58 = Eq(move _59, move _60);
-        switchInt(move _58) -> [0: bb12, otherwise: bb11];
+        _56 = &_50;
+        _57 = &_53;
+        _55 = (move _56, move _57);
+        _58 = (_55.0: &usize);
+        _59 = (_55.1: &usize);
+        _61 = (*_58);
+        _62 = (*_59);
+        _60 = Eq(move _61, move _62);
+        switchInt(move _60) -> [0: bb12, otherwise: bb11];
     }
     bb11: {
         return;
     }
     bb12: {
-        _61 = core::panicking::AssertKind::Eq;
-        _63 = std::option::Option::None;
-        _62 = core::panicking::assert_failed::<usize, usize>(move _61, _56, _57, move _63) -> unwind unreachable;
+        _63 = core::panicking::AssertKind::Eq;
+        _65 = std::option::Option::None;
+        _64 = core::panicking::assert_failed::<usize, usize>(move _63, _58, _59, move _65) -> unwind unreachable;
     }
 }
 fn operands::{constant#0}() -> usize {
diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs
new file mode 100644
index 0000000000000..54854b1b8a522
--- /dev/null
+++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs
@@ -0,0 +1,56 @@
+// Computing the ambiguity causes for the overlap ended up
+// causing an exponential blowup when recursing into the normalization
+// goals for `<Box<?t> as RecursiveSuper>::Assoc`. This test
+// takes multiple minutes when doing so and less than a second
+// otherwise.
+
+//@ compile-flags: -Znext-solver=coherence
+
+trait RecursiveSuper:
+    Super<
+        A0 = Self::Assoc,
+        A1 = Self::Assoc,
+        A2 = Self::Assoc,
+        A3 = Self::Assoc,
+        A4 = Self::Assoc,
+        A5 = Self::Assoc,
+        A6 = Self::Assoc,
+        A7 = Self::Assoc,
+        A8 = Self::Assoc,
+        A9 = Self::Assoc,
+        A10 = Self::Assoc,
+        A11 = Self::Assoc,
+        A12 = Self::Assoc,
+        A13 = Self::Assoc,
+        A14 = Self::Assoc,
+        A15 = Self::Assoc,
+    >
+{
+    type Assoc;
+}
+
+trait Super {
+    type A0;
+    type A1;
+    type A2;
+    type A3;
+    type A4;
+    type A5;
+    type A6;
+    type A7;
+    type A8;
+    type A9;
+    type A10;
+    type A11;
+    type A12;
+    type A13;
+    type A14;
+    type A15;
+}
+
+trait Overlap {}
+impl<T: RecursiveSuper> Overlap for T {}
+impl<T> Overlap for Box<T> {}
+//~^ ERROR conflicting implementations of trait `Overlap` for type `Box<_>`
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr
new file mode 100644
index 0000000000000..3731dc5b74ec0
--- /dev/null
+++ b/tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.stderr
@@ -0,0 +1,14 @@
+error[E0119]: conflicting implementations of trait `Overlap` for type `Box<_>`
+  --> $DIR/ambiguity-causes-visitor-hang.rs:53:1
+   |
+LL | impl<T: RecursiveSuper> Overlap for T {}
+   | ------------------------------------- first implementation here
+LL | impl<T> Overlap for Box<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
+   |
+   = note: downstream crates may implement trait `Super` for type `std::boxed::Box<_>`
+   = note: downstream crates may implement trait `RecursiveSuper` for type `std::boxed::Box<_>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
