about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock72
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs35
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs15
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs4
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs18
-rw-r--r--compiler/rustc_hir/src/def.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs3
-rw-r--r--compiler/rustc_middle/src/ty/util.rs5
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs19
-rw-r--r--compiler/rustc_span/src/symbol.rs21
-rw-r--r--compiler/rustc_target/src/target_features.rs8
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs40
-rw-r--r--library/core/src/ptr/const_ptr.rs78
-rw-r--r--library/core/src/ptr/docs/INFO.md21
-rw-r--r--library/core/src/ptr/docs/addr.md22
-rw-r--r--library/core/src/ptr/docs/as_ref.md19
-rw-r--r--library/core/src/ptr/docs/as_uninit_ref.md15
-rw-r--r--library/core/src/ptr/mut_ptr.rs90
-rw-r--r--library/coretests/tests/array.rs7
-rw-r--r--library/coretests/tests/floats/f128.rs28
-rw-r--r--library/coretests/tests/floats/f16.rs27
-rw-r--r--library/coretests/tests/floats/f32.rs28
-rw-r--r--library/coretests/tests/floats/f64.rs27
-rw-r--r--library/coretests/tests/floats/mod.rs63
-rw-r--r--library/coretests/tests/lib.rs1
-rw-r--r--library/coretests/tests/ops.rs75
-rw-r--r--library/std/src/sys/mod.rs1
-rw-r--r--library/std/src/sys/net/connection/socket/hermit.rs3
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs1
-rw-r--r--library/std/src/sys/pal/hermit/os.rs2
-rw-r--r--library/std/src/sys/pal/sgx/abi/mod.rs2
-rw-r--r--library/std/src/sys/pal/sgx/mod.rs1
-rw-r--r--library/std/src/sys/pal/solid/mod.rs4
-rw-r--r--library/std/src/sys/pal/teeos/mod.rs1
-rw-r--r--library/std/src/sys/pal/uefi/mod.rs1
-rw-r--r--library/std/src/sys/pal/uefi/thread.rs66
-rw-r--r--library/std/src/sys/pal/unix/mod.rs3
-rw-r--r--library/std/src/sys/pal/wasip1/mod.rs1
-rw-r--r--library/std/src/sys/pal/wasip1/thread.rs214
-rw-r--r--library/std/src/sys/pal/wasip2/mod.rs1
-rw-r--r--library/std/src/sys/pal/wasip2/thread.rs73
-rw-r--r--library/std/src/sys/pal/wasip2/time.rs2
-rw-r--r--library/std/src/sys/pal/wasm/atomics/thread.rs75
-rw-r--r--library/std/src/sys/pal/wasm/mod.rs15
-rw-r--r--library/std/src/sys/pal/windows/mod.rs5
-rw-r--r--library/std/src/sys/pal/windows/time.rs2
-rw-r--r--library/std/src/sys/pal/xous/mod.rs1
-rw-r--r--library/std/src/sys/platform_version/darwin/tests.rs6
-rw-r--r--library/std/src/sys/sync/once/queue.rs4
-rw-r--r--library/std/src/sys/thread/hermit.rs (renamed from library/std/src/sys/pal/hermit/thread.rs)66
-rw-r--r--library/std/src/sys/thread/mod.rs152
-rw-r--r--library/std/src/sys/thread/sgx.rs (renamed from library/std/src/sys/pal/sgx/thread.rs)49
-rw-r--r--library/std/src/sys/thread/solid.rs (renamed from library/std/src/sys/pal/itron/thread.rs)42
-rw-r--r--library/std/src/sys/thread/teeos.rs (renamed from library/std/src/sys/pal/teeos/thread.rs)71
-rw-r--r--library/std/src/sys/thread/uefi.rs25
-rw-r--r--library/std/src/sys/thread/unix.rs (renamed from library/std/src/sys/pal/unix/thread.rs)667
-rw-r--r--library/std/src/sys/thread/unsupported.rs (renamed from library/std/src/sys/pal/unsupported/thread.rs)39
-rw-r--r--library/std/src/sys/thread/wasip1.rs185
-rw-r--r--library/std/src/sys/thread/wasip2.rs32
-rw-r--r--library/std/src/sys/thread/wasm.rs23
-rw-r--r--library/std/src/sys/thread/windows.rs (renamed from library/std/src/sys/pal/windows/thread.rs)112
-rw-r--r--library/std/src/sys/thread/xous.rs (renamed from library/std/src/sys/pal/xous/thread.rs)54
-rw-r--r--library/std/src/thread/mod.rs75
-rw-r--r--library/std/src/thread/tests.rs4
-rw-r--r--library/std/tests/sync/rwlock.rs6
-rw-r--r--library/std_detect/src/detect/os/linux/aarch64.rs77
-rw-r--r--package-lock.json8
-rw-r--r--package.json2
-rw-r--r--src/doc/rustc/src/platform-support.md4
-rw-r--r--src/doc/rustc/src/platform-support/loongarch-linux.md15
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs57
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs12
-rw-r--r--src/tools/clippy/tests/ui/const_is_empty.rs1
-rw-r--r--src/tools/clippy/tests/ui/const_is_empty.stderr10
-rw-r--r--src/tools/clippy/tests/ui/incompatible_msrv.rs2
-rw-r--r--src/tools/miri/README.md1
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr4
-rw-r--r--src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr4
-rw-r--r--src/tools/tidy/src/extra_checks/mod.rs52
-rw-r--r--src/tools/tidy/src/extra_checks/rustdoc_js.rs6
-rw-r--r--tests/assembly-llvm/c-variadic-arm.rs26
-rw-r--r--tests/codegen-llvm/c-variadic-lifetime.rs21
-rw-r--r--tests/rustdoc-ui/lints/bare-urls.fixed14
-rw-r--r--tests/rustdoc-ui/lints/bare-urls.rs14
-rw-r--r--tests/rustdoc-ui/lints/bare-urls.stderr70
-rw-r--r--tests/ui/abi/simd-abi-checks-s390x.rs1
-rw-r--r--tests/ui/abi/simd-abi-checks-s390x.z10.stderr20
-rw-r--r--tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr20
-rw-r--r--tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr27
-rw-r--r--tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs17
-rw-r--r--tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr8
-rw-r--r--tests/ui/codemap_tests/issue-28308.rs16
-rw-r--r--tests/ui/codemap_tests/issue-28308.stderr28
-rw-r--r--tests/ui/consts/control-flow/assert.stderr4
-rw-r--r--tests/ui/generics/post_monomorphization_error_backtrace.stderr8
-rw-r--r--tests/ui/inline-const/const-expr-generic-err.stderr4
-rw-r--r--tests/ui/intrinsics/panic-uninitialized-zeroed.rs17
-rw-r--r--tests/ui/macros/assert-desugaring-145770.rs23
-rw-r--r--tests/ui/macros/assert-macro-lifetimes.rs8
-rw-r--r--tests/ui/macros/metavar-expressions/concat-allowed-operations.rs18
-rw-r--r--tests/ui/macros/metavar-expressions/concat-usage-errors.rs10
-rw-r--r--tests/ui/macros/metavar-expressions/concat-usage-errors.stderr40
-rw-r--r--tests/ui/mir/alignment/packed.rs2
-rw-r--r--tests/ui/simd/const-err-trumps-simd-err.stderr4
-rw-r--r--tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs33
-rw-r--r--tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr22
-rw-r--r--tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs30
-rw-r--r--tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr92
-rw-r--r--tests/ui/traits/const-traits/macro-dyn-const-2015.rs15
-rw-r--r--tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs25
-rw-r--r--tests/ui/transmutability/uninhabited.stderr12
123 files changed, 1965 insertions, 1845 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8be13e84596..2dc6e8ff103 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2347,11 +2347,11 @@ dependencies = [
 
 [[package]]
 name = "miow"
-version = "0.6.0"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "359f76430b20a79f9e20e115b3428614e654f04fab314482fc0fda0ebd3c6044"
+checksum = "536bfad37a309d62069485248eeaba1e8d9853aaf951caaeaed0585a95346f08"
 dependencies = [
- "windows-sys 0.48.0",
+ "windows-sys 0.60.2",
 ]
 
 [[package]]
@@ -6316,15 +6316,6 @@ dependencies = [
 
 [[package]]
 name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.5",
-]
-
-[[package]]
-name = "windows-sys"
 version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
@@ -6352,21 +6343,6 @@ dependencies = [
 
 [[package]]
 name = "windows-targets"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
-]
-
-[[package]]
-name = "windows-targets"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
@@ -6409,12 +6385,6 @@ dependencies = [
 
 [[package]]
 name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
@@ -6427,12 +6397,6 @@ checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
-[[package]]
-name = "windows_aarch64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
@@ -6445,12 +6409,6 @@ checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
-[[package]]
-name = "windows_i686_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
@@ -6475,12 +6433,6 @@ checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
-[[package]]
-name = "windows_i686_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
@@ -6493,12 +6445,6 @@ checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
-[[package]]
-name = "windows_x86_64_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
@@ -6511,12 +6457,6 @@ checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
@@ -6529,12 +6469,6 @@ checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
-
-[[package]]
-name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 013258a1b4e..855da5caa31 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -1,8 +1,8 @@
 mod context;
 
-use rustc_ast::token::{self, Delimiter};
+use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::{DelimSpan, TokenStream};
-use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, Path, PathSegment};
+use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, Path, PathSegment, UnOp, token};
 use rustc_ast_pretty::pprust;
 use rustc_errors::PResult;
 use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
@@ -29,7 +29,7 @@ pub(crate) fn expand_assert<'cx>(
 
     // `core::panic` and `std::panic` are different macros, so we use call-site
     // context to pick up whichever is currently in scope.
-    let call_site_span = cx.with_call_site_ctxt(cond_expr.span);
+    let call_site_span = cx.with_call_site_ctxt(span);
 
     let panic_path = || {
         if use_panic_2021(span) {
@@ -63,7 +63,7 @@ pub(crate) fn expand_assert<'cx>(
                 }),
             })),
         );
-        assert_cond_check(cx, call_site_span, cond_expr, then)
+        expr_if_not(cx, call_site_span, cond_expr, then, None)
     }
     // If `generic_assert` is enabled, generates rich captured outputs
     //
@@ -88,33 +88,26 @@ pub(crate) fn expand_assert<'cx>(
                 )),
             )],
         );
-        assert_cond_check(cx, call_site_span, cond_expr, then)
+        expr_if_not(cx, call_site_span, cond_expr, then, None)
     };
 
     ExpandResult::Ready(MacEager::expr(expr))
 }
 
-/// `assert!($cond_expr, $custom_message)`
 struct Assert {
     cond_expr: Box<Expr>,
     custom_message: Option<TokenStream>,
 }
 
-/// `match <cond> { true => {} _ => <then> }`
-fn assert_cond_check(cx: &ExtCtxt<'_>, span: Span, cond: Box<Expr>, then: Box<Expr>) -> Box<Expr> {
-    // Instead of expanding to `if !<cond> { <then> }`, we expand to
-    // `match <cond> { true => {} _ => <then> }`.
-    // This allows us to always complain about mismatched types instead of "cannot apply unary
-    // operator `!` to type `X`" when passing an invalid `<cond>`, while also allowing `<cond>` to
-    // be `&true`.
-    let els = cx.expr_block(cx.block(span, thin_vec![]));
-    let mut arms = thin_vec![];
-    arms.push(cx.arm(span, cx.pat_lit(span, cx.expr_bool(span, true)), els));
-    arms.push(cx.arm(span, cx.pat_wild(span), then));
-
-    // We wrap the `match` in a statement to limit the length of any borrows introduced in the
-    // condition.
-    cx.expr_block(cx.block(span, [cx.stmt_expr(cx.expr_match(span, cond, arms))].into()))
+// if !{ ... } { ... } else { ... }
+fn expr_if_not(
+    cx: &ExtCtxt<'_>,
+    span: Span,
+    cond: Box<Expr>,
+    then: Box<Expr>,
+    els: Option<Box<Expr>>,
+) -> Box<Expr> {
+    cx.expr_if(span, cx.expr(span, ExprKind::Unary(UnOp::Not, cond)), then, els)
 }
 
 fn parse_assert<'a>(cx: &ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PResult<'a, Assert> {
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index 7eb5d302058..ab08125217f 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -908,6 +908,21 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
             )
         }
         "aarch64" => emit_aapcs_va_arg(bx, addr, target_ty),
+        "arm" => {
+            // Types wider than 16 bytes are not currently supported. Clang has special logic for
+            // such types, but `VaArgSafe` is not implemented for any type that is this large.
+            assert!(bx.cx.size_of(target_ty).bytes() <= 16);
+
+            emit_ptr_va_arg(
+                bx,
+                addr,
+                target_ty,
+                PassMode::Direct,
+                SlotSize::Bytes4,
+                AllowHigherAlign::Yes,
+                ForceRightAdjust::No,
+            )
+        }
         "s390x" => emit_s390x_va_arg(bx, addr, target_ty),
         "powerpc" => emit_powerpc_va_arg(bx, addr, target_ty),
         "powerpc64" | "powerpc64le" => emit_ptr_va_arg(
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 5f6976f5d00..6492ef73956 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -520,7 +520,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 LocalRef::Place(va_list) => {
                     bx.va_end(va_list.val.llval);
 
-                    // Explicitly end the lifetime of the `va_list`, this matters for LLVM.
+                    // Explicitly end the lifetime of the `va_list`, improves LLVM codegen.
                     bx.lifetime_end(va_list.val.llval, va_list.layout.size);
                 }
                 _ => bug!("C-variadic function must have a `VaList` place"),
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 06873313e2e..6b109e8b8e2 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -438,6 +438,10 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
             if fx.fn_abi.c_variadic && arg_index == fx.fn_abi.args.len() {
                 let va_list = PlaceRef::alloca(bx, bx.layout_of(arg_ty));
+
+                // Explicitly start the lifetime of the `va_list`, improves LLVM codegen.
+                bx.lifetime_start(va_list.val.llval, va_list.layout.size);
+
                 bx.va_start(va_list.val.llval);
 
                 return LocalRef::Place(va_list);
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index e4e4866b64c..ed8aa71d59d 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -940,11 +940,27 @@ fn extract_symbol_from_pnr<'a>(
         {
             Ok(*symbol)
         }
+        ParseNtResult::Literal(expr)
+            if let ExprKind::Lit(lit @ Lit { kind: LitKind::Integer, symbol, suffix }) =
+                &expr.kind =>
+        {
+            if lit.is_semantic_float() {
+                Err(dcx
+                    .struct_err("floats are not supported as metavariables of `${concat(..)}`")
+                    .with_span(span_err))
+            } else if suffix.is_none() {
+                Ok(*symbol)
+            } else {
+                Err(dcx
+                    .struct_err("integer metavariables of `${concat(..)}` must not be suffixed")
+                    .with_span(span_err))
+            }
+        }
         _ => Err(dcx
             .struct_err(
                 "metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`",
             )
-            .with_note("currently only string literals are supported")
+            .with_note("currently only string and integer literals are supported")
             .with_span(span_err)),
     }
 }
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 8af4740f376..95abe5c40dd 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -440,6 +440,43 @@ impl DefKind {
             | DefKind::ExternCrate => false,
         }
     }
+
+    /// Returns `true` if `self` is a kind of definition that does not have its own
+    /// type-checking context, i.e. closure, coroutine or inline const.
+    #[inline]
+    pub fn is_typeck_child(self) -> bool {
+        match self {
+            DefKind::Closure | DefKind::InlineConst | DefKind::SyntheticCoroutineBody => true,
+            DefKind::Mod
+            | DefKind::Struct
+            | DefKind::Union
+            | DefKind::Enum
+            | DefKind::Variant
+            | DefKind::Trait
+            | DefKind::TyAlias
+            | DefKind::ForeignTy
+            | DefKind::TraitAlias
+            | DefKind::AssocTy
+            | DefKind::TyParam
+            | DefKind::Fn
+            | DefKind::Const
+            | DefKind::ConstParam
+            | DefKind::Static { .. }
+            | DefKind::Ctor(_, _)
+            | DefKind::AssocFn
+            | DefKind::AssocConst
+            | DefKind::Macro(_)
+            | DefKind::ExternCrate
+            | DefKind::Use
+            | DefKind::ForeignMod
+            | DefKind::AnonConst
+            | DefKind::OpaqueTy
+            | DefKind::Field
+            | DefKind::LifetimeParam
+            | DefKind::GlobalAsm
+            | DefKind::Impl { .. } => false,
+        }
+    }
 }
 
 /// The resolution of a path or export.
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 2562ab7542a..6659aff7111 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -238,7 +238,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
             _ => (),
         }
         // Skip `AnonConst`s because we feed their `type_of`.
-        if !matches!(def_kind, DefKind::AnonConst) {
+        // Also skip items for which typeck forwards to parent typeck.
+        if !(matches!(def_kind, DefKind::AnonConst) || def_kind.is_typeck_child()) {
             tcx.ensure_ok().typeck(item_def_id);
         }
         // Ensure we generate the new `DefId` before finishing `check_crate`.
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 96fbdf44791..029586a9c55 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -608,10 +608,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Returns `true` if `def_id` refers to a definition that does not have its own
     /// type-checking context, i.e. closure, coroutine or inline const.
     pub fn is_typeck_child(self, def_id: DefId) -> bool {
-        matches!(
-            self.def_kind(def_id),
-            DefKind::Closure | DefKind::InlineConst | DefKind::SyntheticCoroutineBody
-        )
+        self.def_kind(def_id).is_typeck_child()
     }
 
     /// Returns `true` if `def_id` refers to a trait (i.e., `trait Foo { ... }`).
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 6168647183f..23aaafac934 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -92,10 +92,10 @@ fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
 }
 
 fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool {
-    // `Not`, `Tilde` & `Const` are deliberately not part of this list to
+    // `!`, `const`, `[`, `async` are deliberately not part of this list to
     // contain the number of potential regressions esp. in MBE code.
-    // `Const` would regress `rfc-2632-const-trait-impl/mbe-dyn-const-2015.rs`.
-    // `Not` would regress `dyn!(...)` macro calls in Rust 2015.
+    // `const` and `[` would regress UI test `macro-dyn-const-2015.rs`.
+    // `!` would regress `dyn!(...)` macro calls in Rust 2015.
     t.is_path_start()
         || t.is_lifetime()
         || t == &TokenKind::Question
@@ -1015,12 +1015,18 @@ impl<'a> Parser<'a> {
             || self.check(exp!(Tilde))
             || self.check_keyword(exp!(For))
             || self.check(exp!(OpenParen))
-            || self.check(exp!(OpenBracket))
+            || self.can_begin_maybe_const_bound()
             || self.check_keyword(exp!(Const))
             || self.check_keyword(exp!(Async))
             || self.check_keyword(exp!(Use))
     }
 
+    fn can_begin_maybe_const_bound(&mut self) -> bool {
+        self.check(exp!(OpenBracket))
+            && self.look_ahead(1, |t| t.is_keyword(kw::Const))
+            && self.look_ahead(2, |t| *t == token::CloseBracket)
+    }
+
     /// Parse a bound.
     ///
     /// ```ebnf
@@ -1199,10 +1205,7 @@ impl<'a> Parser<'a> {
             let span = tilde.to(self.prev_token.span);
             self.psess.gated_spans.gate(sym::const_trait_impl, span);
             BoundConstness::Maybe(span)
-        } else if self.check(exp!(OpenBracket))
-            && self.look_ahead(1, |t| t.is_keyword(kw::Const))
-            && self.look_ahead(2, |t| *t == token::CloseBracket)
-        {
+        } else if self.can_begin_maybe_const_bound() {
             let start = self.token.span;
             self.bump();
             self.expect_keyword(exp!(Const)).unwrap();
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index aedeb0e14ed..cdb0b5b58da 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -7,7 +7,7 @@ use std::ops::Deref;
 use std::{fmt, str};
 
 use rustc_arena::DroplessArena;
-use rustc_data_structures::fx::FxIndexSet;
+use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_data_structures::stable_hasher::{
     HashStable, StableCompare, StableHasher, ToStableHashKey,
 };
@@ -2871,11 +2871,20 @@ impl Interner {
         let byte_strs = FxIndexSet::from_iter(
             init.iter().copied().chain(extra.iter().copied()).map(|str| str.as_bytes()),
         );
-        assert_eq!(
-            byte_strs.len(),
-            init.len() + extra.len(),
-            "duplicate symbols in the rustc symbol list and the extra symbols added by the driver",
-        );
+
+        // The order in which duplicates are reported is irrelevant.
+        #[expect(rustc::potential_query_instability)]
+        if byte_strs.len() != init.len() + extra.len() {
+            panic!(
+                "duplicate symbols in the rustc symbol list and the extra symbols added by the driver: {:?}",
+                FxHashSet::intersection(
+                    &init.iter().copied().collect(),
+                    &extra.iter().copied().collect(),
+                )
+                .collect::<Vec<_>>()
+            )
+        }
+
         Interner(Lock::new(InternerInner { arena: Default::default(), byte_strs }))
     }
 
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 4c1b8c99426..dc70089c385 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -849,6 +849,7 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("miscellaneous-extensions-3", Unstable(sym::s390x_target_feature), &[]),
     ("miscellaneous-extensions-4", Unstable(sym::s390x_target_feature), &[]),
     ("nnp-assist", Unstable(sym::s390x_target_feature), &["vector"]),
+    ("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]),
     ("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
     ("vector", Unstable(sym::s390x_target_feature), &[]),
     ("vector-enhancements-1", Unstable(sym::s390x_target_feature), &["vector"]),
@@ -1177,6 +1178,13 @@ impl Target {
                     _ => unreachable!(),
                 }
             }
+            "s390x" => {
+                // We don't currently support a softfloat target on this architecture.
+                // As usual, we have to reject swapping the `soft-float` target feature.
+                // The "vector" target feature does not affect the ABI for floats
+                // because the vector and float registers overlap.
+                FeatureConstraints { required: &[], incompatible: &["soft-float"] }
+            }
             _ => NOTHING,
         }
     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index d71110521ff..e18e294635b 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -1618,18 +1618,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         {
             let e = self.tcx.erase_and_anonymize_regions(e);
             let f = self.tcx.erase_and_anonymize_regions(f);
-            let mut expected = with_forced_trimmed_paths!(e.sort_string(self.tcx));
-            let mut found = with_forced_trimmed_paths!(f.sort_string(self.tcx));
-            if let ObligationCauseCode::Pattern { span, .. } = cause.code()
-                && let Some(span) = span
-                && !span.from_expansion()
-                && cause.span.from_expansion()
-            {
-                // When the type error comes from a macro like `assert!()`, and we are pointing at
-                // code the user wrote the cause and effect are reversed as the expected value is
-                // what the macro expanded to.
-                (found, expected) = (expected, found);
-            }
+            let expected = with_forced_trimmed_paths!(e.sort_string(self.tcx));
+            let found = with_forced_trimmed_paths!(f.sort_string(self.tcx));
             if expected == found {
                 label_or_note(span, terr.to_string(self.tcx));
             } else {
@@ -2152,9 +2142,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     ) -> Option<(DiagStyledString, DiagStyledString)> {
         match values {
             ValuePairs::Regions(exp_found) => self.expected_found_str(exp_found),
-            ValuePairs::Terms(exp_found) => {
-                self.expected_found_str_term(cause, exp_found, long_ty_path)
-            }
+            ValuePairs::Terms(exp_found) => self.expected_found_str_term(exp_found, long_ty_path),
             ValuePairs::Aliases(exp_found) => self.expected_found_str(exp_found),
             ValuePairs::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found),
             ValuePairs::ExistentialProjection(exp_found) => self.expected_found_str(exp_found),
@@ -2193,7 +2181,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
     fn expected_found_str_term(
         &self,
-        cause: &ObligationCause<'tcx>,
         exp_found: ty::error::ExpectedFound<ty::Term<'tcx>>,
         long_ty_path: &mut Option<PathBuf>,
     ) -> Option<(DiagStyledString, DiagStyledString)> {
@@ -2201,27 +2188,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         if exp_found.references_error() {
             return None;
         }
-        let (mut expected, mut found) = (exp_found.expected, exp_found.found);
-
-        if let ObligationCauseCode::Pattern { span, .. } = cause.code()
-            && let Some(span) = span
-            && !span.from_expansion()
-            && cause.span.from_expansion()
-        {
-            // When the type error comes from a macro like `assert!()`, and we are pointing at
-            // code the user wrote, the cause and effect are reversed as the expected value is
-            // what the macro expanded to. So if the user provided a `Type` when the macro is
-            // written in such a way that a `bool` was expected, we want to print:
-            // = note: expected `bool`
-            //            found `Type`"
-            // but as far as the compiler is concerned, after expansion what was expected was `Type`
-            // = note: expected `Type`
-            //            found `bool`"
-            // so we reverse them here to match user expectation.
-            (expected, found) = (found, expected);
-        }
 
-        Some(match (expected.kind(), found.kind()) {
+        Some(match (exp_found.expected.kind(), exp_found.found.kind()) {
             (ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
                 let (mut exp, mut fnd) = self.cmp(expected, found);
                 // Use the terminal width as the basis to determine when to compress the printed
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index c5f0cb8016e..45109270944 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -146,28 +146,7 @@ impl<T: PointeeSized> *const T {
         self as _
     }
 
-    /// Gets the "address" portion of the pointer.
-    ///
-    /// This is similar to `self as usize`, except that the [provenance][crate::ptr#provenance] of
-    /// the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
-    /// casting the returned address back to a pointer yields a [pointer without
-    /// provenance][without_provenance], which is undefined behavior to dereference. To properly
-    /// restore the lost information and obtain a dereferenceable pointer, use
-    /// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
-    ///
-    /// If using those APIs is not possible because there is no way to preserve a pointer with the
-    /// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
-    /// or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
-    /// instead. However, note that this makes your code less portable and less amenable to tools
-    /// that check for compliance with the Rust memory model.
-    ///
-    /// On most platforms this will produce a value with the same bytes as the original
-    /// pointer, because all the bytes are dedicated to describing the address.
-    /// Platforms which need to store additional information in the pointer may
-    /// perform a change of representation to produce a value containing only the address
-    /// portion of the pointer. What that means is up to the platform to define.
-    ///
-    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
+    #[doc = include_str!("./docs/addr.md")]
     #[must_use]
     #[inline(always)]
     #[stable(feature = "strict_provenance", since = "1.84.0")]
@@ -254,23 +233,16 @@ impl<T: PointeeSized> *const T {
         (self.cast(), metadata(self))
     }
 
-    /// Returns `None` if the pointer is null, or else returns a shared reference to
-    /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
-    /// must be used instead.
-    ///
-    /// [`as_uninit_ref`]: #method.as_uninit_ref
-    ///
-    /// # Safety
-    ///
-    /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
+    #[doc = include_str!("./docs/as_ref.md")]
     ///
-    /// # Panics during const evaluation
-    ///
-    /// This method will panic during const evaluation if the pointer cannot be
-    /// determined to be null or not. See [`is_null`] for more information.
+    /// ```
+    /// let ptr: *const u8 = &10u8 as *const u8;
     ///
-    /// [`is_null`]: #method.is_null
+    /// unsafe {
+    ///     let val_back = &*ptr;
+    ///     assert_eq!(val_back, &10);
+    /// }
+    /// ```
     ///
     /// # Examples
     ///
@@ -284,20 +256,9 @@ impl<T: PointeeSized> *const T {
     /// }
     /// ```
     ///
-    /// # Null-unchecked version
     ///
-    /// If you are sure the pointer can never be null and are looking for some kind of
-    /// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
-    /// dereference the pointer directly.
-    ///
-    /// ```
-    /// let ptr: *const u8 = &10u8 as *const u8;
-    ///
-    /// unsafe {
-    ///     let val_back = &*ptr;
-    ///     assert_eq!(val_back, &10);
-    /// }
-    /// ```
+    /// [`is_null`]: #method.is_null
+    /// [`as_uninit_ref`]: #method.as_uninit_ref
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
     #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")]
     #[inline]
@@ -338,23 +299,10 @@ impl<T: PointeeSized> *const T {
         unsafe { &*self }
     }
 
-    /// Returns `None` if the pointer is null, or else returns a shared reference to
-    /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
-    /// that the value has to be initialized.
-    ///
-    /// [`as_ref`]: #method.as_ref
-    ///
-    /// # Safety
-    ///
-    /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
-    ///
-    /// # Panics during const evaluation
-    ///
-    /// This method will panic during const evaluation if the pointer cannot be
-    /// determined to be null or not. See [`is_null`] for more information.
+    #[doc = include_str!("./docs/as_uninit_ref.md")]
     ///
     /// [`is_null`]: #method.is_null
+    /// [`as_ref`]: #method.as_ref
     ///
     /// # Examples
     ///
diff --git a/library/core/src/ptr/docs/INFO.md b/library/core/src/ptr/docs/INFO.md
new file mode 100644
index 00000000000..28a0da4926a
--- /dev/null
+++ b/library/core/src/ptr/docs/INFO.md
@@ -0,0 +1,21 @@
+This directory holds method documentation that otherwise
+would be duplicated across mutable and immutable pointers.
+
+Note that most of the docs here are not the complete docs
+for their corresponding method. This is for a few reasons:
+
+1. Examples need to be different for mutable/immutable
+   pointers, in order to actually call the correct method.
+2. Link reference definitions are frequently different
+   between mutable/immutable pointers, in order to link to
+   the correct method.
+   For example, `<*const T>::as_ref` links to
+   `<*const T>::is_null`, while `<*mut T>::as_ref` links to
+   `<*mut T>::is_null`.
+3. Many methods on mutable pointers link to an alternate
+   version that returns a mutable reference instead of
+   a shared reference.
+
+Always review the rendered docs manually when making
+changes to these files to make sure you're not accidentally
+splitting up a section.
diff --git a/library/core/src/ptr/docs/addr.md b/library/core/src/ptr/docs/addr.md
new file mode 100644
index 00000000000..785b88a9987
--- /dev/null
+++ b/library/core/src/ptr/docs/addr.md
@@ -0,0 +1,22 @@
+Gets the "address" portion of the pointer.
+
+This is similar to `self as usize`, except that the [provenance][crate::ptr#provenance] of
+the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
+casting the returned address back to a pointer yields a [pointer without
+provenance][without_provenance], which is undefined behavior to dereference. To properly
+restore the lost information and obtain a dereferenceable pointer, use
+[`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
+
+If using those APIs is not possible because there is no way to preserve a pointer with the
+required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
+or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
+instead. However, note that this makes your code less portable and less amenable to tools
+that check for compliance with the Rust memory model.
+
+On most platforms this will produce a value with the same bytes as the original
+pointer, because all the bytes are dedicated to describing the address.
+Platforms which need to store additional information in the pointer may
+perform a change of representation to produce a value containing only the address
+portion of the pointer. What that means is up to the platform to define.
+
+This is a [Strict Provenance][crate::ptr#strict-provenance] API.
diff --git a/library/core/src/ptr/docs/as_ref.md b/library/core/src/ptr/docs/as_ref.md
new file mode 100644
index 00000000000..0c0d2768c74
--- /dev/null
+++ b/library/core/src/ptr/docs/as_ref.md
@@ -0,0 +1,19 @@
+Returns `None` if the pointer is null, or else returns a shared reference to
+the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
+must be used instead.
+
+# Safety
+
+When calling this method, you have to ensure that *either* the pointer is null *or*
+the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
+
+# Panics during const evaluation
+
+This method will panic during const evaluation if the pointer cannot be
+determined to be null or not. See [`is_null`] for more information.
+
+# Null-unchecked version
+
+If you are sure the pointer can never be null and are looking for some kind of
+`as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
+dereference the pointer directly.
diff --git a/library/core/src/ptr/docs/as_uninit_ref.md b/library/core/src/ptr/docs/as_uninit_ref.md
new file mode 100644
index 00000000000..5b9a1ecb85b
--- /dev/null
+++ b/library/core/src/ptr/docs/as_uninit_ref.md
@@ -0,0 +1,15 @@
+Returns `None` if the pointer is null, or else returns a shared reference to
+the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
+that the value has to be initialized.
+
+# Safety
+
+When calling this method, you have to ensure that *either* the pointer is null *or*
+the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
+Note that because the created reference is to `MaybeUninit<T>`, the
+source pointer can point to uninitialized memory.
+
+# Panics during const evaluation
+
+This method will panic during const evaluation if the pointer cannot be
+determined to be null or not. See [`is_null`] for more information.
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index ce6eee4f911..ba78afc7ea1 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -135,28 +135,9 @@ impl<T: PointeeSized> *mut T {
         self as _
     }
 
-    /// Gets the "address" portion of the pointer.
-    ///
-    /// This is similar to `self as usize`, except that the [provenance][crate::ptr#provenance] of
-    /// the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
-    /// casting the returned address back to a pointer yields a [pointer without
-    /// provenance][without_provenance_mut], which is undefined behavior to dereference. To properly
-    /// restore the lost information and obtain a dereferenceable pointer, use
-    /// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
-    ///
-    /// If using those APIs is not possible because there is no way to preserve a pointer with the
-    /// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
-    /// or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
-    /// instead. However, note that this makes your code less portable and less amenable to tools
-    /// that check for compliance with the Rust memory model.
-    ///
-    /// On most platforms this will produce a value with the same bytes as the original
-    /// pointer, because all the bytes are dedicated to describing the address.
-    /// Platforms which need to store additional information in the pointer may
-    /// perform a change of representation to produce a value containing only the address
-    /// portion of the pointer. What that means is up to the platform to define.
+    #[doc = include_str!("./docs/addr.md")]
     ///
-    /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
+    /// [without_provenance]: without_provenance_mut
     #[must_use]
     #[inline(always)]
     #[stable(feature = "strict_provenance", since = "1.84.0")]
@@ -243,26 +224,16 @@ impl<T: PointeeSized> *mut T {
         (self.cast(), super::metadata(self))
     }
 
-    /// Returns `None` if the pointer is null, or else returns a shared reference to
-    /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
-    /// must be used instead.
-    ///
-    /// For the mutable counterpart see [`as_mut`].
+    #[doc = include_str!("./docs/as_ref.md")]
     ///
-    /// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1
-    /// [`as_mut`]: #method.as_mut
-    ///
-    /// # Safety
-    ///
-    /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
-    ///
-    /// # Panics during const evaluation
-    ///
-    /// This method will panic during const evaluation if the pointer cannot be
-    /// determined to be null or not. See [`is_null`] for more information.
+    /// ```
+    /// let ptr: *mut u8 = &mut 10u8 as *mut u8;
     ///
-    /// [`is_null`]: #method.is_null-1
+    /// unsafe {
+    ///     let val_back = &*ptr;
+    ///     println!("We got back the value: {val_back}!");
+    /// }
+    /// ```
     ///
     /// # Examples
     ///
@@ -276,20 +247,14 @@ impl<T: PointeeSized> *mut T {
     /// }
     /// ```
     ///
-    /// # Null-unchecked version
-    ///
-    /// If you are sure the pointer can never be null and are looking for some kind of
-    /// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
-    /// dereference the pointer directly.
+    /// # See Also
     ///
-    /// ```
-    /// let ptr: *mut u8 = &mut 10u8 as *mut u8;
+    /// For the mutable counterpart see [`as_mut`].
     ///
-    /// unsafe {
-    ///     let val_back = &*ptr;
-    ///     println!("We got back the value: {val_back}!");
-    /// }
-    /// ```
+    /// [`is_null`]: #method.is_null-1
+    /// [`as_uninit_ref`]: pointer#method.as_uninit_ref-1
+    /// [`as_mut`]: #method.as_mut
+
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
     #[rustc_const_stable(feature = "const_ptr_is_null", since = "1.84.0")]
     #[inline]
@@ -332,28 +297,15 @@ impl<T: PointeeSized> *mut T {
         unsafe { &*self }
     }
 
-    /// Returns `None` if the pointer is null, or else returns a shared reference to
-    /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
-    /// that the value has to be initialized.
-    ///
-    /// For the mutable counterpart see [`as_uninit_mut`].
+    #[doc = include_str!("./docs/as_uninit_ref.md")]
     ///
+    /// [`is_null`]: #method.is_null-1
     /// [`as_ref`]: pointer#method.as_ref-1
-    /// [`as_uninit_mut`]: #method.as_uninit_mut
-    ///
-    /// # Safety
-    ///
-    /// When calling this method, you have to ensure that *either* the pointer is null *or*
-    /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
-    /// Note that because the created reference is to `MaybeUninit<T>`, the
-    /// source pointer can point to uninitialized memory.
-    ///
-    /// # Panics during const evaluation
     ///
-    /// This method will panic during const evaluation if the pointer cannot be
-    /// determined to be null or not. See [`is_null`] for more information.
+    /// # See Also
+    /// For the mutable counterpart see [`as_uninit_mut`].
     ///
-    /// [`is_null`]: #method.is_null-1
+    /// [`as_uninit_mut`]: #method.as_uninit_mut
     ///
     /// # Examples
     ///
diff --git a/library/coretests/tests/array.rs b/library/coretests/tests/array.rs
index 30ccbbc3203..c4a8fc74fec 100644
--- a/library/coretests/tests/array.rs
+++ b/library/coretests/tests/array.rs
@@ -717,3 +717,10 @@ fn array_map_drops_unmapped_elements_on_panic() {
         assert_eq!(counter.load(Ordering::SeqCst), MAX);
     }
 }
+
+// This covers the `PartialEq::<[T]>::eq` impl for `[T; N]` when it returns false.
+#[test]
+fn array_eq() {
+    let not_true = [0u8] == [].as_slice();
+    assert!(!not_true);
+}
diff --git a/library/coretests/tests/floats/f128.rs b/library/coretests/tests/floats/f128.rs
index 4267fef50f8..d31eba863f5 100644
--- a/library/coretests/tests/floats/f128.rs
+++ b/library/coretests/tests/floats/f128.rs
@@ -17,12 +17,6 @@ const TOL: f128 = 1e-12;
 #[allow(unused)]
 const TOL_PRECISE: f128 = 1e-28;
 
-/// First pattern over the mantissa
-const NAN_MASK1: u128 = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa;
-
-/// Second pattern over the mantissa
-const NAN_MASK2: u128 = 0x00005555555555555555555555555555;
-
 // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support
 // the intrinsics.
 
@@ -55,28 +49,6 @@ fn test_max_recip() {
 }
 
 #[test]
-fn test_float_bits_conv() {
-    assert_eq!((1f128).to_bits(), 0x3fff0000000000000000000000000000);
-    assert_eq!((12.5f128).to_bits(), 0x40029000000000000000000000000000);
-    assert_eq!((1337f128).to_bits(), 0x40094e40000000000000000000000000);
-    assert_eq!((-14.25f128).to_bits(), 0xc002c800000000000000000000000000);
-    assert_biteq!(f128::from_bits(0x3fff0000000000000000000000000000), 1.0);
-    assert_biteq!(f128::from_bits(0x40029000000000000000000000000000), 12.5);
-    assert_biteq!(f128::from_bits(0x40094e40000000000000000000000000), 1337.0);
-    assert_biteq!(f128::from_bits(0xc002c800000000000000000000000000), -14.25);
-
-    // Check that NaNs roundtrip their bits regardless of signaling-ness
-    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
-    let masked_nan1 = f128::NAN.to_bits() ^ NAN_MASK1;
-    let masked_nan2 = f128::NAN.to_bits() ^ NAN_MASK2;
-    assert!(f128::from_bits(masked_nan1).is_nan());
-    assert!(f128::from_bits(masked_nan2).is_nan());
-
-    assert_eq!(f128::from_bits(masked_nan1).to_bits(), masked_nan1);
-    assert_eq!(f128::from_bits(masked_nan2).to_bits(), masked_nan2);
-}
-
-#[test]
 fn test_from() {
     assert_biteq!(f128::from(false), 0.0);
     assert_biteq!(f128::from(true), 1.0);
diff --git a/library/coretests/tests/floats/f16.rs b/library/coretests/tests/floats/f16.rs
index d2818a6d768..302fd0861d7 100644
--- a/library/coretests/tests/floats/f16.rs
+++ b/library/coretests/tests/floats/f16.rs
@@ -19,12 +19,6 @@ const TOL_P2: f16 = 0.5;
 #[allow(unused)]
 const TOL_P4: f16 = 10.0;
 
-/// First pattern over the mantissa
-const NAN_MASK1: u16 = 0x02aa;
-
-/// Second pattern over the mantissa
-const NAN_MASK2: u16 = 0x0155;
-
 // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support
 // the intrinsics.
 
@@ -53,27 +47,6 @@ fn test_max_recip() {
 }
 
 #[test]
-fn test_float_bits_conv() {
-    assert_eq!((1f16).to_bits(), 0x3c00);
-    assert_eq!((12.5f16).to_bits(), 0x4a40);
-    assert_eq!((1337f16).to_bits(), 0x6539);
-    assert_eq!((-14.25f16).to_bits(), 0xcb20);
-    assert_biteq!(f16::from_bits(0x3c00), 1.0);
-    assert_biteq!(f16::from_bits(0x4a40), 12.5);
-    assert_biteq!(f16::from_bits(0x6539), 1337.0);
-    assert_biteq!(f16::from_bits(0xcb20), -14.25);
-
-    // Check that NaNs roundtrip their bits regardless of signaling-ness
-    let masked_nan1 = f16::NAN.to_bits() ^ NAN_MASK1;
-    let masked_nan2 = f16::NAN.to_bits() ^ NAN_MASK2;
-    assert!(f16::from_bits(masked_nan1).is_nan());
-    assert!(f16::from_bits(masked_nan2).is_nan());
-
-    assert_eq!(f16::from_bits(masked_nan1).to_bits(), masked_nan1);
-    assert_eq!(f16::from_bits(masked_nan2).to_bits(), masked_nan2);
-}
-
-#[test]
 fn test_from() {
     assert_biteq!(f16::from(false), 0.0);
     assert_biteq!(f16::from(true), 1.0);
diff --git a/library/coretests/tests/floats/f32.rs b/library/coretests/tests/floats/f32.rs
index 7b25f354da4..a1fe8b07650 100644
--- a/library/coretests/tests/floats/f32.rs
+++ b/library/coretests/tests/floats/f32.rs
@@ -2,12 +2,6 @@ use core::f32;
 
 use super::assert_biteq;
 
-/// First pattern over the mantissa
-const NAN_MASK1: u32 = 0x002a_aaaa;
-
-/// Second pattern over the mantissa
-const NAN_MASK2: u32 = 0x0055_5555;
-
 // FIXME(#140515): mingw has an incorrect fma https://sourceforge.net/p/mingw-w64/bugs/848/
 #[cfg_attr(all(target_os = "windows", target_env = "gnu", not(target_abi = "llvm")), ignore)]
 #[test]
@@ -25,25 +19,3 @@ fn test_mul_add() {
     assert_biteq!(f32::math::mul_add(8.9f32, inf, 3.2), inf);
     assert_biteq!(f32::math::mul_add(-3.2f32, 2.4, neg_inf), neg_inf);
 }
-
-#[test]
-fn test_float_bits_conv() {
-    assert_eq!((1f32).to_bits(), 0x3f800000);
-    assert_eq!((12.5f32).to_bits(), 0x41480000);
-    assert_eq!((1337f32).to_bits(), 0x44a72000);
-    assert_eq!((-14.25f32).to_bits(), 0xc1640000);
-    assert_biteq!(f32::from_bits(0x3f800000), 1.0);
-    assert_biteq!(f32::from_bits(0x41480000), 12.5);
-    assert_biteq!(f32::from_bits(0x44a72000), 1337.0);
-    assert_biteq!(f32::from_bits(0xc1640000), -14.25);
-
-    // Check that NaNs roundtrip their bits regardless of signaling-ness
-    // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
-    let masked_nan1 = f32::NAN.to_bits() ^ NAN_MASK1;
-    let masked_nan2 = f32::NAN.to_bits() ^ NAN_MASK2;
-    assert!(f32::from_bits(masked_nan1).is_nan());
-    assert!(f32::from_bits(masked_nan2).is_nan());
-
-    assert_eq!(f32::from_bits(masked_nan1).to_bits(), masked_nan1);
-    assert_eq!(f32::from_bits(masked_nan2).to_bits(), masked_nan2);
-}
diff --git a/library/coretests/tests/floats/f64.rs b/library/coretests/tests/floats/f64.rs
index 099d85627a3..4c5a3d68d1f 100644
--- a/library/coretests/tests/floats/f64.rs
+++ b/library/coretests/tests/floats/f64.rs
@@ -2,12 +2,6 @@ use core::f64;
 
 use super::assert_biteq;
 
-/// First pattern over the mantissa
-const NAN_MASK1: u64 = 0x000a_aaaa_aaaa_aaaa;
-
-/// Second pattern over the mantissa
-const NAN_MASK2: u64 = 0x0005_5555_5555_5555;
-
 // FIXME(#140515): mingw has an incorrect fma https://sourceforge.net/p/mingw-w64/bugs/848/
 #[cfg_attr(all(target_os = "windows", target_env = "gnu", not(target_abi = "llvm")), ignore)]
 #[test]
@@ -25,24 +19,3 @@ fn test_mul_add() {
     assert_biteq!(8.9f64.mul_add(inf, 3.2), inf);
     assert_biteq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf);
 }
-
-#[test]
-fn test_float_bits_conv() {
-    assert_eq!((1f64).to_bits(), 0x3ff0000000000000);
-    assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
-    assert_eq!((1337f64).to_bits(), 0x4094e40000000000);
-    assert_eq!((-14.25f64).to_bits(), 0xc02c800000000000);
-    assert_biteq!(f64::from_bits(0x3ff0000000000000), 1.0);
-    assert_biteq!(f64::from_bits(0x4029000000000000), 12.5);
-    assert_biteq!(f64::from_bits(0x4094e40000000000), 1337.0);
-    assert_biteq!(f64::from_bits(0xc02c800000000000), -14.25);
-
-    // Check that NaNs roundtrip their bits regardless of signaling-ness
-    let masked_nan1 = f64::NAN.to_bits() ^ NAN_MASK1;
-    let masked_nan2 = f64::NAN.to_bits() ^ NAN_MASK2;
-    assert!(f64::from_bits(masked_nan1).is_nan());
-    assert!(f64::from_bits(masked_nan2).is_nan());
-
-    assert_eq!(f64::from_bits(masked_nan1).to_bits(), masked_nan1);
-    assert_eq!(f64::from_bits(masked_nan2).to_bits(), masked_nan2);
-}
diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs
index c0439845a4a..31515561c63 100644
--- a/library/coretests/tests/floats/mod.rs
+++ b/library/coretests/tests/floats/mod.rs
@@ -30,6 +30,10 @@ trait TestableFloat: Sized {
     const EPS_ADD: Self;
     const EPS_MUL: Self;
     const EPS_DIV: Self;
+    const RAW_1: Self;
+    const RAW_12_DOT_5: Self;
+    const RAW_1337: Self;
+    const RAW_MINUS_14_DOT_25: Self;
 }
 
 impl TestableFloat for f16 {
@@ -50,6 +54,10 @@ impl TestableFloat for f16 {
     const EPS_ADD: Self = if cfg!(miri) { 1e1 } else { 0.0 };
     const EPS_MUL: Self = if cfg!(miri) { 1e3 } else { 0.0 };
     const EPS_DIV: Self = if cfg!(miri) { 1e0 } else { 0.0 };
+    const RAW_1: Self = Self::from_bits(0x3c00);
+    const RAW_12_DOT_5: Self = Self::from_bits(0x4a40);
+    const RAW_1337: Self = Self::from_bits(0x6539);
+    const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xcb20);
 }
 
 impl TestableFloat for f32 {
@@ -72,6 +80,10 @@ impl TestableFloat for f32 {
     const EPS_ADD: Self = if cfg!(miri) { 1e-3 } else { 0.0 };
     const EPS_MUL: Self = if cfg!(miri) { 1e-1 } else { 0.0 };
     const EPS_DIV: Self = if cfg!(miri) { 1e-4 } else { 0.0 };
+    const RAW_1: Self = Self::from_bits(0x3f800000);
+    const RAW_12_DOT_5: Self = Self::from_bits(0x41480000);
+    const RAW_1337: Self = Self::from_bits(0x44a72000);
+    const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc1640000);
 }
 
 impl TestableFloat for f64 {
@@ -90,6 +102,10 @@ impl TestableFloat for f64 {
     const EPS_ADD: Self = if cfg!(miri) { 1e-6 } else { 0.0 };
     const EPS_MUL: Self = if cfg!(miri) { 1e-6 } else { 0.0 };
     const EPS_DIV: Self = if cfg!(miri) { 1e-6 } else { 0.0 };
+    const RAW_1: Self = Self::from_bits(0x3ff0000000000000);
+    const RAW_12_DOT_5: Self = Self::from_bits(0x4029000000000000);
+    const RAW_1337: Self = Self::from_bits(0x4094e40000000000);
+    const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc02c800000000000);
 }
 
 impl TestableFloat for f128 {
@@ -108,6 +124,10 @@ impl TestableFloat for f128 {
     const EPS_ADD: Self = if cfg!(miri) { 1e-6 } else { 0.0 };
     const EPS_MUL: Self = if cfg!(miri) { 1e-6 } else { 0.0 };
     const EPS_DIV: Self = if cfg!(miri) { 1e-6 } else { 0.0 };
+    const RAW_1: Self = Self::from_bits(0x3fff0000000000000000000000000000);
+    const RAW_12_DOT_5: Self = Self::from_bits(0x40029000000000000000000000000000);
+    const RAW_1337: Self = Self::from_bits(0x40094e40000000000000000000000000);
+    const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc002c800000000000000000000000000);
 }
 
 /// Determine the tolerance for values of the argument type.
@@ -250,6 +270,8 @@ macro_rules! float_test {
             $( $( #[$f16_meta] )+ )?
             fn test_f16() {
                 type $fty = f16;
+                #[allow(unused)]
+                const fn flt (x: $fty) -> $fty { x }
                 $test
             }
 
@@ -257,6 +279,8 @@ macro_rules! float_test {
             $( $( #[$f32_meta] )+ )?
             fn test_f32() {
                 type $fty = f32;
+                #[allow(unused)]
+                const fn flt (x: $fty) -> $fty { x }
                 $test
             }
 
@@ -264,6 +288,8 @@ macro_rules! float_test {
             $( $( #[$f64_meta] )+ )?
             fn test_f64() {
                 type $fty = f64;
+                #[allow(unused)]
+                const fn flt (x: $fty) -> $fty { x }
                 $test
             }
 
@@ -271,6 +297,8 @@ macro_rules! float_test {
             $( $( #[$f128_meta] )+ )?
             fn test_f128() {
                 type $fty = f128;
+                #[allow(unused)]
+                const fn flt (x: $fty) -> $fty { x }
                 $test
             }
 
@@ -293,6 +321,8 @@ macro_rules! float_test {
                 $( $( #[$f16_const_meta] )+ )?
                 fn test_f16() {
                     type $fty = f16;
+                    #[allow(unused)]
+                    const fn flt (x: $fty) -> $fty { x }
                     const { $test }
                 }
 
@@ -300,6 +330,8 @@ macro_rules! float_test {
                 $( $( #[$f32_const_meta] )+ )?
                 fn test_f32() {
                     type $fty = f32;
+                    #[allow(unused)]
+                    const fn flt (x: $fty) -> $fty { x }
                     const { $test }
                 }
 
@@ -307,6 +339,8 @@ macro_rules! float_test {
                 $( $( #[$f64_const_meta] )+ )?
                 fn test_f64() {
                     type $fty = f64;
+                    #[allow(unused)]
+                    const fn flt (x: $fty) -> $fty { x }
                     const { $test }
                 }
 
@@ -314,6 +348,8 @@ macro_rules! float_test {
                 $( $( #[$f128_const_meta] )+ )?
                 fn test_f128() {
                     type $fty = f128;
+                    #[allow(unused)]
+                    const fn flt (x: $fty) -> $fty { x }
                     const { $test }
                 }
             }
@@ -1479,3 +1515,30 @@ float_test! {
         assert_approx_eq!(a.algebraic_rem(b), a % b, Float::EPS_DIV);
     }
 }
+
+float_test! {
+    name: to_bits_conv,
+    attrs: {
+        f16: #[cfg(target_has_reliable_f16)],
+        f128: #[cfg(target_has_reliable_f128)],
+    },
+    test<Float> {
+        assert_biteq!(flt(1.0), Float::RAW_1);
+        assert_biteq!(flt(12.5), Float::RAW_12_DOT_5);
+        assert_biteq!(flt(1337.0), Float::RAW_1337);
+        assert_biteq!(flt(-14.25), Float::RAW_MINUS_14_DOT_25);
+        assert_biteq!(Float::RAW_1, 1.0);
+        assert_biteq!(Float::RAW_12_DOT_5, 12.5);
+        assert_biteq!(Float::RAW_1337, 1337.0);
+        assert_biteq!(Float::RAW_MINUS_14_DOT_25, -14.25);
+
+        // Check that NaNs roundtrip their bits regardless of signaling-ness
+        let masked_nan1 = Float::NAN.to_bits() ^ Float::NAN_MASK1;
+        let masked_nan2 = Float::NAN.to_bits() ^ Float::NAN_MASK2;
+        assert!(Float::from_bits(masked_nan1).is_nan());
+        assert!(Float::from_bits(masked_nan2).is_nan());
+
+        assert_biteq!(Float::from_bits(masked_nan1), Float::from_bits(masked_nan1));
+        assert_biteq!(Float::from_bits(masked_nan2), Float::from_bits(masked_nan2));
+    }
+}
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index b5658a9970f..1bdaa6965f6 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -81,6 +81,7 @@
 #![feature(next_index)]
 #![feature(non_exhaustive_omitted_patterns_lint)]
 #![feature(numfmt)]
+#![feature(one_sided_range)]
 #![feature(option_reduce)]
 #![feature(pattern)]
 #![feature(peekable_next_if_map)]
diff --git a/library/coretests/tests/ops.rs b/library/coretests/tests/ops.rs
index 501e0f33fe4..121718f2167 100644
--- a/library/coretests/tests/ops.rs
+++ b/library/coretests/tests/ops.rs
@@ -2,7 +2,8 @@ mod control_flow;
 mod from_residual;
 
 use core::ops::{
-    Bound, Deref, DerefMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
+    Bound, Deref, DerefMut, OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeFrom,
+    RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
 };
 
 // Test the Range structs and syntax.
@@ -71,6 +72,36 @@ fn test_range_to_inclusive() {
 }
 
 #[test]
+fn test_range_contains() {
+    assert!(!(1u32..5).contains(&0u32));
+    assert!((1u32..5).contains(&1u32));
+    assert!((1u32..5).contains(&4u32));
+    assert!(!(1u32..5).contains(&5u32));
+    assert!(!(1u32..5).contains(&6u32));
+}
+
+#[test]
+fn test_range_to_contains() {
+    assert!(!(1u32..=5).contains(&0));
+    assert!((1u32..=5).contains(&1));
+    assert!((1u32..=5).contains(&4));
+    assert!((1u32..=5).contains(&5));
+    assert!(!(1u32..=5).contains(&6));
+}
+
+// This test covers `RangeBounds::contains` when the start is excluded,
+// which cannot be directly expressed by Rust's built-in range syntax.
+#[test]
+fn test_range_bounds_contains() {
+    let r = (Bound::Excluded(1u32), Bound::Included(5u32));
+    assert!(!r.contains(&0));
+    assert!(!r.contains(&1));
+    assert!(r.contains(&3));
+    assert!(r.contains(&5));
+    assert!(!r.contains(&6));
+}
+
+#[test]
 fn test_range_is_empty() {
     assert!(!(0.0..10.0).is_empty());
     assert!((-0.0..0.0).is_empty());
@@ -92,6 +123,34 @@ fn test_range_is_empty() {
 }
 
 #[test]
+fn test_range_inclusive_end_bound() {
+    let mut r = 1u32..=1;
+    r.next().unwrap();
+    assert!(!r.contains(&1));
+}
+
+#[test]
+fn test_range_bounds() {
+    let r = (Bound::Included(1u32), Bound::Excluded(5u32));
+    assert!(!r.contains(&0));
+    assert!(r.contains(&1));
+    assert!(r.contains(&3));
+    assert!(!r.contains(&5));
+    assert!(!r.contains(&6));
+
+    let r = (Bound::<u32>::Unbounded, Bound::Unbounded);
+    assert!(r.contains(&0));
+    assert!(r.contains(&u32::MAX));
+}
+
+#[test]
+fn test_one_sided_range_bound() {
+    assert!(matches!((..1u32).bound(), (OneSidedRangeBound::End, 1)));
+    assert!(matches!((1u32..).bound(), (OneSidedRangeBound::StartInclusive, 1)));
+    assert!(matches!((..=1u32).bound(), (OneSidedRangeBound::EndInclusive, 1)));
+}
+
+#[test]
 fn test_bound_cloned_unbounded() {
     assert_eq!(Bound::<&u32>::Unbounded.cloned(), Bound::Unbounded);
 }
@@ -240,3 +299,17 @@ fn deref_on_ref() {
 fn test_not_never() {
     if !return () {}
 }
+
+#[test]
+fn test_fmt() {
+    let mut r = 1..=1;
+    assert_eq!(format!("{:?}", r), "1..=1");
+    r.next().unwrap();
+    assert_eq!(format!("{:?}", r), "1..=1 (exhausted)");
+
+    assert_eq!(format!("{:?}", 1..1), "1..1");
+    assert_eq!(format!("{:?}", 1..), "1..");
+    assert_eq!(format!("{:?}", ..1), "..1");
+    assert_eq!(format!("{:?}", ..=1), "..=1");
+    assert_eq!(format!("{:?}", ..), "..");
+}
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 8c115015580..2dbdc8a4e02 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -31,6 +31,7 @@ pub mod process;
 pub mod random;
 pub mod stdio;
 pub mod sync;
+pub mod thread;
 pub mod thread_local;
 
 // FIXME(117276): remove this, move feature implementations into individual
diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs
index f49821657d9..5200eaa5786 100644
--- a/library/std/src/sys/net/connection/socket/hermit.rs
+++ b/library/std/src/sys/net/connection/socket/hermit.rs
@@ -304,7 +304,8 @@ impl Socket {
     }
 
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        unimplemented!()
+        let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
+        if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
     }
 
     // This is used by sys_common code to abstract over Windows and Unix.
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index fb8d69b7375..3ddf6e5acb0 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -25,7 +25,6 @@ pub mod futex;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-pub mod thread;
 pub mod time;
 
 pub fn unsupported<T>() -> crate::io::Result<T> {
diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs
index 0fe713a503b..9681964ed9b 100644
--- a/library/std/src/sys/pal/hermit/os.rs
+++ b/library/std/src/sys/pal/hermit/os.rs
@@ -3,7 +3,7 @@ use crate::ffi::{OsStr, OsString};
 use crate::marker::PhantomData;
 use crate::path::{self, PathBuf};
 use crate::sys::unsupported;
-use crate::{fmt, io, str};
+use crate::{fmt, io};
 
 pub fn errno() -> i32 {
     unsafe { hermit_abi::get_errno() }
diff --git a/library/std/src/sys/pal/sgx/abi/mod.rs b/library/std/src/sys/pal/sgx/abi/mod.rs
index 57247cffad3..b8c4d7740c4 100644
--- a/library/std/src/sys/pal/sgx/abi/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/mod.rs
@@ -67,7 +67,7 @@ extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64
     let tls_guard = unsafe { tls.activate() };
 
     if secondary {
-        let join_notifier = super::thread::Thread::entry();
+        let join_notifier = crate::sys::thread::Thread::entry();
         drop(tls_guard);
         drop(join_notifier);
 
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
index 4a297b6823f..9a33873af58 100644
--- a/library/std/src/sys/pal/sgx/mod.rs
+++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -13,7 +13,6 @@ mod libunwind_integration;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-pub mod thread;
 pub mod thread_parking;
 pub mod time;
 pub mod waitqueue;
diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs
index 0011cf256df..9ca6dc58118 100644
--- a/library/std/src/sys/pal/solid/mod.rs
+++ b/library/std/src/sys/pal/solid/mod.rs
@@ -10,10 +10,8 @@ pub mod itron {
     pub mod error;
     pub mod spin;
     pub mod task;
-    pub mod thread;
     pub mod thread_parking;
     pub mod time;
-    use super::unsupported;
 }
 
 // `error` is `pub(crate)` so that it can be accessed by `itron/error.rs` as
@@ -22,7 +20,7 @@ pub(crate) mod error;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-pub use self::itron::{thread, thread_parking};
+pub use self::itron::thread_parking;
 pub mod time;
 
 // SAFETY: must be called only once during runtime initialization.
diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs
index c7b17777258..dd0155265da 100644
--- a/library/std/src/sys/pal/teeos/mod.rs
+++ b/library/std/src/sys/pal/teeos/mod.rs
@@ -9,7 +9,6 @@
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-pub mod thread;
 #[allow(non_upper_case_globals)]
 #[path = "../unix/time.rs"]
 pub mod time;
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index 8911a2ee519..ebd311db1e1 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -17,7 +17,6 @@ pub mod helpers;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-pub mod thread;
 pub mod time;
 
 #[cfg(test)]
diff --git a/library/std/src/sys/pal/uefi/thread.rs b/library/std/src/sys/pal/uefi/thread.rs
deleted file mode 100644
index 47a48008c76..00000000000
--- a/library/std/src/sys/pal/uefi/thread.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-use super::unsupported;
-use crate::ffi::CStr;
-use crate::io;
-use crate::num::NonZero;
-use crate::ptr::NonNull;
-use crate::time::{Duration, Instant};
-
-pub struct Thread(!);
-
-pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024;
-
-impl Thread {
-    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(
-        _stack: usize,
-        _name: Option<&str>,
-        _p: Box<dyn FnOnce()>,
-    ) -> io::Result<Thread> {
-        unsupported()
-    }
-
-    pub fn yield_now() {
-        // do nothing
-    }
-
-    pub fn set_name(_name: &CStr) {
-        // nope
-    }
-
-    pub fn sleep(dur: Duration) {
-        let boot_services: NonNull<r_efi::efi::BootServices> =
-            crate::os::uefi::env::boot_services().expect("can't sleep").cast();
-        let mut dur_ms = dur.as_micros();
-        // ceil up to the nearest microsecond
-        if dur.subsec_nanos() % 1000 > 0 {
-            dur_ms += 1;
-        }
-
-        while dur_ms > 0 {
-            let ms = crate::cmp::min(dur_ms, usize::MAX as u128);
-            let _ = unsafe { ((*boot_services.as_ptr()).stall)(ms as usize) };
-            dur_ms -= ms;
-        }
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
-    pub fn join(self) {
-        self.0
-    }
-}
-
-pub(crate) fn current_os_id() -> Option<u64> {
-    None
-}
-
-pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    // UEFI is single threaded
-    Ok(NonZero::new(1).unwrap())
-}
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index ac5c823a1bf..dd1059fe04a 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -17,7 +17,6 @@ pub mod os;
 pub mod pipe;
 pub mod stack_overflow;
 pub mod sync;
-pub mod thread;
 pub mod thread_parking;
 pub mod time;
 
@@ -55,7 +54,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
     // thread-id for the main thread and so renaming the main thread will rename the
     // process and we only want to enable this on platforms we've tested.
     if cfg!(target_vendor = "apple") {
-        thread::Thread::set_name(&c"main");
+        crate::sys::thread::set_name(c"main");
     }
 
     unsafe fn sanitize_standard_fds() {
diff --git a/library/std/src/sys/pal/wasip1/mod.rs b/library/std/src/sys/pal/wasip1/mod.rs
index 61dd1c3f98b..ae5da3c1f77 100644
--- a/library/std/src/sys/pal/wasip1/mod.rs
+++ b/library/std/src/sys/pal/wasip1/mod.rs
@@ -20,7 +20,6 @@ pub mod futex;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-pub mod thread;
 pub mod time;
 
 #[path = "../unsupported/common.rs"]
diff --git a/library/std/src/sys/pal/wasip1/thread.rs b/library/std/src/sys/pal/wasip1/thread.rs
deleted file mode 100644
index e062b49bd7a..00000000000
--- a/library/std/src/sys/pal/wasip1/thread.rs
+++ /dev/null
@@ -1,214 +0,0 @@
-#![forbid(unsafe_op_in_unsafe_fn)]
-
-use crate::ffi::CStr;
-use crate::num::NonZero;
-use crate::time::{Duration, Instant};
-use crate::{io, mem};
-
-cfg_select! {
-    target_feature = "atomics" => {
-        use crate::cmp;
-        use crate::ptr;
-        use crate::sys::os;
-        // Add a few symbols not in upstream `libc` just yet.
-        mod libc {
-            pub use crate::ffi;
-            pub use libc::*;
-
-            // defined in wasi-libc
-            // https://github.com/WebAssembly/wasi-libc/blob/a6f871343313220b76009827ed0153586361c0d5/libc-top-half/musl/include/alltypes.h.in#L108
-            #[repr(C)]
-            union pthread_attr_union {
-                __i: [ffi::c_int; if size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
-                __vi: [ffi::c_int; if size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
-                __s: [ffi::c_ulong; if size_of::<ffi::c_long>() == 8 { 7 } else { 9 }],
-            }
-
-            #[repr(C)]
-            pub struct pthread_attr_t {
-                __u: pthread_attr_union,
-            }
-
-            #[allow(non_camel_case_types)]
-            pub type pthread_t = *mut ffi::c_void;
-
-            pub const _SC_NPROCESSORS_ONLN: ffi::c_int = 84;
-
-            unsafe extern "C" {
-                pub fn pthread_create(
-                    native: *mut pthread_t,
-                    attr: *const pthread_attr_t,
-                    f: extern "C" fn(*mut ffi::c_void) -> *mut ffi::c_void,
-                    value: *mut ffi::c_void,
-                ) -> ffi::c_int;
-                pub fn pthread_join(native: pthread_t, value: *mut *mut ffi::c_void) -> ffi::c_int;
-                pub fn pthread_attr_init(attrp: *mut pthread_attr_t) -> ffi::c_int;
-                pub fn pthread_attr_setstacksize(
-                    attr: *mut pthread_attr_t,
-                    stack_size: libc::size_t,
-                ) -> ffi::c_int;
-                pub fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> ffi::c_int;
-                pub fn pthread_detach(thread: pthread_t) -> ffi::c_int;
-            }
-        }
-
-        pub struct Thread {
-            id: libc::pthread_t,
-        }
-
-        impl Drop for Thread {
-            fn drop(&mut self) {
-                let ret = unsafe { libc::pthread_detach(self.id) };
-                debug_assert_eq!(ret, 0);
-            }
-        }
-    }
-    _ => {
-        pub struct Thread(!);
-    }
-}
-
-pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
-
-impl Thread {
-    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    cfg_select! {
-        target_feature = "atomics" => {
-            pub unsafe fn new(stack: usize, _name: Option<&str>, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-                let p = Box::into_raw(Box::new(p));
-                let mut native: libc::pthread_t = unsafe { mem::zeroed() };
-                let mut attr: libc::pthread_attr_t = unsafe { mem::zeroed() };
-                assert_eq!(unsafe { libc::pthread_attr_init(&mut attr) }, 0);
-
-                let stack_size = cmp::max(stack, DEFAULT_MIN_STACK_SIZE);
-
-                match unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) } {
-                    0 => {}
-                    n => {
-                        assert_eq!(n, libc::EINVAL);
-                        // EINVAL means |stack_size| is either too small or not a
-                        // multiple of the system page size. Because it's definitely
-                        // >= PTHREAD_STACK_MIN, it must be an alignment issue.
-                        // Round up to the nearest page and try again.
-                        let page_size = os::page_size();
-                        let stack_size =
-                            (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
-                        assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0);
-                    }
-                };
-
-                let ret = unsafe { libc::pthread_create(&mut native, &attr, thread_start, p as *mut _) };
-                // Note: if the thread creation fails and this assert fails, then p will
-                // be leaked. However, an alternative design could cause double-free
-                // which is clearly worse.
-                assert_eq!(unsafe {libc::pthread_attr_destroy(&mut attr) }, 0);
-
-                return if ret != 0 {
-                    // The thread failed to start and as a result p was not consumed. Therefore, it is
-                    // safe to reconstruct the box so that it gets deallocated.
-                    unsafe { drop(Box::from_raw(p)); }
-                    Err(io::Error::from_raw_os_error(ret))
-                } else {
-                    Ok(Thread { id: native })
-                };
-
-                extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
-                    unsafe {
-                        // Finally, let's run some code.
-                        Box::from_raw(main as *mut Box<dyn FnOnce()>)();
-                    }
-                    ptr::null_mut()
-                }
-            }
-        }
-        _ => {
-            pub unsafe fn new(_stack: usize, _name: Option<&str>, _p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-                crate::sys::unsupported()
-            }
-        }
-    }
-
-    pub fn yield_now() {
-        let ret = unsafe { wasi::sched_yield() };
-        debug_assert_eq!(ret, Ok(()));
-    }
-
-    pub fn set_name(_name: &CStr) {
-        // nope
-    }
-
-    pub fn sleep(dur: Duration) {
-        let mut nanos = dur.as_nanos();
-        while nanos > 0 {
-            const USERDATA: wasi::Userdata = 0x0123_45678;
-
-            let clock = wasi::SubscriptionClock {
-                id: wasi::CLOCKID_MONOTONIC,
-                timeout: u64::try_from(nanos).unwrap_or(u64::MAX),
-                precision: 0,
-                flags: 0,
-            };
-            nanos -= u128::from(clock.timeout);
-
-            let in_ = wasi::Subscription {
-                userdata: USERDATA,
-                u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } },
-            };
-            unsafe {
-                let mut event: wasi::Event = mem::zeroed();
-                let res = wasi::poll_oneoff(&in_, &mut event, 1);
-                match (res, event) {
-                    (
-                        Ok(1),
-                        wasi::Event {
-                            userdata: USERDATA,
-                            error: wasi::ERRNO_SUCCESS,
-                            type_: wasi::EVENTTYPE_CLOCK,
-                            ..
-                        },
-                    ) => {}
-                    _ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
-                }
-            }
-        }
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
-    pub fn join(self) {
-        cfg_select! {
-            target_feature = "atomics" => {
-                let id = mem::ManuallyDrop::new(self).id;
-                let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
-                if ret != 0 {
-                    rtabort!("failed to join thread: {}", io::Error::from_raw_os_error(ret));
-                }
-            }
-            _ => {
-                self.0
-            }
-        }
-    }
-}
-
-pub(crate) fn current_os_id() -> Option<u64> {
-    None
-}
-
-pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    cfg_select! {
-        target_feature = "atomics" => {
-            match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
-                -1 => Err(io::Error::last_os_error()),
-                cpus => NonZero::new(cpus as usize).ok_or(io::Error::UNKNOWN_THREAD_COUNT),
-            }
-        }
-        _ => crate::sys::unsupported(),
-    }
-}
diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs
index 5f3fb6d6ddf..c1d89da2677 100644
--- a/library/std/src/sys/pal/wasip2/mod.rs
+++ b/library/std/src/sys/pal/wasip2/mod.rs
@@ -14,7 +14,6 @@ pub mod futex;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-pub mod thread;
 pub mod time;
 
 #[path = "../unsupported/common.rs"]
diff --git a/library/std/src/sys/pal/wasip2/thread.rs b/library/std/src/sys/pal/wasip2/thread.rs
deleted file mode 100644
index ad52918f15a..00000000000
--- a/library/std/src/sys/pal/wasip2/thread.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use crate::ffi::CStr;
-use crate::io;
-use crate::num::NonZero;
-use crate::time::{Duration, Instant};
-
-pub struct Thread(!);
-
-pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
-
-impl Thread {
-    pub unsafe fn new(
-        _stack: usize,
-        _name: Option<&str>,
-        _p: Box<dyn FnOnce()>,
-    ) -> io::Result<Thread> {
-        // Note that unlike WASIp1 even if the wasm `atomics` feature is enabled
-        // there is no support for threads, not even experimentally, not even in
-        // wasi-libc. Thus this is unconditionally unsupported.
-        crate::sys::unsupported()
-    }
-
-    pub fn yield_now() {
-        // no API for this in WASIp2, but there's also no threads, so that's
-        // sort of expected.
-    }
-
-    pub fn set_name(_name: &CStr) {
-        // nope
-    }
-
-    pub fn sleep(dur: Duration) {
-        // Sleep in increments of `u64::MAX` nanoseconds until the `dur` is
-        // entirely drained.
-        let mut remaining = dur.as_nanos();
-        while remaining > 0 {
-            let amt = u64::try_from(remaining).unwrap_or(u64::MAX);
-            wasip2::clocks::monotonic_clock::subscribe_duration(amt).block();
-            remaining -= u128::from(amt);
-        }
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        match u64::try_from(deadline.into_inner().as_duration().as_nanos()) {
-            // If the point in time we're sleeping to fits within a 64-bit
-            // number of nanoseconds then directly use `subscribe_instant`.
-            Ok(deadline) => {
-                wasip2::clocks::monotonic_clock::subscribe_instant(deadline).block();
-            }
-            // ... otherwise we're sleeping for 500+ years relative to the
-            // "start" of what the system is using as a clock so speed/accuracy
-            // is not so much of a concern. Use `sleep` instead.
-            Err(_) => {
-                let now = Instant::now();
-
-                if let Some(delay) = deadline.checked_duration_since(now) {
-                    Self::sleep(delay);
-                }
-            }
-        }
-    }
-
-    pub fn join(self) {
-        self.0
-    }
-}
-
-pub(crate) fn current_os_id() -> Option<u64> {
-    None
-}
-
-pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    crate::sys::unsupported()
-}
diff --git a/library/std/src/sys/pal/wasip2/time.rs b/library/std/src/sys/pal/wasip2/time.rs
index f1f6839774b..980070e7b85 100644
--- a/library/std/src/sys/pal/wasip2/time.rs
+++ b/library/std/src/sys/pal/wasip2/time.rs
@@ -25,7 +25,7 @@ impl Instant {
         Some(Instant(self.0.checked_sub(*other)?))
     }
 
-    pub(super) fn as_duration(&self) -> &Duration {
+    pub(crate) fn as_duration(&self) -> &Duration {
         &self.0
     }
 }
diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs
deleted file mode 100644
index 42a7dbdf8b8..00000000000
--- a/library/std/src/sys/pal/wasm/atomics/thread.rs
+++ /dev/null
@@ -1,75 +0,0 @@
-use crate::ffi::CStr;
-use crate::io;
-use crate::num::NonZero;
-use crate::sys::unsupported;
-use crate::time::{Duration, Instant};
-
-pub struct Thread(!);
-
-pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
-
-impl Thread {
-    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(
-        _stack: usize,
-        _name: Option<&str>,
-        _p: Box<dyn FnOnce()>,
-    ) -> io::Result<Thread> {
-        unsupported()
-    }
-
-    pub fn yield_now() {}
-
-    pub fn set_name(_name: &CStr) {}
-
-    pub fn sleep(dur: Duration) {
-        #[cfg(target_arch = "wasm32")]
-        use core::arch::wasm32 as wasm;
-        #[cfg(target_arch = "wasm64")]
-        use core::arch::wasm64 as wasm;
-
-        use crate::cmp;
-
-        // Use an atomic wait to block the current thread artificially with a
-        // timeout listed. Note that we should never be notified (return value
-        // of 0) or our comparison should never fail (return value of 1) so we
-        // should always only resume execution through a timeout (return value
-        // 2).
-        let mut nanos = dur.as_nanos();
-        while nanos > 0 {
-            let amt = cmp::min(i64::MAX as u128, nanos);
-            let mut x = 0;
-            let val = unsafe { wasm::memory_atomic_wait32(&mut x, 0, amt as i64) };
-            debug_assert_eq!(val, 2);
-            nanos -= amt;
-        }
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
-    pub fn join(self) {}
-}
-
-pub(crate) fn current_os_id() -> Option<u64> {
-    None
-}
-
-pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    unsupported()
-}
-
-pub mod guard {
-    pub type Guard = !;
-    pub unsafe fn current() -> Option<Guard> {
-        None
-    }
-    pub unsafe fn init() -> Option<Guard> {
-        None
-    }
-}
diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs
index 346c9ff88c9..a20cd0e9ac7 100644
--- a/library/std/src/sys/pal/wasm/mod.rs
+++ b/library/std/src/sys/pal/wasm/mod.rs
@@ -23,18 +23,9 @@ pub mod pipe;
 #[path = "../unsupported/time.rs"]
 pub mod time;
 
-cfg_select! {
-    target_feature = "atomics" => {
-        #[path = "atomics/futex.rs"]
-        pub mod futex;
-        #[path = "atomics/thread.rs"]
-        pub mod thread;
-    }
-    _ => {
-        #[path = "../unsupported/thread.rs"]
-        pub mod thread;
-    }
-}
+#[cfg(target_feature = "atomics")]
+#[path = "atomics/futex.rs"]
+pub mod futex;
 
 #[path = "../unsupported/common.rs"]
 #[deny(unsafe_op_in_unsafe_fn)]
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 3b6a86cbc8f..3357946b8f7 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -20,7 +20,6 @@ pub mod futex;
 pub mod handle;
 pub mod os;
 pub mod pipe;
-pub mod thread;
 pub mod time;
 cfg_select! {
     not(target_vendor = "uwp") => {
@@ -48,9 +47,9 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {
     unsafe {
         stack_overflow::init();
 
-        // Normally, `thread::spawn` will call `Thread::set_name` but since this thread already
+        // Normally, `thread::spawn` will call `set_name` but since this thread already
         // exists, we have to call it ourselves.
-        thread::Thread::set_name_wide(wide_str!("main"));
+        crate::sys::thread::set_name_wide(wide_str!("main"));
     }
 }
 
diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs
index a948c07e0a3..f8f9a9fd818 100644
--- a/library/std/src/sys/pal/windows/time.rs
+++ b/library/std/src/sys/pal/windows/time.rs
@@ -232,7 +232,7 @@ mod perf_counter {
 }
 
 /// A timer you can wait on.
-pub(super) struct WaitableTimer {
+pub(crate) struct WaitableTimer {
     handle: c::HANDLE,
 }
 impl WaitableTimer {
diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs
index 042c4ff862f..e673157e0eb 100644
--- a/library/std/src/sys/pal/xous/mod.rs
+++ b/library/std/src/sys/pal/xous/mod.rs
@@ -5,7 +5,6 @@ use crate::os::xous::ffi::exit;
 pub mod os;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
-pub mod thread;
 pub mod time;
 
 #[path = "../unsupported/common.rs"]
diff --git a/library/std/src/sys/platform_version/darwin/tests.rs b/library/std/src/sys/platform_version/darwin/tests.rs
index eecd58ec79e..17b2cc18ec0 100644
--- a/library/std/src/sys/platform_version/darwin/tests.rs
+++ b/library/std/src/sys/platform_version/darwin/tests.rs
@@ -35,9 +35,9 @@ fn compare_against_sw_vers() {
     assert_eq!(__isOSVersionAtLeast(major, minor, subminor), 1);
 
     // One lower is available
-    assert_eq!(__isOSVersionAtLeast(major, minor, subminor.saturating_sub(1)), 1);
-    assert_eq!(__isOSVersionAtLeast(major, minor.saturating_sub(1), subminor), 1);
-    assert_eq!(__isOSVersionAtLeast(major.saturating_sub(1), minor, subminor), 1);
+    assert_eq!(__isOSVersionAtLeast(major, minor, (subminor as u32).saturating_sub(1) as i32), 1);
+    assert_eq!(__isOSVersionAtLeast(major, (minor as u32).saturating_sub(1) as i32, subminor), 1);
+    assert_eq!(__isOSVersionAtLeast((major as u32).saturating_sub(1) as i32, minor, subminor), 1);
 
     // One higher isn't available
     assert_eq!(__isOSVersionAtLeast(major, minor, subminor + 1), 0);
diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs
index 49e15d65f25..17d99cdb385 100644
--- a/library/std/src/sys/sync/once/queue.rs
+++ b/library/std/src/sys/sync/once/queue.rs
@@ -276,7 +276,9 @@ fn wait(
             // If the managing thread happens to signal and unpark us before we
             // can park ourselves, the result could be this thread never gets
             // unparked. Luckily `park` comes with the guarantee that if it got
-            // an `unpark` just before on an unparked thread it does not park.
+            // an `unpark` just before on an unparked thread it does not park. Crucially, we know
+            // the `unpark` must have happened between the `compare_exchange_weak` above and here,
+            // and there's no other `park` in that code that could steal our token.
             // SAFETY: we retrieved this handle on the current thread above.
             unsafe { node.thread.park() }
         }
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/thread/hermit.rs
index cc4734b6819..4d9f3b114c2 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/thread/hermit.rs
@@ -1,10 +1,5 @@
-#![allow(dead_code)]
-
-use super::hermit_abi;
-use crate::ffi::CStr;
-use crate::mem::ManuallyDrop;
 use crate::num::NonZero;
-use crate::time::{Duration, Instant};
+use crate::time::Duration;
 use crate::{io, ptr};
 
 pub type Tid = hermit_abi::Tid;
@@ -68,57 +63,30 @@ impl Thread {
         }
     }
 
-    #[inline]
-    pub fn yield_now() {
-        unsafe {
-            hermit_abi::yield_now();
-        }
-    }
-
-    #[inline]
-    pub fn set_name(_name: &CStr) {
-        // nope
-    }
-
-    #[inline]
-    pub fn sleep(dur: Duration) {
-        let micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 };
-        let micros = u64::try_from(micros).unwrap_or(u64::MAX);
-
-        unsafe {
-            hermit_abi::usleep(micros);
-        }
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
     pub fn join(self) {
         unsafe {
             let _ = hermit_abi::join(self.tid);
         }
     }
+}
 
-    #[inline]
-    pub fn id(&self) -> Tid {
-        self.tid
-    }
-
-    #[inline]
-    pub fn into_id(self) -> Tid {
-        ManuallyDrop::new(self).tid
-    }
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
+    unsafe { Ok(NonZero::new_unchecked(hermit_abi::available_parallelism())) }
 }
 
-pub(crate) fn current_os_id() -> Option<u64> {
-    None
+#[inline]
+pub fn sleep(dur: Duration) {
+    let micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 };
+    let micros = u64::try_from(micros).unwrap_or(u64::MAX);
+
+    unsafe {
+        hermit_abi::usleep(micros);
+    }
 }
 
-pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    unsafe { Ok(NonZero::new_unchecked(hermit_abi::available_parallelism())) }
+#[inline]
+pub fn yield_now() {
+    unsafe {
+        hermit_abi::yield_now();
+    }
 }
diff --git a/library/std/src/sys/thread/mod.rs b/library/std/src/sys/thread/mod.rs
new file mode 100644
index 00000000000..6bb7fc1a20e
--- /dev/null
+++ b/library/std/src/sys/thread/mod.rs
@@ -0,0 +1,152 @@
+cfg_select! {
+    target_os = "hermit" => {
+        mod hermit;
+        pub use hermit::{Thread, available_parallelism, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
+        #[expect(dead_code)]
+        mod unsupported;
+        pub use unsupported::{current_os_id, set_name};
+    }
+    all(target_vendor = "fortanix", target_env = "sgx") => {
+        mod sgx;
+        pub use sgx::{Thread, current_os_id, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
+
+        // SGX should protect in-enclave data from outside attackers, so there
+        // must not be any data leakage to the OS, particularly no 1-1 mapping
+        // between SGX thread names and OS thread names. Hence `set_name` is
+        // intentionally a no-op.
+        //
+        // Note that the internally visible SGX thread name is already provided
+        // by the platform-agnostic Rust thread code. This can be observed in
+        // the [`std::thread::tests::test_named_thread`] test, which succeeds
+        // as-is with the SGX target.
+        #[expect(dead_code)]
+        mod unsupported;
+        pub use unsupported::{available_parallelism, set_name};
+    }
+    target_os = "solid_asp3" => {
+        mod solid;
+        pub use solid::{Thread, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
+        #[expect(dead_code)]
+        mod unsupported;
+        pub use unsupported::{available_parallelism, current_os_id, set_name};
+    }
+    target_os = "teeos" => {
+        mod teeos;
+        pub use teeos::{Thread, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
+        #[expect(dead_code)]
+        mod unsupported;
+        pub use unsupported::{available_parallelism, current_os_id, set_name};
+    }
+    target_os = "uefi" => {
+        mod uefi;
+        pub use uefi::{available_parallelism, sleep};
+        #[expect(dead_code)]
+        mod unsupported;
+        pub use unsupported::{Thread, current_os_id, set_name, yield_now, DEFAULT_MIN_STACK_SIZE};
+    }
+    target_family = "unix" => {
+        mod unix;
+        pub use unix::{Thread, available_parallelism, current_os_id, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
+        #[cfg(not(any(
+            target_env = "newlib",
+            target_os = "l4re",
+            target_os = "emscripten",
+            target_os = "redox",
+            target_os = "hurd",
+            target_os = "aix",
+        )))]
+        pub use unix::set_name;
+        #[cfg(any(
+            target_os = "freebsd",
+            target_os = "netbsd",
+            target_os = "linux",
+            target_os = "android",
+            target_os = "solaris",
+            target_os = "illumos",
+            target_os = "dragonfly",
+            target_os = "hurd",
+            target_os = "fuchsia",
+            target_os = "vxworks",
+        ))]
+        pub use unix::sleep_until;
+        #[expect(dead_code)]
+        mod unsupported;
+        #[cfg(any(
+            target_env = "newlib",
+            target_os = "l4re",
+            target_os = "emscripten",
+            target_os = "redox",
+            target_os = "hurd",
+            target_os = "aix",
+        ))]
+        pub use unsupported::set_name;
+    }
+    all(target_os = "wasi", target_env = "p1") => {
+        mod wasip1;
+        pub use wasip1::{DEFAULT_MIN_STACK_SIZE, sleep, yield_now};
+        #[cfg(target_feature = "atomics")]
+        pub use wasip1::{Thread, available_parallelism};
+        #[expect(dead_code)]
+        mod unsupported;
+        pub use unsupported::{current_os_id, set_name};
+        #[cfg(not(target_feature = "atomics"))]
+        pub use unsupported::{Thread, available_parallelism};
+    }
+    all(target_os = "wasi", target_env = "p2") => {
+        mod wasip2;
+        pub use wasip2::{sleep, sleep_until};
+        #[expect(dead_code)]
+        mod unsupported;
+        // Note that unlike WASIp1 even if the wasm `atomics` feature is enabled
+        // there is no support for threads, not even experimentally, not even in
+        // wasi-libc. Thus this is unconditionally unsupported.
+        pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, yield_now, DEFAULT_MIN_STACK_SIZE};
+    }
+    all(target_family = "wasm", target_feature = "atomics") => {
+        mod wasm;
+        pub use wasm::sleep;
+
+        #[expect(dead_code)]
+        mod unsupported;
+        pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, yield_now, DEFAULT_MIN_STACK_SIZE};
+    }
+    target_os = "windows" => {
+        mod windows;
+        pub use windows::{Thread, available_parallelism, current_os_id, set_name, set_name_wide, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
+    }
+    target_os = "xous" => {
+        mod xous;
+        pub use xous::{Thread, available_parallelism, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
+
+        #[expect(dead_code)]
+        mod unsupported;
+        pub use unsupported::{current_os_id, set_name};
+    }
+    _ => {
+        mod unsupported;
+        pub use unsupported::{Thread, available_parallelism, current_os_id, set_name, sleep, yield_now, DEFAULT_MIN_STACK_SIZE};
+    }
+}
+
+#[cfg(not(any(
+    target_os = "freebsd",
+    target_os = "netbsd",
+    target_os = "linux",
+    target_os = "android",
+    target_os = "solaris",
+    target_os = "illumos",
+    target_os = "dragonfly",
+    target_os = "hurd",
+    target_os = "fuchsia",
+    target_os = "vxworks",
+    all(target_os = "wasi", target_env = "p2"),
+)))]
+pub fn sleep_until(deadline: crate::time::Instant) {
+    use crate::time::Instant;
+
+    let now = Instant::now();
+
+    if let Some(delay) = deadline.checked_duration_since(now) {
+        sleep(delay);
+    }
+}
diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/thread/sgx.rs
index 1f613badcd7..f20ef7d86b9 100644
--- a/library/std/src/sys/pal/sgx/thread.rs
+++ b/library/std/src/sys/thread/sgx.rs
@@ -1,11 +1,8 @@
 #![cfg_attr(test, allow(dead_code))] // why is this necessary?
 
-use super::abi::{thread, usercalls};
-use super::unsupported;
-use crate::ffi::CStr;
 use crate::io;
-use crate::num::NonZero;
-use crate::time::{Duration, Instant};
+use crate::sys::pal::abi::{thread, usercalls};
+use crate::time::Duration;
 
 pub struct Thread(task_queue::JoinHandle);
 
@@ -108,51 +105,27 @@ impl Thread {
         Ok(Thread(handle))
     }
 
-    pub(super) fn entry() -> JoinNotifier {
+    pub(crate) fn entry() -> JoinNotifier {
         let mut pending_tasks = task_queue::lock();
         let task = rtunwrap!(Some, pending_tasks.pop());
         drop(pending_tasks); // make sure to not hold the task queue lock longer than necessary
         task.run()
     }
 
-    pub fn yield_now() {
-        let wait_error = rtunwrap!(Err, usercalls::wait(0, usercalls::raw::WAIT_NO));
-        rtassert!(wait_error.kind() == io::ErrorKind::WouldBlock);
-    }
-
-    /// SGX should protect in-enclave data from the outside (attacker),
-    /// so there should be no data leakage to the OS,
-    /// and therefore also no 1-1 mapping between SGX thread names and OS thread names.
-    ///
-    /// This is why the method is intentionally No-Op.
-    pub fn set_name(_name: &CStr) {
-        // Note that the internally visible SGX thread name is already provided
-        // by the platform-agnostic (target-agnostic) Rust thread code.
-        // This can be observed in the [`std::thread::tests::test_named_thread`] test,
-        // which succeeds as-is with the SGX target.
-    }
-
-    pub fn sleep(dur: Duration) {
-        usercalls::wait_timeout(0, dur, || true);
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
     pub fn join(self) {
         self.0.wait();
     }
 }
 
-pub(crate) fn current_os_id() -> Option<u64> {
+pub fn current_os_id() -> Option<u64> {
     Some(thread::current().addr().get() as u64)
 }
 
-pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    unsupported()
+pub fn sleep(dur: Duration) {
+    usercalls::wait_timeout(0, dur, || true);
+}
+
+pub fn yield_now() {
+    let wait_error = rtunwrap!(Err, usercalls::wait(0, usercalls::raw::WAIT_NO));
+    rtassert!(wait_error.kind() == io::ErrorKind::WouldBlock);
 }
diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/thread/solid.rs
index 4e14cb3cbca..46a84faa802 100644
--- a/library/std/src/sys/pal/itron/thread.rs
+++ b/library/std/src/sys/thread/solid.rs
@@ -1,16 +1,14 @@
 //! Thread implementation backed by μITRON tasks. Assumes `acre_tsk` and
 //! `exd_tsk` are available.
 
-use super::error::{ItronError, expect_success, expect_success_aborting};
-use super::time::dur2reltims;
-use super::{abi, task};
 use crate::cell::UnsafeCell;
-use crate::ffi::CStr;
 use crate::mem::ManuallyDrop;
-use crate::num::NonZero;
 use crate::ptr::NonNull;
 use crate::sync::atomic::{Atomic, AtomicUsize, Ordering};
-use crate::time::{Duration, Instant};
+use crate::sys::pal::itron::error::{ItronError, expect_success, expect_success_aborting};
+use crate::sys::pal::itron::time::dur2reltims;
+use crate::sys::pal::itron::{abi, task};
+use crate::time::Duration;
 use crate::{hint, io};
 
 pub struct Thread {
@@ -195,28 +193,6 @@ impl Thread {
         Ok(Self { p_inner, task: new_task })
     }
 
-    pub fn yield_now() {
-        expect_success(unsafe { abi::rot_rdq(abi::TPRI_SELF) }, &"rot_rdq");
-    }
-
-    pub fn set_name(_name: &CStr) {
-        // nope
-    }
-
-    pub fn sleep(dur: Duration) {
-        for timeout in dur2reltims(dur) {
-            expect_success(unsafe { abi::dly_tsk(timeout) }, &"dly_tsk");
-        }
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
     pub fn join(self) {
         // Safety: `ThreadInner` is alive at this point
         let inner = unsafe { self.p_inner.as_ref() };
@@ -361,10 +337,12 @@ unsafe fn terminate_and_delete_current_task() -> ! {
     unsafe { crate::hint::unreachable_unchecked() };
 }
 
-pub(crate) fn current_os_id() -> Option<u64> {
-    None
+pub fn yield_now() {
+    expect_success(unsafe { abi::rot_rdq(abi::TPRI_SELF) }, &"rot_rdq");
 }
 
-pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    super::unsupported()
+pub fn sleep(dur: Duration) {
+    for timeout in dur2reltims(dur) {
+        expect_success(unsafe { abi::dly_tsk(timeout) }, &"dly_tsk");
+    }
 }
diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/thread/teeos.rs
index 1812d11e692..cad100395c9 100644
--- a/library/std/src/sys/pal/teeos/thread.rs
+++ b/library/std/src/sys/thread/teeos.rs
@@ -1,12 +1,18 @@
-use crate::ffi::CStr;
 use crate::mem::{self, ManuallyDrop};
-use crate::num::NonZero;
 use crate::sys::os;
-use crate::time::{Duration, Instant};
+use crate::time::Duration;
 use crate::{cmp, io, ptr};
 
 pub const DEFAULT_MIN_STACK_SIZE: usize = 8 * 1024;
 
+unsafe extern "C" {
+    safe fn TEE_Wait(timeout: u32) -> u32;
+}
+
+fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
+    libc::PTHREAD_STACK_MIN.try_into().expect("Infallible")
+}
+
 pub struct Thread {
     id: libc::pthread_t,
 }
@@ -16,10 +22,6 @@ pub struct Thread {
 unsafe impl Send for Thread {}
 unsafe impl Sync for Thread {}
 
-unsafe extern "C" {
-    pub fn TEE_Wait(timeout: u32) -> u32;
-}
-
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(
@@ -74,7 +76,7 @@ impl Thread {
         } else {
             // The new thread will start running earliest after the next yield.
             // We add a yield here, so that the user does not have to.
-            Thread::yield_now();
+            yield_now();
             Ok(Thread { id: native })
         };
 
@@ -91,36 +93,6 @@ impl Thread {
         }
     }
 
-    pub fn yield_now() {
-        let ret = unsafe { libc::sched_yield() };
-        debug_assert_eq!(ret, 0);
-    }
-
-    /// This does not do anything on teeos
-    pub fn set_name(_name: &CStr) {
-        // Both pthread_setname_np and prctl are not available to the TA,
-        // so we can't implement this currently. If the need arises please
-        // contact the teeos rustzone team.
-    }
-
-    /// only main thread could wait for sometime in teeos
-    pub fn sleep(dur: Duration) {
-        let sleep_millis = dur.as_millis();
-        let final_sleep: u32 =
-            if sleep_millis >= u32::MAX as u128 { u32::MAX } else { sleep_millis as u32 };
-        unsafe {
-            let _ = TEE_Wait(final_sleep);
-        }
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
     /// must join, because no pthread_detach supported
     pub fn join(self) {
         let id = self.into_id();
@@ -128,10 +100,6 @@ impl Thread {
         assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret));
     }
 
-    pub fn id(&self) -> libc::pthread_t {
-        self.id
-    }
-
     pub fn into_id(self) -> libc::pthread_t {
         ManuallyDrop::new(self).id
     }
@@ -144,16 +112,15 @@ impl Drop for Thread {
     }
 }
 
-pub(crate) fn current_os_id() -> Option<u64> {
-    None
-}
-
-// Note: Both `sched_getaffinity` and `sysconf` are available but not functional on
-// teeos, so this function always returns an Error!
-pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    Err(io::Error::UNKNOWN_THREAD_COUNT)
+pub fn yield_now() {
+    let ret = unsafe { libc::sched_yield() };
+    debug_assert_eq!(ret, 0);
 }
 
-fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
-    libc::PTHREAD_STACK_MIN.try_into().expect("Infallible")
+/// only main thread could wait for sometime in teeos
+pub fn sleep(dur: Duration) {
+    let sleep_millis = dur.as_millis();
+    let final_sleep: u32 =
+        if sleep_millis >= u32::MAX as u128 { u32::MAX } else { sleep_millis as u32 };
+    TEE_Wait(final_sleep);
 }
diff --git a/library/std/src/sys/thread/uefi.rs b/library/std/src/sys/thread/uefi.rs
new file mode 100644
index 00000000000..94f67d7ace2
--- /dev/null
+++ b/library/std/src/sys/thread/uefi.rs
@@ -0,0 +1,25 @@
+use crate::io;
+use crate::num::NonZero;
+use crate::ptr::NonNull;
+use crate::time::Duration;
+
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
+    // UEFI is single threaded
+    Ok(NonZero::new(1).unwrap())
+}
+
+pub fn sleep(dur: Duration) {
+    let boot_services: NonNull<r_efi::efi::BootServices> =
+        crate::os::uefi::env::boot_services().expect("can't sleep").cast();
+    let mut dur_ms = dur.as_micros();
+    // ceil up to the nearest microsecond
+    if dur.subsec_nanos() % 1000 > 0 {
+        dur_ms += 1;
+    }
+
+    while dur_ms > 0 {
+        let ms = crate::cmp::min(dur_ms, usize::MAX as u128);
+        let _ = unsafe { ((*boot_services.as_ptr()).stall)(ms as usize) };
+        dur_ms -= ms;
+    }
+}
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/thread/unix.rs
index 3389b8c0c8a..2d2c4f90212 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/thread/unix.rs
@@ -1,3 +1,11 @@
+#[cfg(not(any(
+    target_env = "newlib",
+    target_os = "l4re",
+    target_os = "emscripten",
+    target_os = "redox",
+    target_os = "hurd",
+    target_os = "aix",
+)))]
 use crate::ffi::CStr;
 use crate::mem::{self, ManuallyDrop};
 use crate::num::NonZero;
@@ -6,7 +14,7 @@ use crate::sys::weak::dlsym;
 #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))]
 use crate::sys::weak::weak;
 use crate::sys::{os, stack_overflow};
-use crate::time::{Duration, Instant};
+use crate::time::Duration;
 use crate::{cmp, io, ptr};
 #[cfg(not(any(
     target_os = "l4re",
@@ -121,273 +129,6 @@ impl Thread {
         }
     }
 
-    pub fn yield_now() {
-        let ret = unsafe { libc::sched_yield() };
-        debug_assert_eq!(ret, 0);
-    }
-
-    #[cfg(target_os = "android")]
-    pub fn set_name(name: &CStr) {
-        const PR_SET_NAME: libc::c_int = 15;
-        unsafe {
-            let res = libc::prctl(
-                PR_SET_NAME,
-                name.as_ptr(),
-                0 as libc::c_ulong,
-                0 as libc::c_ulong,
-                0 as libc::c_ulong,
-            );
-            // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked.
-            debug_assert_eq!(res, 0);
-        }
-    }
-
-    #[cfg(any(
-        target_os = "linux",
-        target_os = "freebsd",
-        target_os = "dragonfly",
-        target_os = "nuttx",
-        target_os = "cygwin"
-    ))]
-    pub fn set_name(name: &CStr) {
-        unsafe {
-            cfg_select! {
-                any(target_os = "linux", target_os = "cygwin") => {
-                    // Linux and Cygwin limits the allowed length of the name.
-                    const TASK_COMM_LEN: usize = 16;
-                    let name = truncate_cstr::<{ TASK_COMM_LEN }>(name);
-                }
-                _ => {
-                    // FreeBSD, DragonFly BSD and NuttX do not enforce length limits.
-                }
-            };
-            // Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20 for Linux,
-            // FreeBSD 12.2 and 13.0, and DragonFly BSD 6.0.
-            let res = libc::pthread_setname_np(libc::pthread_self(), name.as_ptr());
-            // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked.
-            debug_assert_eq!(res, 0);
-        }
-    }
-
-    #[cfg(target_os = "openbsd")]
-    pub fn set_name(name: &CStr) {
-        unsafe {
-            libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());
-        }
-    }
-
-    #[cfg(target_vendor = "apple")]
-    pub fn set_name(name: &CStr) {
-        unsafe {
-            let name = truncate_cstr::<{ libc::MAXTHREADNAMESIZE }>(name);
-            let res = libc::pthread_setname_np(name.as_ptr());
-            // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked.
-            debug_assert_eq!(res, 0);
-        }
-    }
-
-    #[cfg(target_os = "netbsd")]
-    pub fn set_name(name: &CStr) {
-        unsafe {
-            let res = libc::pthread_setname_np(
-                libc::pthread_self(),
-                c"%s".as_ptr(),
-                name.as_ptr() as *mut libc::c_void,
-            );
-            debug_assert_eq!(res, 0);
-        }
-    }
-
-    #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))]
-    pub fn set_name(name: &CStr) {
-        weak!(
-            fn pthread_setname_np(
-                thread: libc::pthread_t,
-                name: *const libc::c_char,
-            ) -> libc::c_int;
-        );
-
-        if let Some(f) = pthread_setname_np.get() {
-            #[cfg(target_os = "nto")]
-            const THREAD_NAME_MAX: usize = libc::_NTO_THREAD_NAME_MAX as usize;
-            #[cfg(any(target_os = "solaris", target_os = "illumos"))]
-            const THREAD_NAME_MAX: usize = 32;
-
-            let name = truncate_cstr::<{ THREAD_NAME_MAX }>(name);
-            let res = unsafe { f(libc::pthread_self(), name.as_ptr()) };
-            debug_assert_eq!(res, 0);
-        }
-    }
-
-    #[cfg(target_os = "fuchsia")]
-    pub fn set_name(name: &CStr) {
-        use super::fuchsia::*;
-        unsafe {
-            zx_object_set_property(
-                zx_thread_self(),
-                ZX_PROP_NAME,
-                name.as_ptr() as *const libc::c_void,
-                name.to_bytes().len(),
-            );
-        }
-    }
-
-    #[cfg(target_os = "haiku")]
-    pub fn set_name(name: &CStr) {
-        unsafe {
-            let thread_self = libc::find_thread(ptr::null_mut());
-            let res = libc::rename_thread(thread_self, name.as_ptr());
-            // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked.
-            debug_assert_eq!(res, libc::B_OK);
-        }
-    }
-
-    #[cfg(target_os = "vxworks")]
-    pub fn set_name(name: &CStr) {
-        let mut name = truncate_cstr::<{ (libc::VX_TASK_RENAME_LENGTH - 1) as usize }>(name);
-        let res = unsafe { libc::taskNameSet(libc::taskIdSelf(), name.as_mut_ptr()) };
-        debug_assert_eq!(res, libc::OK);
-    }
-
-    #[cfg(any(
-        target_env = "newlib",
-        target_os = "l4re",
-        target_os = "emscripten",
-        target_os = "redox",
-        target_os = "hurd",
-        target_os = "aix",
-    ))]
-    pub fn set_name(_name: &CStr) {
-        // Newlib and Emscripten have no way to set a thread name.
-    }
-
-    #[cfg(not(target_os = "espidf"))]
-    pub fn sleep(dur: Duration) {
-        let mut secs = dur.as_secs();
-        let mut nsecs = dur.subsec_nanos() as _;
-
-        // If we're awoken with a signal then the return value will be -1 and
-        // nanosleep will fill in `ts` with the remaining time.
-        unsafe {
-            while secs > 0 || nsecs > 0 {
-                let mut ts = libc::timespec {
-                    tv_sec: cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t,
-                    tv_nsec: nsecs,
-                };
-                secs -= ts.tv_sec as u64;
-                let ts_ptr = &raw mut ts;
-                if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
-                    assert_eq!(os::errno(), libc::EINTR);
-                    secs += ts.tv_sec as u64;
-                    nsecs = ts.tv_nsec;
-                } else {
-                    nsecs = 0;
-                }
-            }
-        }
-    }
-
-    #[cfg(target_os = "espidf")]
-    pub fn sleep(dur: Duration) {
-        // ESP-IDF does not have `nanosleep`, so we use `usleep` instead.
-        // As per the documentation of `usleep`, it is expected to support
-        // sleep times as big as at least up to 1 second.
-        //
-        // ESP-IDF does support almost up to `u32::MAX`, but due to a potential integer overflow in its
-        // `usleep` implementation
-        // (https://github.com/espressif/esp-idf/blob/d7ca8b94c852052e3bc33292287ef4dd62c9eeb1/components/newlib/time.c#L210),
-        // we limit the sleep time to the maximum one that would not cause the underlying `usleep` implementation to overflow
-        // (`portTICK_PERIOD_MS` can be anything between 1 to 1000, and is 10 by default).
-        const MAX_MICROS: u32 = u32::MAX - 1_000_000 - 1;
-
-        // Add any nanoseconds smaller than a microsecond as an extra microsecond
-        // so as to comply with the `std::thread::sleep` contract which mandates
-        // implementations to sleep for _at least_ the provided `dur`.
-        // We can't overflow `micros` as it is a `u128`, while `Duration` is a pair of
-        // (`u64` secs, `u32` nanos), where the nanos are strictly smaller than 1 second
-        // (i.e. < 1_000_000_000)
-        let mut micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 };
-
-        while micros > 0 {
-            let st = if micros > MAX_MICROS as u128 { MAX_MICROS } else { micros as u32 };
-            unsafe {
-                libc::usleep(st);
-            }
-
-            micros -= st as u128;
-        }
-    }
-
-    // Any unix that has clock_nanosleep
-    // If this list changes update the MIRI chock_nanosleep shim
-    #[cfg(any(
-        target_os = "freebsd",
-        target_os = "netbsd",
-        target_os = "linux",
-        target_os = "android",
-        target_os = "solaris",
-        target_os = "illumos",
-        target_os = "dragonfly",
-        target_os = "hurd",
-        target_os = "fuchsia",
-        target_os = "vxworks",
-    ))]
-    pub fn sleep_until(deadline: Instant) {
-        let Some(ts) = deadline.into_inner().into_timespec().to_timespec() else {
-            // The deadline is further in the future then can be passed to
-            // clock_nanosleep. We have to use Self::sleep instead. This might
-            // happen on 32 bit platforms, especially closer to 2038.
-            let now = Instant::now();
-            if let Some(delay) = deadline.checked_duration_since(now) {
-                Self::sleep(delay);
-            }
-            return;
-        };
-
-        unsafe {
-            // When we get interrupted (res = EINTR) call clock_nanosleep again
-            loop {
-                let res = libc::clock_nanosleep(
-                    super::time::Instant::CLOCK_ID,
-                    libc::TIMER_ABSTIME,
-                    &ts,
-                    core::ptr::null_mut(), // not required with TIMER_ABSTIME
-                );
-
-                if res == 0 {
-                    break;
-                } else {
-                    assert_eq!(
-                        res,
-                        libc::EINTR,
-                        "timespec is in range,
-                         clockid is valid and kernel should support it"
-                    );
-                }
-            }
-        }
-    }
-
-    // Any unix that does not have clock_nanosleep
-    #[cfg(not(any(
-        target_os = "freebsd",
-        target_os = "netbsd",
-        target_os = "linux",
-        target_os = "android",
-        target_os = "solaris",
-        target_os = "illumos",
-        target_os = "dragonfly",
-        target_os = "hurd",
-        target_os = "fuchsia",
-        target_os = "vxworks",
-    )))]
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
     pub fn join(self) {
         let id = self.into_id();
         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
@@ -410,84 +151,6 @@ impl Drop for Thread {
     }
 }
 
-pub(crate) fn current_os_id() -> Option<u64> {
-    // Most Unix platforms have a way to query an integer ID of the current thread, all with
-    // slightly different spellings.
-    //
-    // The OS thread ID is used rather than `pthread_self` so as to match what will be displayed
-    // for process inspection (debuggers, trace, `top`, etc.).
-    cfg_select! {
-        // Most platforms have a function returning a `pid_t` or int, which is an `i32`.
-        any(target_os = "android", target_os = "linux") => {
-            use crate::sys::weak::syscall;
-
-            // `libc::gettid` is only available on glibc 2.30+, but the syscall is available
-            // since Linux 2.4.11.
-            syscall!(fn gettid() -> libc::pid_t;);
-
-            // SAFETY: FFI call with no preconditions.
-            let id: libc::pid_t = unsafe { gettid() };
-            Some(id as u64)
-        }
-        target_os = "nto" => {
-            // SAFETY: FFI call with no preconditions.
-            let id: libc::pid_t = unsafe { libc::gettid() };
-            Some(id as u64)
-        }
-        target_os = "openbsd" => {
-            // SAFETY: FFI call with no preconditions.
-            let id: libc::pid_t = unsafe { libc::getthrid() };
-            Some(id as u64)
-        }
-        target_os = "freebsd" => {
-            // SAFETY: FFI call with no preconditions.
-            let id: libc::c_int = unsafe { libc::pthread_getthreadid_np() };
-            Some(id as u64)
-        }
-        target_os = "netbsd" => {
-            // SAFETY: FFI call with no preconditions.
-            let id: libc::lwpid_t = unsafe { libc::_lwp_self() };
-            Some(id as u64)
-        }
-        any(target_os = "illumos", target_os = "solaris") => {
-            // On Illumos and Solaris, the `pthread_t` is the same as the OS thread ID.
-            // SAFETY: FFI call with no preconditions.
-            let id: libc::pthread_t = unsafe { libc::pthread_self() };
-            Some(id as u64)
-        }
-        target_vendor = "apple" => {
-            // Apple allows querying arbitrary thread IDs, `thread=NULL` queries the current thread.
-            let mut id = 0u64;
-            // SAFETY: `thread_id` is a valid pointer, no other preconditions.
-            let status: libc::c_int = unsafe { libc::pthread_threadid_np(0, &mut id) };
-            if status == 0 {
-                Some(id)
-            } else {
-                None
-            }
-        }
-        // Other platforms don't have an OS thread ID or don't have a way to access it.
-        _ => None,
-    }
-}
-
-#[cfg(any(
-    target_os = "linux",
-    target_os = "nto",
-    target_os = "solaris",
-    target_os = "illumos",
-    target_os = "vxworks",
-    target_os = "cygwin",
-    target_vendor = "apple",
-))]
-fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] {
-    let mut result = [0; MAX_WITH_NUL];
-    for (src, dst) in cstr.to_bytes().iter().zip(&mut result[..MAX_WITH_NUL - 1]) {
-        *dst = *src as libc::c_char;
-    }
-    result
-}
-
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     cfg_select! {
         any(
@@ -668,6 +331,318 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     }
 }
 
+pub fn current_os_id() -> Option<u64> {
+    // Most Unix platforms have a way to query an integer ID of the current thread, all with
+    // slightly different spellings.
+    //
+    // The OS thread ID is used rather than `pthread_self` so as to match what will be displayed
+    // for process inspection (debuggers, trace, `top`, etc.).
+    cfg_select! {
+        // Most platforms have a function returning a `pid_t` or int, which is an `i32`.
+        any(target_os = "android", target_os = "linux") => {
+            use crate::sys::pal::weak::syscall;
+
+            // `libc::gettid` is only available on glibc 2.30+, but the syscall is available
+            // since Linux 2.4.11.
+            syscall!(fn gettid() -> libc::pid_t;);
+
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pid_t = unsafe { gettid() };
+            Some(id as u64)
+        }
+        target_os = "nto" => {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pid_t = unsafe { libc::gettid() };
+            Some(id as u64)
+        }
+        target_os = "openbsd" => {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pid_t = unsafe { libc::getthrid() };
+            Some(id as u64)
+        }
+        target_os = "freebsd" => {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::c_int = unsafe { libc::pthread_getthreadid_np() };
+            Some(id as u64)
+        }
+        target_os = "netbsd" => {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::lwpid_t = unsafe { libc::_lwp_self() };
+            Some(id as u64)
+        }
+        any(target_os = "illumos", target_os = "solaris") => {
+            // On Illumos and Solaris, the `pthread_t` is the same as the OS thread ID.
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pthread_t = unsafe { libc::pthread_self() };
+            Some(id as u64)
+        }
+        target_vendor = "apple" => {
+            // Apple allows querying arbitrary thread IDs, `thread=NULL` queries the current thread.
+            let mut id = 0u64;
+            // SAFETY: `thread_id` is a valid pointer, no other preconditions.
+            let status: libc::c_int = unsafe { libc::pthread_threadid_np(0, &mut id) };
+            if status == 0 {
+                Some(id)
+            } else {
+                None
+            }
+        }
+        // Other platforms don't have an OS thread ID or don't have a way to access it.
+        _ => None,
+    }
+}
+
+#[cfg(any(
+    target_os = "linux",
+    target_os = "nto",
+    target_os = "solaris",
+    target_os = "illumos",
+    target_os = "vxworks",
+    target_os = "cygwin",
+    target_vendor = "apple",
+))]
+fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] {
+    let mut result = [0; MAX_WITH_NUL];
+    for (src, dst) in cstr.to_bytes().iter().zip(&mut result[..MAX_WITH_NUL - 1]) {
+        *dst = *src as libc::c_char;
+    }
+    result
+}
+
+#[cfg(target_os = "android")]
+pub fn set_name(name: &CStr) {
+    const PR_SET_NAME: libc::c_int = 15;
+    unsafe {
+        let res = libc::prctl(
+            PR_SET_NAME,
+            name.as_ptr(),
+            0 as libc::c_ulong,
+            0 as libc::c_ulong,
+            0 as libc::c_ulong,
+        );
+        // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked.
+        debug_assert_eq!(res, 0);
+    }
+}
+
+#[cfg(any(
+    target_os = "linux",
+    target_os = "freebsd",
+    target_os = "dragonfly",
+    target_os = "nuttx",
+    target_os = "cygwin"
+))]
+pub fn set_name(name: &CStr) {
+    unsafe {
+        cfg_select! {
+            any(target_os = "linux", target_os = "cygwin") => {
+                // Linux and Cygwin limits the allowed length of the name.
+                const TASK_COMM_LEN: usize = 16;
+                let name = truncate_cstr::<{ TASK_COMM_LEN }>(name);
+            }
+            _ => {
+                // FreeBSD, DragonFly BSD and NuttX do not enforce length limits.
+            }
+        };
+        // Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20 for Linux,
+        // FreeBSD 12.2 and 13.0, and DragonFly BSD 6.0.
+        let res = libc::pthread_setname_np(libc::pthread_self(), name.as_ptr());
+        // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked.
+        debug_assert_eq!(res, 0);
+    }
+}
+
+#[cfg(target_os = "openbsd")]
+pub fn set_name(name: &CStr) {
+    unsafe {
+        libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());
+    }
+}
+
+#[cfg(target_vendor = "apple")]
+pub fn set_name(name: &CStr) {
+    unsafe {
+        let name = truncate_cstr::<{ libc::MAXTHREADNAMESIZE }>(name);
+        let res = libc::pthread_setname_np(name.as_ptr());
+        // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked.
+        debug_assert_eq!(res, 0);
+    }
+}
+
+#[cfg(target_os = "netbsd")]
+pub fn set_name(name: &CStr) {
+    unsafe {
+        let res = libc::pthread_setname_np(
+            libc::pthread_self(),
+            c"%s".as_ptr(),
+            name.as_ptr() as *mut libc::c_void,
+        );
+        debug_assert_eq!(res, 0);
+    }
+}
+
+#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))]
+pub fn set_name(name: &CStr) {
+    weak!(
+        fn pthread_setname_np(thread: libc::pthread_t, name: *const libc::c_char) -> libc::c_int;
+    );
+
+    if let Some(f) = pthread_setname_np.get() {
+        #[cfg(target_os = "nto")]
+        const THREAD_NAME_MAX: usize = libc::_NTO_THREAD_NAME_MAX as usize;
+        #[cfg(any(target_os = "solaris", target_os = "illumos"))]
+        const THREAD_NAME_MAX: usize = 32;
+
+        let name = truncate_cstr::<{ THREAD_NAME_MAX }>(name);
+        let res = unsafe { f(libc::pthread_self(), name.as_ptr()) };
+        debug_assert_eq!(res, 0);
+    }
+}
+
+#[cfg(target_os = "fuchsia")]
+pub fn set_name(name: &CStr) {
+    use crate::sys::pal::fuchsia::*;
+    unsafe {
+        zx_object_set_property(
+            zx_thread_self(),
+            ZX_PROP_NAME,
+            name.as_ptr() as *const libc::c_void,
+            name.to_bytes().len(),
+        );
+    }
+}
+
+#[cfg(target_os = "haiku")]
+pub fn set_name(name: &CStr) {
+    unsafe {
+        let thread_self = libc::find_thread(ptr::null_mut());
+        let res = libc::rename_thread(thread_self, name.as_ptr());
+        // We have no good way of propagating errors here, but in debug-builds let's check that this actually worked.
+        debug_assert_eq!(res, libc::B_OK);
+    }
+}
+
+#[cfg(target_os = "vxworks")]
+pub fn set_name(name: &CStr) {
+    let mut name = truncate_cstr::<{ (libc::VX_TASK_RENAME_LENGTH - 1) as usize }>(name);
+    let res = unsafe { libc::taskNameSet(libc::taskIdSelf(), name.as_mut_ptr()) };
+    debug_assert_eq!(res, libc::OK);
+}
+
+#[cfg(not(target_os = "espidf"))]
+pub fn sleep(dur: Duration) {
+    let mut secs = dur.as_secs();
+    let mut nsecs = dur.subsec_nanos() as _;
+
+    // If we're awoken with a signal then the return value will be -1 and
+    // nanosleep will fill in `ts` with the remaining time.
+    unsafe {
+        while secs > 0 || nsecs > 0 {
+            let mut ts = libc::timespec {
+                tv_sec: cmp::min(libc::time_t::MAX as u64, secs) as libc::time_t,
+                tv_nsec: nsecs,
+            };
+            secs -= ts.tv_sec as u64;
+            let ts_ptr = &raw mut ts;
+            if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
+                assert_eq!(os::errno(), libc::EINTR);
+                secs += ts.tv_sec as u64;
+                nsecs = ts.tv_nsec;
+            } else {
+                nsecs = 0;
+            }
+        }
+    }
+}
+
+#[cfg(target_os = "espidf")]
+pub fn sleep(dur: Duration) {
+    // ESP-IDF does not have `nanosleep`, so we use `usleep` instead.
+    // As per the documentation of `usleep`, it is expected to support
+    // sleep times as big as at least up to 1 second.
+    //
+    // ESP-IDF does support almost up to `u32::MAX`, but due to a potential integer overflow in its
+    // `usleep` implementation
+    // (https://github.com/espressif/esp-idf/blob/d7ca8b94c852052e3bc33292287ef4dd62c9eeb1/components/newlib/time.c#L210),
+    // we limit the sleep time to the maximum one that would not cause the underlying `usleep` implementation to overflow
+    // (`portTICK_PERIOD_MS` can be anything between 1 to 1000, and is 10 by default).
+    const MAX_MICROS: u32 = u32::MAX - 1_000_000 - 1;
+
+    // Add any nanoseconds smaller than a microsecond as an extra microsecond
+    // so as to comply with the `std::thread::sleep` contract which mandates
+    // implementations to sleep for _at least_ the provided `dur`.
+    // We can't overflow `micros` as it is a `u128`, while `Duration` is a pair of
+    // (`u64` secs, `u32` nanos), where the nanos are strictly smaller than 1 second
+    // (i.e. < 1_000_000_000)
+    let mut micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 };
+
+    while micros > 0 {
+        let st = if micros > MAX_MICROS as u128 { MAX_MICROS } else { micros as u32 };
+        unsafe {
+            libc::usleep(st);
+        }
+
+        micros -= st as u128;
+    }
+}
+
+// Any unix that has clock_nanosleep
+// If this list changes update the MIRI chock_nanosleep shim
+#[cfg(any(
+    target_os = "freebsd",
+    target_os = "netbsd",
+    target_os = "linux",
+    target_os = "android",
+    target_os = "solaris",
+    target_os = "illumos",
+    target_os = "dragonfly",
+    target_os = "hurd",
+    target_os = "fuchsia",
+    target_os = "vxworks",
+))]
+pub fn sleep_until(deadline: crate::time::Instant) {
+    use crate::time::Instant;
+
+    let Some(ts) = deadline.into_inner().into_timespec().to_timespec() else {
+        // The deadline is further in the future then can be passed to
+        // clock_nanosleep. We have to use Self::sleep instead. This might
+        // happen on 32 bit platforms, especially closer to 2038.
+        let now = Instant::now();
+        if let Some(delay) = deadline.checked_duration_since(now) {
+            sleep(delay);
+        }
+        return;
+    };
+
+    unsafe {
+        // When we get interrupted (res = EINTR) call clock_nanosleep again
+        loop {
+            let res = libc::clock_nanosleep(
+                crate::sys::time::Instant::CLOCK_ID,
+                libc::TIMER_ABSTIME,
+                &ts,
+                core::ptr::null_mut(), // not required with TIMER_ABSTIME
+            );
+
+            if res == 0 {
+                break;
+            } else {
+                assert_eq!(
+                    res,
+                    libc::EINTR,
+                    "timespec is in range,
+                         clockid is valid and kernel should support it"
+                );
+            }
+        }
+    }
+}
+
+pub fn yield_now() {
+    let ret = unsafe { libc::sched_yield() };
+    debug_assert_eq!(ret, 0);
+}
+
 #[cfg(any(target_os = "android", target_os = "linux"))]
 mod cgroups {
     //! Currently not covered
diff --git a/library/std/src/sys/pal/unsupported/thread.rs b/library/std/src/sys/thread/unsupported.rs
index 34d9b5ec70c..a5001efa3b4 100644
--- a/library/std/src/sys/pal/unsupported/thread.rs
+++ b/library/std/src/sys/thread/unsupported.rs
@@ -1,8 +1,7 @@
-use super::unsupported;
 use crate::ffi::CStr;
 use crate::io;
 use crate::num::NonZero;
-use crate::time::{Duration, Instant};
+use crate::time::Duration;
 
 pub struct Thread(!);
 
@@ -15,23 +14,7 @@ impl Thread {
         _name: Option<&str>,
         _p: Box<dyn FnOnce()>,
     ) -> io::Result<Thread> {
-        unsupported()
-    }
-
-    pub fn yield_now() {
-        // do nothing
-    }
-
-    pub fn set_name(_name: &CStr) {
-        // nope
-    }
-
-    pub fn sleep(_dur: Duration) {
-        panic!("can't sleep");
-    }
-
-    pub fn sleep_until(_deadline: Instant) {
-        panic!("can't sleep");
+        Err(io::Error::UNSUPPORTED_PLATFORM)
     }
 
     pub fn join(self) {
@@ -39,10 +22,22 @@ impl Thread {
     }
 }
 
-pub(crate) fn current_os_id() -> Option<u64> {
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
+    Err(io::Error::UNKNOWN_THREAD_COUNT)
+}
+
+pub fn current_os_id() -> Option<u64> {
     None
 }
 
-pub fn available_parallelism() -> io::Result<NonZero<usize>> {
-    unsupported()
+pub fn yield_now() {
+    // do nothing
+}
+
+pub fn set_name(_name: &CStr) {
+    // nope
+}
+
+pub fn sleep(_dur: Duration) {
+    panic!("can't sleep");
 }
diff --git a/library/std/src/sys/thread/wasip1.rs b/library/std/src/sys/thread/wasip1.rs
new file mode 100644
index 00000000000..83001fad49c
--- /dev/null
+++ b/library/std/src/sys/thread/wasip1.rs
@@ -0,0 +1,185 @@
+#![forbid(unsafe_op_in_unsafe_fn)]
+
+#[cfg(target_feature = "atomics")]
+use crate::io;
+use crate::mem;
+#[cfg(target_feature = "atomics")]
+use crate::num::NonZero;
+#[cfg(target_feature = "atomics")]
+use crate::sys::os;
+use crate::time::Duration;
+#[cfg(target_feature = "atomics")]
+use crate::{cmp, ptr};
+
+// Add a few symbols not in upstream `libc` just yet.
+#[cfg(target_feature = "atomics")]
+mod libc {
+    pub use libc::*;
+
+    pub use crate::ffi;
+
+    // defined in wasi-libc
+    // https://github.com/WebAssembly/wasi-libc/blob/a6f871343313220b76009827ed0153586361c0d5/libc-top-half/musl/include/alltypes.h.in#L108
+    #[repr(C)]
+    union pthread_attr_union {
+        __i: [ffi::c_int; if size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
+        __vi: [ffi::c_int; if size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
+        __s: [ffi::c_ulong; if size_of::<ffi::c_long>() == 8 { 7 } else { 9 }],
+    }
+
+    #[repr(C)]
+    pub struct pthread_attr_t {
+        __u: pthread_attr_union,
+    }
+
+    #[allow(non_camel_case_types)]
+    pub type pthread_t = *mut ffi::c_void;
+
+    pub const _SC_NPROCESSORS_ONLN: ffi::c_int = 84;
+
+    unsafe extern "C" {
+        pub fn pthread_create(
+            native: *mut pthread_t,
+            attr: *const pthread_attr_t,
+            f: extern "C" fn(*mut ffi::c_void) -> *mut ffi::c_void,
+            value: *mut ffi::c_void,
+        ) -> ffi::c_int;
+        pub fn pthread_join(native: pthread_t, value: *mut *mut ffi::c_void) -> ffi::c_int;
+        pub fn pthread_attr_init(attrp: *mut pthread_attr_t) -> ffi::c_int;
+        pub fn pthread_attr_setstacksize(
+            attr: *mut pthread_attr_t,
+            stack_size: libc::size_t,
+        ) -> ffi::c_int;
+        pub fn pthread_attr_destroy(attr: *mut pthread_attr_t) -> ffi::c_int;
+        pub fn pthread_detach(thread: pthread_t) -> ffi::c_int;
+    }
+}
+
+#[cfg(target_feature = "atomics")]
+pub struct Thread {
+    id: libc::pthread_t,
+}
+
+#[cfg(target_feature = "atomics")]
+impl Drop for Thread {
+    fn drop(&mut self) {
+        let ret = unsafe { libc::pthread_detach(self.id) };
+        debug_assert_eq!(ret, 0);
+    }
+}
+
+pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
+
+#[cfg(target_feature = "atomics")]
+impl Thread {
+    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
+    pub unsafe fn new(
+        stack: usize,
+        _name: Option<&str>,
+        p: Box<dyn FnOnce()>,
+    ) -> io::Result<Thread> {
+        let p = Box::into_raw(Box::new(p));
+        let mut native: libc::pthread_t = unsafe { mem::zeroed() };
+        let mut attr: libc::pthread_attr_t = unsafe { mem::zeroed() };
+        assert_eq!(unsafe { libc::pthread_attr_init(&mut attr) }, 0);
+
+        let stack_size = cmp::max(stack, DEFAULT_MIN_STACK_SIZE);
+
+        match unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) } {
+            0 => {}
+            n => {
+                assert_eq!(n, libc::EINVAL);
+                // EINVAL means |stack_size| is either too small or not a
+                // multiple of the system page size. Because it's definitely
+                // >= PTHREAD_STACK_MIN, it must be an alignment issue.
+                // Round up to the nearest page and try again.
+                let page_size = os::page_size();
+                let stack_size =
+                    (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
+                assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0);
+            }
+        };
+
+        let ret = unsafe { libc::pthread_create(&mut native, &attr, thread_start, p as *mut _) };
+        // Note: if the thread creation fails and this assert fails, then p will
+        // be leaked. However, an alternative design could cause double-free
+        // which is clearly worse.
+        assert_eq!(unsafe { libc::pthread_attr_destroy(&mut attr) }, 0);
+
+        return if ret != 0 {
+            // The thread failed to start and as a result p was not consumed. Therefore, it is
+            // safe to reconstruct the box so that it gets deallocated.
+            unsafe {
+                drop(Box::from_raw(p));
+            }
+            Err(io::Error::from_raw_os_error(ret))
+        } else {
+            Ok(Thread { id: native })
+        };
+
+        extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
+            unsafe {
+                // Finally, let's run some code.
+                Box::from_raw(main as *mut Box<dyn FnOnce()>)();
+            }
+            ptr::null_mut()
+        }
+    }
+
+    pub fn join(self) {
+        let id = mem::ManuallyDrop::new(self).id;
+        let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
+        if ret != 0 {
+            rtabort!("failed to join thread: {}", io::Error::from_raw_os_error(ret));
+        }
+    }
+}
+
+#[cfg(target_feature = "atomics")]
+pub fn available_parallelism() -> io::Result<NonZero<usize>> {
+    match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } {
+        -1 => Err(io::Error::last_os_error()),
+        cpus => NonZero::new(cpus as usize).ok_or(io::Error::UNKNOWN_THREAD_COUNT),
+    }
+}
+
+pub fn yield_now() {
+    let ret = unsafe { wasi::sched_yield() };
+    debug_assert_eq!(ret, Ok(()));
+}
+
+pub fn sleep(dur: Duration) {
+    let mut nanos = dur.as_nanos();
+    while nanos > 0 {
+        const USERDATA: wasi::Userdata = 0x0123_45678;
+
+        let clock = wasi::SubscriptionClock {
+            id: wasi::CLOCKID_MONOTONIC,
+            timeout: u64::try_from(nanos).unwrap_or(u64::MAX),
+            precision: 0,
+            flags: 0,
+        };
+        nanos -= u128::from(clock.timeout);
+
+        let in_ = wasi::Subscription {
+            userdata: USERDATA,
+            u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } },
+        };
+        unsafe {
+            let mut event: wasi::Event = mem::zeroed();
+            let res = wasi::poll_oneoff(&in_, &mut event, 1);
+            match (res, event) {
+                (
+                    Ok(1),
+                    wasi::Event {
+                        userdata: USERDATA,
+                        error: wasi::ERRNO_SUCCESS,
+                        type_: wasi::EVENTTYPE_CLOCK,
+                        ..
+                    },
+                ) => {}
+                _ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
+            }
+        }
+    }
+}
diff --git a/library/std/src/sys/thread/wasip2.rs b/library/std/src/sys/thread/wasip2.rs
new file mode 100644
index 00000000000..420cad2a5e4
--- /dev/null
+++ b/library/std/src/sys/thread/wasip2.rs
@@ -0,0 +1,32 @@
+use crate::time::{Duration, Instant};
+
+pub fn sleep(dur: Duration) {
+    // Sleep in increments of `u64::MAX` nanoseconds until the `dur` is
+    // entirely drained.
+    let mut remaining = dur.as_nanos();
+    while remaining > 0 {
+        let amt = u64::try_from(remaining).unwrap_or(u64::MAX);
+        wasip2::clocks::monotonic_clock::subscribe_duration(amt).block();
+        remaining -= u128::from(amt);
+    }
+}
+
+pub fn sleep_until(deadline: Instant) {
+    match u64::try_from(deadline.into_inner().as_duration().as_nanos()) {
+        // If the point in time we're sleeping to fits within a 64-bit
+        // number of nanoseconds then directly use `subscribe_instant`.
+        Ok(deadline) => {
+            wasip2::clocks::monotonic_clock::subscribe_instant(deadline).block();
+        }
+        // ... otherwise we're sleeping for 500+ years relative to the
+        // "start" of what the system is using as a clock so speed/accuracy
+        // is not so much of a concern. Use `sleep` instead.
+        Err(_) => {
+            let now = Instant::now();
+
+            if let Some(delay) = deadline.checked_duration_since(now) {
+                sleep(delay);
+            }
+        }
+    }
+}
diff --git a/library/std/src/sys/thread/wasm.rs b/library/std/src/sys/thread/wasm.rs
new file mode 100644
index 00000000000..e843bc992ba
--- /dev/null
+++ b/library/std/src/sys/thread/wasm.rs
@@ -0,0 +1,23 @@
+use crate::cmp;
+use crate::time::Duration;
+
+pub fn sleep(dur: Duration) {
+    #[cfg(target_arch = "wasm32")]
+    use core::arch::wasm32 as wasm;
+    #[cfg(target_arch = "wasm64")]
+    use core::arch::wasm64 as wasm;
+
+    // Use an atomic wait to block the current thread artificially with a
+    // timeout listed. Note that we should never be notified (return value
+    // of 0) or our comparison should never fail (return value of 1) so we
+    // should always only resume execution through a timeout (return value
+    // 2).
+    let mut nanos = dur.as_nanos();
+    while nanos > 0 {
+        let amt = cmp::min(i64::MAX as u128, nanos);
+        let mut x = 0;
+        let val = unsafe { wasm::memory_atomic_wait32(&mut x, 0, amt as i64) };
+        debug_assert_eq!(val, 2);
+        nanos -= amt;
+    }
+}
diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/thread/windows.rs
index b0e38220a2d..a5640c51c4a 100644
--- a/library/std/src/sys/pal/windows/thread.rs
+++ b/library/std/src/sys/thread/windows.rs
@@ -1,14 +1,14 @@
 use core::ffi::c_void;
 
-use super::time::WaitableTimer;
-use super::to_u16s;
 use crate::ffi::CStr;
 use crate::num::NonZero;
 use crate::os::windows::io::{AsRawHandle, HandleOrNull};
 use crate::sys::handle::Handle;
+use crate::sys::pal::time::WaitableTimer;
+use crate::sys::pal::{dur2timeout, to_u16s};
 use crate::sys::{c, stack_overflow};
 use crate::sys_common::FromInner;
-use crate::time::{Duration, Instant};
+use crate::time::Duration;
 use crate::{io, ptr};
 
 pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
@@ -62,24 +62,6 @@ impl Thread {
         }
     }
 
-    pub fn set_name(name: &CStr) {
-        if let Ok(utf8) = name.to_str() {
-            if let Ok(utf16) = to_u16s(utf8) {
-                unsafe {
-                    // SAFETY: the vec returned by `to_u16s` ends with a zero value
-                    Self::set_name_wide(&utf16)
-                }
-            };
-        };
-    }
-
-    /// # Safety
-    ///
-    /// `name` must end with a zero value
-    pub unsafe fn set_name_wide(name: &[u16]) {
-        unsafe { c::SetThreadDescription(c::GetCurrentThread(), name.as_ptr()) };
-    }
-
     pub fn join(self) {
         let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) };
         if rc == c::WAIT_FAILED {
@@ -87,37 +69,6 @@ impl Thread {
         }
     }
 
-    pub fn yield_now() {
-        // This function will return 0 if there are no other threads to execute,
-        // but this also means that the yield was useless so this isn't really a
-        // case that needs to be worried about.
-        unsafe {
-            c::SwitchToThread();
-        }
-    }
-
-    pub fn sleep(dur: Duration) {
-        fn high_precision_sleep(dur: Duration) -> Result<(), ()> {
-            let timer = WaitableTimer::high_resolution()?;
-            timer.set(dur)?;
-            timer.wait()
-        }
-        // Attempt to use high-precision sleep (Windows 10, version 1803+).
-        // On error fallback to the standard `Sleep` function.
-        // Also preserves the zero duration behavior of `Sleep`.
-        if dur.is_zero() || high_precision_sleep(dur).is_err() {
-            unsafe { c::Sleep(super::dur2timeout(dur)) }
-        }
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
     pub fn handle(&self) -> &Handle {
         &self.handle
     }
@@ -127,14 +78,6 @@ impl Thread {
     }
 }
 
-pub(crate) fn current_os_id() -> Option<u64> {
-    // SAFETY: FFI call with no preconditions.
-    let id: u32 = unsafe { c::GetCurrentThreadId() };
-
-    // A return value of 0 indicates failed lookup.
-    if id == 0 { None } else { Some(id.into()) }
-}
-
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     let res = unsafe {
         let mut sysinfo: c::SYSTEM_INFO = crate::mem::zeroed();
@@ -146,3 +89,52 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
         cpus => Ok(unsafe { NonZero::new_unchecked(cpus) }),
     }
 }
+
+pub fn current_os_id() -> Option<u64> {
+    // SAFETY: FFI call with no preconditions.
+    let id: u32 = unsafe { c::GetCurrentThreadId() };
+
+    // A return value of 0 indicates failed lookup.
+    if id == 0 { None } else { Some(id.into()) }
+}
+
+pub fn set_name(name: &CStr) {
+    if let Ok(utf8) = name.to_str() {
+        if let Ok(utf16) = to_u16s(utf8) {
+            unsafe {
+                // SAFETY: the vec returned by `to_u16s` ends with a zero value
+                set_name_wide(&utf16)
+            }
+        };
+    };
+}
+
+/// # Safety
+///
+/// `name` must end with a zero value
+pub unsafe fn set_name_wide(name: &[u16]) {
+    unsafe { c::SetThreadDescription(c::GetCurrentThread(), name.as_ptr()) };
+}
+
+pub fn sleep(dur: Duration) {
+    fn high_precision_sleep(dur: Duration) -> Result<(), ()> {
+        let timer = WaitableTimer::high_resolution()?;
+        timer.set(dur)?;
+        timer.wait()
+    }
+    // Attempt to use high-precision sleep (Windows 10, version 1803+).
+    // On error fallback to the standard `Sleep` function.
+    // Also preserves the zero duration behavior of `Sleep`.
+    if dur.is_zero() || high_precision_sleep(dur).is_err() {
+        unsafe { c::Sleep(dur2timeout(dur)) }
+    }
+}
+
+pub fn yield_now() {
+    // This function will return 0 if there are no other threads to execute,
+    // but this also means that the yield was useless so this isn't really a
+    // case that needs to be worried about.
+    unsafe {
+        c::SwitchToThread();
+    }
+}
diff --git a/library/std/src/sys/pal/xous/thread.rs b/library/std/src/sys/thread/xous.rs
index 92803c94c6e..133e15a0928 100644
--- a/library/std/src/sys/pal/xous/thread.rs
+++ b/library/std/src/sys/thread/xous.rs
@@ -1,6 +1,5 @@
 use core::arch::asm;
 
-use crate::ffi::CStr;
 use crate::io;
 use crate::num::NonZero;
 use crate::os::xous::ffi::{
@@ -8,7 +7,7 @@ use crate::os::xous::ffi::{
     map_memory, update_memory_flags,
 };
 use crate::os::xous::services::{TicktimerScalar, ticktimer_server};
-use crate::time::{Duration, Instant};
+use crate::time::Duration;
 
 pub struct Thread {
     tid: ThreadId,
@@ -110,46 +109,29 @@ impl Thread {
         Ok(Thread { tid })
     }
 
-    pub fn yield_now() {
-        do_yield();
-    }
-
-    pub fn set_name(_name: &CStr) {
-        // nope
-    }
-
-    pub fn sleep(dur: Duration) {
-        // Because the sleep server works on units of `usized milliseconds`, split
-        // the messages up into these chunks. This means we may run into issues
-        // if you try to sleep a thread for more than 49 days on a 32-bit system.
-        let mut millis = dur.as_millis();
-        while millis > 0 {
-            let sleep_duration =
-                if millis > (usize::MAX as _) { usize::MAX } else { millis as usize };
-            blocking_scalar(ticktimer_server(), TicktimerScalar::SleepMs(sleep_duration).into())
-                .expect("failed to send message to ticktimer server");
-            millis -= sleep_duration as u128;
-        }
-    }
-
-    pub fn sleep_until(deadline: Instant) {
-        let now = Instant::now();
-
-        if let Some(delay) = deadline.checked_duration_since(now) {
-            Self::sleep(delay);
-        }
-    }
-
     pub fn join(self) {
         join_thread(self.tid).unwrap();
     }
 }
 
-pub(crate) fn current_os_id() -> Option<u64> {
-    None
-}
-
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     // We're unicore right now.
     Ok(unsafe { NonZero::new_unchecked(1) })
 }
+
+pub fn yield_now() {
+    do_yield();
+}
+
+pub fn sleep(dur: Duration) {
+    // Because the sleep server works on units of `usized milliseconds`, split
+    // the messages up into these chunks. This means we may run into issues
+    // if you try to sleep a thread for more than 49 days on a 32-bit system.
+    let mut millis = dur.as_millis();
+    while millis > 0 {
+        let sleep_duration = if millis > (usize::MAX as _) { usize::MAX } else { millis as usize };
+        blocking_scalar(ticktimer_server(), TicktimerScalar::SleepMs(sleep_duration).into())
+            .expect("failed to send message to ticktimer server");
+        millis -= sleep_duration as u128;
+    }
+}
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index b6059c28cec..4d09b2b4e9d 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -550,7 +550,7 @@ impl Builder {
             }
 
             if let Some(name) = their_thread.cname() {
-                imp::Thread::set_name(name);
+                imp::set_name(name);
             }
 
             let f = f.into_inner();
@@ -763,7 +763,7 @@ where
 /// [`Mutex`]: crate::sync::Mutex
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn yield_now() {
-    imp::Thread::yield_now()
+    imp::yield_now()
 }
 
 /// Determines whether the current thread is unwinding because of panic.
@@ -884,7 +884,7 @@ pub fn sleep_ms(ms: u32) {
 /// ```
 #[stable(feature = "thread_sleep", since = "1.4.0")]
 pub fn sleep(dur: Duration) {
-    imp::Thread::sleep(dur)
+    imp::sleep(dur)
 }
 
 /// Puts the current thread to sleep until the specified deadline has passed.
@@ -983,7 +983,7 @@ pub fn sleep(dur: Duration) {
 /// ```
 #[unstable(feature = "thread_sleep_until", issue = "113752")]
 pub fn sleep_until(deadline: Instant) {
-    imp::Thread::sleep_until(deadline)
+    imp::sleep_until(deadline)
 }
 
 /// Used to ensure that `park` and `park_timeout` do not unwind, as that can
@@ -1021,13 +1021,23 @@ impl Drop for PanicGuard {
 ///   specifying a maximum time to block the thread for.
 ///
 /// * The [`unpark`] method on a [`Thread`] atomically makes the token available
-///   if it wasn't already. Because the token is initially absent, [`unpark`]
-///   followed by [`park`] will result in the second call returning immediately.
-///
-/// The API is typically used by acquiring a handle to the current thread,
-/// placing that handle in a shared data structure so that other threads can
-/// find it, and then `park`ing in a loop. When some desired condition is met, another
-/// thread calls [`unpark`] on the handle.
+///   if it wasn't already. Because the token can be held by a thread even if it is currently not
+///   parked, [`unpark`] followed by [`park`] will result in the second call returning immediately.
+///   However, note that to rely on this guarantee, you need to make sure that your `unpark` happens
+///   after all `park` that may be done by other data structures!
+///
+/// The API is typically used by acquiring a handle to the current thread, placing that handle in a
+/// shared data structure so that other threads can find it, and then `park`ing in a loop. When some
+/// desired condition is met, another thread calls [`unpark`] on the handle. The last bullet point
+/// above guarantees that even if the `unpark` occurs before the thread is finished `park`ing, it
+/// will be woken up properly.
+///
+/// Note that the coordination via the shared data structure is crucial: If you `unpark` a thread
+/// without first establishing that it is about to be `park`ing within your code, that `unpark` may
+/// get consumed by a *different* `park` in the same thread, leading to a deadlock. This also means
+/// you must not call unknown code between setting up for parking and calling `park`; for instance,
+/// if you invoke `println!`, that may itself call `park` and thus consume your `unpark` and cause a
+/// deadlock.
 ///
 /// The motivation for this design is twofold:
 ///
@@ -1058,21 +1068,24 @@ impl Drop for PanicGuard {
 ///
 /// ```
 /// use std::thread;
-/// use std::sync::{Arc, atomic::{Ordering, AtomicBool}};
+/// use std::sync::atomic::{Ordering, AtomicBool};
 /// use std::time::Duration;
 ///
-/// let flag = Arc::new(AtomicBool::new(false));
-/// let flag2 = Arc::clone(&flag);
+/// static QUEUED: AtomicBool = AtomicBool::new(false);
+/// static FLAG: AtomicBool = AtomicBool::new(false);
 ///
 /// let parked_thread = thread::spawn(move || {
+///     println!("Thread spawned");
+///     // Signal that we are going to `park`. Between this store and our `park`, there may
+///     // be no other `park`, or else that `park` could consume our `unpark` token!
+///     QUEUED.store(true, Ordering::Release);
 ///     // We want to wait until the flag is set. We *could* just spin, but using
 ///     // park/unpark is more efficient.
-///     while !flag2.load(Ordering::Relaxed) {
-///         println!("Parking thread");
+///     while !FLAG.load(Ordering::Acquire) {
+///         // We can *not* use `println!` here since that could use thread parking internally.
 ///         thread::park();
 ///         // We *could* get here spuriously, i.e., way before the 10ms below are over!
 ///         // But that is no problem, we are in a loop until the flag is set anyway.
-///         println!("Thread unparked");
 ///     }
 ///     println!("Flag received");
 /// });
@@ -1080,11 +1093,22 @@ impl Drop for PanicGuard {
 /// // Let some time pass for the thread to be spawned.
 /// thread::sleep(Duration::from_millis(10));
 ///
+/// // Ensure the thread is about to park.
+/// // This is crucial! It guarantees that the `unpark` below is not consumed
+/// // by some other code in the parked thread (e.g. inside `println!`).
+/// while !QUEUED.load(Ordering::Acquire) {
+///     // Spinning is of course inefficient; in practice, this would more likely be
+///     // a dequeue where we have no work to do if there's nobody queued.
+///     std::hint::spin_loop();
+/// }
+///
 /// // Set the flag, and let the thread wake up.
-/// // There is no race condition here, if `unpark`
+/// // There is no race condition here: if `unpark`
 /// // happens first, `park` will return immediately.
+/// // There is also no other `park` that could consume this token,
+/// // since we waited until the other thread got queued.
 /// // Hence there is no risk of a deadlock.
-/// flag.store(true, Ordering::Relaxed);
+/// FLAG.store(true, Ordering::Release);
 /// println!("Unpark the thread");
 /// parked_thread.thread().unpark();
 ///
@@ -1494,10 +1518,14 @@ impl Thread {
     /// ```
     /// use std::thread;
     /// use std::time::Duration;
+    /// use std::sync::atomic::{AtomicBool, Ordering};
+    ///
+    /// static QUEUED: AtomicBool = AtomicBool::new(false);
     ///
     /// let parked_thread = thread::Builder::new()
     ///     .spawn(|| {
     ///         println!("Parking thread");
+    ///         QUEUED.store(true, Ordering::Release);
     ///         thread::park();
     ///         println!("Thread unparked");
     ///     })
@@ -1506,6 +1534,15 @@ impl Thread {
     /// // Let some time pass for the thread to be spawned.
     /// thread::sleep(Duration::from_millis(10));
     ///
+    /// // Wait until the other thread is queued.
+    /// // This is crucial! It guarantees that the `unpark` below is not consumed
+    /// // by some other code in the parked thread (e.g. inside `println!`).
+    /// while !QUEUED.load(Ordering::Acquire) {
+    ///     // Spinning is of course inefficient; in practice, this would more likely be
+    ///     // a dequeue where we have no work to do if there's nobody queued.
+    ///     std::hint::spin_loop();
+    /// }
+    ///
     /// println!("Unpark the thread");
     /// parked_thread.thread().unpark();
     ///
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index ae889f1e778..2117f5f93ce 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -287,6 +287,8 @@ fn test_park_unpark_called_other_thread() {
     for _ in 0..10 {
         let th = thread::current();
 
+        // Here we rely on `thread::spawn` (specifically the part that runs after spawning
+        // the thread) to not consume the parking token.
         let _guard = thread::spawn(move || {
             super::sleep(Duration::from_millis(50));
             th.unpark();
@@ -316,6 +318,8 @@ fn test_park_timeout_unpark_called_other_thread() {
     for _ in 0..10 {
         let th = thread::current();
 
+        // Here we rely on `thread::spawn` (specifically the part that runs after spawning
+        // the thread) to not consume the parking token.
         let _guard = thread::spawn(move || {
             super::sleep(Duration::from_millis(50));
             th.unpark();
diff --git a/library/std/tests/sync/rwlock.rs b/library/std/tests/sync/rwlock.rs
index eca15d2a4ad..2554316e907 100644
--- a/library/std/tests/sync/rwlock.rs
+++ b/library/std/tests/sync/rwlock.rs
@@ -50,7 +50,7 @@ nonpoison_and_poison_unwrap_test!(
 // FIXME: On macOS we use a provenance-incorrect implementation and Miri
 // catches that issue with a chance of around 1/1000.
 // See <https://github.com/rust-lang/rust/issues/121950> for details.
-#[cfg_attr(all(miri, target_os = "macos"), ignore)]
+#[cfg(not(all(miri, target_os = "macos")))]
 nonpoison_and_poison_unwrap_test!(
     name: frob,
     test_body: {
@@ -315,7 +315,7 @@ nonpoison_and_poison_unwrap_test!(
 
 // FIXME: On macOS we use a provenance-incorrect implementation and Miri catches that issue.
 // See <https://github.com/rust-lang/rust/issues/121950> for details.
-#[cfg_attr(all(miri, target_os = "macos"), ignore)]
+#[cfg(not(all(miri, target_os = "macos")))]
 nonpoison_and_poison_unwrap_test!(
     name: test_downgrade_observe,
     test_body: {
@@ -362,7 +362,7 @@ nonpoison_and_poison_unwrap_test!(
 
 // FIXME: On macOS we use a provenance-incorrect implementation and Miri catches that issue.
 // See <https://github.com/rust-lang/rust/issues/121950> for details.
-#[cfg_attr(all(miri, target_os = "macos"), ignore)]
+#[cfg(not(all(miri, target_os = "macos")))]
 nonpoison_and_poison_unwrap_test!(
     name: test_downgrade_atomic,
     test_body: {
diff --git a/library/std_detect/src/detect/os/linux/aarch64.rs b/library/std_detect/src/detect/os/linux/aarch64.rs
index 87a9d6ebb88..b733b8a9eb2 100644
--- a/library/std_detect/src/detect/os/linux/aarch64.rs
+++ b/library/std_detect/src/detect/os/linux/aarch64.rs
@@ -140,7 +140,7 @@ struct AtHwcap {
 impl From<auxvec::AuxVec> for AtHwcap {
     /// Reads AtHwcap from the auxiliary vector.
     fn from(auxv: auxvec::AuxVec) -> Self {
-        AtHwcap {
+        let mut cap = AtHwcap {
             fp: bit::test(auxv.hwcap, 0),
             asimd: bit::test(auxv.hwcap, 1),
             // evtstrm: bit::test(auxv.hwcap, 2),
@@ -207,39 +207,50 @@ impl From<auxvec::AuxVec> for AtHwcap {
             // smef32f32: bit::test(auxv.hwcap2, 29),
             smefa64: bit::test(auxv.hwcap2, 30),
             wfxt: bit::test(auxv.hwcap2, 31),
-            // ebf16: bit::test(auxv.hwcap2, 32),
-            // sveebf16: bit::test(auxv.hwcap2, 33),
-            cssc: bit::test(auxv.hwcap2, 34),
-            // rprfm: bit::test(auxv.hwcap2, 35),
-            sve2p1: bit::test(auxv.hwcap2, 36),
-            sme2: bit::test(auxv.hwcap2, 37),
-            sme2p1: bit::test(auxv.hwcap2, 38),
-            // smei16i32: bit::test(auxv.hwcap2, 39),
-            // smebi32i32: bit::test(auxv.hwcap2, 40),
-            smeb16b16: bit::test(auxv.hwcap2, 41),
-            smef16f16: bit::test(auxv.hwcap2, 42),
-            mops: bit::test(auxv.hwcap2, 43),
-            hbc: bit::test(auxv.hwcap2, 44),
-            sveb16b16: bit::test(auxv.hwcap2, 45),
-            lrcpc3: bit::test(auxv.hwcap2, 46),
-            lse128: bit::test(auxv.hwcap2, 47),
-            fpmr: bit::test(auxv.hwcap2, 48),
-            lut: bit::test(auxv.hwcap2, 49),
-            faminmax: bit::test(auxv.hwcap2, 50),
-            f8cvt: bit::test(auxv.hwcap2, 51),
-            f8fma: bit::test(auxv.hwcap2, 52),
-            f8dp4: bit::test(auxv.hwcap2, 53),
-            f8dp2: bit::test(auxv.hwcap2, 54),
-            f8e4m3: bit::test(auxv.hwcap2, 55),
-            f8e5m2: bit::test(auxv.hwcap2, 56),
-            smelutv2: bit::test(auxv.hwcap2, 57),
-            smef8f16: bit::test(auxv.hwcap2, 58),
-            smef8f32: bit::test(auxv.hwcap2, 59),
-            smesf8fma: bit::test(auxv.hwcap2, 60),
-            smesf8dp4: bit::test(auxv.hwcap2, 61),
-            smesf8dp2: bit::test(auxv.hwcap2, 62),
-            // pauthlr: bit::test(auxv.hwcap2, ??),
+            ..Default::default()
+        };
+
+        // Hardware capabilities from bits 32 to 63 should only
+        // be tested on LP64 targets with 64 bits `usize`.
+        // On ILP32 targets like `aarch64-unknown-linux-gnu_ilp32`,
+        // these hardware capabilities will default to `false`.
+        // https://github.com/rust-lang/rust/issues/146230
+        #[cfg(target_pointer_width = "64")]
+        {
+            // cap.ebf16: bit::test(auxv.hwcap2, 32);
+            // cap.sveebf16: bit::test(auxv.hwcap2, 33);
+            cap.cssc = bit::test(auxv.hwcap2, 34);
+            // cap.rprfm: bit::test(auxv.hwcap2, 35);
+            cap.sve2p1 = bit::test(auxv.hwcap2, 36);
+            cap.sme2 = bit::test(auxv.hwcap2, 37);
+            cap.sme2p1 = bit::test(auxv.hwcap2, 38);
+            // cap.smei16i32 = bit::test(auxv.hwcap2, 39);
+            // cap.smebi32i32 = bit::test(auxv.hwcap2, 40);
+            cap.smeb16b16 = bit::test(auxv.hwcap2, 41);
+            cap.smef16f16 = bit::test(auxv.hwcap2, 42);
+            cap.mops = bit::test(auxv.hwcap2, 43);
+            cap.hbc = bit::test(auxv.hwcap2, 44);
+            cap.sveb16b16 = bit::test(auxv.hwcap2, 45);
+            cap.lrcpc3 = bit::test(auxv.hwcap2, 46);
+            cap.lse128 = bit::test(auxv.hwcap2, 47);
+            cap.fpmr = bit::test(auxv.hwcap2, 48);
+            cap.lut = bit::test(auxv.hwcap2, 49);
+            cap.faminmax = bit::test(auxv.hwcap2, 50);
+            cap.f8cvt = bit::test(auxv.hwcap2, 51);
+            cap.f8fma = bit::test(auxv.hwcap2, 52);
+            cap.f8dp4 = bit::test(auxv.hwcap2, 53);
+            cap.f8dp2 = bit::test(auxv.hwcap2, 54);
+            cap.f8e4m3 = bit::test(auxv.hwcap2, 55);
+            cap.f8e5m2 = bit::test(auxv.hwcap2, 56);
+            cap.smelutv2 = bit::test(auxv.hwcap2, 57);
+            cap.smef8f16 = bit::test(auxv.hwcap2, 58);
+            cap.smef8f32 = bit::test(auxv.hwcap2, 59);
+            cap.smesf8fma = bit::test(auxv.hwcap2, 60);
+            cap.smesf8dp4 = bit::test(auxv.hwcap2, 61);
+            cap.smesf8dp2 = bit::test(auxv.hwcap2, 62);
+            // cap.pauthlr = bit::test(auxv.hwcap2, ??);
         }
+        cap
     }
 }
 
diff --git a/package-lock.json b/package-lock.json
index def0cfa86a5..d0297bf70b6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,7 +5,7 @@
   "packages": {
     "": {
       "dependencies": {
-        "browser-ui-test": "^0.22.0",
+        "browser-ui-test": "^0.22.2",
         "es-check": "^6.2.1",
         "eslint": "^8.57.1",
         "eslint-js": "github:eslint/js",
@@ -485,9 +485,9 @@
       }
     },
     "node_modules/browser-ui-test": {
-      "version": "0.22.0",
-      "resolved": "https://registry.npmjs.org/browser-ui-test/-/browser-ui-test-0.22.0.tgz",
-      "integrity": "sha512-p/C02TMybTDKsAjpGOdnyNC0Q25KDae/fKMnvHaqcJ0tXRqNKwndW2Ltq7HTmin5xqg8GGOmysEgWTZkXu6pfA==",
+      "version": "0.22.2",
+      "resolved": "https://registry.npmjs.org/browser-ui-test/-/browser-ui-test-0.22.2.tgz",
+      "integrity": "sha512-eNB/PN2yDGe5n5IwE3ld/N6A39jM1oRzJmT5nOVQqrvoZEtcd9JSggDQPNVUnMEyuGcD4OEOWMsEa4oJppAmDQ==",
       "license": "MIT",
       "dependencies": {
         "css-unit-converter": "^1.1.2",
diff --git a/package.json b/package.json
index 976d6303634..04e0f6af19a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "dependencies": {
-    "browser-ui-test": "^0.22.0",
+    "browser-ui-test": "^0.22.2",
     "es-check": "^6.2.1",
     "eslint": "^8.57.1",
     "eslint-js": "github:eslint/js",
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 6c5b48d8c8f..9ad9cb5b526 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -95,8 +95,8 @@ target | notes
 `arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2+, glibc 2.17)
 `armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2+, glibc 2.17)
 [`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | Armv7-A OpenHarmony
-[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19+, glibc 2.36)
-[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19+, musl 1.2.5)
+[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19+, glibc 2.36), LSX required
+[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19+, musl 1.2.5), LSX required
 [`i686-pc-windows-gnu`](platform-support/windows-gnu.md) | 32-bit MinGW (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI] [^win32-msvc-alignment]
 `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2+, glibc 2.17)
 `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2+, glibc 2.17)
diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md
index 817d3a89230..a923218282c 100644
--- a/src/doc/rustc/src/platform-support/loongarch-linux.md
+++ b/src/doc/rustc/src/platform-support/loongarch-linux.md
@@ -7,8 +7,8 @@ LoongArch is a RISC ISA developed by Loongson Technology Corporation Limited.
 
 | Target | Description |
 |--------|-------------|
-| `loongarch64-unknown-linux-gnu` | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36) |
-| `loongarch64-unknown-linux-musl` | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5) |
+| `loongarch64-unknown-linux-gnu` | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36), LSX required |
+| `loongarch64-unknown-linux-musl` | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5), LSX required |
 
 These support both native and cross builds, and have full support for `std`.
 
@@ -23,8 +23,6 @@ Reference material:
 ## Target maintainers
 
 [@heiher](https://github.com/heiher)
-[@xiangzhai](https://github.com/xiangzhai)
-[@zhaixiaojuan](https://github.com/zhaixiaojuan)
 [@xen0n](https://github.com/xen0n)
 
 ## Requirements
@@ -46,8 +44,8 @@ The targets require a reasonably up-to-date LoongArch toolchain on the host.
 Currently the following components are used by the Rust CI to build the target,
 and the versions can be seen as the minimum requirement:
 
-* GNU Binutils 2.40
-* GCC 13.x
+* GNU Binutils 2.42
+* GCC 14.x
 * glibc 2.36
 * linux-headers 5.19
 
@@ -59,6 +57,11 @@ for newer LoongArch ELF relocation types, among other features.
 Recent LLVM/Clang toolchains may be able to build the targets, but are not
 currently being actively tested.
 
+### CPU features
+
+These targets require the double-precision floating-point and LSX (LoongArch
+SIMD Extension) features.
+
 ## Building
 
 These targets are distributed through `rustup`, and otherwise require no
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
index f70bdf4e4fe..06256d61151 100644
--- a/src/librustdoc/passes/lint/bare_urls.rs
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -17,7 +17,10 @@ use crate::core::DocContext;
 use crate::html::markdown::main_body_opts;
 
 pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
-    let report_diag = |cx: &DocContext<'_>, msg: &'static str, range: Range<usize>| {
+    let report_diag = |cx: &DocContext<'_>,
+                       msg: &'static str,
+                       range: Range<usize>,
+                       without_brackets: Option<&str>| {
         let maybe_sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings)
             .map(|(sp, _)| sp);
         let sp = maybe_sp.unwrap_or_else(|| item.attr_span(cx.tcx));
@@ -27,14 +30,22 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
             // The fallback of using the attribute span is suitable for
             // highlighting where the error is, but not for placing the < and >
             if let Some(sp) = maybe_sp {
-                lint.multipart_suggestion(
-                    "use an automatic link instead",
-                    vec![
-                        (sp.shrink_to_lo(), "<".to_string()),
-                        (sp.shrink_to_hi(), ">".to_string()),
-                    ],
-                    Applicability::MachineApplicable,
-                );
+                if let Some(without_brackets) = without_brackets {
+                    lint.multipart_suggestion(
+                        "use an automatic link instead",
+                        vec![(sp, format!("<{without_brackets}>"))],
+                        Applicability::MachineApplicable,
+                    );
+                } else {
+                    lint.multipart_suggestion(
+                        "use an automatic link instead",
+                        vec![
+                            (sp.shrink_to_lo(), "<".to_string()),
+                            (sp.shrink_to_hi(), ">".to_string()),
+                        ],
+                        Applicability::MachineApplicable,
+                    );
+                }
             }
         });
     };
@@ -43,7 +54,7 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
 
     while let Some((event, range)) = p.next() {
         match event {
-            Event::Text(s) => find_raw_urls(cx, &s, range, &report_diag),
+            Event::Text(s) => find_raw_urls(cx, dox, &s, range, &report_diag),
             // We don't want to check the text inside code blocks or links.
             Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link { .. })) => {
                 for (event, _) in p.by_ref() {
@@ -67,25 +78,35 @@ static URL_REGEX: LazyLock<Regex> = LazyLock::new(|| {
         r"https?://",                          // url scheme
         r"([-a-zA-Z0-9@:%._\+~#=]{2,256}\.)+", // one or more subdomains
         r"[a-zA-Z]{2,63}",                     // root domain
-        r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)"      // optional query or url fragments
+        r"\b([-a-zA-Z0-9@:%_\+.~#?&/=]*)",     // optional query or url fragments
     ))
     .expect("failed to build regex")
 });
 
 fn find_raw_urls(
     cx: &DocContext<'_>,
+    dox: &str,
     text: &str,
     range: Range<usize>,
-    f: &impl Fn(&DocContext<'_>, &'static str, Range<usize>),
+    f: &impl Fn(&DocContext<'_>, &'static str, Range<usize>, Option<&str>),
 ) {
     trace!("looking for raw urls in {text}");
     // For now, we only check "full" URLs (meaning, starting with "http://" or "https://").
     for match_ in URL_REGEX.find_iter(text) {
-        let url_range = match_.range();
-        f(
-            cx,
-            "this URL is not a hyperlink",
-            Range { start: range.start + url_range.start, end: range.start + url_range.end },
-        );
+        let mut url_range = match_.range();
+        url_range.start += range.start;
+        url_range.end += range.start;
+        let mut without_brackets = None;
+        // If the link is contained inside `[]`, then we need to replace the brackets and
+        // not just add `<>`.
+        if dox[..url_range.start].ends_with('[')
+            && url_range.end <= dox.len()
+            && dox[url_range.end..].starts_with(']')
+        {
+            url_range.start -= 1;
+            url_range.end += 1;
+            without_brackets = Some(match_.as_str());
+        }
+        f(cx, "this URL is not a hyperlink", url_range, without_brackets);
     }
 }
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 761c4658d0079d607e6d33cf0c060e61a617cad
+Subproject 24bb93c388fb8c211a37986539f24a819dc669d
diff --git a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
index 788a04357b1..cf0c85990b1 100644
--- a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
@@ -11,7 +11,7 @@ use rustc_ast::{BinOpKind, LitKind, RangeLimits};
 use rustc_data_structures::packed::Pu128;
 use rustc_data_structures::unhash::UnindexMap;
 use rustc_errors::{Applicability, Diag};
-use rustc_hir::{Body, Expr, ExprKind};
+use rustc_hir::{Block, Body, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
@@ -135,12 +135,12 @@ fn assert_len_expr<'hir>(
     cx: &LateContext<'_>,
     expr: &'hir Expr<'hir>,
 ) -> Option<(LengthComparison, usize, &'hir Expr<'hir>)> {
-    let (cmp, asserted_len, slice_len) = if let Some(
-        higher::IfLetOrMatch::Match(cond, [_, then], _)
-    ) = higher::IfLetOrMatch::parse(cx, expr)
-        && let ExprKind::Binary(bin_op, left, right) = &cond.kind
+    let (cmp, asserted_len, slice_len) = if let Some(higher::If { cond, then, .. }) = higher::If::hir(expr)
+        && let ExprKind::Unary(UnOp::Not, condition) = &cond.kind
+        && let ExprKind::Binary(bin_op, left, right) = &condition.kind
         // check if `then` block has a never type expression
-        && cx.typeck_results().expr_ty(then.body).is_never()
+        && let ExprKind::Block(Block { expr: Some(then_expr), .. }, _) = then.kind
+        && cx.typeck_results().expr_ty(then_expr).is_never()
     {
         len_comparison(bin_op.node, left, right)?
     } else if let Some((macro_call, bin_op)) = first_node_macro_backtrace(cx, expr).find_map(|macro_call| {
diff --git a/src/tools/clippy/tests/ui/const_is_empty.rs b/src/tools/clippy/tests/ui/const_is_empty.rs
index 63c6342a323..8bb4f0e5d97 100644
--- a/src/tools/clippy/tests/ui/const_is_empty.rs
+++ b/src/tools/clippy/tests/ui/const_is_empty.rs
@@ -196,7 +196,6 @@ fn issue_13106() {
 
     const {
         assert!(EMPTY_STR.is_empty());
-        //~^ const_is_empty
     }
 
     const {
diff --git a/src/tools/clippy/tests/ui/const_is_empty.stderr b/src/tools/clippy/tests/ui/const_is_empty.stderr
index 9a42518698e..2ba189058e8 100644
--- a/src/tools/clippy/tests/ui/const_is_empty.stderr
+++ b/src/tools/clippy/tests/ui/const_is_empty.stderr
@@ -158,16 +158,10 @@ LL |     let _ = val.is_empty();
    |             ^^^^^^^^^^^^^^
 
 error: this expression always evaluates to true
-  --> tests/ui/const_is_empty.rs:198:17
-   |
-LL |         assert!(EMPTY_STR.is_empty());
-   |                 ^^^^^^^^^^^^^^^^^^^^
-
-error: this expression always evaluates to true
-  --> tests/ui/const_is_empty.rs:203:9
+  --> tests/ui/const_is_empty.rs:202:9
    |
 LL |         EMPTY_STR.is_empty();
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 28 previous errors
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.rs b/src/tools/clippy/tests/ui/incompatible_msrv.rs
index 882f909e30c..f7f21e1850d 100644
--- a/src/tools/clippy/tests/ui/incompatible_msrv.rs
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::incompatible_msrv)]
 #![feature(custom_inner_attributes)]
-#![allow(stable_features, clippy::diverging_sub_expression)]
+#![allow(stable_features)]
 #![feature(strict_provenance)] // For use in test
 #![clippy::msrv = "1.3.0"]
 
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 517aa343a6d..d433ee8daaa 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -606,6 +606,7 @@ Definite bugs found:
 * [A bug in the new `RwLock::downgrade` implementation](https://rust-lang.zulipchat.com/#narrow/channel/269128-miri/topic/Miri.20error.20library.20test) (caught by Miri before it landed in the Rust repo)
 * [Mockall reading uninitialized memory when mocking `std::io::Read::read`, even if all expectations are satisfied](https://github.com/asomers/mockall/issues/647) (caught by Miri running Tokio's test suite)
 * [`ReentrantLock` not correctly dealing with reuse of addresses for TLS storage of different threads](https://github.com/rust-lang/rust/pull/141248)
+* [Rare Deadlock in the thread (un)parking example code](https://github.com/rust-lang/rust/issues/145816)
 
 Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):
 
diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr
index bcec5557a3f..c7c1a769cda 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr
@@ -8,13 +8,13 @@ LL |             assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _
    = note: inside closure at tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC
 
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
    |                                                                  ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr
index 51533cd17a8..ae8b2b936a7 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr
@@ -8,13 +8,13 @@ LL |             assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mu
    = note: inside closure at tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC
 
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
    |                                                                  ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr
index 63fc7ce346e..dfa9a6e2583 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr
@@ -8,13 +8,13 @@ LL |             assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mu
    = note: inside closure at tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC
 
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
    |                                                                  ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr
index d8a3e058da9..47a0ebdcfef 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_detached.stderr
@@ -1,5 +1,5 @@
 error: Undefined Behavior: trying to join a detached thread
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) };
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
@@ -7,7 +7,7 @@ LL |         let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr
index 079f01c0e54..3b1181c92fd 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.stderr
@@ -9,13 +9,13 @@ LL |             assert_eq!(WaitForSingleObject(MAIN_THREAD, INFINITE), WAIT_OBJ
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) };
    |                                                                                          ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr
index 70de94f56ba..6eefa2da1d8 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.stderr
@@ -8,13 +8,13 @@ LL |             assert_eq!(WaitForSingleObject(native, INFINITE), WAIT_OBJECT_0
    = note: inside closure at tests/fail-dep/concurrency/windows_join_self.rs:LL:CC
 
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) };
    |                                                                                          ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr
index 4f3a56fef82..6dd6c36ab65 100644
--- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr
+++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_read_twice.stderr
@@ -1,11 +1,11 @@
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
    |                                                                  ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr
index 5045badaa87..3154197b95e 100644
--- a/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr
+++ b/src/tools/miri/tests/fail-dep/libc/eventfd_block_write_twice.stderr
@@ -1,11 +1,11 @@
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
    |                                                                  ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr
index 3713c8da392..1af44c107ff 100644
--- a/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr
+++ b/src/tools/miri/tests/fail-dep/libc/libc_epoll_block_two_thread.stderr
@@ -5,13 +5,13 @@ error: the evaluated program deadlocked
    = note: BACKTRACE on thread `unnamed-ID`:
 
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
    |                                                                  ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr
index 47fc889b001..b85470225c6 100644
--- a/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair-close-while-blocked.stderr
@@ -1,11 +1,11 @@
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
    |                                                                  ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr
index 99d242ec7da..bbd2ab1c4d8 100644
--- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_read_twice.stderr
@@ -1,11 +1,11 @@
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
    |                                                                  ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr
index f766500d331..c3cc2068173 100644
--- a/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr
+++ b/src/tools/miri/tests/fail-dep/libc/socketpair_block_write_twice.stderr
@@ -1,11 +1,11 @@
 error: the evaluated program deadlocked
-  --> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+  --> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    |
 LL |         let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
    |                                                                  ^ this thread got stuck here
    |
    = note: BACKTRACE:
-   = note: inside `std::sys::pal::PLATFORM::thread::Thread::join` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
+   = note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
    = note: inside `std::thread::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
    = note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/mod.rs:LL:CC
 note: inside `main`
diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs
index 321ef65117e..a6b50b5ca47 100644
--- a/src/tools/tidy/src/extra_checks/mod.rs
+++ b/src/tools/tidy/src/extra_checks/mod.rs
@@ -124,6 +124,12 @@ fn check_impl(
         };
     }
 
+    let rerun_with_bless = |mode: &str, action: &str| {
+        if !bless {
+            eprintln!("rerun tidy with `--extra-checks={mode} --bless` to {action}");
+        }
+    };
+
     let python_lint = extra_check!(Py, Lint);
     let python_fmt = extra_check!(Py, Fmt);
     let shell_lint = extra_check!(Shell, Lint);
@@ -147,14 +153,21 @@ fn check_impl(
     }
 
     if python_lint {
-        eprintln!("linting python files");
         let py_path = py_path.as_ref().unwrap();
-        let res = run_ruff(root_path, outdir, py_path, &cfg_args, &file_args, &["check".as_ref()]);
+        let args: &[&OsStr] = if bless {
+            eprintln!("linting python files and applying suggestions");
+            &["check".as_ref(), "--fix".as_ref()]
+        } else {
+            eprintln!("linting python files");
+            &["check".as_ref()]
+        };
+
+        let res = run_ruff(root_path, outdir, py_path, &cfg_args, &file_args, args);
 
-        if res.is_err() && show_diff {
+        if res.is_err() && show_diff && !bless {
             eprintln!("\npython linting failed! Printing diff suggestions:");
 
-            let _ = run_ruff(
+            let diff_res = run_ruff(
                 root_path,
                 outdir,
                 py_path,
@@ -162,6 +175,10 @@ fn check_impl(
                 &file_args,
                 &["check".as_ref(), "--diff".as_ref()],
             );
+            // `ruff check --diff` will return status 0 if there are no suggestions.
+            if diff_res.is_err() {
+                rerun_with_bless("py:lint", "apply ruff suggestions");
+            }
         }
         // Rethrow error
         res?;
@@ -192,7 +209,7 @@ fn check_impl(
                     &["format".as_ref(), "--diff".as_ref()],
                 );
             }
-            eprintln!("rerun tidy with `--extra-checks=py:fmt --bless` to reformat Python code");
+            rerun_with_bless("py:fmt", "reformat Python code");
         }
 
         // Rethrow error
@@ -225,7 +242,7 @@ fn check_impl(
         let args = merge_args(&cfg_args_clang_format, &file_args_clang_format);
         let res = py_runner(py_path.as_ref().unwrap(), false, None, "clang-format", &args);
 
-        if res.is_err() && show_diff {
+        if res.is_err() && show_diff && !bless {
             eprintln!("\nclang-format linting failed! Printing diff suggestions:");
 
             let mut cfg_args_clang_format_diff = cfg_args.clone();
@@ -265,6 +282,7 @@ fn check_impl(
                     );
                 }
             }
+            rerun_with_bless("cpp:fmt", "reformat C++ code");
         }
         // Rethrow error
         res?;
@@ -290,12 +308,16 @@ fn check_impl(
         args.extend_from_slice(SPELLCHECK_DIRS);
 
         if bless {
-            eprintln!("spellcheck files and fix");
+            eprintln!("spellchecking files and fixing typos");
             args.push("--write-changes");
         } else {
-            eprintln!("spellcheck files");
+            eprintln!("spellchecking files");
         }
-        spellcheck_runner(root_path, &outdir, &cargo, &args)?;
+        let res = spellcheck_runner(root_path, &outdir, &cargo, &args);
+        if res.is_err() {
+            rerun_with_bless("spellcheck", "fix typos");
+        }
+        res?;
     }
 
     if js_lint || js_typecheck {
@@ -303,11 +325,21 @@ fn check_impl(
     }
 
     if js_lint {
-        rustdoc_js::lint(outdir, librustdoc_path, tools_path, bless)?;
+        if bless {
+            eprintln!("linting javascript files");
+        } else {
+            eprintln!("linting javascript files and applying suggestions");
+        }
+        let res = rustdoc_js::lint(outdir, librustdoc_path, tools_path, bless);
+        if res.is_err() {
+            rerun_with_bless("js:lint", "apply eslint suggestions");
+        }
+        res?;
         rustdoc_js::es_check(outdir, librustdoc_path)?;
     }
 
     if js_typecheck {
+        eprintln!("typechecking javascript files");
         rustdoc_js::typecheck(outdir, librustdoc_path)?;
     }
 
diff --git a/src/tools/tidy/src/extra_checks/rustdoc_js.rs b/src/tools/tidy/src/extra_checks/rustdoc_js.rs
index a6c66b8be80..5137e618367 100644
--- a/src/tools/tidy/src/extra_checks/rustdoc_js.rs
+++ b/src/tools/tidy/src/extra_checks/rustdoc_js.rs
@@ -57,7 +57,7 @@ fn run_eslint(
             if exit_status.success() {
                 return Ok(());
             }
-            Err(super::Error::FailedCheck("eslint command failed"))
+            Err(super::Error::FailedCheck("eslint"))
         }
         Err(error) => Err(super::Error::Generic(format!("eslint command failed: {error:?}"))),
     }
@@ -94,7 +94,7 @@ pub(super) fn typecheck(outdir: &Path, librustdoc_path: &Path) -> Result<(), sup
             if exit_status.success() {
                 return Ok(());
             }
-            Err(super::Error::FailedCheck("tsc command failed"))
+            Err(super::Error::FailedCheck("tsc"))
         }
         Err(error) => Err(super::Error::Generic(format!("tsc command failed: {error:?}"))),
     }
@@ -112,7 +112,7 @@ pub(super) fn es_check(outdir: &Path, librustdoc_path: &Path) -> Result<(), supe
             if exit_status.success() {
                 return Ok(());
             }
-            Err(super::Error::FailedCheck("es-check command failed"))
+            Err(super::Error::FailedCheck("es-check"))
         }
         Err(error) => Err(super::Error::Generic(format!("es-check command failed: {error:?}"))),
     }
diff --git a/tests/assembly-llvm/c-variadic-arm.rs b/tests/assembly-llvm/c-variadic-arm.rs
new file mode 100644
index 00000000000..2ef307405e1
--- /dev/null
+++ b/tests/assembly-llvm/c-variadic-arm.rs
@@ -0,0 +1,26 @@
+//@ assembly-output: emit-asm
+//@ compile-flags: -Copt-level=3
+//@ only-arm
+//@ ignore-thumb
+//@ ignore-android
+#![no_std]
+#![crate_type = "lib"]
+#![feature(c_variadic)]
+
+// Check that the assembly that rustc generates matches what clang emits.
+
+#[unsafe(no_mangle)]
+unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
+    // CHECK-LABEL: variadic
+    // CHECK: sub sp, sp
+
+    // CHECK: vldr
+    // CHECK: vadd.f64
+    // CHECK: vldr
+    // CHECK: vadd.f64
+    let b = args.arg::<f64>();
+    let c = args.arg::<f64>();
+    a + b + c
+
+    // CHECK: add sp, sp
+}
diff --git a/tests/codegen-llvm/c-variadic-lifetime.rs b/tests/codegen-llvm/c-variadic-lifetime.rs
new file mode 100644
index 00000000000..5b2f8af18c8
--- /dev/null
+++ b/tests/codegen-llvm/c-variadic-lifetime.rs
@@ -0,0 +1,21 @@
+//@ add-core-stubs
+//@ compile-flags: -Copt-level=3
+#![feature(c_variadic)]
+#![crate_type = "lib"]
+
+// Check that `%args` explicitly has its lifetime start and end. Being explicit can improve
+// instruction and register selection, see e.g. https://github.com/rust-lang/rust/pull/144549
+
+#[unsafe(no_mangle)]
+unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
+    // CHECK: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %args)
+    // CHECK: call void @llvm.va_start.p0(ptr nonnull %args)
+
+    let b = args.arg::<f64>();
+    let c = args.arg::<f64>();
+
+    a + b + c
+
+    // CHECK: call void @llvm.va_end.p0(ptr nonnull %args)
+    // CHECK: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %args)
+}
diff --git a/tests/rustdoc-ui/lints/bare-urls.fixed b/tests/rustdoc-ui/lints/bare-urls.fixed
index a91573146b8..ac63e291c5b 100644
--- a/tests/rustdoc-ui/lints/bare-urls.fixed
+++ b/tests/rustdoc-ui/lints/bare-urls.fixed
@@ -68,3 +68,17 @@ pub mod foo {
     /// https://somewhere.com/a?hello=12&bye=11#xyz
     pub fn bar() {}
 }
+
+/// <https://bloob.blob>
+//~^ ERROR this URL is not a hyperlink
+/// [ <https://bloob.blob> ]
+//~^ ERROR this URL is not a hyperlink
+/// [ <https://bloob.blob>]
+//~^ ERROR this URL is not a hyperlink
+/// [<https://bloob.blob> ]
+//~^ ERROR this URL is not a hyperlink
+/// [<https://bloob.blob>
+//~^ ERROR this URL is not a hyperlink
+/// <https://bloob.blob>]
+//~^ ERROR this URL is not a hyperlink
+pub fn lint_with_brackets() {}
diff --git a/tests/rustdoc-ui/lints/bare-urls.rs b/tests/rustdoc-ui/lints/bare-urls.rs
index 5b008cdafa2..a70a3ec822e 100644
--- a/tests/rustdoc-ui/lints/bare-urls.rs
+++ b/tests/rustdoc-ui/lints/bare-urls.rs
@@ -68,3 +68,17 @@ pub mod foo {
     /// https://somewhere.com/a?hello=12&bye=11#xyz
     pub fn bar() {}
 }
+
+/// [https://bloob.blob]
+//~^ ERROR this URL is not a hyperlink
+/// [ https://bloob.blob ]
+//~^ ERROR this URL is not a hyperlink
+/// [ https://bloob.blob]
+//~^ ERROR this URL is not a hyperlink
+/// [https://bloob.blob ]
+//~^ ERROR this URL is not a hyperlink
+/// [https://bloob.blob
+//~^ ERROR this URL is not a hyperlink
+/// https://bloob.blob]
+//~^ ERROR this URL is not a hyperlink
+pub fn lint_with_brackets() {}
diff --git a/tests/rustdoc-ui/lints/bare-urls.stderr b/tests/rustdoc-ui/lints/bare-urls.stderr
index e1108c7e7f8..fc3c642f5aa 100644
--- a/tests/rustdoc-ui/lints/bare-urls.stderr
+++ b/tests/rustdoc-ui/lints/bare-urls.stderr
@@ -243,5 +243,73 @@ help: use an automatic link instead
 LL | #[doc = "<https://example.com/raw>"]
    |          +                       +
 
-error: aborting due to 20 previous errors
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls.rs:72:5
+   |
+LL | /// [https://bloob.blob]
+   |     ^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://bloob.blob>`
+   |
+   = note: bare URLs are not automatically turned into clickable links
+
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls.rs:74:7
+   |
+LL | /// [ https://bloob.blob ]
+   |       ^^^^^^^^^^^^^^^^^^
+   |
+   = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// [ <https://bloob.blob> ]
+   |       +                  +
+
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls.rs:76:7
+   |
+LL | /// [ https://bloob.blob]
+   |       ^^^^^^^^^^^^^^^^^^
+   |
+   = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// [ <https://bloob.blob>]
+   |       +                  +
+
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls.rs:78:6
+   |
+LL | /// [https://bloob.blob ]
+   |      ^^^^^^^^^^^^^^^^^^
+   |
+   = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// [<https://bloob.blob> ]
+   |      +                  +
+
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls.rs:80:6
+   |
+LL | /// [https://bloob.blob
+   |      ^^^^^^^^^^^^^^^^^^
+   |
+   = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// [<https://bloob.blob>
+   |      +                  +
+
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls.rs:82:5
+   |
+LL | /// https://bloob.blob]
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+   = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://bloob.blob>]
+   |     +                  +
+
+error: aborting due to 26 previous errors
 
diff --git a/tests/ui/abi/simd-abi-checks-s390x.rs b/tests/ui/abi/simd-abi-checks-s390x.rs
index 877a25e8b08..75232a66ab0 100644
--- a/tests/ui/abi/simd-abi-checks-s390x.rs
+++ b/tests/ui/abi/simd-abi-checks-s390x.rs
@@ -8,6 +8,7 @@
 // FIXME: +soft-float itself doesn't set -vector
 //@[z13_soft_float] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector,+soft-float
 //@[z13_soft_float] needs-llvm-components: systemz
+//[z13_soft_float]~? WARN must be disabled to ensure that the ABI of the current target can be implemented correctly
 
 #![feature(no_core, repr_simd, s390x_target_feature)]
 #![no_core]
diff --git a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr
index c1c4e90f3cf..e1cfa373c63 100644
--- a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr
+++ b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr
@@ -1,5 +1,5 @@
 error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:38:1
+  --> $DIR/simd-abi-checks-s390x.rs:39:1
    |
 LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -7,7 +7,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:43:1
+  --> $DIR/simd-abi-checks-s390x.rs:44:1
    |
 LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -15,7 +15,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:89:1
+  --> $DIR/simd-abi-checks-s390x.rs:90:1
    |
 LL | / extern "C" fn vector_transparent_wrapper_ret_small(
 LL | |     x: &TransparentWrapper<i8x8>,
@@ -25,7 +25,7 @@ LL | | ) -> TransparentWrapper<i8x8> {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:96:1
+  --> $DIR/simd-abi-checks-s390x.rs:97:1
    |
 LL | / extern "C" fn vector_transparent_wrapper_ret(
 LL | |     x: &TransparentWrapper<i8x16>,
@@ -35,7 +35,7 @@ LL | | ) -> TransparentWrapper<i8x16> {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:111:1
+  --> $DIR/simd-abi-checks-s390x.rs:112:1
    |
 LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -43,7 +43,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:116:1
+  --> $DIR/simd-abi-checks-s390x.rs:117:1
    |
 LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -51,7 +51,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `Wrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:127:1
+  --> $DIR/simd-abi-checks-s390x.rs:128:1
    |
 LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -59,7 +59,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `Wrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:132:1
+  --> $DIR/simd-abi-checks-s390x.rs:133:1
    |
 LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -67,7 +67,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:143:1
+  --> $DIR/simd-abi-checks-s390x.rs:144:1
    |
 LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -75,7 +75,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:148:1
+  --> $DIR/simd-abi-checks-s390x.rs:149:1
    |
 LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr
index c1c4e90f3cf..e1cfa373c63 100644
--- a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr
+++ b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr
@@ -1,5 +1,5 @@
 error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:38:1
+  --> $DIR/simd-abi-checks-s390x.rs:39:1
    |
 LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -7,7 +7,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:43:1
+  --> $DIR/simd-abi-checks-s390x.rs:44:1
    |
 LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -15,7 +15,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:89:1
+  --> $DIR/simd-abi-checks-s390x.rs:90:1
    |
 LL | / extern "C" fn vector_transparent_wrapper_ret_small(
 LL | |     x: &TransparentWrapper<i8x8>,
@@ -25,7 +25,7 @@ LL | | ) -> TransparentWrapper<i8x8> {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:96:1
+  --> $DIR/simd-abi-checks-s390x.rs:97:1
    |
 LL | / extern "C" fn vector_transparent_wrapper_ret(
 LL | |     x: &TransparentWrapper<i8x16>,
@@ -35,7 +35,7 @@ LL | | ) -> TransparentWrapper<i8x16> {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:111:1
+  --> $DIR/simd-abi-checks-s390x.rs:112:1
    |
 LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -43,7 +43,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:116:1
+  --> $DIR/simd-abi-checks-s390x.rs:117:1
    |
 LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -51,7 +51,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `Wrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:127:1
+  --> $DIR/simd-abi-checks-s390x.rs:128:1
    |
 LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -59,7 +59,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `Wrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:132:1
+  --> $DIR/simd-abi-checks-s390x.rs:133:1
    |
 LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -67,7 +67,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:143:1
+  --> $DIR/simd-abi-checks-s390x.rs:144:1
    |
 LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -75,7 +75,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:148:1
+  --> $DIR/simd-abi-checks-s390x.rs:149:1
    |
 LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr
index c1c4e90f3cf..577fcc23bf1 100644
--- a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr
+++ b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr
@@ -1,5 +1,10 @@
+warning: target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctly
+   |
+   = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
+
 error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:38:1
+  --> $DIR/simd-abi-checks-s390x.rs:39:1
    |
 LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -7,7 +12,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:43:1
+  --> $DIR/simd-abi-checks-s390x.rs:44:1
    |
 LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -15,7 +20,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:89:1
+  --> $DIR/simd-abi-checks-s390x.rs:90:1
    |
 LL | / extern "C" fn vector_transparent_wrapper_ret_small(
 LL | |     x: &TransparentWrapper<i8x8>,
@@ -25,7 +30,7 @@ LL | | ) -> TransparentWrapper<i8x8> {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:96:1
+  --> $DIR/simd-abi-checks-s390x.rs:97:1
    |
 LL | / extern "C" fn vector_transparent_wrapper_ret(
 LL | |     x: &TransparentWrapper<i8x16>,
@@ -35,7 +40,7 @@ LL | | ) -> TransparentWrapper<i8x16> {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:111:1
+  --> $DIR/simd-abi-checks-s390x.rs:112:1
    |
 LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -43,7 +48,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:116:1
+  --> $DIR/simd-abi-checks-s390x.rs:117:1
    |
 LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -51,7 +56,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `Wrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:127:1
+  --> $DIR/simd-abi-checks-s390x.rs:128:1
    |
 LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -59,7 +64,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper<i8x8>) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `Wrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:132:1
+  --> $DIR/simd-abi-checks-s390x.rs:133:1
    |
 LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -67,7 +72,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper<i8x16>) -> i64 {
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x8>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:143:1
+  --> $DIR/simd-abi-checks-s390x.rs:144:1
    |
 LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8x8>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
@@ -75,12 +80,12 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper<i8
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
 error: this function definition uses SIMD vector type `TransparentWrapper<i8x16>` which (with the chosen ABI) requires the `vector` target feature, which is not enabled
-  --> $DIR/simd-abi-checks-s390x.rs:148:1
+  --> $DIR/simd-abi-checks-s390x.rs:149:1
    |
 LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper<i8x16>) -> i64 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
    |
    = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`)
 
-error: aborting due to 10 previous errors
+error: aborting due to 10 previous errors; 1 warning emitted
 
diff --git a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs
index ea67831b68e..a13a255d536 100644
--- a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs
+++ b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs
@@ -1,21 +1,22 @@
 // Demonstrates and records a theoretical regressions / breaking changes caused by the
 // introduction of async trait bounds.
 
-// Setting the edition to 2018 since we don't regress `demo! { dyn async }` in Rust <2018.
+// Setting the edition to >2015 since we didn't regress `demo! { dyn async }` in Rust 2015.
 //@ edition:2018
 
 macro_rules! demo {
-    ($ty:ty) => { compile_error!("ty"); };
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
     //~^ ERROR ty
     //~| ERROR ty
-    (impl $c:ident Trait) => {};
-    (dyn $c:ident Trait) => {};
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE ASYNC TRAIT MODIFIER SYNTAX CHANGES!
+
+    (impl $c:ident Trait) => { /* KEEP THIS EMPTY! */ };
+    (dyn $c:ident Trait) => { /* KEEP THIS EMPTY! */ };
 }
 
-demo! { impl async Trait }
-//~^ ERROR `async` trait bounds are unstable
+demo! { impl async Trait } //~ ERROR `async` trait bounds are unstable
 
-demo! { dyn async Trait }
-//~^ ERROR `async` trait bounds are unstable
+demo! { dyn async Trait } //~ ERROR `async` trait bounds are unstable
 
 fn main() {}
diff --git a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr
index 6c3044e64d2..0292c53fb1c 100644
--- a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr
+++ b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr
@@ -1,7 +1,7 @@
 error: ty
   --> $DIR/macro-async-trait-bound-theoretical-regression.rs:8:19
    |
-LL |     ($ty:ty) => { compile_error!("ty"); };
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
    |                   ^^^^^^^^^^^^^^^^^^^^
 ...
 LL | demo! { impl async Trait }
@@ -12,7 +12,7 @@ LL | demo! { impl async Trait }
 error: ty
   --> $DIR/macro-async-trait-bound-theoretical-regression.rs:8:19
    |
-LL |     ($ty:ty) => { compile_error!("ty"); };
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
    |                   ^^^^^^^^^^^^^^^^^^^^
 ...
 LL | demo! { dyn async Trait }
@@ -21,7 +21,7 @@ LL | demo! { dyn async Trait }
    = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: `async` trait bounds are unstable
-  --> $DIR/macro-async-trait-bound-theoretical-regression.rs:15:14
+  --> $DIR/macro-async-trait-bound-theoretical-regression.rs:18:14
    |
 LL | demo! { impl async Trait }
    |              ^^^^^
@@ -32,7 +32,7 @@ LL | demo! { impl async Trait }
    = help: use the desugared name of the async trait, such as `AsyncFn`
 
 error[E0658]: `async` trait bounds are unstable
-  --> $DIR/macro-async-trait-bound-theoretical-regression.rs:18:13
+  --> $DIR/macro-async-trait-bound-theoretical-regression.rs:20:13
    |
 LL | demo! { dyn async Trait }
    |             ^^^^^
diff --git a/tests/ui/codemap_tests/issue-28308.rs b/tests/ui/codemap_tests/issue-28308.rs
index b0e04d0f1f6..81493f8c453 100644
--- a/tests/ui/codemap_tests/issue-28308.rs
+++ b/tests/ui/codemap_tests/issue-28308.rs
@@ -1,16 +1,4 @@
 fn main() {
-    assert!("foo"); //~ ERROR mismatched types
-    //~^ NOTE expected `bool`, found `str`
-    //~| NOTE in this expansion of assert!
-    let x = Some(&1);
-    assert!(x); //~ ERROR mismatched types
-    //~^ NOTE expected `bool`, found `Option<&{integer}>`
-    //~| NOTE expected enum `bool`
-    //~| NOTE in this expansion of assert!
-    //~| NOTE in this expansion of assert!
-    assert!(x, ""); //~ ERROR mismatched types
-    //~^ NOTE expected `bool`, found `Option<&{integer}>`
-    //~| NOTE expected enum `bool`
-    //~| NOTE in this expansion of assert!
-    //~| NOTE in this expansion of assert!
+    assert!("foo");
+    //~^ ERROR cannot apply unary operator `!`
 }
diff --git a/tests/ui/codemap_tests/issue-28308.stderr b/tests/ui/codemap_tests/issue-28308.stderr
index e84ceb44aac..7bc9e05dfc0 100644
--- a/tests/ui/codemap_tests/issue-28308.stderr
+++ b/tests/ui/codemap_tests/issue-28308.stderr
@@ -1,27 +1,9 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-28308.rs:2:13
+error[E0600]: cannot apply unary operator `!` to type `&'static str`
+  --> $DIR/issue-28308.rs:2:5
    |
 LL |     assert!("foo");
-   |             ^^^^^ expected `bool`, found `str`
+   |     ^^^^^^^^^^^^^^ cannot apply unary operator `!`
 
-error[E0308]: mismatched types
-  --> $DIR/issue-28308.rs:6:13
-   |
-LL |     assert!(x);
-   |             ^ expected `bool`, found `Option<&{integer}>`
-   |
-   = note: expected enum `bool`
-              found type `Option<&{integer}>`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-28308.rs:11:13
-   |
-LL |     assert!(x, "");
-   |             ^ expected `bool`, found `Option<&{integer}>`
-   |
-   = note: expected enum `bool`
-              found type `Option<&{integer}>`
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0600`.
diff --git a/tests/ui/consts/control-flow/assert.stderr b/tests/ui/consts/control-flow/assert.stderr
index deaad6abbcc..026097a6ba0 100644
--- a/tests/ui/consts/control-flow/assert.stderr
+++ b/tests/ui/consts/control-flow/assert.stderr
@@ -1,8 +1,8 @@
 error[E0080]: evaluation panicked: assertion failed: false
-  --> $DIR/assert.rs:5:23
+  --> $DIR/assert.rs:5:15
    |
 LL | const _: () = assert!(false);
-   |                       ^^^^^ evaluation of `_` failed here
+   |               ^^^^^^^^^^^^^^ evaluation of `_` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generics/post_monomorphization_error_backtrace.stderr b/tests/ui/generics/post_monomorphization_error_backtrace.stderr
index 92c7df73638..6953414f0c2 100644
--- a/tests/ui/generics/post_monomorphization_error_backtrace.stderr
+++ b/tests/ui/generics/post_monomorphization_error_backtrace.stderr
@@ -1,8 +1,8 @@
 error[E0080]: evaluation panicked: assertion failed: std::mem::size_of::<T>() == 0
-  --> $DIR/post_monomorphization_error_backtrace.rs:6:31
+  --> $DIR/post_monomorphization_error_backtrace.rs:6:23
    |
 LL |         const V: () = assert!(std::mem::size_of::<T>() == 0);
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `assert_zst::F::<u32>::V` failed here
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `assert_zst::F::<u32>::V` failed here
 
 note: erroneous constant encountered
   --> $DIR/post_monomorphization_error_backtrace.rs:14:5
@@ -17,10 +17,10 @@ LL |     assert_zst::<U>()
    |     ^^^^^^^^^^^^^^^^^
 
 error[E0080]: evaluation panicked: assertion failed: std::mem::size_of::<T>() == 0
-  --> $DIR/post_monomorphization_error_backtrace.rs:6:31
+  --> $DIR/post_monomorphization_error_backtrace.rs:6:23
    |
 LL |         const V: () = assert!(std::mem::size_of::<T>() == 0);
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `assert_zst::F::<i32>::V` failed here
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `assert_zst::F::<i32>::V` failed here
 
 note: erroneous constant encountered
   --> $DIR/post_monomorphization_error_backtrace.rs:14:5
diff --git a/tests/ui/inline-const/const-expr-generic-err.stderr b/tests/ui/inline-const/const-expr-generic-err.stderr
index e053e88db17..26039ba6d44 100644
--- a/tests/ui/inline-const/const-expr-generic-err.stderr
+++ b/tests/ui/inline-const/const-expr-generic-err.stderr
@@ -1,8 +1,8 @@
 error[E0080]: evaluation panicked: assertion failed: std::mem::size_of::<T>() == 0
-  --> $DIR/const-expr-generic-err.rs:4:21
+  --> $DIR/const-expr-generic-err.rs:4:13
    |
 LL |     const { assert!(std::mem::size_of::<T>() == 0); }
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `foo::<i32>::{constant#0}` failed here
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `foo::<i32>::{constant#0}` failed here
 
 note: erroneous constant encountered
   --> $DIR/const-expr-generic-err.rs:4:5
diff --git a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs
index cdf8aa85482..db2b4a6ad20 100644
--- a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs
+++ b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -5,9 +5,10 @@
 //@ [strict]compile-flags: -Zstrict-init-checks
 //@ needs-subprocess
 //@ ignore-backends: gcc
+//@ edition:2024
 
 #![allow(deprecated, invalid_value)]
-#![feature(never_type)]
+#![feature(never_type, rustc_private)]
 
 use std::{
     mem::{self, MaybeUninit, ManuallyDrop},
@@ -15,6 +16,9 @@ use std::{
     num,
 };
 
+#[cfg(target_os = "linux")]
+extern crate libc;
+
 #[allow(dead_code)]
 struct Foo {
     x: u8,
@@ -108,6 +112,17 @@ fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + 'static, msg: &st
 
 fn main() {
     unsafe {
+        #[cfg(target_os = "linux")]
+        {
+            // This test causes a large amount of crashes. If a system
+            // has a /proc/sys/kernel/core_pattern that uploads core dumps enabled,
+            // it will take a long time to complete. Set dumpable to 0 to avoid that.
+            if libc::prctl(libc::PR_SET_DUMPABLE, 0) < 0 {
+                let err = std::io::Error::last_os_error();
+                panic!("failed to disable core dumps {err:?}");
+            }
+        }
+
         // Uninhabited types
         test_panic_msg(
             || mem::uninitialized::<!>(),
diff --git a/tests/ui/macros/assert-desugaring-145770.rs b/tests/ui/macros/assert-desugaring-145770.rs
new file mode 100644
index 00000000000..d56e771ecfb
--- /dev/null
+++ b/tests/ui/macros/assert-desugaring-145770.rs
@@ -0,0 +1,23 @@
+//! Regression test for #145770.
+//!
+//! Changing the `assert!` desugaring from an `if !cond {}` to `match` expression is
+//! backwards-incompatible, and may need to be done over an edition boundary or limit editions for
+//! which the desguaring change impacts.
+
+//@ check-pass
+
+#[derive(Debug)]
+struct F {
+    data: bool
+}
+
+impl std::ops::Not for F {
+  type Output = bool;
+  fn not(self) -> Self::Output { !self.data }
+}
+
+fn main() {
+  let f = F { data: true };
+
+  assert!(f);
+}
diff --git a/tests/ui/macros/assert-macro-lifetimes.rs b/tests/ui/macros/assert-macro-lifetimes.rs
deleted file mode 100644
index cc259283204..00000000000
--- a/tests/ui/macros/assert-macro-lifetimes.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ check-pass
-#[derive(PartialEq, Eq, Hash)]
-struct S;
-fn main() {
-    let foo = std::rc::Rc::new(std::cell::RefCell::new(std::collections::HashMap::<S, S>::new()));
-    // Ensure that the lifetimes of the borrow do not leak past the end of `main`.
-    assert!(matches!(foo.borrow().get(&S).unwrap(), S))
-}
diff --git a/tests/ui/macros/metavar-expressions/concat-allowed-operations.rs b/tests/ui/macros/metavar-expressions/concat-allowed-operations.rs
index 695a752fe17..5ac50c943d0 100644
--- a/tests/ui/macros/metavar-expressions/concat-allowed-operations.rs
+++ b/tests/ui/macros/metavar-expressions/concat-allowed-operations.rs
@@ -92,6 +92,12 @@ macro_rules! combinations {
     }};
 }
 
+macro_rules! int_struct {
+    ($n: literal) => {
+        struct ${concat(E, $n)};
+    }
+}
+
 fn main() {
     create_things!(behold);
     behold_separated_idents_in_a_fn();
@@ -112,4 +118,16 @@ fn main() {
     assert_eq!(VAR_123, 2);
 
     combinations!(_hello, "a", b, "b");
+
+    int_struct!(1_0);
+    int_struct!(2);
+    int_struct!(3___0);
+    int_struct!(7_);
+    int_struct!(08);
+
+    let _ = E1_0;
+    let _ = E2;
+    let _ = E3___0;
+    let _ = E7_;
+    let _ = E08;
 }
diff --git a/tests/ui/macros/metavar-expressions/concat-usage-errors.rs b/tests/ui/macros/metavar-expressions/concat-usage-errors.rs
index 7d8756de9e2..277ad240b1b 100644
--- a/tests/ui/macros/metavar-expressions/concat-usage-errors.rs
+++ b/tests/ui/macros/metavar-expressions/concat-usage-errors.rs
@@ -140,7 +140,9 @@ macro_rules! bad_literal_non_string {
         //~| ERROR metavariables of `${concat(..)}` must be of type
         //~| ERROR metavariables of `${concat(..)}` must be of type
         //~| ERROR metavariables of `${concat(..)}` must be of type
-        //~| ERROR metavariables of `${concat(..)}` must be of type
+        //~| ERROR floats are not supported as metavariables of `${concat(..)}`
+        //~| ERROR integer metavariables of `${concat(..)}` must not be suffixed
+        //~| ERROR integer metavariables of `${concat(..)}` must not be suffixed
     }
 }
 
@@ -149,7 +151,6 @@ macro_rules! bad_tt_literal {
         const ${concat(_foo, $tt)}: () = ();
         //~^ ERROR metavariables of `${concat(..)}` must be of type
         //~| ERROR metavariables of `${concat(..)}` must be of type
-        //~| ERROR metavariables of `${concat(..)}` must be of type
     }
 }
 
@@ -178,13 +179,14 @@ fn main() {
     bad_literal_string!("1.0");
     bad_literal_string!("'1'");
 
-    bad_literal_non_string!(1);
     bad_literal_non_string!(-1);
     bad_literal_non_string!(1.0);
     bad_literal_non_string!('1');
     bad_literal_non_string!(false);
+    bad_literal_non_string!(4f64);
+    bad_literal_non_string!(5u8);
+    bad_literal_non_string!(6_u8);
 
-    bad_tt_literal!(1);
     bad_tt_literal!(1.0);
     bad_tt_literal!('1');
 }
diff --git a/tests/ui/macros/metavar-expressions/concat-usage-errors.stderr b/tests/ui/macros/metavar-expressions/concat-usage-errors.stderr
index 8be3e792ec3..c124b76cb78 100644
--- a/tests/ui/macros/metavar-expressions/concat-usage-errors.stderr
+++ b/tests/ui/macros/metavar-expressions/concat-usage-errors.stderr
@@ -130,7 +130,7 @@ error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `t
 LL |         ${concat($ex, aaaa)}
    |                   ^^
    |
-   = note: currently only string literals are supported
+   = note: currently only string and integer literals are supported
 
 error: variable `foo` is not recognized in meta-variable expression
   --> $DIR/concat-usage-errors.rs:37:30
@@ -276,7 +276,7 @@ error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `t
 LL |         const ${concat(_foo, $literal)}: () = ();
    |                               ^^^^^^^
    |
-   = note: currently only string literals are supported
+   = note: currently only string and integer literals are supported
 
 error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`
   --> $DIR/concat-usage-errors.rs:138:31
@@ -284,7 +284,7 @@ error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `t
 LL |         const ${concat(_foo, $literal)}: () = ();
    |                               ^^^^^^^
    |
-   = note: currently only string literals are supported
+   = note: currently only string and integer literals are supported
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`
@@ -293,7 +293,7 @@ error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `t
 LL |         const ${concat(_foo, $literal)}: () = ();
    |                               ^^^^^^^
    |
-   = note: currently only string literals are supported
+   = note: currently only string and integer literals are supported
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`
@@ -302,43 +302,45 @@ error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `t
 LL |         const ${concat(_foo, $literal)}: () = ();
    |                               ^^^^^^^
    |
-   = note: currently only string literals are supported
+   = note: currently only string and integer literals are supported
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`
+error: floats are not supported as metavariables of `${concat(..)}`
   --> $DIR/concat-usage-errors.rs:138:31
    |
 LL |         const ${concat(_foo, $literal)}: () = ();
    |                               ^^^^^^^
+
+error: integer metavariables of `${concat(..)}` must not be suffixed
+  --> $DIR/concat-usage-errors.rs:138:31
    |
-   = note: currently only string literals are supported
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+LL |         const ${concat(_foo, $literal)}: () = ();
+   |                               ^^^^^^^
 
-error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`
-  --> $DIR/concat-usage-errors.rs:149:31
+error: integer metavariables of `${concat(..)}` must not be suffixed
+  --> $DIR/concat-usage-errors.rs:138:31
    |
-LL |         const ${concat(_foo, $tt)}: () = ();
-   |                               ^^
+LL |         const ${concat(_foo, $literal)}: () = ();
+   |                               ^^^^^^^
    |
-   = note: currently only string literals are supported
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`
-  --> $DIR/concat-usage-errors.rs:149:31
+  --> $DIR/concat-usage-errors.rs:151:31
    |
 LL |         const ${concat(_foo, $tt)}: () = ();
    |                               ^^
    |
-   = note: currently only string literals are supported
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+   = note: currently only string and integer literals are supported
 
 error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`
-  --> $DIR/concat-usage-errors.rs:149:31
+  --> $DIR/concat-usage-errors.rs:151:31
    |
 LL |         const ${concat(_foo, $tt)}: () = ();
    |                               ^^
    |
-   = note: currently only string literals are supported
+   = note: currently only string and integer literals are supported
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 43 previous errors
+error: aborting due to 44 previous errors
 
diff --git a/tests/ui/mir/alignment/packed.rs b/tests/ui/mir/alignment/packed.rs
index aa79880a21a..cf908365e1a 100644
--- a/tests/ui/mir/alignment/packed.rs
+++ b/tests/ui/mir/alignment/packed.rs
@@ -12,7 +12,7 @@ fn main() {
     // Test that we can use addr_of! to get the address of a packed member which according to its
     // type is not aligned, but because it is a projection from a packed type is a valid place.
     let ptr0 = std::ptr::addr_of!(memory[0].tail);
-    let ptr1 = std::ptr::addr_of!(memory[1].tail);
+    let ptr1 = std::ptr::addr_of!(memory[0].tail);
     // Even if ptr0 happens to be aligned by chance, ptr1 is not.
     assert!(!ptr0.is_aligned() || !ptr1.is_aligned());
 
diff --git a/tests/ui/simd/const-err-trumps-simd-err.stderr b/tests/ui/simd/const-err-trumps-simd-err.stderr
index 6d25a28c92c..93d1fce637f 100644
--- a/tests/ui/simd/const-err-trumps-simd-err.stderr
+++ b/tests/ui/simd/const-err-trumps-simd-err.stderr
@@ -1,8 +1,8 @@
 error[E0080]: evaluation panicked: assertion failed: LANE < 4
-  --> $DIR/const-err-trumps-simd-err.rs:17:21
+  --> $DIR/const-err-trumps-simd-err.rs:17:13
    |
 LL |     const { assert!(LANE < 4); } // the error should be here...
-   |                     ^^^^^^^^ evaluation of `get_elem::<4>::{constant#0}` failed here
+   |             ^^^^^^^^^^^^^^^^^ evaluation of `get_elem::<4>::{constant#0}` failed here
 
 note: erroneous constant encountered
   --> $DIR/const-err-trumps-simd-err.rs:17:5
diff --git a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs
index ee04f74c8a6..9b03ec7553d 100644
--- a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs
+++ b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs
@@ -1,24 +1,23 @@
-// Ensure that we don't consider `const Trait` to
-// match the macro fragment specifier `ty` as that would be a breaking
-// change theoretically speaking. Syntactically trait object types can
-// be "bare", i.e., lack the prefix `dyn`.
-// By contrast, `?Trait` *does* match `ty` and therefore an arm like
-// `?$Trait:path` would never be reached.
-// See `parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs`.
-// `[const] Trait` is already an error for a `ty` fragment,
-// so we do not need to prevent that.
+// Ensure that we don't consider `const Trait` to match the macro fragment specifier `ty`
+// as that would be a breaking change theoretically speaking.
+//
+// Syntactically trait object types can be "bare", i.e., lack the prefix `dyn`.
+// By contrast, `?Trait` *does* match `ty` and therefore an arm like `?$Trait:path`
+// would never be reached. See `parser/macro/macro-bare-trait-object-maybe-trait-bound.rs`.
+
+//@ check-pass (KEEP THIS AS A PASSING TEST!)
 
 macro_rules! check {
-    ($Type:ty) => {
-        compile_error!("ty");
-    };
-    (const $Trait:path) => {};
-    ([const] $Trait:path) => { [const] Trait };
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
+
+    (const $Trait:path) => { /* KEEP THIS EMPTY! */ };
+    // We don't need to check `[const] Trait` here since that matches the `ty` fragment
+    // already anyway since `[` may begin a slice or array type. However, it'll then
+    // subsequently fail due to #146122 (section 3).
 }
 
 check! { const Trait }
-check! { [const] Trait }
-//~^ ERROR: expected identifier, found `]`
-//~| ERROR: const trait impls are experimental
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr
deleted file mode 100644
index a4e77154b17..00000000000
--- a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error: expected identifier, found `]`
-  --> $DIR/macro-bare-trait-objects-const-trait-bounds.rs:20:16
-   |
-LL |     ($Type:ty) => {
-   |      -------- while parsing argument for this `ty` macro fragment
-...
-LL | check! { [const] Trait }
-   |                ^ expected identifier
-
-error[E0658]: const trait impls are experimental
-  --> $DIR/macro-bare-trait-objects-const-trait-bounds.rs:20:11
-   |
-LL | check! { [const] Trait }
-   |           ^^^^^
-   |
-   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
-   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs
index 35e964eacec..3f70ffa7d10 100644
--- a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs
+++ b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs
@@ -1,22 +1,32 @@
 // Demonstrates and records a theoretical regressions / breaking changes caused by the
-// introduction of const trait bounds.
+// introduction of `const` and `[const]` trait bounds.
 
-// Setting the edition to 2018 since we don't regress `demo! { dyn const }` in Rust <2018.
+// Setting the edition to >2015 since we didn't regress `demo! { dyn const }` in Rust 2015.
+// See also test `traits/const-traits/macro-dyn-const-2015.rs`.
 //@ edition:2018
 
 trait Trait {}
 
 macro_rules! demo {
-    (impl $c:ident Trait) => { impl $c Trait {} };
-    //~^ ERROR inherent
-    //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-    (dyn $c:ident Trait) => { dyn $c Trait {} }; //~ ERROR macro expansion
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+    //~^ ERROR ty
+    //~| ERROR ty
+    //~| ERROR ty
+    //~| ERROR ty
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
+
+    (impl $c:ident Trait) => { /* KEEP THIS EMPTY! */ };
+    (dyn $c:ident Trait) => { /* KEEP THIS EMPTY! */ };
+
+    (impl [const] Trait) => { /* KEEP THIS EMPTY! */ };
+    (dyn [const] Trait) => { /* KEEP THIS EMPTY! */ };
 }
 
-demo! { impl const Trait }
-//~^ ERROR const trait impls are experimental
+demo! { impl const Trait } //~ ERROR const trait impls are experimental
+demo! { dyn const Trait } //~ ERROR const trait impls are experimental
 
-demo! { dyn const Trait }
+demo! { impl [const] Trait } //~ ERROR const trait impls are experimental
+demo! { dyn [const] Trait } //~ ERROR const trait impls are experimental
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr
index 7a4061d9c18..383936b9df1 100644
--- a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr
+++ b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr
@@ -1,31 +1,49 @@
-error: inherent impls cannot be const
-  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:10:40
+error: ty
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:11:19
    |
-LL |     (impl $c:ident Trait) => { impl $c Trait {} };
-   |                                        ^^^^^ inherent impl for this type
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+   |                   ^^^^^^^^^^^^^^^^^^^^
 ...
 LL | demo! { impl const Trait }
-   | --------------------------
-   | |            |
-   | |            const because of this
-   | in this macro invocation
+   | -------------------------- in this macro invocation
    |
-   = note: only trait implementations may be annotated with `const`
    = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: macro expansion ignores keyword `dyn` and any tokens following
-  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:14:31
+error: ty
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:11:19
    |
-LL |     (dyn $c:ident Trait) => { dyn $c Trait {} };
-   |                               ^^^
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+   |                   ^^^^^^^^^^^^^^^^^^^^
 ...
 LL | demo! { dyn const Trait }
-   | ------------------------- caused by the macro expansion here
+   | ------------------------- in this macro invocation
    |
-   = note: the usage of `demo!` is likely invalid in item context
+   = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: ty
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:11:19
+   |
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+   |                   ^^^^^^^^^^^^^^^^^^^^
+...
+LL | demo! { impl [const] Trait }
+   | ---------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: ty
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:11:19
+   |
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+   |                   ^^^^^^^^^^^^^^^^^^^^
+...
+LL | demo! { dyn [const] Trait }
+   | --------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: const trait impls are experimental
-  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:17:14
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:26:14
    |
 LL | demo! { impl const Trait }
    |              ^^^^^
@@ -34,24 +52,36 @@ LL | demo! { impl const Trait }
    = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:10:40
+error[E0658]: const trait impls are experimental
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:27:13
    |
-LL |     (impl $c:ident Trait) => { impl $c Trait {} };
-   |                                        ^^^^^
-...
-LL | demo! { impl const Trait }
-   | -------------------------- in this macro invocation
+LL | demo! { dyn const Trait }
+   |             ^^^^^
    |
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: `#[warn(bare_trait_objects)]` (part of `#[warn(rust_2021_compatibility)]`) on by default
-   = note: this warning originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: you might have intended to implement this trait for a given type
+   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:29:14
+   |
+LL | demo! { impl [const] Trait }
+   |              ^^^^^^^
+   |
+   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:30:13
    |
-LL |     (impl $c:ident Trait) => { impl $c Trait for /* Type */ {} };
-   |                                              ++++++++++++++
+LL | demo! { dyn [const] Trait }
+   |             ^^^^^^^
+   |
+   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/macro-dyn-const-2015.rs b/tests/ui/traits/const-traits/macro-dyn-const-2015.rs
index fadfbe66788..0dfa482b986 100644
--- a/tests/ui/traits/const-traits/macro-dyn-const-2015.rs
+++ b/tests/ui/traits/const-traits/macro-dyn-const-2015.rs
@@ -1,14 +1,19 @@
-// Ensure that the introduction of const trait bound didn't regress this code in Rust 2015.
-// See also `mbe-const-trait-bound-theoretical-regression.rs`.
+// Ensure that the introduction of `const` and `[const]` trait bounds didn't regress this
+// Rust 2015 code. See also test `macro-const-trait-bound-theoretical-regression.rs`.
 
 //@ edition: 2015
-//@ check-pass
+//@ check-pass (KEEP THIS AS A PASSING TEST!)
 
 macro_rules! check {
-    ($ty:ty) => { compile_error!("ty"); };
-    (dyn $c:ident) => {};
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
+
+    (dyn $c:ident) => { /* KEEP THIS EMPTY! */ };
+    (dyn [$c:ident]) => { /* KEEP THIS EMPTY! */ };
 }
 
 check! { dyn const }
+check! { dyn [const] }
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs b/tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs
new file mode 100644
index 00000000000..75077577b8c
--- /dev/null
+++ b/tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs
@@ -0,0 +1,25 @@
+// Ensure that we don't consider `[` to begin trait bounds to contain breakages.
+// Only `[const]` in its entirety begins a trait bound.
+// See also test `macro-const-trait-bound-theoretical-regression.rs`.
+
+//@ check-pass (KEEP THIS AS A PASSING TEST!)
+// Setting the edition to >2015 since we didn't regress `check! { dyn [const] Trait }` in Rust 2015.
+// See also test `traits/const-traits/macro-dyn-const-2015.rs`.
+//@ edition:2018
+
+macro_rules! check {
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
+
+    (dyn [$($any:tt)*] Trait) => { /* KEEP THIS EMPTY! */ };
+    (impl [$($any:tt)*] Trait) => { /* KEEP THIS EMPTY! */ };
+}
+
+check!(dyn [T] Trait);
+
+// issue: <https://github.com/rust-lang/rust/issues/146417>
+check!(impl [T] Trait);
+check!(impl [T: Bound] Trait);
+
+fn main() {}
diff --git a/tests/ui/transmutability/uninhabited.stderr b/tests/ui/transmutability/uninhabited.stderr
index 9f289852809..4757daec997 100644
--- a/tests/ui/transmutability/uninhabited.stderr
+++ b/tests/ui/transmutability/uninhabited.stderr
@@ -41,10 +41,10 @@ LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
 error[E0080]: evaluation panicked: assertion failed: false
-  --> $DIR/uninhabited.rs:41:17
+  --> $DIR/uninhabited.rs:41:9
    |
 LL |         assert!(false);
-   |                 ^^^^^ evaluation of `yawning_void_struct::_` failed here
+   |         ^^^^^^^^^^^^^^ evaluation of `yawning_void_struct::_` failed here
 
 error[E0277]: `()` cannot be safely transmuted into `yawning_void_enum::Void`
   --> $DIR/uninhabited.rs:71:41
@@ -68,10 +68,10 @@ LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
 error[E0080]: evaluation panicked: assertion failed: false
-  --> $DIR/uninhabited.rs:63:17
+  --> $DIR/uninhabited.rs:63:9
    |
 LL |         assert!(false);
-   |                 ^^^^^ evaluation of `yawning_void_enum::_` failed here
+   |         ^^^^^^^^^^^^^^ evaluation of `yawning_void_enum::_` failed here
 
 error[E0277]: `u128` cannot be safely transmuted into `DistantVoid`
   --> $DIR/uninhabited.rs:92:43
@@ -95,10 +95,10 @@ LL | |         }>
    | |__________^ required by this bound in `is_maybe_transmutable`
 
 error[E0080]: evaluation panicked: assertion failed: false
-  --> $DIR/uninhabited.rs:87:17
+  --> $DIR/uninhabited.rs:87:9
    |
 LL |         assert!(false);
-   |                 ^^^^^ evaluation of `distant_void::_` failed here
+   |         ^^^^^^^^^^^^^^ evaluation of `distant_void::_` failed here
 
 error[E0277]: `Src` cannot be safely transmuted into `issue_126267::Error`
   --> $DIR/uninhabited.rs:108:42