about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock135
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs31
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/crate_level.rs24
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs6
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs35
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs15
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/command.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs16
-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_driver_impl/src/lib.rs4
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs18
-rw-r--r--compiler/rustc_hir/src/attrs/data_structures.rs6
-rw-r--r--compiler/rustc_hir/src/attrs/encode_cross_crate.rs4
-rw-r--r--compiler/rustc_hir/src/def.rs37
-rw-r--r--compiler/rustc_hir/src/hir.rs26
-rw-r--r--compiler/rustc_hir/src/intravisit.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs10
-rw-r--r--compiler/rustc_lint/src/builtin.rs20
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs35
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs13
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs38
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/parameterized.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs7
-rw-r--r--compiler/rustc_middle/src/query/erase.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs1
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs63
-rw-r--r--compiler/rustc_middle/src/ty/context.rs32
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs43
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs14
-rw-r--r--compiler/rustc_middle/src/ty/util.rs5
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs137
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs3
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs80
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs7
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs3
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs19
-rw-r--r--compiler/rustc_passes/messages.ftl2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs2
-rw-r--r--compiler/rustc_passes/src/dead.rs44
-rw-r--r--compiler/rustc_passes/src/stability.rs7
-rw-r--r--compiler/rustc_public/src/ty.rs12
-rw-r--r--compiler/rustc_public/src/unstable/convert/stable/ty.rs20
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs3
-rw-r--r--compiler/rustc_session/src/config.rs5
-rw-r--r--compiler/rustc_span/src/hygiene.rs30
-rw-r--r--compiler/rustc_span/src/lib.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs21
-rw-r--r--compiler/rustc_target/Cargo.toml1
-rw-r--r--compiler/rustc_target/src/lib.rs62
-rw-r--r--compiler/rustc_target/src/spec/json.rs38
-rw-r--r--compiler/rustc_target/src/spec/mod.rs969
-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--compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs4
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/region.rs7
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs7
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs18
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs2
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs35
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs2
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs2
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs7
-rw-r--r--compiler/rustc_type_ir/src/interner.rs1
-rw-r--r--library/alloc/src/collections/btree/map.rs11
-rw-r--r--library/alloc/src/collections/btree/set.rs11
-rw-r--r--library/alloctests/benches/lib.rs1
-rw-r--r--library/alloctests/tests/lib.rs1
-rw-r--r--library/core/src/any.rs3
-rw-r--r--library/core/src/array/equality.rs46
-rw-r--r--library/core/src/ascii/ascii_char.rs3
-rw-r--r--library/core/src/cmp.rs162
-rw-r--r--library/core/src/convert/mod.rs9
-rw-r--r--library/core/src/num/nonzero.rs17
-rw-r--r--library/core/src/ops/control_flow.rs3
-rw-r--r--library/core/src/option.rs9
-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/core/src/range.rs6
-rw-r--r--library/core/src/result.rs3
-rw-r--r--library/core/src/slice/cmp.rs43
-rw-r--r--library/core/src/str/traits.rs3
-rw-r--r--library/core/src/tuple.rs12
-rw-r--r--library/coretests/tests/alloc.rs24
-rw-r--r--library/coretests/tests/array.rs7
-rw-r--r--library/coretests/tests/char.rs43
-rw-r--r--library/coretests/tests/cmp.rs6
-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/hash/mod.rs13
-rw-r--r--library/coretests/tests/lib.rs3
-rw-r--r--library/coretests/tests/ops.rs75
-rw-r--r--library/std/src/keyword_docs.rs102
-rw-r--r--library/std/src/lib.rs6
-rw-r--r--library/std/src/sync/nonpoison/condvar.rs9
-rw-r--r--library/std/src/sync/poison/condvar.rs9
-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/hermit/time.rs32
-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/sgx/time.rs15
-rw-r--r--library/std/src/sys/pal/solid/mod.rs4
-rw-r--r--library/std/src/sys/pal/solid/time.rs9
-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/uefi/time.rs27
-rw-r--r--library/std/src/sys/pal/unix/mod.rs3
-rw-r--r--library/std/src/sys/pal/unix/time.rs30
-rw-r--r--library/std/src/sys/pal/unix/weak.rs130
-rw-r--r--library/std/src/sys/pal/unix/weak/tests.rs32
-rw-r--r--library/std/src/sys/pal/unsupported/time.rs15
-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/wasip1/time.rs25
-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.rs27
-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.rs32
-rw-r--r--library/std/src/sys/pal/xous/mod.rs1
-rw-r--r--library/std/src/sys/pal/xous/time.rs15
-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/src/time.rs30
-rw-r--r--library/std/tests/sync/condvar.rs18
-rw-r--r--library/std/tests/sync/lib.rs3
-rw-r--r--library/std/tests/sync/mutex.rs4
-rw-r--r--library/std/tests/sync/rwlock.rs8
-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/bootstrap/defaults/bootstrap.dist.toml4
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs17
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs24
-rw-r--r--src/bootstrap/src/core/build_steps/gcc.rs14
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs16
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs14
-rw-r--r--src/bootstrap/src/core/config/mod.rs2
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/proc_macro_deps.rs1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile2
-rw-r--r--src/doc/rustc/src/SUMMARY.md5
-rw-r--r--src/doc/rustc/src/check-cfg.md2
-rw-r--r--src/doc/rustc/src/platform-support.md14
-rw-r--r--src/doc/rustc/src/platform-support/aarch64-unknown-none.md78
-rw-r--r--src/doc/rustc/src/platform-support/arm-none-eabi.md6
-rw-r--r--src/doc/rustc/src/platform-support/armebv7r-none-eabi.md55
-rw-r--r--src/doc/rustc/src/platform-support/armv4t-none-eabi.md3
-rw-r--r--src/doc/rustc/src/platform-support/armv5te-none-eabi.md3
-rw-r--r--src/doc/rustc/src/platform-support/armv7a-none-eabi.md70
-rw-r--r--src/doc/rustc/src/platform-support/armv7r-none-eabi.md28
-rw-r--r--src/doc/rustc/src/platform-support/armv8r-none-eabihf.md21
-rw-r--r--src/doc/rustc/src/platform-support/loongarch-linux.md15
-rw-r--r--src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md5
-rw-r--r--src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md5
-rw-r--r--src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md5
-rw-r--r--src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md5
-rw-r--r--src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md5
-rw-r--r--src/doc/rustc/src/targets/custom.md15
-rw-r--r--src/librustdoc/clean/mod.rs35
-rw-r--r--src/librustdoc/clean/types.rs33
-rw-r--r--src/librustdoc/html/static/js/search.js6
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs57
m---------src/llvm-project0
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_macros.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/min_ident_chars.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_trait_methods.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs32
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs14
-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/miri/tests/pass/btreemap.rs1
-rw-r--r--src/tools/tidy/src/deps.rs6
-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--src/tools/tidy/src/fluent_lowercase.rs64
-rw-r--r--src/tools/tidy/src/lib.rs1
-rw-r--r--src/tools/tidy/src/main.rs1
-rw-r--r--tests/assembly-llvm/c-variadic-arm.rs26
-rw-r--r--tests/codegen-llvm/c-variadic-lifetime.rs21
-rw-r--r--tests/run-make/print-request-help-stable-unstable/help-diff.diff2
-rw-r--r--tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err2
-rw-r--r--tests/run-make/rustc-help/help-v.stdout2
-rw-r--r--tests/run-make/rustc-help/help.stdout2
-rw-r--r--tests/rustdoc-js/literal-path.js23
-rw-r--r--tests/rustdoc-js/literal-path.rs7
-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/invalid-self-parameter-type-56806.rs (renamed from tests/ui/issues/issue-56806.rs)1
-rw-r--r--tests/ui/abi/invalid-self-parameter-type-56806.stderr (renamed from tests/ui/issues/issue-56806.stderr)2
-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/associated-consts/traits-associated-consts-ice-56870.rs (renamed from tests/ui/issues/issue-56870.rs)1
-rw-r--r--tests/ui/associated-types/duplicate-associated-type-resolution-59326.rs (renamed from tests/ui/issues/issue-59326.rs)1
-rw-r--r--tests/ui/associated-types/impl-trait-member-type-resolution-57399.rs (renamed from tests/ui/issues/issue-57399-self-return-impl-trait.rs)2
-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/async-await/future-sizes/async-awaiting-fut.rs2
-rw-r--r--tests/ui/async-await/future-sizes/large-arg.rs2
-rw-r--r--tests/ui/attributes/malformed-no-std.rs25
-rw-r--r--tests/ui/attributes/malformed-no-std.stderr86
-rw-r--r--tests/ui/binop/function-comparison-errors-59488.rs (renamed from tests/ui/issues/issue-59488.rs)1
-rw-r--r--tests/ui/binop/function-comparison-errors-59488.stderr (renamed from tests/ui/issues/issue-59488.stderr)20
-rw-r--r--tests/ui/box/boxed-value-matching-57741.rs (renamed from tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.rs)1
-rw-r--r--tests/ui/box/boxed-value-matching-57741.stderr (renamed from tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.stderr)4
-rw-r--r--tests/ui/box/dereferencing-boxed-enum-in-match-57741.fixed (renamed from tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.fixed)1
-rw-r--r--tests/ui/box/dereferencing-boxed-enum-in-match-57741.rs (renamed from tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.rs)1
-rw-r--r--tests/ui/box/dereferencing-boxed-enum-in-match-57741.stderr (renamed from tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr)8
-rw-r--r--tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs1
-rw-r--r--tests/ui/closures/generic-typed-nested-closures-59494.rs (renamed from tests/ui/issues/issue-59494.rs)1
-rw-r--r--tests/ui/closures/generic-typed-nested-closures-59494.stderr (renamed from tests/ui/issues/issue-59494.stderr)2
-rw-r--r--tests/ui/codegen/mono-item-collector-default-impl-58375.rs (renamed from tests/ui/issues/issue-58375-monomorphize-default-impls.rs)1
-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/coherence/trait-implementation-coherence-check-57162.rs (renamed from tests/ui/issues/issue-57162.rs)1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr19
-rw-r--r--tests/ui/consts/const_cmp_type_id.rs5
-rw-r--r--tests/ui/consts/const_cmp_type_id.stderr8
-rw-r--r--tests/ui/consts/control-flow/assert.stderr4
-rw-r--r--tests/ui/consts/fn_trait_refs.rs3
-rw-r--r--tests/ui/consts/fn_trait_refs.stderr22
-rw-r--r--tests/ui/consts/missing-larger-array-impl.stderr10
-rw-r--r--tests/ui/consts/oncecell-const-init-57781.rs (renamed from tests/ui/issues/issue-57781.rs)1
-rw-r--r--tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr6
-rw-r--r--tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr10
-rw-r--r--tests/ui/consts/required-consts/collect-in-promoted-const.rs2
-rw-r--r--tests/ui/debuginfo/impl-copy-function-debuginfo-58463.rs (renamed from tests/ui/issues/issue-58463.rs)1
-rw-r--r--tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.rs (renamed from tests/ui/issues/issue-58734.rs)1
-rw-r--r--tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.stderr (renamed from tests/ui/issues/issue-58734.stderr)6
-rw-r--r--tests/ui/feature-gates/feature-gate-sanitize.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-sanitize.stderr4
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs12
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr131
-rw-r--r--tests/ui/generics/generic-associated-type-deref-target-56237.rs (renamed from tests/ui/issues/issue-56237.rs)1
-rw-r--r--tests/ui/generics/post_monomorphization_error_backtrace.stderr8
-rw-r--r--tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.rs (renamed from tests/ui/issues/issue-55731.rs)1
-rw-r--r--tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.stderr (renamed from tests/ui/issues/issue-55731.stderr)2
-rw-r--r--tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-2.next.stderr16
-rw-r--r--tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-2.rs31
-rw-r--r--tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-3.rs25
-rw-r--r--tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-3.stderr25
-rw-r--r--tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket.rs25
-rw-r--r--tests/ui/impl-trait/non-defining-uses/multiple-opaques-ambig.rs23
-rw-r--r--tests/ui/impl-trait/non-defining-uses/multiple-opaques-ok.rs37
-rw-r--r--tests/ui/impl-trait/non-defining-uses/no-rigid-alias.rs27
-rw-r--r--tests/ui/impl-trait/non-defining-uses/use-blanket-impl.rs19
-rw-r--r--tests/ui/impl-trait/non-defining-uses/use-item-bound-over-blanket-impl.rs30
-rw-r--r--tests/ui/impl-trait/non-defining-uses/use-item-bound.rs25
-rw-r--r--tests/ui/imports/auxiliary/reexported-trait-56175.rs17
-rw-r--r--tests/ui/imports/private-types-suggested-without-extern-crate-56175.rs (renamed from tests/ui/issues/issue-56175.rs)3
-rw-r--r--tests/ui/imports/private-types-suggested-without-extern-crate-56175.stderr (renamed from tests/ui/issues/issue-56175.stderr)12
-rw-r--r--tests/ui/infinite/auxiliary/aux-57271-lib.rs (renamed from tests/ui/issues/auxiliary/issue-57271-lib.rs)0
-rw-r--r--tests/ui/infinite/mutually-recursive-infinite-types-57271.rs (renamed from tests/ui/issues/issue-57271.rs)7
-rw-r--r--tests/ui/infinite/mutually-recursive-infinite-types-57271.stderr (renamed from tests/ui/issues/issue-57271.stderr)2
-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/invalid-compile-flags/print-without-arg.stderr2
-rw-r--r--tests/ui/invalid-compile-flags/print.stderr2
-rw-r--r--tests/ui/issues/issue-56943.rs8
-rw-r--r--tests/ui/keyword/raw-identifier-for-function-57198.rs (renamed from tests/ui/issues/issue-57198-pass.rs)1
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs2
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr2
-rw-r--r--tests/ui/lint/unused/unused-attr-duplicate.stderr24
-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/mismatched_types/auxiliary/aux-56943.rs (renamed from tests/ui/issues/auxiliary/issue-56943.rs)0
-rw-r--r--tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.rs9
-rw-r--r--tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.stderr (renamed from tests/ui/issues/issue-56943.stderr)6
-rw-r--r--tests/ui/modules/pub-use-handling-in-modules-56128.rs (renamed from tests/ui/issues/issue-56128.rs)0
-rw-r--r--tests/ui/parser/invalid-variable-definition-55587.rs (renamed from tests/ui/issues/issue-55587.rs)1
-rw-r--r--tests/ui/parser/invalid-variable-definition-55587.stderr (renamed from tests/ui/issues/issue-55587.stderr)2
-rw-r--r--tests/ui/print-request/print-lints-help.stderr2
-rw-r--r--tests/ui/print_type_sizes/async.rs2
-rw-r--r--tests/ui/resolve/missing-type-in-scope-58712.rs (renamed from tests/ui/issues/issue-58712.rs)1
-rw-r--r--tests/ui/resolve/missing-type-in-scope-58712.stderr (renamed from tests/ui/issues/issue-58712.stderr)4
-rw-r--r--tests/ui/simd/const-err-trumps-simd-err.stderr4
-rw-r--r--tests/ui/std/park-timeout-wakeup-59020.rs (renamed from tests/ui/issues/issue-59020.rs)1
-rw-r--r--tests/ui/structs/invalid-self-constructor-56835.rs (renamed from tests/ui/issues/issue-56835.rs)1
-rw-r--r--tests/ui/structs/invalid-self-constructor-56835.stderr (renamed from tests/ui/issues/issue-56835.stderr)4
-rw-r--r--tests/ui/suggestions/incompatible-types-in-try-expression-59756.fixed (renamed from tests/ui/issues/issue-59756.fixed)0
-rw-r--r--tests/ui/suggestions/incompatible-types-in-try-expression-59756.rs (renamed from tests/ui/issues/issue-59756.rs)1
-rw-r--r--tests/ui/suggestions/incompatible-types-in-try-expression-59756.stderr (renamed from tests/ui/issues/issue-59756.stderr)2
-rw-r--r--tests/ui/suggestions/issue-71394-no-from-impl.stderr6
-rw-r--r--tests/ui/suggestions/missing-format-specifiers-issue-68293.rs29
-rw-r--r--tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr49
-rw-r--r--tests/ui/trait-bounds/negative-bound-not-supported-58857.rs (renamed from tests/ui/issues/issue-58857.rs)1
-rw-r--r--tests/ui/trait-bounds/negative-bound-not-supported-58857.stderr (renamed from tests/ui/issues/issue-58857.stderr)2
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.rs4
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.stderr17
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.rs3
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.stderr11
-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/traits/generic-trait-impl-aliased-array-58212.rs (renamed from tests/ui/issues/issue-58212.rs)1
-rw-r--r--tests/ui/traits/trait-object-lifetime-bounds-57156.rs (renamed from tests/ui/issues/issue-57156.rs)1
-rw-r--r--tests/ui/traits/trait-objects-with-supertraits-56229.rs (renamed from tests/ui/issues/issue-56229.rs)1
-rw-r--r--tests/ui/transmutability/uninhabited.stderr12
-rw-r--r--tests/ui/typeck/self-constructor-type-args-not-allowed-57924.rs (renamed from tests/ui/issues/issue-57924.rs)1
-rw-r--r--tests/ui/typeck/self-constructor-type-args-not-allowed-57924.stderr (renamed from tests/ui/issues/issue-57924.stderr)2
-rw-r--r--tests/ui/typeck/self-constructor-type-error-56199.rs (renamed from tests/ui/issues/issue-56199.rs)1
-rw-r--r--tests/ui/typeck/self-constructor-type-error-56199.stderr (renamed from tests/ui/issues/issue-56199.stderr)8
-rw-r--r--tests/ui/unpretty/exhaustive.hir.stdout2
382 files changed, 4866 insertions, 3712 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8be13e84596..4677d34d2a6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1192,6 +1192,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921"
 
 [[package]]
+name = "dyn-clone"
+version = "1.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005"
+
+[[package]]
 name = "either"
 version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2347,11 +2353,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]]
@@ -3123,6 +3129,26 @@ dependencies = [
 ]
 
 [[package]]
+name = "ref-cast"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf"
+dependencies = [
+ "ref-cast-impl",
+]
+
+[[package]]
+name = "ref-cast-impl"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
 name = "regex"
 version = "1.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4577,6 +4603,7 @@ dependencies = [
  "rustc_macros",
  "rustc_serialize",
  "rustc_span",
+ "schemars",
  "serde",
  "serde_derive",
  "serde_json",
@@ -4901,6 +4928,31 @@ dependencies = [
 ]
 
 [[package]]
+name = "schemars"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0"
+dependencies = [
+ "dyn-clone",
+ "ref-cast",
+ "schemars_derive",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "schemars_derive"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33d020396d1d138dc19f1165df7545479dcd58d93810dc5d646a16e55abefa80"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde_derive_internals",
+ "syn 2.0.106",
+]
+
+[[package]]
 name = "scoped-tls"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4975,6 +5027,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "serde_derive_internals"
+version = "0.29.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
 name = "serde_json"
 version = "1.0.142"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6316,15 +6379,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 +6406,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 +6448,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 +6460,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 +6472,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 +6496,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 +6508,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 +6520,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 +6532,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_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index bb559bd8921..53351f91c46 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -5,7 +5,9 @@ use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
 use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::{DefKind, PerNS, Res};
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
-use rustc_hir::{self as hir, HirId, LifetimeSource, PredicateOrigin, Target, find_attr};
+use rustc_hir::{
+    self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr,
+};
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::span_bug;
 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
@@ -1117,20 +1119,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
             }
         };
 
+        let span = self.lower_span(i.span);
         let item = hir::ImplItem {
             owner_id: hir_id.expect_owner(),
             ident: self.lower_ident(ident),
             generics,
+            impl_kind: if is_in_trait_impl {
+                ImplItemImplKind::Trait {
+                    defaultness,
+                    trait_item_def_id: self
+                        .resolver
+                        .get_partial_res(i.id)
+                        .and_then(|r| r.expect_full_res().opt_def_id())
+                        .ok_or_else(|| {
+                            self.dcx().span_delayed_bug(
+                                span,
+                                "could not resolve trait item being implemented",
+                            )
+                        }),
+                }
+            } else {
+                ImplItemImplKind::Inherent { vis_span: self.lower_span(i.vis.span) }
+            },
             kind,
-            vis_span: self.lower_span(i.vis.span),
-            span: self.lower_span(i.span),
-            defaultness,
+            span,
             has_delayed_lints: !self.delayed_lints.is_empty(),
-            trait_item_def_id: self
-                .resolver
-                .get_partial_res(i.id)
-                .map(|r| r.expect_full_res().opt_def_id())
-                .unwrap_or(None),
         };
         self.arena.alloc(item)
     }
diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
index d23a7ae72f8..0b2c05482bf 100644
--- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
@@ -176,3 +176,27 @@ impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser {
         })
     }
 }
+
+pub(crate) struct NoCoreParser;
+
+impl<S: Stage> NoArgsAttributeParser<S> for NoCoreParser {
+    const PATH: &[Symbol] = &[sym::no_core];
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
+    // because it's a crate-level attribute, we already warn about it.
+    // Putting target limitations here would give duplicate warnings
+    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore;
+    const TYPE: AttributeType = AttributeType::CrateLevel;
+}
+
+pub(crate) struct NoStdParser;
+
+impl<S: Stage> NoArgsAttributeParser<S> for NoStdParser {
+    const PATH: &[Symbol] = &[sym::no_std];
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
+    // because it's a crate-level attribute, we already warn about it.
+    // Putting target limitations here would give duplicate warnings
+    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd;
+    const TYPE: AttributeType = AttributeType::CrateLevel;
+}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index d2b35090135..b3ab1d3edd6 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -25,8 +25,8 @@ use crate::attributes::codegen_attrs::{
 };
 use crate::attributes::confusables::ConfusablesParser;
 use crate::attributes::crate_level::{
-    CrateNameParser, MoveSizeLimitParser, PatternComplexityLimitParser, RecursionLimitParser,
-    TypeLengthLimitParser,
+    CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser,
+    RecursionLimitParser, TypeLengthLimitParser,
 };
 use crate::attributes::deprecation::DeprecationParser;
 use crate::attributes::dummy::DummyParser;
@@ -223,8 +223,10 @@ attribute_parsers!(
         Single<WithoutArgs<MacroEscapeParser>>,
         Single<WithoutArgs<MarkerParser>>,
         Single<WithoutArgs<MayDangleParser>>,
+        Single<WithoutArgs<NoCoreParser>>,
         Single<WithoutArgs<NoImplicitPreludeParser>>,
         Single<WithoutArgs<NoMangleParser>>,
+        Single<WithoutArgs<NoStdParser>>,
         Single<WithoutArgs<NonExhaustiveParser>>,
         Single<WithoutArgs<ParenSugarParser>>,
         Single<WithoutArgs<PassByValueParser>>,
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index ea264c8064a..6d69040c711 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -716,7 +716,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             return (false, false, None);
         };
 
-        let implemented_trait_item = self.infcx.tcx.associated_item(my_def).trait_item_def_id;
+        let implemented_trait_item = self.infcx.tcx.trait_item_of(my_def);
 
         (
             true,
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_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index a6c8e7d29cc..d70888205a5 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -569,6 +569,7 @@ fn make_format_args(
             detect_foreign_fmt,
             str_style,
             fmt_str,
+            uncooked_fmt_str.1.as_str(),
             fmt_span,
         );
     }
@@ -650,6 +651,7 @@ fn report_missing_placeholders(
     detect_foreign_fmt: bool,
     str_style: Option<usize>,
     fmt_str: &str,
+    uncooked_fmt_str: &str,
     fmt_span: Span,
 ) {
     let mut diag = if let &[(span, named)] = &unused[..] {
@@ -773,16 +775,20 @@ fn report_missing_placeholders(
                 diag.note(format!("consider adding {} format specifiers", unused.len()));
             }
         } else {
-            let original_fmt_str =
-                if fmt_str.len() >= 1 { &fmt_str[..fmt_str.len() - 1] } else { "" };
-
             let msg = if unused.len() == 1 {
                 "a format specifier".to_string()
             } else {
                 format!("{} format specifiers", unused.len())
             };
 
-            let sugg = format!("\"{}{}\"", original_fmt_str, "{}".repeat(unused.len()));
+            let sugg = match str_style {
+                None => format!("\"{}{}\"", uncooked_fmt_str, "{}".repeat(unused.len())),
+                Some(n_hashes) => format!(
+                    "r{hashes}\"{uncooked_fmt_str}{fmt_specifiers}\"{hashes}",
+                    hashes = "#".repeat(n_hashes),
+                    fmt_specifiers = "{}".repeat(unused.len())
+                ),
+            };
             let msg = format!("format specifiers use curly braces, consider adding {msg}");
 
             diag.span_suggestion_verbose(fmt_span, msg, sugg, Applicability::MaybeIncorrect);
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/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index dd688b8b345..1dd65d38a2b 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -31,7 +31,7 @@ codegen_ssa_cpu_required = target requires explicitly specifying a cpu with `-C
 codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
 
 codegen_ssa_dlltool_fail_import_library =
-    Dlltool could not create import library with {$dlltool_path} {$dlltool_args}:
+    dlltool could not create import library with {$dlltool_path} {$dlltool_args}:
     {$stdout}
     {$stderr}
 
diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs
index 05351bd6ca3..7420f18aacb 100644
--- a/compiler/rustc_codegen_ssa/src/back/command.rs
+++ b/compiler/rustc_codegen_ssa/src/back/command.rs
@@ -109,7 +109,7 @@ impl Command {
             }
             Program::Lld(ref p, flavor) => {
                 let mut c = process::Command::new(p);
-                c.arg("-flavor").arg(flavor.as_str());
+                c.arg("-flavor").arg(flavor.desc());
                 c
             }
         };
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 008340e614d..dc500c363f4 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -562,15 +562,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
     codegen_fn_attrs
 }
 
-/// If the provided DefId is a method in a trait impl, return the DefId of the method prototype.
-fn opt_trait_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
-    let impl_item = tcx.opt_associated_item(def_id)?;
-    match impl_item.container {
-        ty::AssocItemContainer::Impl => impl_item.trait_item_def_id,
-        _ => None,
-    }
-}
-
 fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet {
     // Backtrack to the crate root.
     let mut disabled = match tcx.opt_local_parent(did) {
@@ -600,14 +591,15 @@ fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet {
 /// Checks if the provided DefId is a method in a trait impl for a trait which has track_caller
 /// applied to the method prototype.
 fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
-    let Some(trait_item) = opt_trait_item(tcx, def_id) else { return false };
-    tcx.codegen_fn_attrs(trait_item).flags.intersects(CodegenFnAttrFlags::TRACK_CALLER)
+    tcx.trait_item_of(def_id).is_some_and(|id| {
+        tcx.codegen_fn_attrs(id).flags.intersects(CodegenFnAttrFlags::TRACK_CALLER)
+    })
 }
 
 /// If the provided DefId is a method in a trait impl, return the value of the `#[align]`
 /// attribute on the method prototype (if any).
 fn inherited_align<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Align> {
-    tcx.codegen_fn_attrs(opt_trait_item(tcx, def_id)?).alignment
+    tcx.codegen_fn_attrs(tcx.trait_item_of(def_id)?).alignment
 }
 
 /// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)]
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_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index d00a4c35834..4f875cf99ec 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -668,6 +668,10 @@ fn print_crate_info(
             TargetSpecJson => {
                 println_info!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
             }
+            TargetSpecJsonSchema => {
+                let schema = rustc_target::spec::json_schema();
+                println_info!("{}", serde_json::to_string_pretty(&schema).unwrap());
+            }
             AllTargetSpecsJson => {
                 let mut targets = BTreeMap::new();
                 for name in rustc_target::spec::TARGETS {
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/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
index b4c1b61b9b5..ea11a99efbc 100644
--- a/compiler/rustc_hir/src/attrs/data_structures.rs
+++ b/compiler/rustc_hir/src/attrs/data_structures.rs
@@ -579,12 +579,18 @@ pub enum AttributeKind {
     /// Represents `#[naked]`
     Naked(Span),
 
+    /// Represents `#[no_core]`
+    NoCore(Span),
+
     /// Represents `#[no_implicit_prelude]`
     NoImplicitPrelude(Span),
 
     /// Represents `#[no_mangle]`
     NoMangle(Span),
 
+    /// Represents `#[no_std]`
+    NoStd(Span),
+
     /// Represents `#[non_exhaustive]`
     NonExhaustive(Span),
 
diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
index 0e208be3497..55521c15854 100644
--- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
+++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
@@ -64,8 +64,10 @@ impl AttributeKind {
             MoveSizeLimit { .. } => No,
             MustUse { .. } => Yes,
             Naked(..) => No,
+            NoCore(..) => No,
             NoImplicitPrelude(..) => No,
-            NoMangle(..) => Yes,      // Needed for rustdoc
+            NoMangle(..) => Yes, // Needed for rustdoc
+            NoStd(..) => No,
             NonExhaustive(..) => Yes, // Needed for rustdoc
             Optimize(..) => No,
             ParenSugar(..) => No,
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/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 75551fe4c19..493236718a8 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3220,12 +3220,21 @@ pub struct ImplItem<'hir> {
     pub owner_id: OwnerId,
     pub generics: &'hir Generics<'hir>,
     pub kind: ImplItemKind<'hir>,
-    pub defaultness: Defaultness,
+    pub impl_kind: ImplItemImplKind,
     pub span: Span,
-    pub vis_span: Span,
     pub has_delayed_lints: bool,
-    /// When we are in a trait impl, link to the trait-item's id.
-    pub trait_item_def_id: Option<DefId>,
+}
+
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
+pub enum ImplItemImplKind {
+    Inherent {
+        vis_span: Span,
+    },
+    Trait {
+        defaultness: Defaultness,
+        /// Item in the trait that this item implements
+        trait_item_def_id: Result<DefId, ErrorGuaranteed>,
+    },
 }
 
 impl<'hir> ImplItem<'hir> {
@@ -3239,6 +3248,13 @@ impl<'hir> ImplItem<'hir> {
         ImplItemId { owner_id: self.owner_id }
     }
 
+    pub fn vis_span(&self) -> Option<Span> {
+        match self.impl_kind {
+            ImplItemImplKind::Trait { .. } => None,
+            ImplItemImplKind::Inherent { vis_span, .. } => Some(vis_span),
+        }
+    }
+
     expect_methods_self_kind! {
         expect_const, (&'hir Ty<'hir>, BodyId), ImplItemKind::Const(ty, body), (ty, *body);
         expect_fn,    (&FnSig<'hir>, BodyId),   ImplItemKind::Fn(ty, body),    (ty, *body);
@@ -4985,7 +5001,7 @@ mod size_asserts {
     static_assert_size!(GenericBound<'_>, 64);
     static_assert_size!(Generics<'_>, 56);
     static_assert_size!(Impl<'_>, 40);
-    static_assert_size!(ImplItem<'_>, 96);
+    static_assert_size!(ImplItem<'_>, 88);
     static_assert_size!(ImplItemKind<'_>, 40);
     static_assert_size!(Item<'_>, 88);
     static_assert_size!(ItemKind<'_>, 64);
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 25a7ae239f3..eb682f32111 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -1257,18 +1257,21 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(
         owner_id: _,
         ident,
         ref generics,
+        ref impl_kind,
         ref kind,
-        ref defaultness,
         span: _,
-        vis_span: _,
         has_delayed_lints: _,
-        trait_item_def_id: _,
     } = *impl_item;
 
     try_visit!(visitor.visit_ident(ident));
     try_visit!(visitor.visit_generics(generics));
-    try_visit!(visitor.visit_defaultness(defaultness));
     try_visit!(visitor.visit_id(impl_item.hir_id()));
+    match impl_kind {
+        ImplItemImplKind::Inherent { vis_span: _ } => {}
+        ImplItemImplKind::Trait { defaultness, trait_item_def_id: _ } => {
+            try_visit!(visitor.visit_defaultness(defaultness));
+        }
+    }
     match *kind {
         ImplItemKind::Const(ref ty, body) => {
             try_visit!(visitor.visit_ty_unambig(ty));
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 08b344638dd..886ebddc75c 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1009,8 +1009,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
             res = res.and(check_associated_item(tcx, def_id));
             let assoc_item = tcx.associated_item(def_id);
             match assoc_item.container {
-                ty::AssocItemContainer::Impl => {}
-                ty::AssocItemContainer::Trait => {
+                ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {}
+                ty::AssocContainer::Trait => {
                     res = res.and(check_trait_item(tcx, def_id));
                 }
             }
@@ -1026,8 +1026,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
             res = res.and(check_associated_item(tcx, def_id));
             let assoc_item = tcx.associated_item(def_id);
             match assoc_item.container {
-                ty::AssocItemContainer::Impl => {}
-                ty::AssocItemContainer::Trait => {
+                ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {}
+                ty::AssocContainer::Trait => {
                     res = res.and(check_trait_item(tcx, def_id));
                 }
             }
@@ -1043,8 +1043,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
 
             let assoc_item = tcx.associated_item(def_id);
             let has_type = match assoc_item.container {
-                ty::AssocItemContainer::Impl => true,
-                ty::AssocItemContainer::Trait => {
+                ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true,
+                ty::AssocContainer::Trait => {
                     tcx.ensure_ok().explicit_item_bounds(def_id);
                     tcx.ensure_ok().explicit_item_self_bounds(def_id);
                     if tcx.is_conditionally_const(def_id) {
@@ -1177,12 +1177,9 @@ fn check_impl_items_against_trait<'tcx>(
 
     for &impl_item in impl_item_refs {
         let ty_impl_item = tcx.associated_item(impl_item);
-        let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id {
-            tcx.associated_item(trait_item_id)
-        } else {
-            // Checked in `associated_item`.
-            tcx.dcx().span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait");
-            continue;
+        let ty_trait_item = match ty_impl_item.expect_trait_impl() {
+            Ok(trait_item_id) => tcx.associated_item(trait_item_id),
+            Err(ErrorGuaranteed { .. }) => continue,
         };
 
         let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local());
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index e4827256193..84fb09b7390 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -37,7 +37,7 @@ pub(super) fn compare_impl_item(
     impl_item_def_id: LocalDefId,
 ) -> Result<(), ErrorGuaranteed> {
     let impl_item = tcx.associated_item(impl_item_def_id);
-    let trait_item = tcx.associated_item(impl_item.trait_item_def_id.unwrap());
+    let trait_item = tcx.associated_item(impl_item.expect_trait_impl()?);
     let impl_trait_ref =
         tcx.impl_trait_ref(impl_item.container_id(tcx)).unwrap().instantiate_identity();
     debug!(?impl_trait_ref);
@@ -446,7 +446,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     impl_m_def_id: LocalDefId,
 ) -> Result<&'tcx DefIdMap<ty::EarlyBinder<'tcx, Ty<'tcx>>>, ErrorGuaranteed> {
     let impl_m = tcx.associated_item(impl_m_def_id.to_def_id());
-    let trait_m = tcx.associated_item(impl_m.trait_item_def_id.unwrap());
+    let trait_m = tcx.associated_item(impl_m.expect_trait_impl()?);
     let impl_trait_ref =
         tcx.impl_trait_ref(tcx.parent(impl_m_def_id.to_def_id())).unwrap().instantiate_identity();
     // First, check a few of the same things as `compare_impl_method`,
@@ -1449,8 +1449,10 @@ fn compare_self_type<'tcx>(
 
     let self_string = |method: ty::AssocItem| {
         let untransformed_self_ty = match method.container {
-            ty::AssocItemContainer::Impl => impl_trait_ref.self_ty(),
-            ty::AssocItemContainer::Trait => tcx.types.self_param,
+            ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
+                impl_trait_ref.self_ty()
+            }
+            ty::AssocContainer::Trait => tcx.types.self_param,
         };
         let self_arg_ty = tcx.fn_sig(method.def_id).instantiate_identity().input(0);
         let (infcx, param_env) = tcx
@@ -2458,8 +2460,12 @@ fn param_env_with_gat_bounds<'tcx>(
 
     for impl_ty in impl_tys_to_install {
         let trait_ty = match impl_ty.container {
-            ty::AssocItemContainer::Trait => impl_ty,
-            ty::AssocItemContainer::Impl => tcx.associated_item(impl_ty.trait_item_def_id.unwrap()),
+            ty::AssocContainer::InherentImpl => bug!(),
+            ty::AssocContainer::Trait => impl_ty,
+            ty::AssocContainer::TraitImpl(Err(_)) => continue,
+            ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) => {
+                tcx.associated_item(trait_item_def_id)
+            }
         };
 
         let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 22a9446fd4c..d33f1f3e12a 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -944,12 +944,11 @@ pub(crate) fn check_associated_item(
 
         // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
         // other `Foo` impls are incoherent.
-        tcx.ensure_ok()
-            .coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?;
+        tcx.ensure_ok().coherent_trait(tcx.parent(item.trait_item_or_self()?))?;
 
         let self_ty = match item.container {
-            ty::AssocItemContainer::Trait => tcx.types.self_param,
-            ty::AssocItemContainer::Impl => {
+            ty::AssocContainer::Trait => tcx.types.self_param,
+            ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
                 tcx.type_of(item.container_id(tcx)).instantiate_identity()
             }
         };
@@ -978,7 +977,7 @@ pub(crate) fn check_associated_item(
                 check_method_receiver(wfcx, hir_sig, item, self_ty)
             }
             ty::AssocKind::Type { .. } => {
-                if let ty::AssocItemContainer::Trait = item.container {
+                if let ty::AssocContainer::Trait = item.container {
                     check_associated_type_bounds(wfcx, item, span)
                 }
                 if item.defaultness(tcx).has_value() {
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 126ffabd448..dd3590f9ac5 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -111,9 +111,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
         }
 
         Some(ImplTraitInTraitData::Impl { fn_def_id }) => {
-            let assoc_item = tcx.associated_item(def_id);
-            let trait_assoc_predicates =
-                tcx.explicit_predicates_of(assoc_item.trait_item_def_id.unwrap());
+            let trait_item_def_id = tcx.trait_item_of(def_id).unwrap();
+            let trait_assoc_predicates = tcx.explicit_predicates_of(trait_item_def_id);
 
             let impl_assoc_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
             let impl_def_id = tcx.parent(fn_def_id);
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 62125c99d80..8cbf17162e3 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -125,8 +125,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
         Some(ty::ImplTraitInTraitData::Impl { fn_def_id }) => {
             match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
                 Ok(map) => {
-                    let assoc_item = tcx.associated_item(def_id);
-                    return map[&assoc_item.trait_item_def_id.unwrap()];
+                    let trait_item_def_id = tcx.trait_item_of(def_id).unwrap();
+                    return map[&trait_item_def_id];
                 }
                 Err(_) => {
                     return ty::EarlyBinder::bind(Ty::new_error_with_message(
@@ -198,7 +198,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
                 }
             }
             ImplItemKind::Type(ty) => {
-                if tcx.impl_trait_ref(tcx.hir_get_parent_item(hir_id)).is_none() {
+                if let ImplItemImplKind::Inherent { .. } = item.impl_kind {
                     check_feature_inherent_assoc_ty(tcx, item.span);
                 }
 
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_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 0b3d50ff219..7370124e800 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1021,7 +1021,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let container_id = assoc_item.container_id(tcx);
                 debug!(?def_id, ?container, ?container_id);
                 match container {
-                    ty::AssocItemContainer::Trait => {
+                    ty::AssocContainer::Trait => {
                         if let Err(e) = callee::check_legal_trait_for_method_call(
                             tcx,
                             path_span,
@@ -1033,7 +1033,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             self.set_tainted_by_errors(e);
                         }
                     }
-                    ty::AssocItemContainer::Impl => {
+                    ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
                         if segments.len() == 1 {
                             // `<T>::assoc` will end up here, and so
                             // can `T::assoc`. If this came from an
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 94b635c41b4..44a6084ebd5 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -2354,7 +2354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // We want it to always point to the trait item.
             // If we're pointing at an inherent function, we don't need to do anything,
             // so we fetch the parent and verify if it's a trait item.
-            && let maybe_trait_item_def_id = assoc_item.trait_item_def_id.unwrap_or(def_id)
+            && let Ok(maybe_trait_item_def_id) = assoc_item.trait_item_or_self()
             && let maybe_trait_def_id = self.tcx.parent(maybe_trait_item_def_id)
             // Just an easy way to check "trait_def_id == Fn/FnMut/FnOnce"
             && let Some(call_kind) = self.tcx.fn_trait_kind_from_def_id(maybe_trait_def_id)
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index d7ddbcc8b53..1998a1884b7 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1882,7 +1882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if segment.ident.name == sym::clone
             && results.type_dependent_def_id(expr.hir_id).is_some_and(|did| {
                     let assoc_item = self.tcx.associated_item(did);
-                    assoc_item.container == ty::AssocItemContainer::Trait
+                    assoc_item.container == ty::AssocContainer::Trait
                         && assoc_item.container_id(self.tcx) == clone_trait_did
                 })
             // If that clone call hasn't already dereferenced the self type (i.e. don't give this
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 129de32fd4a..7f5397a7926 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -278,8 +278,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti
     {
         if let Some(item) = tcx.opt_associated_item(def_id.into())
             && let ty::AssocKind::Const { .. } = item.kind
-            && let ty::AssocItemContainer::Impl = item.container
-            && let Some(trait_item_def_id) = item.trait_item_def_id
+            && let ty::AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container
         {
             let impl_def_id = item.container_id(tcx);
             let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 52a8eff984b..4185f7f6996 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -18,8 +18,8 @@ use rustc_middle::middle::stability;
 use rustc_middle::ty::elaborate::supertrait_def_ids;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type};
 use rustc_middle::ty::{
-    self, AssocItem, AssocItemContainer, GenericArgs, GenericArgsRef, GenericParamDefKind,
-    ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt, Upcast,
+    self, AssocContainer, AssocItem, GenericArgs, GenericArgsRef, GenericParamDefKind, ParamEnvAnd,
+    Ty, TyCtxt, TypeVisitableExt, Upcast,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
@@ -528,7 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ProbeScope::Single(def_id) => {
                     let item = self.tcx.associated_item(def_id);
                     // FIXME(fn_delegation): Delegation to inherent methods is not yet supported.
-                    assert_eq!(item.container, AssocItemContainer::Trait);
+                    assert_eq!(item.container, AssocContainer::Trait);
 
                     let trait_def_id = self.tcx.parent(def_id);
                     let trait_span = self.tcx.def_span(trait_def_id);
@@ -1659,7 +1659,7 @@ impl<'tcx> Pick<'tcx> {
     /// Do not use for type checking.
     pub(crate) fn differs_from(&self, other: &Self) -> bool {
         let Self {
-            item: AssocItem { def_id, kind: _, container: _, trait_item_def_id: _ },
+            item: AssocItem { def_id, kind: _, container: _ },
             kind: _,
             import_ids: _,
             autoderefs: _,
@@ -1702,7 +1702,7 @@ impl<'tcx> Pick<'tcx> {
                         tcx.def_path_str(self.item.def_id),
                     ));
                 }
-                (ty::AssocKind::Const { name }, ty::AssocItemContainer::Trait) => {
+                (ty::AssocKind::Const { name }, ty::AssocContainer::Trait) => {
                     let def_id = self.item.container_id(tcx);
                     lint.span_suggestion(
                         span,
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index c3c0a34df71..75a0f89321b 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -29,12 +29,12 @@ use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
 use rustc_hir::intravisit::FnKind as HirFnKind;
-use rustc_hir::{Body, FnDecl, PatKind, PredicateOrigin, find_attr};
+use rustc_hir::{Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin, find_attr};
 use rustc_middle::bug;
 use rustc_middle::lint::LevelAndSource;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
+use rustc_middle::ty::{self, AssocContainer, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
 use rustc_session::lint::FutureIncompatibilityReason;
 // hardwired lints from rustc_lint_defs
 pub use rustc_session::lint::builtin::*;
@@ -61,7 +61,6 @@ use crate::lints::{
     BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment,
     BuiltinUnusedDocCommentSub, BuiltinWhileTrue, InvalidAsmLabel,
 };
-use crate::nonstandard_style::{MethodLateContext, method_context};
 use crate::{
     EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,
     fluent_generated as fluent,
@@ -469,14 +468,14 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
-        let context = method_context(cx, impl_item.owner_id.def_id);
+        let container = cx.tcx.associated_item(impl_item.owner_id.def_id).container;
 
-        match context {
+        match container {
             // If the method is an impl for a trait, don't doc.
-            MethodLateContext::TraitImpl => return,
-            MethodLateContext::TraitAutoImpl => {}
+            AssocContainer::TraitImpl(_) => return,
+            AssocContainer::Trait => {}
             // If the method is an impl for an item with docs_hidden, don't doc.
-            MethodLateContext::PlainImpl => {
+            AssocContainer::InherentImpl => {
                 let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id());
                 let impl_ty = cx.tcx.type_of(parent).instantiate_identity();
                 let outerdef = match impl_ty.kind() {
@@ -1321,9 +1320,8 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
-        // Only lint inherent impl items.
-        if cx.tcx.associated_item(impl_item.owner_id).trait_item_def_id.is_none() {
-            self.perform_lint(cx, "item", impl_item.owner_id.def_id, impl_item.vis_span, false);
+        if let ImplItemImplKind::Inherent { vis_span } = impl_item.impl_kind {
+            self.perform_lint(cx, "item", impl_item.owner_id.def_id, vis_span, false);
         }
     }
 }
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 65075cfecfa..7f643a551bb 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{FnKind, Visitor};
 use rustc_hir::{Attribute, GenericParamKind, PatExprKind, PatKind, find_attr};
 use rustc_middle::hir::nested_filter::All;
-use rustc_middle::ty;
+use rustc_middle::ty::AssocContainer;
 use rustc_session::config::CrateType;
 use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::def_id::LocalDefId;
@@ -20,29 +20,6 @@ use crate::lints::{
 };
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 
-#[derive(PartialEq)]
-pub(crate) enum MethodLateContext {
-    TraitAutoImpl,
-    TraitImpl,
-    PlainImpl,
-}
-
-pub(crate) fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext {
-    let item = cx.tcx.associated_item(id);
-    match item.container {
-        ty::AssocItemContainer::Trait => MethodLateContext::TraitAutoImpl,
-        ty::AssocItemContainer::Impl => match cx.tcx.impl_trait_ref(item.container_id(cx.tcx)) {
-            Some(_) => MethodLateContext::TraitImpl,
-            None => MethodLateContext::PlainImpl,
-        },
-    }
-}
-
-fn assoc_item_in_trait_impl(cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) -> bool {
-    let item = cx.tcx.associated_item(ii.owner_id);
-    item.trait_item_def_id.is_some()
-}
-
 declare_lint! {
     /// The `non_camel_case_types` lint detects types, variants, traits and
     /// type parameters that don't have camel case names.
@@ -389,8 +366,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
         id: LocalDefId,
     ) {
         match &fk {
-            FnKind::Method(ident, sig, ..) => match method_context(cx, id) {
-                MethodLateContext::PlainImpl => {
+            FnKind::Method(ident, sig, ..) => match cx.tcx.associated_item(id).container {
+                AssocContainer::InherentImpl => {
                     if sig.header.abi != ExternAbi::Rust
                         && find_attr!(cx.tcx.get_all_attrs(id), AttributeKind::NoMangle(..))
                     {
@@ -398,10 +375,10 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
                     }
                     self.check_snake_case(cx, "method", ident);
                 }
-                MethodLateContext::TraitAutoImpl => {
+                AssocContainer::Trait => {
                     self.check_snake_case(cx, "trait method", ident);
                 }
-                _ => (),
+                AssocContainer::TraitImpl(_) => {}
             },
             FnKind::ItemFn(ident, _, header) => {
                 // Skip foreign-ABI #[no_mangle] functions (Issue #31924)
@@ -602,7 +579,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
 
     fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) {
         if let hir::ImplItemKind::Const(..) = ii.kind
-            && !assoc_item_in_trait_impl(cx, ii)
+            && let hir::ImplItemImplKind::Inherent { .. } = ii.impl_kind
         {
             NonUpperCaseGlobals::check_upper_case(cx, "associated constant", None, &ii.ident);
         }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 110b26c62ef..0c8d1f32e99 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1194,10 +1194,6 @@ impl<'a> CrateMetadataRef<'a> {
         self.root.tables.default_fields.get(self, id).map(|d| d.decode(self))
     }
 
-    fn get_trait_item_def_id(self, id: DefIndex) -> Option<DefId> {
-        self.root.tables.trait_item_def_id.get(self, id).map(|d| d.decode_from_cdata(self))
-    }
-
     fn get_expn_that_defined(self, id: DefIndex, sess: &Session) -> ExpnId {
         self.root
             .tables
@@ -1359,14 +1355,9 @@ impl<'a> CrateMetadataRef<'a> {
             }
             _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)),
         };
-        let container = self.root.tables.assoc_container.get(self, id).unwrap();
+        let container = self.root.tables.assoc_container.get(self, id).unwrap().decode(self);
 
-        ty::AssocItem {
-            kind,
-            def_id: self.local_def_id(id),
-            trait_item_def_id: self.get_trait_item_def_id(id),
-            container,
-        }
+        ty::AssocItem { kind, def_id: self.local_def_id(id), container }
     }
 
     fn get_ctor(self, node_id: DefIndex) -> Option<(CtorKind, DefId)> {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index a7e7e9985f4..db66938457f 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -22,7 +22,7 @@ use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::mir::interpret;
 use rustc_middle::query::Providers;
 use rustc_middle::traits::specialization_graph;
-use rustc_middle::ty::AssocItemContainer;
+use rustc_middle::ty::AssocContainer;
 use rustc_middle::ty::codec::TyEncoder;
 use rustc_middle::ty::fast_reject::{self, TreatParams};
 use rustc_middle::{bug, span_bug};
@@ -1254,8 +1254,8 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
         DefKind::AssocTy => {
             let assoc_item = tcx.associated_item(def_id);
             match assoc_item.container {
-                ty::AssocItemContainer::Impl => true,
-                ty::AssocItemContainer::Trait => assoc_item.defaultness(tcx).has_value(),
+                ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true,
+                ty::AssocContainer::Trait => assoc_item.defaultness(tcx).has_value(),
             }
         }
         DefKind::TyParam => {
@@ -1725,24 +1725,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         let tcx = self.tcx;
         let item = tcx.associated_item(def_id);
 
-        self.tables.defaultness.set_some(def_id.index, item.defaultness(tcx));
-        self.tables.assoc_container.set_some(def_id.index, item.container);
-
-        match item.container {
-            AssocItemContainer::Trait => {
-                if item.is_type() {
-                    self.encode_explicit_item_bounds(def_id);
-                    self.encode_explicit_item_self_bounds(def_id);
-                    if tcx.is_conditionally_const(def_id) {
-                        record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
-                            <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
-                    }
-                }
-            }
-            AssocItemContainer::Impl => {
-                if let Some(trait_item_def_id) = item.trait_item_def_id {
-                    self.tables.trait_item_def_id.set_some(def_id.index, trait_item_def_id.into());
-                }
+        if matches!(item.container, AssocContainer::Trait | AssocContainer::TraitImpl(_)) {
+            self.tables.defaultness.set_some(def_id.index, item.defaultness(tcx));
+        }
+
+        record!(self.tables.assoc_container[def_id] <- item.container);
+
+        if let AssocContainer::Trait = item.container
+            && item.is_type()
+        {
+            self.encode_explicit_item_bounds(def_id);
+            self.encode_explicit_item_self_bounds(def_id);
+            if tcx.is_conditionally_const(def_id) {
+                record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
+                    <- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
             }
         }
         if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 1f7d142d330..720970bbaf9 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -447,7 +447,6 @@ define_tables! {
     coroutine_by_move_body_def_id: Table<DefIndex, RawDefId>,
     eval_static_initializer: Table<DefIndex, LazyValue<mir::interpret::ConstAllocation<'static>>>,
     trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
-    trait_item_def_id: Table<DefIndex, RawDefId>,
     expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
     default_fields: Table<DefIndex, LazyValue<DefId>>,
     params_in_repr: Table<DefIndex, LazyValue<DenseBitSet<u32>>>,
@@ -459,7 +458,7 @@ define_tables! {
     def_keys: Table<DefIndex, LazyValue<DefKey>>,
     proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
     variant_data: Table<DefIndex, LazyValue<VariantData>>,
-    assoc_container: Table<DefIndex, ty::AssocItemContainer>,
+    assoc_container: Table<DefIndex, LazyValue<ty::AssocContainer>>,
     macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
     proc_macro: Table<DefIndex, MacroKind>,
     deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>,
diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs
index 34180001f80..4b2dc2c814e 100644
--- a/compiler/rustc_metadata/src/rmeta/parameterized.rs
+++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs
@@ -102,7 +102,7 @@ trivially_parameterized_over_tcx! {
     rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
     rustc_middle::mir::ConstQualifs,
     rustc_middle::ty::AnonConstKind,
-    rustc_middle::ty::AssocItemContainer,
+    rustc_middle::ty::AssocContainer,
     rustc_middle::ty::AsyncDestructor,
     rustc_middle::ty::Asyncness,
     rustc_middle::ty::DeducedParamAttrs,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 2cb07a28a8a..a882ee4f2b9 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -222,13 +222,6 @@ fixed_size_enum! {
 }
 
 fixed_size_enum! {
-    ty::AssocItemContainer {
-        ( Trait )
-        ( Impl  )
-    }
-}
-
-fixed_size_enum! {
     MacroKind {
         ( Attr   )
         ( Bang   )
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index bea2191c560..4c00b769237 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -318,7 +318,7 @@ trivial! {
     rustc_middle::traits::WellFormedLoc,
     rustc_middle::ty::adjustment::CoerceUnsizedInfo,
     rustc_middle::ty::AssocItem,
-    rustc_middle::ty::AssocItemContainer,
+    rustc_middle::ty::AssocContainer,
     rustc_middle::ty::Asyncness,
     rustc_middle::ty::AsyncDestructor,
     rustc_middle::ty::BoundVariableKind,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 2aa32dfa0d8..0e645a3aae4 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1881,6 +1881,7 @@ rustc_queries! {
     }
 
     /// Returns whether the impl or associated function has the `default` keyword.
+    /// Note: This will ICE on inherent impl items. Consider using `AssocItem::defaultness`.
     query defaultness(def_id: DefId) -> hir::Defaultness {
         desc { |tcx| "looking up whether `{}` has `default`", tcx.def_path_str(def_id) }
         separate_provide_extern
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index a902a8a61e5..768646c7630 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -5,15 +5,17 @@ use rustc_hir::def::{DefKind, Namespace};
 use rustc_hir::def_id::DefId;
 use rustc_hir::find_attr;
 use rustc_macros::{Decodable, Encodable, HashStable};
-use rustc_span::{Ident, Symbol};
+use rustc_span::{ErrorGuaranteed, Ident, Symbol};
 
 use super::{TyCtxt, Visibility};
 use crate::ty;
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash, Encodable, Decodable)]
-pub enum AssocItemContainer {
+pub enum AssocContainer {
     Trait,
-    Impl,
+    InherentImpl,
+    /// The `DefId` points to the trait item being implemented.
+    TraitImpl(Result<DefId, ErrorGuaranteed>),
 }
 
 /// Information about an associated item
@@ -21,11 +23,7 @@ pub enum AssocItemContainer {
 pub struct AssocItem {
     pub def_id: DefId,
     pub kind: AssocKind,
-    pub container: AssocItemContainer,
-
-    /// If this is an item in an impl of a trait then this is the `DefId` of
-    /// the associated item on the trait that this implements.
-    pub trait_item_def_id: Option<DefId>,
+    pub container: AssocContainer,
 }
 
 impl AssocItem {
@@ -55,7 +53,34 @@ impl AssocItem {
     ///
     /// [`type_of`]: crate::ty::TyCtxt::type_of
     pub fn defaultness(&self, tcx: TyCtxt<'_>) -> hir::Defaultness {
-        tcx.defaultness(self.def_id)
+        match self.container {
+            AssocContainer::InherentImpl => hir::Defaultness::Final,
+            AssocContainer::Trait | AssocContainer::TraitImpl(_) => tcx.defaultness(self.def_id),
+        }
+    }
+
+    pub fn expect_trait_impl(&self) -> Result<DefId, ErrorGuaranteed> {
+        let AssocContainer::TraitImpl(trait_item_id) = self.container else {
+            bug!("expected item to be in a trait impl: {:?}", self.def_id);
+        };
+        trait_item_id
+    }
+
+    /// If this is a trait impl item, returns the `DefId` of the trait item this implements.
+    /// Otherwise, returns `DefId` for self. Returns an Err in case the trait item was not
+    /// resolved successfully.
+    pub fn trait_item_or_self(&self) -> Result<DefId, ErrorGuaranteed> {
+        match self.container {
+            AssocContainer::TraitImpl(id) => id,
+            AssocContainer::Trait | AssocContainer::InherentImpl => Ok(self.def_id),
+        }
+    }
+
+    pub fn trait_item_def_id(&self) -> Option<DefId> {
+        match self.container {
+            AssocContainer::TraitImpl(Ok(id)) => Some(id),
+            _ => None,
+        }
     }
 
     #[inline]
@@ -71,16 +96,18 @@ impl AssocItem {
     #[inline]
     pub fn trait_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
         match self.container {
-            AssocItemContainer::Impl => None,
-            AssocItemContainer::Trait => Some(tcx.parent(self.def_id)),
+            AssocContainer::InherentImpl | AssocContainer::TraitImpl(_) => None,
+            AssocContainer::Trait => Some(tcx.parent(self.def_id)),
         }
     }
 
     #[inline]
     pub fn impl_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
         match self.container {
-            AssocItemContainer::Impl => Some(tcx.parent(self.def_id)),
-            AssocItemContainer::Trait => None,
+            AssocContainer::InherentImpl | AssocContainer::TraitImpl(_) => {
+                Some(tcx.parent(self.def_id))
+            }
+            AssocContainer::Trait => None,
         }
     }
 
@@ -156,11 +183,11 @@ impl AssocItem {
             return false;
         }
 
-        let def_id = match (self.container, self.trait_item_def_id) {
-            (AssocItemContainer::Trait, _) => self.def_id,
-            (AssocItemContainer::Impl, Some(trait_item_did)) => trait_item_did,
-            // Inherent impl but this attr is only applied to trait assoc items.
-            (AssocItemContainer::Impl, None) => return true,
+        let def_id = match self.container {
+            AssocContainer::Trait => self.def_id,
+            AssocContainer::TraitImpl(Ok(trait_item_did)) => trait_item_did,
+            AssocContainer::TraitImpl(Err(_)) => return false,
+            AssocContainer::InherentImpl => return true,
         };
         find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_))
     }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 218ac2cfbc1..79700d485c4 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -651,7 +651,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
             | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
         }
 
-        let trait_impls = tcx.trait_impls_of(trait_def_id);
+        #[allow(rustc::usage_of_type_ir_traits)]
+        self.for_each_blanket_impl(trait_def_id, f)
+    }
+    fn for_each_blanket_impl(self, trait_def_id: DefId, mut f: impl FnMut(DefId)) {
+        let trait_impls = self.trait_impls_of(trait_def_id);
         for &impl_def_id in trait_impls.blanket_impls() {
             f(impl_def_id);
         }
@@ -2272,7 +2276,16 @@ impl<'tcx> TyCtxt<'tcx> {
 
         let is_impl_item = match self.hir_node_by_def_id(suitable_region_binding_scope) {
             Node::Item(..) | Node::TraitItem(..) => false,
-            Node::ImplItem(..) => self.is_bound_region_in_impl_item(suitable_region_binding_scope),
+            Node::ImplItem(impl_item) => match impl_item.impl_kind {
+                // For now, we do not try to target impls of traits. This is
+                // because this message is going to suggest that the user
+                // change the fn signature, but they may not be free to do so,
+                // since the signature must match the trait.
+                //
+                // FIXME(#42706) -- in some cases, we could do better here.
+                hir::ImplItemImplKind::Trait { .. } => true,
+                _ => false,
+            },
             _ => false,
         };
 
@@ -2326,21 +2339,6 @@ impl<'tcx> TyCtxt<'tcx> {
         None
     }
 
-    /// Checks if the bound region is in Impl Item.
-    pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
-        let container_id = self.parent(suitable_region_binding_scope.to_def_id());
-        if self.impl_trait_ref(container_id).is_some() {
-            // For now, we do not try to target impls of traits. This is
-            // because this message is going to suggest that the user
-            // change the fn signature, but they may not be free to do so,
-            // since the signature must match the trait.
-            //
-            // FIXME(#42706) -- in some cases, we could do better here.
-            return true;
-        }
-        false
-    }
-
     /// Determines whether identifiers in the assembly have strict naming rules.
     /// Currently, only NVPTX* targets need it.
     pub fn has_strict_asm_symbol_naming(self) -> bool {
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index e76993e0542..34ead91b4f6 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -18,8 +18,8 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::ty::normalize_erasing_regions::NormalizationError;
 use crate::ty::print::{FmtPrinter, Print};
 use crate::ty::{
-    self, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
-    TypeVisitable, TypeVisitableExt, TypeVisitor,
+    self, AssocContainer, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable,
+    TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
 
 /// An `InstanceKind` along with the args that are needed to substitute the instance.
@@ -611,26 +611,23 @@ impl<'tcx> Instance<'tcx> {
                     debug!(" => fn pointer created for virtual call");
                     resolved.def = InstanceKind::ReifyShim(def_id, reason);
                 }
-                // Reify `Trait::method` implementations if KCFI is enabled
-                // FIXME(maurer) only reify it if it is a vtable-safe function
-                _ if tcx.sess.is_sanitizer_kcfi_enabled()
-                    && tcx
-                        .opt_associated_item(def_id)
-                        .and_then(|assoc| assoc.trait_item_def_id)
-                        .is_some() =>
-                {
-                    // If this function could also go in a vtable, we need to `ReifyShim` it with
-                    // KCFI because it can only attach one type per function.
-                    resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason)
-                }
-                // Reify `::call`-like method implementations if KCFI is enabled
-                _ if tcx.sess.is_sanitizer_kcfi_enabled()
-                    && tcx.is_closure_like(resolved.def_id()) =>
-                {
-                    // Reroute through a reify via the *unresolved* instance. The resolved one can't
-                    // be directly reified because it's closure-like. The reify can handle the
-                    // unresolved instance.
-                    resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
+                _ if tcx.sess.is_sanitizer_kcfi_enabled() => {
+                    // Reify `::call`-like method implementations
+                    if tcx.is_closure_like(resolved.def_id()) {
+                        // Reroute through a reify via the *unresolved* instance. The resolved one can't
+                        // be directly reified because it's closure-like. The reify can handle the
+                        // unresolved instance.
+                        resolved = Instance { def: InstanceKind::ReifyShim(def_id, reason), args }
+                    // Reify `Trait::method` implementations
+                    // FIXME(maurer) only reify it if it is a vtable-safe function
+                    } else if let Some(assoc) = tcx.opt_associated_item(def_id)
+                        && let AssocContainer::Trait | AssocContainer::TraitImpl(Ok(_)) =
+                            assoc.container
+                    {
+                        // If this function could also go in a vtable, we need to `ReifyShim` it with
+                        // KCFI because it can only attach one type per function.
+                        resolved.def = InstanceKind::ReifyShim(resolved.def_id(), reason)
+                    }
                 }
                 _ => {}
             }
@@ -683,7 +680,7 @@ impl<'tcx> Instance<'tcx> {
                     && !matches!(
                         tcx.opt_associated_item(def),
                         Some(ty::AssocItem {
-                            container: ty::AssocItemContainer::Trait,
+                            container: ty::AssocContainer::Trait,
                             ..
                         })
                     );
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index da17ec1f9f3..d4c001f625e 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1934,6 +1934,11 @@ impl<'tcx> TyCtxt<'tcx> {
         Some((parent, def_kind))
     }
 
+    /// Returns the trait item that is implemented by the given item `DefId`.
+    pub fn trait_item_of(self, def_id: impl IntoQueryParam<DefId>) -> Option<DefId> {
+        self.opt_associated_item(def_id.into_query_param())?.trait_item_def_id()
+    }
+
     /// If the given `DefId` is an associated item of a trait,
     /// returns the `DefId` of the trait; otherwise, returns `None`.
     pub fn trait_of_assoc(self, def_id: DefId) -> Option<DefId> {
@@ -2149,17 +2154,12 @@ impl<'tcx> TyCtxt<'tcx> {
         let Some(item) = self.opt_associated_item(def_id) else {
             return false;
         };
-        if item.container != ty::AssocItemContainer::Impl {
-            return false;
-        }
 
-        let Some(trait_item_def_id) = item.trait_item_def_id else {
+        let AssocContainer::TraitImpl(Ok(trait_item_def_id)) = item.container else {
             return false;
         };
 
-        return !self
-            .associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
-            .is_empty();
+        !self.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id).is_empty()
     }
 }
 
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_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index e3cf0330b14..fb777496e31 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -11,8 +11,9 @@ use rustc_type_ir::lang_items::SolverTraitLangItem;
 use rustc_type_ir::search_graph::CandidateHeadUsages;
 use rustc_type_ir::solve::SizedTraitKind;
 use rustc_type_ir::{
-    self as ty, Interner, TypeFlags, TypeFoldable, TypeSuperVisitable, TypeVisitable,
-    TypeVisitableExt as _, TypeVisitor, TypingMode, Upcast as _, elaborate,
+    self as ty, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
+    elaborate,
 };
 use tracing::{debug, instrument};
 
@@ -187,6 +188,7 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
         impl_def_id: I::ImplId,
+        then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResult<I>,
     ) -> Result<Candidate<I>, NoSolution>;
 
     /// If the predicate contained an error, we want to avoid emitting unnecessary trait
@@ -365,6 +367,15 @@ pub(super) enum AssembleCandidatesFrom {
     EnvAndBounds,
 }
 
+impl AssembleCandidatesFrom {
+    fn should_assemble_impl_candidates(&self) -> bool {
+        match self {
+            AssembleCandidatesFrom::All => true,
+            AssembleCandidatesFrom::EnvAndBounds => false,
+        }
+    }
+}
+
 /// This is currently used to track the [CandidateHeadUsages] of all failed `ParamEnv`
 /// candidates. This is then used to ignore their head usages in case there's another
 /// always applicable `ParamEnv` candidate. Look at how `param_env_head_usages` is
@@ -397,14 +408,15 @@ where
             return (candidates, failed_candidate_info);
         };
 
+        let goal: Goal<I, G> = goal
+            .with(self.cx(), goal.predicate.with_replaced_self_ty(self.cx(), normalized_self_ty));
+
         if normalized_self_ty.is_ty_var() {
             debug!("self type has been normalized to infer");
-            candidates.extend(self.forced_ambiguity(MaybeCause::Ambiguity));
+            self.try_assemble_bounds_via_registered_opaques(goal, assemble_from, &mut candidates);
             return (candidates, failed_candidate_info);
         }
 
-        let goal: Goal<I, G> = goal
-            .with(self.cx(), goal.predicate.with_replaced_self_ty(self.cx(), normalized_self_ty));
         // Vars that show up in the rest of the goal substs may have been constrained by
         // normalizing the self type as well, since type variables are not uniquified.
         let goal = self.resolve_vars_if_possible(goal);
@@ -484,8 +496,9 @@ where
                 if cx.impl_is_default(impl_def_id) {
                     return;
                 }
-
-                match G::consider_impl_candidate(self, goal, impl_def_id) {
+                match G::consider_impl_candidate(self, goal, impl_def_id, |ecx, certainty| {
+                    ecx.evaluate_added_goals_and_make_canonical_response(certainty)
+                }) {
                     Ok(candidate) => candidates.push(candidate),
                     Err(NoSolution) => (),
                 }
@@ -943,6 +956,116 @@ where
         }
     }
 
+    /// If the self type is the hidden type of an opaque, try to assemble
+    /// candidates for it by consider its item bounds and by using blanket
+    /// impls. This is used to incompletely guide type inference when handling
+    /// non-defining uses in the defining scope.
+    ///
+    /// We otherwise just fail fail with ambiguity. Even if we're using an
+    /// opaque type item bound or a blank impls, we still force its certainty
+    /// to be `Maybe` so that we properly prove this goal later.
+    ///
+    /// See <https://github.com/rust-lang/trait-system-refactor-initiative/issues/182>
+    /// for why this is necessary.
+    fn try_assemble_bounds_via_registered_opaques<G: GoalKind<D>>(
+        &mut self,
+        goal: Goal<I, G>,
+        assemble_from: AssembleCandidatesFrom,
+        candidates: &mut Vec<Candidate<I>>,
+    ) {
+        let self_ty = goal.predicate.self_ty();
+        // If the self type is sub unified with any opaque type, we
+        // also look at blanket impls for it.
+        let mut assemble_blanket_impls = false;
+        for alias_ty in self.opaques_with_sub_unified_hidden_type(self_ty) {
+            assemble_blanket_impls = true;
+            debug!("self ty is sub unified with {alias_ty:?}");
+
+            struct ReplaceOpaque<I: Interner> {
+                cx: I,
+                alias_ty: ty::AliasTy<I>,
+                self_ty: I::Ty,
+            }
+            impl<I: Interner> TypeFolder<I> for ReplaceOpaque<I> {
+                fn cx(&self) -> I {
+                    self.cx
+                }
+                fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
+                    if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() {
+                        if alias_ty == self.alias_ty {
+                            return self.self_ty;
+                        }
+                    }
+                    ty.super_fold_with(self)
+                }
+            }
+
+            // We look at all item-bounds of the opaque, replacing the
+            // opaque with the current self type before considering
+            // them as a candidate. Imagine e've got `?x: Trait<?y>`
+            // and `?x` has been sub-unified with the hidden type of
+            // `impl Trait<u32>`, We take the item bound `opaque: Trait<u32>`
+            // and replace all occurrences of `opaque` with `?x`. This results
+            // in a `?x: Trait<u32>` alias-bound candidate.
+            for item_bound in self
+                .cx()
+                .item_self_bounds(alias_ty.def_id)
+                .iter_instantiated(self.cx(), alias_ty.args)
+            {
+                let assumption =
+                    item_bound.fold_with(&mut ReplaceOpaque { cx: self.cx(), alias_ty, self_ty });
+                candidates.extend(G::probe_and_match_goal_against_assumption(
+                    self,
+                    CandidateSource::AliasBound,
+                    goal,
+                    assumption,
+                    |ecx| {
+                        // We want to reprove this goal once we've inferred the
+                        // hidden type, so we force the certainty to `Maybe`.
+                        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
+                    },
+                ));
+            }
+        }
+
+        // We also need to consider blanket impls for not-yet-defined opaque types.
+        //
+        // See tests/ui/impl-trait/non-defining-uses/use-blanket-impl.rs for an example.
+        if assemble_blanket_impls && assemble_from.should_assemble_impl_candidates() {
+            let cx = self.cx();
+            cx.for_each_blanket_impl(goal.predicate.trait_def_id(cx), |impl_def_id| {
+                // For every `default impl`, there's always a non-default `impl`
+                // that will *also* apply. There's no reason to register a candidate
+                // for this impl, since it is *not* proof that the trait goal holds.
+                if cx.impl_is_default(impl_def_id) {
+                    return;
+                }
+
+                match G::consider_impl_candidate(self, goal, impl_def_id, |ecx, certainty| {
+                    if ecx.shallow_resolve(self_ty).is_ty_var() {
+                        // We force the certainty of impl candidates to be `Maybe`.
+                        let certainty = certainty.and(Certainty::AMBIGUOUS);
+                        ecx.evaluate_added_goals_and_make_canonical_response(certainty)
+                    } else {
+                        // We don't want to use impls if they constrain the opaque.
+                        //
+                        // FIXME(trait-system-refactor-initiative#229): This isn't
+                        // perfect yet as it still allows us to incorrectly constrain
+                        // other inference variables.
+                        Err(NoSolution)
+                    }
+                }) {
+                    Ok(candidate) => candidates.push(candidate),
+                    Err(NoSolution) => (),
+                }
+            });
+        }
+
+        if candidates.is_empty() {
+            candidates.extend(self.forced_ambiguity(MaybeCause::Ambiguity));
+        }
+    }
+
     /// Assemble and merge candidates for goals which are related to an underlying trait
     /// goal. Right now, this is normalizes-to and host effect goals.
     ///
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 6646857a136..cb72c1cd92b 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -124,6 +124,7 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
         impl_def_id: I::ImplId,
+        then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResult<I>,
     ) -> Result<Candidate<I>, NoSolution> {
         let cx = ecx.cx();
 
@@ -175,7 +176,7 @@ where
                 });
             ecx.add_goals(GoalSource::ImplWhereBound, const_conditions);
 
-            ecx.evaluate_added_goals_and_make_canonical_response(certainty)
+            then(ecx, certainty)
         })
     }
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 5cd597d4fe6..3e3a5246f3d 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -407,20 +407,21 @@ where
         // If we have run this goal before, and it was stalled, check that any of the goal's
         // args have changed. Otherwise, we don't need to re-run the goal because it'll remain
         // stalled, since it'll canonicalize the same way and evaluation is pure.
-        if let Some(stalled_on) = stalled_on
-            && !stalled_on.stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
-            && !self
-                .delegate
-                .opaque_types_storage_num_entries()
-                .needs_reevaluation(stalled_on.num_opaques)
+        if let Some(GoalStalledOn { num_opaques, ref stalled_vars, ref sub_roots, stalled_cause }) =
+            stalled_on
+            && !stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
+            && !sub_roots
+                .iter()
+                .any(|&vid| self.delegate.sub_unification_table_root_var(vid) != vid)
+            && !self.delegate.opaque_types_storage_num_entries().needs_reevaluation(num_opaques)
         {
             return Ok((
                 NestedNormalizationGoals::empty(),
                 GoalEvaluation {
                     goal,
-                    certainty: Certainty::Maybe(stalled_on.stalled_cause),
+                    certainty: Certainty::Maybe(stalled_cause),
                     has_changed: HasChanged::No,
-                    stalled_on: Some(stalled_on),
+                    stalled_on,
                 },
             ));
         }
@@ -476,16 +477,6 @@ where
                 HasChanged::No => {
                     let mut stalled_vars = orig_values;
 
-                    // Remove the canonicalized universal vars, since we only care about stalled existentials.
-                    stalled_vars.retain(|arg| match arg.kind() {
-                        ty::GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Infer(_)),
-                        ty::GenericArgKind::Const(ct) => {
-                            matches!(ct.kind(), ty::ConstKind::Infer(_))
-                        }
-                        // Lifetimes can never stall goals.
-                        ty::GenericArgKind::Lifetime(_) => false,
-                    });
-
                     // Remove the unconstrained RHS arg, which is expected to have changed.
                     if let Some(normalizes_to) = goal.predicate.as_normalizes_to() {
                         let normalizes_to = normalizes_to.skip_binder();
@@ -497,6 +488,27 @@ where
                         stalled_vars.swap_remove(idx);
                     }
 
+                    // Remove the canonicalized universal vars, since we only care about stalled existentials.
+                    let mut sub_roots = Vec::new();
+                    stalled_vars.retain(|arg| match arg.kind() {
+                        // Lifetimes can never stall goals.
+                        ty::GenericArgKind::Lifetime(_) => false,
+                        ty::GenericArgKind::Type(ty) => match ty.kind() {
+                            ty::Infer(ty::TyVar(vid)) => {
+                                sub_roots.push(self.delegate.sub_unification_table_root_var(vid));
+                                true
+                            }
+                            ty::Infer(_) => true,
+                            ty::Param(_) | ty::Placeholder(_) => false,
+                            _ => unreachable!("unexpected orig_value: {ty:?}"),
+                        },
+                        ty::GenericArgKind::Const(ct) => match ct.kind() {
+                            ty::ConstKind::Infer(_) => true,
+                            ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(_) => false,
+                            _ => unreachable!("unexpected orig_value: {ct:?}"),
+                        },
+                    });
+
                     Some(GoalStalledOn {
                         num_opaques: canonical_goal
                             .canonical
@@ -505,6 +517,7 @@ where
                             .opaque_types
                             .len(),
                         stalled_vars,
+                        sub_roots,
                         stalled_cause,
                     })
                 }
@@ -1047,6 +1060,10 @@ where
         self.delegate.resolve_vars_if_possible(value)
     }
 
+    pub(super) fn shallow_resolve(&self, ty: I::Ty) -> I::Ty {
+        self.delegate.shallow_resolve(ty)
+    }
+
     pub(super) fn eager_resolve_region(&self, r: I::Region) -> I::Region {
         if let ty::ReVar(vid) = r.kind() {
             self.delegate.opportunistic_resolve_lt_var(vid)
@@ -1163,6 +1180,33 @@ where
     ) -> bool {
         may_use_unstable_feature(&**self.delegate, param_env, symbol)
     }
+
+    pub(crate) fn opaques_with_sub_unified_hidden_type(
+        &self,
+        self_ty: I::Ty,
+    ) -> impl Iterator<Item = ty::AliasTy<I>> + use<'a, D, I> {
+        let delegate = self.delegate;
+        delegate
+            .clone_opaque_types_lookup_table()
+            .into_iter()
+            .chain(delegate.clone_duplicate_opaque_types())
+            .filter_map(move |(key, hidden_ty)| {
+                if let ty::Infer(ty::TyVar(self_vid)) = self_ty.kind() {
+                    if let ty::Infer(ty::TyVar(hidden_vid)) = hidden_ty.kind() {
+                        if delegate.sub_unification_table_root_var(self_vid)
+                            == delegate.sub_unification_table_root_var(hidden_vid)
+                        {
+                            return Some(ty::AliasTy::new_from_args(
+                                delegate.cx(),
+                                key.def_id.into(),
+                                key.args,
+                            ));
+                        }
+                    }
+                }
+                None
+            })
+    }
 }
 
 /// Eagerly replace aliases with inference variables, emitting `AliasRelate`
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index db3460c4ff6..cd27c9c26c1 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -24,7 +24,7 @@ mod trait_goals;
 use derive_where::derive_where;
 use rustc_type_ir::inherent::*;
 pub use rustc_type_ir::solve::*;
-use rustc_type_ir::{self as ty, Interner, TypingMode};
+use rustc_type_ir::{self as ty, Interner, TyVid, TypingMode};
 use tracing::instrument;
 
 pub use self::eval_ctxt::{
@@ -418,11 +418,6 @@ pub struct GoalEvaluation<I: Interner> {
     pub has_changed: HasChanged,
     /// If the [`Certainty`] was `Maybe`, then keep track of whether the goal has changed
     /// before rerunning it.
-    ///
-    /// We knowingly ignore the `sub_root` of our inference variables here. This means we
-    /// may not reevaluate a goal even though a change to the `sub_root` could cause a goal
-    /// to make progress. Tracking them adds additional complexity for an incredibly minor
-    /// type inference improvement. We could look into properly handling this in the future.
     pub stalled_on: Option<GoalStalledOn<I>>,
 }
 
@@ -431,6 +426,7 @@ pub struct GoalEvaluation<I: Interner> {
 pub struct GoalStalledOn<I: Interner> {
     pub num_opaques: usize,
     pub stalled_vars: Vec<I::GenericArg>,
+    pub sub_roots: Vec<TyVid>,
     /// The cause that will be returned on subsequent evaluations if this goal remains stalled.
     pub stalled_cause: MaybeCause,
 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index 6e6be829f52..54b92ebac1d 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -194,6 +194,7 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, NormalizesTo<I>>,
         impl_def_id: I::ImplId,
+        then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResult<I>,
     ) -> Result<Candidate<I>, NoSolution> {
         let cx = ecx.cx();
 
@@ -314,8 +315,7 @@ where
                         // nested goal for consistency.
                         ty::TypingMode::Coherence => {
                             ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous));
-                            return ecx
-                                .evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
+                            return then(ecx, Certainty::Yes);
                         }
                         ty::TypingMode::Analysis { .. }
                         | ty::TypingMode::Borrowck { .. }
@@ -325,8 +325,7 @@ where
                                 goal,
                                 goal.predicate.alias,
                             );
-                            return ecx
-                                .evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
+                            return then(ecx, Certainty::Yes);
                         }
                     }
                 } else {
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 3e720a47f32..a69e867289c 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -55,6 +55,7 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, TraitPredicate<I>>,
         impl_def_id: I::ImplId,
+        then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResult<I>,
     ) -> Result<Candidate<I>, NoSolution> {
         let cx = ecx.cx();
 
@@ -112,7 +113,7 @@ where
                     .map(|pred| goal.with(cx, pred)),
             );
 
-            ecx.evaluate_added_goals_and_make_canonical_response(maximal_certainty)
+            then(ecx, maximal_certainty)
         })
     }
 
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_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index ab7885905a6..75537caa894 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -75,7 +75,7 @@ passes_const_stable_not_stable =
     .label = attribute specified here
 
 passes_custom_mir_incompatible_dialect_and_phase =
-    The {$dialect} dialect is not compatible with the {$phase} phase
+    the {$dialect} dialect is not compatible with the {$phase} phase
     .dialect_span = this dialect...
     .phase_span = ... is not compatible with this phase
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 38a6b4b16c9..2562d2e0b83 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -274,6 +274,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     | AttributeKind::MoveSizeLimit { .. }
                     | AttributeKind::TypeLengthLimit { .. }
                     | AttributeKind::PatternComplexityLimit { .. }
+                    | AttributeKind::NoCore { .. }
+                    | AttributeKind::NoStd { .. }
                 ) => { /* do nothing  */ }
                 Attribute::Unparsed(attr_item) => {
                     style = Some(attr_item.style);
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index fc33405d455..3c2c9683a4d 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -373,31 +373,27 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
     /// Automatically generated items marked with `rustc_trivial_field_reads`
     /// will be ignored for the purposes of dead code analysis (see PR #85200
     /// for discussion).
-    fn should_ignore_item(&mut self, def_id: DefId) -> bool {
-        if let Some(impl_of) = self.tcx.trait_impl_of_assoc(def_id) {
-            if !self.tcx.is_automatically_derived(impl_of) {
-                return false;
-            }
-
-            if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of)
-                && self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads)
+    fn should_ignore_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) -> bool {
+        if let hir::ImplItemImplKind::Trait { .. } = impl_item.impl_kind
+            && let impl_of = self.tcx.parent(impl_item.owner_id.to_def_id())
+            && self.tcx.is_automatically_derived(impl_of)
+            && let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap().instantiate_identity()
+            && self.tcx.has_attr(trait_ref.def_id, sym::rustc_trivial_field_reads)
+        {
+            if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind()
+                && let Some(adt_def_id) = adt_def.did().as_local()
             {
-                let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap().instantiate_identity();
-                if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind()
-                    && let Some(adt_def_id) = adt_def.did().as_local()
-                {
-                    self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_of);
-                }
-                return true;
+                self.ignored_derived_traits.entry(adt_def_id).or_default().insert(trait_ref.def_id);
             }
+            return true;
         }
 
         false
     }
 
     fn visit_node(&mut self, node: Node<'tcx>) {
-        if let Node::ImplItem(hir::ImplItem { owner_id, .. }) = node
-            && self.should_ignore_item(owner_id.to_def_id())
+        if let Node::ImplItem(impl_item) = node
+            && self.should_ignore_impl_item(impl_item)
         {
             return;
         }
@@ -439,7 +435,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
             }
             Node::ImplItem(impl_item) => {
                 let item = self.tcx.local_parent(impl_item.owner_id.def_id);
-                if self.tcx.impl_trait_ref(item).is_none() {
+                if let hir::ImplItemImplKind::Inherent { .. } = impl_item.impl_kind {
                     //// If it's a type whose items are live, then it's live, too.
                     //// This is done to handle the case where, for example, the static
                     //// method of a private type is used, but the type itself is never
@@ -484,13 +480,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
     fn check_impl_or_impl_item_live(&mut self, local_def_id: LocalDefId) -> bool {
         let (impl_block_id, trait_def_id) = match self.tcx.def_kind(local_def_id) {
             // assoc impl items of traits are live if the corresponding trait items are live
-            DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => (
-                self.tcx.local_parent(local_def_id),
-                self.tcx
-                    .associated_item(local_def_id)
-                    .trait_item_def_id
-                    .and_then(|def_id| def_id.as_local()),
-            ),
+            DefKind::AssocConst | DefKind::AssocTy | DefKind::AssocFn => {
+                let trait_item_id =
+                    self.tcx.trait_item_of(local_def_id).and_then(|def_id| def_id.as_local());
+                (self.tcx.local_parent(local_def_id), trait_item_id)
+            }
             // impl items are live if the corresponding traits are live
             DefKind::Impl { of_trait: true } => (
                 local_def_id,
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 71650c6b9b9..2ee1bd0dfd1 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -21,8 +21,8 @@ use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures};
 use rustc_middle::middle::privacy::EffectiveVisibilities;
 use rustc_middle::middle::stability::{AllowUnstable, Deprecated, DeprecationEntry, EvalResult};
 use rustc_middle::query::{LocalCrate, Providers};
-use rustc_middle::ty::TyCtxt;
 use rustc_middle::ty::print::with_no_trimmed_paths;
+use rustc_middle::ty::{AssocContainer, TyCtxt};
 use rustc_session::lint;
 use rustc_session::lint::builtin::{DEPRECATED, INEFFECTIVE_UNSTABLE_TRAIT_IMPL};
 use rustc_span::{Span, Symbol, sym};
@@ -486,8 +486,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
 
     fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
         self.check_compatible_stability(ii.owner_id.def_id);
-        let impl_def_id = self.tcx.hir_get_parent_item(ii.hir_id());
-        if self.tcx.impl_trait_ref(impl_def_id).is_none() {
+        if let hir::ImplItemImplKind::Inherent { .. } = ii.impl_kind {
             self.check_missing_stability(ii.owner_id.def_id);
             self.check_missing_const_stability(ii.owner_id.def_id);
         }
@@ -711,7 +710,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                 for impl_item_ref in items {
                     let impl_item = self.tcx.associated_item(impl_item_ref.owner_id);
 
-                    if let Some(def_id) = impl_item.trait_item_def_id {
+                    if let AssocContainer::TraitImpl(Ok(def_id)) = impl_item.container {
                         // Pass `None` to skip deprecation warnings.
                         self.tcx.check_stability(
                             def_id,
diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs
index 1b5f0ed1429..bcc77ff849d 100644
--- a/compiler/rustc_public/src/ty.rs
+++ b/compiler/rustc_public/src/ty.rs
@@ -1612,11 +1612,7 @@ crate_def! {
 pub struct AssocItem {
     pub def_id: AssocDef,
     pub kind: AssocKind,
-    pub container: AssocItemContainer,
-
-    /// If this is an item in an impl of a trait then this is the `DefId` of
-    /// the associated item on the trait that this implements.
-    pub trait_item_def_id: Option<AssocDef>,
+    pub container: AssocContainer,
 }
 
 #[derive(Clone, PartialEq, Debug, Eq, Serialize)]
@@ -1636,9 +1632,11 @@ pub enum AssocKind {
 }
 
 #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
-pub enum AssocItemContainer {
+pub enum AssocContainer {
+    InherentImpl,
+    /// The `AssocDef` points to the trait item being implemented.
+    TraitImpl(AssocDef),
     Trait,
-    Impl,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs
index 207038db40d..5131611eb02 100644
--- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs
+++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs
@@ -1076,14 +1076,21 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind {
     }
 }
 
-impl<'tcx> Stable<'tcx> for ty::AssocItemContainer {
-    type T = crate::ty::AssocItemContainer;
+impl<'tcx> Stable<'tcx> for ty::AssocContainer {
+    type T = crate::ty::AssocContainer;
 
-    fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
-        use crate::ty::AssocItemContainer;
+    fn stable(
+        &self,
+        tables: &mut Tables<'_, BridgeTys>,
+        _: &CompilerCtxt<'_, BridgeTys>,
+    ) -> Self::T {
+        use crate::ty::AssocContainer;
         match self {
-            ty::AssocItemContainer::Trait => AssocItemContainer::Trait,
-            ty::AssocItemContainer::Impl => AssocItemContainer::Impl,
+            ty::AssocContainer::Trait => AssocContainer::Trait,
+            ty::AssocContainer::InherentImpl => AssocContainer::InherentImpl,
+            ty::AssocContainer::TraitImpl(trait_item_id) => {
+                AssocContainer::TraitImpl(tables.assoc_def(trait_item_id.unwrap()))
+            }
         }
     }
 }
@@ -1100,7 +1107,6 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem {
             def_id: tables.assoc_def(self.def_id),
             kind: self.kind.stable(tables, cx),
             container: self.container.stable(tables, cx),
-            trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)),
         }
     }
 }
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
index d81fa062e01..577a16a0d25 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
@@ -469,8 +469,7 @@ fn implemented_method<'tcx>(
     let ancestor = if let Some(impl_id) = tcx.impl_of_assoc(instance.def_id()) {
         // Implementation in an `impl` block
         trait_ref = tcx.impl_trait_ref(impl_id)?;
-        let impl_method = tcx.associated_item(instance.def_id());
-        method_id = impl_method.trait_item_def_id?;
+        method_id = tcx.trait_item_of(instance.def_id())?;
         trait_method = tcx.associated_item(method_id);
         trait_id = trait_ref.skip_binder().def_id;
         impl_id
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 9793d8091e2..297df7c2c97 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -70,6 +70,7 @@ pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
     ("target-libdir", PrintKind::TargetLibdir),
     ("target-list", PrintKind::TargetList),
     ("target-spec-json", PrintKind::TargetSpecJson),
+    ("target-spec-json-schema", PrintKind::TargetSpecJsonSchema),
     ("tls-models", PrintKind::TlsModels),
     // tidy-alphabetical-end
 ];
@@ -1043,6 +1044,7 @@ pub enum PrintKind {
     TargetLibdir,
     TargetList,
     TargetSpecJson,
+    TargetSpecJsonSchema,
     TlsModels,
     // tidy-alphabetical-end
 }
@@ -2323,7 +2325,8 @@ fn is_print_request_stable(print_kind: PrintKind) -> bool {
         | PrintKind::CheckCfg
         | PrintKind::CrateRootLintLevels
         | PrintKind::SupportedCrateTypes
-        | PrintKind::TargetSpecJson => false,
+        | PrintKind::TargetSpecJson
+        | PrintKind::TargetSpecJsonSchema => false,
         _ => true,
     }
 }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 19494ffc37e..633cbc3a4ae 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -46,6 +46,8 @@ use crate::symbol::{Symbol, kw, sym};
 use crate::{DUMMY_SP, HashStableContext, Span, SpanDecoder, SpanEncoder, with_session_globals};
 
 /// A `SyntaxContext` represents a chain of pairs `(ExpnId, Transparency)` named "marks".
+///
+/// See <https://rustc-dev-guide.rust-lang.org/macro-expansion.html> for more explanation.
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
 pub struct SyntaxContext(u32);
 
@@ -61,7 +63,10 @@ pub type SyntaxContextKey = (SyntaxContext, ExpnId, Transparency);
 
 #[derive(Clone, Copy, Debug)]
 struct SyntaxContextData {
+    /// The last macro expansion in the chain.
+    /// (Here we say the most deeply nested macro expansion is the "outermost" expansion.)
     outer_expn: ExpnId,
+    /// Transparency of the last macro expansion
     outer_transparency: Transparency,
     parent: SyntaxContext,
     /// This context, but with all transparent and semi-opaque expansions filtered away.
@@ -450,11 +455,13 @@ impl HygieneData {
         self.syntax_context_data[ctxt.0 as usize].opaque_and_semiopaque
     }
 
+    /// See [`SyntaxContextData::outer_expn`]
     #[inline]
     fn outer_expn(&self, ctxt: SyntaxContext) -> ExpnId {
         self.syntax_context_data[ctxt.0 as usize].outer_expn
     }
 
+    /// The last macro expansion and its Transparency
     #[inline]
     fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) {
         let data = &self.syntax_context_data[ctxt.0 as usize];
@@ -900,6 +907,7 @@ impl SyntaxContext {
         HygieneData::with(|data| data.normalize_to_macro_rules(self))
     }
 
+    /// See [`SyntaxContextData::outer_expn`]
     #[inline]
     pub fn outer_expn(self) -> ExpnId {
         HygieneData::with(|data| data.outer_expn(self))
@@ -912,6 +920,7 @@ impl SyntaxContext {
         HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
     }
 
+    /// See [`HygieneData::outer_mark`]
     #[inline]
     fn outer_mark(self) -> (ExpnId, Transparency) {
         HygieneData::with(|data| data.outer_mark(self))
@@ -982,19 +991,20 @@ impl Span {
 #[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)]
 pub struct ExpnData {
     // --- The part unique to each expansion.
-    /// The kind of this expansion - macro or compiler desugaring.
     pub kind: ExpnKind,
-    /// The expansion that produced this expansion.
+    /// The expansion that contains the definition of the macro for this expansion.
     pub parent: ExpnId,
-    /// The location of the actual macro invocation or syntax sugar , e.g.
-    /// `let x = foo!();` or `if let Some(y) = x {}`
+    /// The span of the macro call which produced this expansion.
+    ///
+    /// This span will typically have a different `ExpnData` and `call_site`.
+    /// This recursively traces back through any macro calls which expanded into further
+    /// macro calls, until the "source call-site" is reached at the root SyntaxContext.
+    /// For example, if `food!()` expands to `fruit!()` which then expands to `grape`,
+    /// then the call-site of `grape` is `fruit!()` and the call-site of `fruit!()`
+    /// is `food!()`.
     ///
-    /// This may recursively refer to other macro invocations, e.g., if
-    /// `foo!()` invoked `bar!()` internally, and there was an
-    /// expression inside `bar!`; the call_site of the expression in
-    /// the expansion would point to the `bar!` invocation; that
-    /// call_site span would have its own ExpnData, with the call_site
-    /// pointing to the `foo!` invocation.
+    /// For a desugaring expansion, this is the span of the expression or node that was
+    /// desugared.
     pub call_site: Span,
     /// Used to force two `ExpnData`s to have different `Fingerprint`s.
     /// Due to macro expansion, it's possible to end up with two `ExpnId`s
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index ae6755f0764..e95b743b1ce 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -710,8 +710,8 @@ impl Span {
         if !ctxt.is_root() { ctxt.outer_expn_data().call_site.source_callsite() } else { self }
     }
 
-    /// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
-    /// if any.
+    /// Returns the call-site span of the last macro expansion which produced this `Span`.
+    /// (see [`ExpnData::call_site`]). Returns `None` if this is not an expansion.
     pub fn parent_callsite(self) -> Option<Span> {
         let ctxt = self.ctxt();
         (!ctxt.is_root()).then(|| ctxt.outer_expn_data().call_site)
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/Cargo.toml b/compiler/rustc_target/Cargo.toml
index 7fabb227d9a..ecdb6ab5a57 100644
--- a/compiler/rustc_target/Cargo.toml
+++ b/compiler/rustc_target/Cargo.toml
@@ -14,6 +14,7 @@ rustc_fs_util = { path = "../rustc_fs_util" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
+schemars = "1.0.4"
 serde = "1.0.219"
 serde_derive = "1.0.219"
 serde_json = "1.0.59"
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index 91657fef803..b3fe1fffcce 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -72,3 +72,65 @@ fn find_relative_libdir(sysroot: &Path) -> std::borrow::Cow<'static, str> {
         Some(libdir) => libdir.into(),
     }
 }
+
+macro_rules! target_spec_enum {
+    (
+        $( #[$attr:meta] )*
+        pub enum $name:ident {
+            $(
+                $( #[$variant_attr:meta] )*
+                $variant:ident = $string:literal,
+            )*
+        }
+        parse_error_type = $parse_error_type:literal;
+    ) => {
+        $( #[$attr] )*
+        #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
+        #[derive(schemars::JsonSchema)]
+        pub enum $name {
+            $(
+                $( #[$variant_attr] )*
+                #[serde(rename = $string)] // for JSON schema generation only
+                $variant,
+            )*
+        }
+
+        impl FromStr for $name {
+            type Err = String;
+
+            fn from_str(s: &str) -> Result<Self, Self::Err> {
+                Ok(match s {
+                    $( $string => Self::$variant, )*
+                    _ => {
+                        let all = [$( concat!("'", $string, "'") ),*].join(", ");
+                        return Err(format!("invalid {}: '{s}'. allowed values: {all}", $parse_error_type));
+                    }
+                })
+            }
+        }
+
+        impl $name {
+            pub fn desc(&self) -> &'static str {
+                match self {
+                    $( Self::$variant => $string, )*
+                }
+            }
+        }
+
+        impl crate::json::ToJson for $name {
+            fn to_json(&self) -> crate::json::Json {
+                self.desc().to_json()
+            }
+        }
+
+        crate::json::serde_deserialize_from_str!($name);
+
+
+        impl std::fmt::Display for $name {
+            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                f.write_str(self.desc())
+            }
+        }
+    };
+}
+use target_spec_enum;
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs
index e9ae5734d5b..f236be92b3b 100644
--- a/compiler/rustc_target/src/spec/json.rs
+++ b/compiler/rustc_target/src/spec/json.rs
@@ -408,12 +408,12 @@ impl ToJson for Target {
     }
 }
 
-#[derive(serde_derive::Deserialize)]
+#[derive(serde_derive::Deserialize, schemars::JsonSchema)]
 struct LinkSelfContainedComponentsWrapper {
     components: Vec<LinkSelfContainedComponents>,
 }
 
-#[derive(serde_derive::Deserialize)]
+#[derive(serde_derive::Deserialize, schemars::JsonSchema)]
 #[serde(untagged)]
 enum TargetFamiliesJson {
     Array(StaticCow<[StaticCow<str>]>),
@@ -429,6 +429,18 @@ impl FromStr for EndianWrapper {
     }
 }
 crate::json::serde_deserialize_from_str!(EndianWrapper);
+impl schemars::JsonSchema for EndianWrapper {
+    fn schema_name() -> std::borrow::Cow<'static, str> {
+        "Endian".into()
+    }
+    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
+        schemars::json_schema! ({
+            "type": "string",
+            "enum": ["big", "little"]
+        })
+        .into()
+    }
+}
 
 /// `ExternAbi` is in `rustc_abi`, which doesn't have access to the macro and serde.
 struct ExternAbiWrapper(rustc_abi::ExternAbi);
@@ -441,8 +453,22 @@ impl FromStr for ExternAbiWrapper {
     }
 }
 crate::json::serde_deserialize_from_str!(ExternAbiWrapper);
+impl schemars::JsonSchema for ExternAbiWrapper {
+    fn schema_name() -> std::borrow::Cow<'static, str> {
+        "ExternAbi".into()
+    }
+    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
+        let all =
+            rustc_abi::ExternAbi::ALL_VARIANTS.iter().map(|abi| abi.as_str()).collect::<Vec<_>>();
+        schemars::json_schema! ({
+            "type": "string",
+            "enum": all,
+        })
+        .into()
+    }
+}
 
-#[derive(serde_derive::Deserialize)]
+#[derive(serde_derive::Deserialize, schemars::JsonSchema)]
 struct TargetSpecJsonMetadata {
     description: Option<StaticCow<str>>,
     tier: Option<u64>,
@@ -450,7 +476,7 @@ struct TargetSpecJsonMetadata {
     std: Option<bool>,
 }
 
-#[derive(serde_derive::Deserialize)]
+#[derive(serde_derive::Deserialize, schemars::JsonSchema)]
 #[serde(rename_all = "kebab-case")]
 // Ensure that all unexpected fields get turned into errors.
 // This helps users stay up to date when the schema changes instead of silently
@@ -593,3 +619,7 @@ struct TargetSpecJson {
     supports_xray: Option<bool>,
     entry_abi: Option<ExternAbiWrapper>,
 }
+
+pub fn json_schema() -> schemars::Schema {
+    schemars::schema_for!(TargetSpecJson)
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 4d9f06c568b..07fb1ce63f7 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -70,6 +70,7 @@ mod json;
 pub use abi_map::{AbiMap, AbiMapping};
 pub use base::apple;
 pub use base::avr::ef_avr_arch;
+pub use json::json_schema;
 
 /// Linker is called through a C/C++ compiler.
 #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@@ -183,50 +184,15 @@ impl LinkerFlavorCli {
     }
 }
 
-#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
-pub enum LldFlavor {
-    Wasm,
-    Ld64,
-    Ld,
-    Link,
-}
-
-impl LldFlavor {
-    pub fn as_str(&self) -> &'static str {
-        match self {
-            LldFlavor::Wasm => "wasm",
-            LldFlavor::Ld64 => "darwin",
-            LldFlavor::Ld => "gnu",
-            LldFlavor::Link => "link",
-        }
-    }
-}
-
-impl FromStr for LldFlavor {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Ok(match s {
-            "darwin" => LldFlavor::Ld64,
-            "gnu" => LldFlavor::Ld,
-            "link" => LldFlavor::Link,
-            "wasm" => LldFlavor::Wasm,
-            _ => {
-                return Err(
-                    "invalid value for lld flavor: '{s}', expected one of 'darwin', 'gnu', 'link', 'wasm'"
-                        .into(),
-                );
-            }
-        })
+crate::target_spec_enum! {
+    pub enum LldFlavor {
+        Wasm = "wasm",
+        Ld64 = "darwin",
+        Ld = "gnu",
+        Link = "link",
     }
-}
 
-crate::json::serde_deserialize_from_str!(LldFlavor);
-
-impl ToJson for LldFlavor {
-    fn to_json(&self) -> Json {
-        self.as_str().to_json()
-    }
+    parse_error_type = "LLD flavor";
 }
 
 impl LinkerFlavor {
@@ -558,6 +524,20 @@ linker_flavor_cli_impls! {
 }
 
 crate::json::serde_deserialize_from_str!(LinkerFlavorCli);
+impl schemars::JsonSchema for LinkerFlavorCli {
+    fn schema_name() -> std::borrow::Cow<'static, str> {
+        "LinkerFlavor".into()
+    }
+    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
+        let all: Vec<&'static str> =
+            Self::all().iter().map(|flavor| flavor.desc()).collect::<Vec<_>>();
+        schemars::json_schema! ({
+            "type": "string",
+            "enum": all
+        })
+        .into()
+    }
+}
 
 impl ToJson for LinkerFlavorCli {
     fn to_json(&self) -> Json {
@@ -611,6 +591,18 @@ impl FromStr for LinkSelfContainedDefault {
 }
 
 crate::json::serde_deserialize_from_str!(LinkSelfContainedDefault);
+impl schemars::JsonSchema for LinkSelfContainedDefault {
+    fn schema_name() -> std::borrow::Cow<'static, str> {
+        "LinkSelfContainedDefault".into()
+    }
+    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
+        schemars::json_schema! ({
+            "type": "string",
+            "enum": ["false", "true", "wasm", "musl", "mingw"]
+        })
+        .into()
+    }
+}
 
 impl ToJson for LinkSelfContainedDefault {
     fn to_json(&self) -> Json {
@@ -743,6 +735,20 @@ impl FromStr for LinkSelfContainedComponents {
 }
 
 crate::json::serde_deserialize_from_str!(LinkSelfContainedComponents);
+impl schemars::JsonSchema for LinkSelfContainedComponents {
+    fn schema_name() -> std::borrow::Cow<'static, str> {
+        "LinkSelfContainedComponents".into()
+    }
+    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
+        let all =
+            Self::all_components().iter().map(|component| component.as_str()).collect::<Vec<_>>();
+        schemars::json_schema! ({
+            "type": "string",
+            "enum": all,
+        })
+        .into()
+    }
+}
 
 impl ToJson for LinkSelfContainedComponents {
     fn to_json(&self) -> Json {
@@ -823,10 +829,14 @@ impl LinkerFeatures {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
-pub enum PanicStrategy {
-    Unwind,
-    Abort,
+crate::target_spec_enum! {
+    #[derive(Encodable, Decodable, HashStable_Generic)]
+    pub enum PanicStrategy {
+        Unwind = "unwind",
+        Abort = "abort",
+    }
+
+    parse_error_type = "panic strategy";
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
@@ -838,13 +848,6 @@ pub enum OnBrokenPipe {
 }
 
 impl PanicStrategy {
-    pub fn desc(&self) -> &str {
-        match *self {
-            PanicStrategy::Unwind => "unwind",
-            PanicStrategy::Abort => "abort",
-        }
-    }
-
     pub const fn desc_symbol(&self) -> Symbol {
         match *self {
             PanicStrategy::Unwind => sym::unwind,
@@ -857,24 +860,16 @@ impl PanicStrategy {
     }
 }
 
-impl FromStr for PanicStrategy {
-    type Err = String;
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Ok(match s {
-            "unwind" => PanicStrategy::Unwind,
-            "abort" => PanicStrategy::Abort,
-            _ => {
-                return Err(format!(
-                    "'{}' is not a valid value for \
-                    panic-strategy. Use 'unwind' or 'abort'.",
-                    s
-                ));
-            }
-        })
+crate::target_spec_enum! {
+    pub enum RelroLevel {
+        Full = "full",
+        Partial = "partial",
+        Off = "off",
+        None = "none",
     }
-}
 
-crate::json::serde_deserialize_from_str!(PanicStrategy);
+    parse_error_type = "relro level";
+}
 
 impl IntoDiagArg for PanicStrategy {
     fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
@@ -882,109 +877,14 @@ impl IntoDiagArg for PanicStrategy {
     }
 }
 
-impl ToJson for PanicStrategy {
-    fn to_json(&self) -> Json {
-        match *self {
-            PanicStrategy::Abort => "abort".to_json(),
-            PanicStrategy::Unwind => "unwind".to_json(),
-        }
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Hash)]
-pub enum RelroLevel {
-    Full,
-    Partial,
-    Off,
-    None,
-}
-
-impl RelroLevel {
-    pub fn desc(&self) -> &str {
-        match *self {
-            RelroLevel::Full => "full",
-            RelroLevel::Partial => "partial",
-            RelroLevel::Off => "off",
-            RelroLevel::None => "none",
-        }
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Hash)]
-pub enum SymbolVisibility {
-    Hidden,
-    Protected,
-    Interposable,
-}
-
-impl SymbolVisibility {
-    pub fn desc(&self) -> &str {
-        match *self {
-            SymbolVisibility::Hidden => "hidden",
-            SymbolVisibility::Protected => "protected",
-            SymbolVisibility::Interposable => "interposable",
-        }
-    }
-}
-
-impl FromStr for SymbolVisibility {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<SymbolVisibility, Self::Err> {
-        match s {
-            "hidden" => Ok(SymbolVisibility::Hidden),
-            "protected" => Ok(SymbolVisibility::Protected),
-            "interposable" => Ok(SymbolVisibility::Interposable),
-            _ => Err(format!(
-                "'{}' is not a valid value for \
-                    symbol-visibility. Use 'hidden', 'protected, or 'interposable'.",
-                s
-            )),
-        }
-    }
-}
-
-crate::json::serde_deserialize_from_str!(SymbolVisibility);
-
-impl ToJson for SymbolVisibility {
-    fn to_json(&self) -> Json {
-        match *self {
-            SymbolVisibility::Hidden => "hidden".to_json(),
-            SymbolVisibility::Protected => "protected".to_json(),
-            SymbolVisibility::Interposable => "interposable".to_json(),
-        }
-    }
-}
-
-impl FromStr for RelroLevel {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<RelroLevel, Self::Err> {
-        match s {
-            "full" => Ok(RelroLevel::Full),
-            "partial" => Ok(RelroLevel::Partial),
-            "off" => Ok(RelroLevel::Off),
-            "none" => Ok(RelroLevel::None),
-            _ => Err(format!(
-                "'{}' is not a valid value for \
-                        relro-level. Use 'full', 'partial, 'off', or 'none'.",
-                s
-            )),
-        }
+crate::target_spec_enum! {
+    pub enum SymbolVisibility {
+        Hidden = "hidden",
+        Protected = "protected",
+        Interposable = "interposable",
     }
-}
-
-crate::json::serde_deserialize_from_str!(RelroLevel);
 
-impl ToJson for RelroLevel {
-    fn to_json(&self) -> Json {
-        match *self {
-            RelroLevel::Full => "full".to_json(),
-            RelroLevel::Partial => "partial".to_json(),
-            RelroLevel::Off => "off".to_json(),
-            RelroLevel::None => "None".to_json(),
-        }
-    }
+    parse_error_type = "symbol visibility";
 }
 
 #[derive(Clone, Debug, PartialEq, Hash)]
@@ -1014,6 +914,18 @@ impl FromStr for SmallDataThresholdSupport {
 }
 
 crate::json::serde_deserialize_from_str!(SmallDataThresholdSupport);
+impl schemars::JsonSchema for SmallDataThresholdSupport {
+    fn schema_name() -> std::borrow::Cow<'static, str> {
+        "SmallDataThresholdSupport".into()
+    }
+    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
+        schemars::json_schema! ({
+            "type": "string",
+            "pattern": r#"^none|default-for-arch|llvm-module-flag=.+|llvm-arg=.+$"#,
+        })
+        .into()
+    }
+}
 
 impl ToJson for SmallDataThresholdSupport {
     fn to_json(&self) -> Value {
@@ -1026,76 +938,31 @@ impl ToJson for SmallDataThresholdSupport {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Hash)]
-pub enum MergeFunctions {
-    Disabled,
-    Trampolines,
-    Aliases,
-}
-
-impl MergeFunctions {
-    pub fn desc(&self) -> &str {
-        match *self {
-            MergeFunctions::Disabled => "disabled",
-            MergeFunctions::Trampolines => "trampolines",
-            MergeFunctions::Aliases => "aliases",
-        }
+crate::target_spec_enum! {
+    pub enum MergeFunctions {
+        Disabled = "disabled",
+        Trampolines = "trampolines",
+        Aliases = "aliases",
     }
-}
-
-impl FromStr for MergeFunctions {
-    type Err = String;
 
-    fn from_str(s: &str) -> Result<MergeFunctions, Self::Err> {
-        match s {
-            "disabled" => Ok(MergeFunctions::Disabled),
-            "trampolines" => Ok(MergeFunctions::Trampolines),
-            "aliases" => Ok(MergeFunctions::Aliases),
-            _ => Err(format!(
-                "'{}' is not a valid value for \
-                    merge-functions. Use 'disabled', \
-                    'trampolines', or 'aliases'.",
-                s
-            )),
-        }
-    }
+    parse_error_type = "value for merge-functions";
 }
 
-crate::json::serde_deserialize_from_str!(MergeFunctions);
-
-impl ToJson for MergeFunctions {
-    fn to_json(&self) -> Json {
-        match *self {
-            MergeFunctions::Disabled => "disabled".to_json(),
-            MergeFunctions::Trampolines => "trampolines".to_json(),
-            MergeFunctions::Aliases => "aliases".to_json(),
-        }
+crate::target_spec_enum! {
+    pub enum RelocModel {
+        Static = "static",
+        Pic = "pic",
+        Pie = "pie",
+        DynamicNoPic = "dynamic-no-pic",
+        Ropi = "ropi",
+        Rwpi = "rwpi",
+        RopiRwpi = "ropi-rwpi",
     }
-}
 
-#[derive(Clone, Copy, PartialEq, Hash, Debug)]
-pub enum RelocModel {
-    Static,
-    Pic,
-    Pie,
-    DynamicNoPic,
-    Ropi,
-    Rwpi,
-    RopiRwpi,
+    parse_error_type = "relocation model";
 }
 
 impl RelocModel {
-    pub fn desc(&self) -> &str {
-        match *self {
-            RelocModel::Static => "static",
-            RelocModel::Pic => "pic",
-            RelocModel::Pie => "pie",
-            RelocModel::DynamicNoPic => "dynamic-no-pic",
-            RelocModel::Ropi => "ropi",
-            RelocModel::Rwpi => "rwpi",
-            RelocModel::RopiRwpi => "ropi-rwpi",
-        }
-    }
     pub const fn desc_symbol(&self) -> Symbol {
         match *self {
             RelocModel::Static => kw::Static,
@@ -1121,236 +988,75 @@ impl RelocModel {
     }
 }
 
-impl FromStr for RelocModel {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<RelocModel, Self::Err> {
-        Ok(match s {
-            "static" => RelocModel::Static,
-            "pic" => RelocModel::Pic,
-            "pie" => RelocModel::Pie,
-            "dynamic-no-pic" => RelocModel::DynamicNoPic,
-            "ropi" => RelocModel::Ropi,
-            "rwpi" => RelocModel::Rwpi,
-            "ropi-rwpi" => RelocModel::RopiRwpi,
-            _ => {
-                return Err(format!(
-                    "invalid relocation model '{s}'.
-                        Run `rustc --print relocation-models` to \
-                        see the list of supported values.'"
-                ));
-            }
-        })
+crate::target_spec_enum! {
+    pub enum CodeModel {
+        Tiny = "tiny",
+        Small = "small",
+        Kernel = "kernel",
+        Medium = "medium",
+        Large = "large",
     }
-}
 
-crate::json::serde_deserialize_from_str!(RelocModel);
-
-impl ToJson for RelocModel {
-    fn to_json(&self) -> Json {
-        self.desc().to_json()
-    }
-}
-
-#[derive(Clone, Copy, PartialEq, Hash, Debug)]
-pub enum CodeModel {
-    Tiny,
-    Small,
-    Kernel,
-    Medium,
-    Large,
+    parse_error_type = "code model";
 }
 
-impl FromStr for CodeModel {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<CodeModel, Self::Err> {
-        Ok(match s {
-            "tiny" => CodeModel::Tiny,
-            "small" => CodeModel::Small,
-            "kernel" => CodeModel::Kernel,
-            "medium" => CodeModel::Medium,
-            "large" => CodeModel::Large,
-            _ => {
-                return Err(format!(
-                    "'{s}' is not a valid code model. \
-                        Run `rustc --print code-models` to \
-                        see the list of supported values."
-                ));
-            }
-        })
+crate::target_spec_enum! {
+    /// The float ABI setting to be configured in the LLVM target machine.
+    pub enum FloatAbi {
+        Soft = "soft",
+        Hard = "hard",
     }
-}
 
-crate::json::serde_deserialize_from_str!(CodeModel);
-
-impl ToJson for CodeModel {
-    fn to_json(&self) -> Json {
-        match *self {
-            CodeModel::Tiny => "tiny",
-            CodeModel::Small => "small",
-            CodeModel::Kernel => "kernel",
-            CodeModel::Medium => "medium",
-            CodeModel::Large => "large",
-        }
-        .to_json()
-    }
+    parse_error_type = "float abi";
 }
 
-/// The float ABI setting to be configured in the LLVM target machine.
-#[derive(Clone, Copy, PartialEq, Hash, Debug)]
-pub enum FloatAbi {
-    Soft,
-    Hard,
-}
-
-impl FromStr for FloatAbi {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<FloatAbi, Self::Err> {
-        Ok(match s {
-            "soft" => FloatAbi::Soft,
-            "hard" => FloatAbi::Hard,
-            _ => {
-                return Err(format!(
-                    "'{}' is not a valid value for \
-                        llvm-floatabi. Use 'soft' or 'hard'.",
-                    s
-                ));
-            }
-        })
+crate::target_spec_enum! {
+    /// The Rustc-specific variant of the ABI used for this target.
+    pub enum RustcAbi {
+        /// On x86-32 only: make use of SSE and SSE2 for ABI purposes.
+        X86Sse2 = "x86-sse2",
+        /// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI.
+        X86Softfloat = "x86-softfloat",
     }
-}
-
-crate::json::serde_deserialize_from_str!(FloatAbi);
 
-impl ToJson for FloatAbi {
-    fn to_json(&self) -> Json {
-        match *self {
-            FloatAbi::Soft => "soft",
-            FloatAbi::Hard => "hard",
-        }
-        .to_json()
-    }
-}
-
-/// The Rustc-specific variant of the ABI used for this target.
-#[derive(Clone, Copy, PartialEq, Hash, Debug)]
-pub enum RustcAbi {
-    /// On x86-32 only: make use of SSE and SSE2 for ABI purposes.
-    X86Sse2,
-    /// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI.
-    X86Softfloat,
+    parse_error_type = "rustc abi";
 }
 
-impl FromStr for RustcAbi {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<RustcAbi, Self::Err> {
-        Ok(match s {
-            "x86-sse2" => RustcAbi::X86Sse2,
-            "x86-softfloat" => RustcAbi::X86Softfloat,
-            _ => {
-                return Err(format!(
-                    "'{s}' is not a valid value for rustc-abi. \
-                        Use 'x86-softfloat' or leave the field unset."
-                ));
-            }
-        })
-    }
-}
-
-crate::json::serde_deserialize_from_str!(RustcAbi);
-
-impl ToJson for RustcAbi {
-    fn to_json(&self) -> Json {
-        match *self {
-            RustcAbi::X86Sse2 => "x86-sse2",
-            RustcAbi::X86Softfloat => "x86-softfloat",
-        }
-        .to_json()
+crate::target_spec_enum! {
+    pub enum TlsModel {
+        GeneralDynamic = "global-dynamic",
+        LocalDynamic = "local-dynamic",
+        InitialExec = "initial-exec",
+        LocalExec = "local-exec",
+        Emulated = "emulated",
     }
-}
 
-#[derive(Clone, Copy, PartialEq, Hash, Debug)]
-pub enum TlsModel {
-    GeneralDynamic,
-    LocalDynamic,
-    InitialExec,
-    LocalExec,
-    Emulated,
-}
-
-impl FromStr for TlsModel {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<TlsModel, Self::Err> {
-        Ok(match s {
-            // Note the difference "general" vs "global" difference. The model name is "general",
-            // but the user-facing option name is "global" for consistency with other compilers.
-            "global-dynamic" => TlsModel::GeneralDynamic,
-            "local-dynamic" => TlsModel::LocalDynamic,
-            "initial-exec" => TlsModel::InitialExec,
-            "local-exec" => TlsModel::LocalExec,
-            "emulated" => TlsModel::Emulated,
-            _ => {
-                return Err(format!(
-                    "'{s}' is not a valid TLS model. \
-                        Run `rustc --print tls-models` to \
-                        see the list of supported values."
-                ));
-            }
-        })
-    }
+    parse_error_type = "TLS model";
 }
 
-crate::json::serde_deserialize_from_str!(TlsModel);
-
-impl ToJson for TlsModel {
-    fn to_json(&self) -> Json {
-        match *self {
-            TlsModel::GeneralDynamic => "global-dynamic",
-            TlsModel::LocalDynamic => "local-dynamic",
-            TlsModel::InitialExec => "initial-exec",
-            TlsModel::LocalExec => "local-exec",
-            TlsModel::Emulated => "emulated",
-        }
-        .to_json()
+crate::target_spec_enum! {
+    /// Everything is flattened to a single enum to make the json encoding/decoding less annoying.
+    pub enum LinkOutputKind {
+        /// Dynamically linked non position-independent executable.
+        DynamicNoPicExe = "dynamic-nopic-exe",
+        /// Dynamically linked position-independent executable.
+        DynamicPicExe = "dynamic-pic-exe",
+        /// Statically linked non position-independent executable.
+        StaticNoPicExe = "static-nopic-exe",
+        /// Statically linked position-independent executable.
+        StaticPicExe = "static-pic-exe",
+        /// Regular dynamic library ("dynamically linked").
+        DynamicDylib = "dynamic-dylib",
+        /// Dynamic library with bundled libc ("statically linked").
+        StaticDylib = "static-dylib",
+        /// WASI module with a lifetime past the _initialize entry point
+        WasiReactorExe = "wasi-reactor-exe",
     }
-}
 
-/// Everything is flattened to a single enum to make the json encoding/decoding less annoying.
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
-pub enum LinkOutputKind {
-    /// Dynamically linked non position-independent executable.
-    DynamicNoPicExe,
-    /// Dynamically linked position-independent executable.
-    DynamicPicExe,
-    /// Statically linked non position-independent executable.
-    StaticNoPicExe,
-    /// Statically linked position-independent executable.
-    StaticPicExe,
-    /// Regular dynamic library ("dynamically linked").
-    DynamicDylib,
-    /// Dynamic library with bundled libc ("statically linked").
-    StaticDylib,
-    /// WASI module with a lifetime past the _initialize entry point
-    WasiReactorExe,
+    parse_error_type = "CRT object kind";
 }
 
 impl LinkOutputKind {
-    fn as_str(&self) -> &'static str {
-        match self {
-            LinkOutputKind::DynamicNoPicExe => "dynamic-nopic-exe",
-            LinkOutputKind::DynamicPicExe => "dynamic-pic-exe",
-            LinkOutputKind::StaticNoPicExe => "static-nopic-exe",
-            LinkOutputKind::StaticPicExe => "static-pic-exe",
-            LinkOutputKind::DynamicDylib => "dynamic-dylib",
-            LinkOutputKind::StaticDylib => "static-dylib",
-            LinkOutputKind::WasiReactorExe => "wasi-reactor-exe",
-        }
-    }
-
     pub fn can_link_dylib(self) -> bool {
         match self {
             LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => false,
@@ -1363,171 +1069,64 @@ impl LinkOutputKind {
     }
 }
 
-impl FromStr for LinkOutputKind {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<LinkOutputKind, Self::Err> {
-        Ok(match s {
-            "dynamic-nopic-exe" => LinkOutputKind::DynamicNoPicExe,
-            "dynamic-pic-exe" => LinkOutputKind::DynamicPicExe,
-            "static-nopic-exe" => LinkOutputKind::StaticNoPicExe,
-            "static-pic-exe" => LinkOutputKind::StaticPicExe,
-            "dynamic-dylib" => LinkOutputKind::DynamicDylib,
-            "static-dylib" => LinkOutputKind::StaticDylib,
-            "wasi-reactor-exe" => LinkOutputKind::WasiReactorExe,
-            _ => {
-                return Err(format!(
-                    "invalid value for CRT object kind. \
-                        Use '(dynamic,static)-(nopic,pic)-exe' or \
-                        '(dynamic,static)-dylib' or 'wasi-reactor-exe'"
-                ));
-            }
-        })
-    }
-}
-
-crate::json::serde_deserialize_from_str!(LinkOutputKind);
-
-impl fmt::Display for LinkOutputKind {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.as_str())
-    }
-}
-
 pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<StaticCow<str>>>;
 pub type LinkArgsCli = BTreeMap<LinkerFlavorCli, Vec<StaticCow<str>>>;
 
-/// Which kind of debuginfo does the target use?
-///
-/// Useful in determining whether a target supports Split DWARF (a target with
-/// `DebuginfoKind::Dwarf` and supporting `SplitDebuginfo::Unpacked` for example).
-#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
-pub enum DebuginfoKind {
-    /// DWARF debuginfo (such as that used on `x86_64_unknown_linux_gnu`).
-    #[default]
-    Dwarf,
-    /// DWARF debuginfo in dSYM files (such as on Apple platforms).
-    DwarfDsym,
-    /// Program database files (such as on Windows).
-    Pdb,
-}
-
-impl DebuginfoKind {
-    fn as_str(&self) -> &'static str {
-        match self {
-            DebuginfoKind::Dwarf => "dwarf",
-            DebuginfoKind::DwarfDsym => "dwarf-dsym",
-            DebuginfoKind::Pdb => "pdb",
-        }
-    }
-}
-
-impl FromStr for DebuginfoKind {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Ok(match s {
-            "dwarf" => DebuginfoKind::Dwarf,
-            "dwarf-dsym" => DebuginfoKind::DwarfDsym,
-            "pdb" => DebuginfoKind::Pdb,
-            _ => {
-                return Err(format!(
-                    "'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \
-                        'dwarf-dsym' or 'pdb'."
-                ));
-            }
-        })
-    }
-}
-
-crate::json::serde_deserialize_from_str!(DebuginfoKind);
-
-impl ToJson for DebuginfoKind {
-    fn to_json(&self) -> Json {
-        self.as_str().to_json()
-    }
-}
-
-impl fmt::Display for DebuginfoKind {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.as_str())
-    }
-}
-
-#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
-pub enum SplitDebuginfo {
-    /// Split debug-information is disabled, meaning that on supported platforms
-    /// you can find all debug information in the executable itself. This is
-    /// only supported for ELF effectively.
-    ///
-    /// * Windows - not supported
-    /// * macOS - don't run `dsymutil`
-    /// * ELF - `.debug_*` sections
-    #[default]
-    Off,
-
-    /// Split debug-information can be found in a "packed" location separate
-    /// from the final artifact. This is supported on all platforms.
+crate::target_spec_enum! {
+    /// Which kind of debuginfo does the target use?
     ///
-    /// * Windows - `*.pdb`
-    /// * macOS - `*.dSYM` (run `dsymutil`)
-    /// * ELF - `*.dwp` (run `thorin`)
-    Packed,
-
-    /// Split debug-information can be found in individual object files on the
-    /// filesystem. The main executable may point to the object files.
-    ///
-    /// * Windows - not supported
-    /// * macOS - supported, scattered object files
-    /// * ELF - supported, scattered `*.dwo` or `*.o` files (see `SplitDwarfKind`)
-    Unpacked,
-}
-
-impl SplitDebuginfo {
-    fn as_str(&self) -> &'static str {
-        match self {
-            SplitDebuginfo::Off => "off",
-            SplitDebuginfo::Packed => "packed",
-            SplitDebuginfo::Unpacked => "unpacked",
-        }
-    }
-}
-
-impl FromStr for SplitDebuginfo {
-    type Err = String;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Ok(match s {
-            "off" => SplitDebuginfo::Off,
-            "unpacked" => SplitDebuginfo::Unpacked,
-            "packed" => SplitDebuginfo::Packed,
-            _ => {
-                return Err(format!(
-                    "'{s}' is not a valid value for \
-                        split-debuginfo. Use 'off', 'unpacked', or 'packed'.",
-                ));
-            }
-        })
-    }
-}
-
-crate::json::serde_deserialize_from_str!(SplitDebuginfo);
-
-impl ToJson for SplitDebuginfo {
-    fn to_json(&self) -> Json {
-        self.as_str().to_json()
-    }
-}
-
-impl fmt::Display for SplitDebuginfo {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.as_str())
-    }
+    /// Useful in determining whether a target supports Split DWARF (a target with
+    /// `DebuginfoKind::Dwarf` and supporting `SplitDebuginfo::Unpacked` for example).
+    #[derive(Default)]
+    pub enum DebuginfoKind {
+        /// DWARF debuginfo (such as that used on `x86_64_unknown_linux_gnu`).
+        #[default]
+        Dwarf = "dwarf",
+        /// DWARF debuginfo in dSYM files (such as on Apple platforms).
+        DwarfDsym = "dwarf-dsym",
+        /// Program database files (such as on Windows).
+        Pdb = "pdb",
+    }
+
+    parse_error_type = "debuginfo kind";
+}
+
+crate::target_spec_enum! {
+    #[derive(Default)]
+    pub enum SplitDebuginfo {
+        /// Split debug-information is disabled, meaning that on supported platforms
+        /// you can find all debug information in the executable itself. This is
+        /// only supported for ELF effectively.
+        ///
+        /// * Windows - not supported
+        /// * macOS - don't run `dsymutil`
+        /// * ELF - `.debug_*` sections
+        #[default]
+        Off = "off",
+
+        /// Split debug-information can be found in a "packed" location separate
+        /// from the final artifact. This is supported on all platforms.
+        ///
+        /// * Windows - `*.pdb`
+        /// * macOS - `*.dSYM` (run `dsymutil`)
+        /// * ELF - `*.dwp` (run `thorin`)
+        Packed = "packed",
+
+        /// Split debug-information can be found in individual object files on the
+        /// filesystem. The main executable may point to the object files.
+        ///
+        /// * Windows - not supported
+        /// * macOS - supported, scattered object files
+        /// * ELF - supported, scattered `*.dwo` or `*.o` files (see `SplitDwarfKind`)
+        Unpacked = "unpacked",
+    }
+
+    parse_error_type = "split debuginfo";
 }
 
 into_diag_arg_using_display!(SplitDebuginfo);
 
-#[derive(Clone, Debug, PartialEq, Eq, serde_derive::Deserialize)]
+#[derive(Clone, Debug, PartialEq, Eq, serde_derive::Deserialize, schemars::JsonSchema)]
 #[serde(tag = "kind")]
 #[serde(rename_all = "kebab-case")]
 pub enum StackProbeType {
@@ -1688,6 +1287,19 @@ impl FromStr for SanitizerSet {
 }
 
 crate::json::serde_deserialize_from_str!(SanitizerSet);
+impl schemars::JsonSchema for SanitizerSet {
+    fn schema_name() -> std::borrow::Cow<'static, str> {
+        "SanitizerSet".into()
+    }
+    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
+        let all = Self::all().iter().map(|sanitizer| sanitizer.as_str()).collect::<Vec<_>>();
+        schemars::json_schema! ({
+            "type": "string",
+            "enum": all,
+        })
+        .into()
+    }
+}
 
 impl ToJson for SanitizerSet {
     fn to_json(&self) -> Json {
@@ -1699,17 +1311,20 @@ impl ToJson for SanitizerSet {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Hash, Debug)]
-pub enum FramePointer {
-    /// Forces the machine code generator to always preserve the frame pointers.
-    Always,
-    /// Forces the machine code generator to preserve the frame pointers except for the leaf
-    /// functions (i.e. those that don't call other functions).
-    NonLeaf,
-    /// Allows the machine code generator to omit the frame pointers.
-    ///
-    /// This option does not guarantee that the frame pointers will be omitted.
-    MayOmit,
+crate::target_spec_enum! {
+    pub enum FramePointer {
+        /// Forces the machine code generator to always preserve the frame pointers.
+        Always = "always",
+        /// Forces the machine code generator to preserve the frame pointers except for the leaf
+        /// functions (i.e. those that don't call other functions).
+        NonLeaf = "non-leaf",
+        /// Allows the machine code generator to omit the frame pointers.
+        ///
+        /// This option does not guarantee that the frame pointers will be omitted.
+        MayOmit = "may-omit",
+    }
+
+    parse_error_type = "frame pointer";
 }
 
 impl FramePointer {
@@ -1726,93 +1341,43 @@ impl FramePointer {
     }
 }
 
-impl FromStr for FramePointer {
-    type Err = String;
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Ok(match s {
-            "always" => Self::Always,
-            "non-leaf" => Self::NonLeaf,
-            "may-omit" => Self::MayOmit,
-            _ => return Err(format!("'{s}' is not a valid value for frame-pointer")),
-        })
-    }
-}
-
-crate::json::serde_deserialize_from_str!(FramePointer);
-
-impl ToJson for FramePointer {
-    fn to_json(&self) -> Json {
-        match *self {
-            Self::Always => "always",
-            Self::NonLeaf => "non-leaf",
-            Self::MayOmit => "may-omit",
-        }
-        .to_json()
-    }
-}
-
-/// Controls use of stack canaries.
-#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq)]
-pub enum StackProtector {
-    /// Disable stack canary generation.
-    None,
-
-    /// On LLVM, mark all generated LLVM functions with the `ssp` attribute (see
-    /// llvm/docs/LangRef.rst). This triggers stack canary generation in
-    /// functions which contain an array of a byte-sized type with more than
-    /// eight elements.
-    Basic,
+crate::target_spec_enum! {
+    /// Controls use of stack canaries.
+    pub enum StackProtector {
+        /// Disable stack canary generation.
+        None = "none",
 
-    /// On LLVM, mark all generated LLVM functions with the `sspstrong`
-    /// attribute (see llvm/docs/LangRef.rst). This triggers stack canary
-    /// generation in functions which either contain an array, or which take
-    /// the address of a local variable.
-    Strong,
+        /// On LLVM, mark all generated LLVM functions with the `ssp` attribute (see
+        /// llvm/docs/LangRef.rst). This triggers stack canary generation in
+        /// functions which contain an array of a byte-sized type with more than
+        /// eight elements.
+        Basic = "basic",
 
-    /// Generate stack canaries in all functions.
-    All,
-}
+        /// On LLVM, mark all generated LLVM functions with the `sspstrong`
+        /// attribute (see llvm/docs/LangRef.rst). This triggers stack canary
+        /// generation in functions which either contain an array, or which take
+        /// the address of a local variable.
+        Strong = "strong",
 
-impl StackProtector {
-    fn as_str(&self) -> &'static str {
-        match self {
-            StackProtector::None => "none",
-            StackProtector::Basic => "basic",
-            StackProtector::Strong => "strong",
-            StackProtector::All => "all",
-        }
+        /// Generate stack canaries in all functions.
+        All = "all",
     }
-}
 
-impl FromStr for StackProtector {
-    type Err = ();
-
-    fn from_str(s: &str) -> Result<StackProtector, ()> {
-        Ok(match s {
-            "none" => StackProtector::None,
-            "basic" => StackProtector::Basic,
-            "strong" => StackProtector::Strong,
-            "all" => StackProtector::All,
-            _ => return Err(()),
-        })
-    }
-}
-
-impl fmt::Display for StackProtector {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.as_str())
-    }
+    parse_error_type = "stack protector";
 }
 
 into_diag_arg_using_display!(StackProtector);
 
-#[derive(PartialEq, Clone, Debug)]
-pub enum BinaryFormat {
-    Coff,
-    Elf,
-    MachO,
-    Wasm,
-    Xcoff,
+crate::target_spec_enum! {
+    pub enum BinaryFormat {
+        Coff = "coff",
+        Elf = "elf",
+        MachO = "mach-o",
+        Wasm = "wasm",
+        Xcoff = "xcoff",
+    }
+
+    parse_error_type = "binary format";
 }
 
 impl BinaryFormat {
@@ -1828,38 +1393,6 @@ impl BinaryFormat {
     }
 }
 
-impl FromStr for BinaryFormat {
-    type Err = String;
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        match s {
-            "coff" => Ok(Self::Coff),
-            "elf" => Ok(Self::Elf),
-            "mach-o" => Ok(Self::MachO),
-            "wasm" => Ok(Self::Wasm),
-            "xcoff" => Ok(Self::Xcoff),
-            _ => Err(format!(
-                "'{s}' is not a valid value for binary_format. \
-                    Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' "
-            )),
-        }
-    }
-}
-
-crate::json::serde_deserialize_from_str!(BinaryFormat);
-
-impl ToJson for BinaryFormat {
-    fn to_json(&self) -> Json {
-        match self {
-            Self::Coff => "coff",
-            Self::Elf => "elf",
-            Self::MachO => "mach-o",
-            Self::Wasm => "wasm",
-            Self::Xcoff => "xcoff",
-        }
-        .to_json()
-    }
-}
-
 impl ToJson for Align {
     fn to_json(&self) -> Json {
         self.bits().to_json()
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/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
index e042ce84955..f997842a607 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
@@ -857,11 +857,11 @@ fn foo(&self) -> Self::T { String::new() }
                     && self.infcx.can_eq(param_env, assoc_ty, found)
                 {
                     let msg = match assoc_item.container {
-                        ty::AssocItemContainer::Trait => {
+                        ty::AssocContainer::Trait => {
                             "associated type defaults can't be assumed inside the \
                                             trait defining them"
                         }
-                        ty::AssocItemContainer::Impl => {
+                        ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
                             "associated type is `default` and may be overridden"
                         }
                     };
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
index 7369134420c..518d4fe17e8 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
@@ -571,13 +571,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         // but right now it's not really very smart when it comes to implicit `Sized`
         // predicates and bounds on the trait itself.
 
-        let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx)
-        else {
-            return;
-        };
-        let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else {
+        let Some(impl_def_id) = self.tcx.trait_impl_of_assoc(impl_item_def_id.to_def_id()) else {
             return;
         };
+        let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
         let trait_args = trait_ref
             .instantiate_identity()
             // Replace the explicit self type with `Self` for better suggestion rendering
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs
index 8a67e4ccd45..f54ebd76cab 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs
@@ -5,7 +5,7 @@
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{LangItem, lang_items};
-use rustc_middle::ty::{AssocItemContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
+use rustc_middle::ty::{AssocContainer, GenericArgsRef, Instance, Ty, TyCtxt, TypingEnv};
 use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, sym};
 use tracing::debug;
 
@@ -76,8 +76,9 @@ pub fn call_kind<'tcx>(
     let parent = tcx.opt_associated_item(method_did).and_then(|assoc| {
         let container_id = assoc.container_id(tcx);
         match assoc.container {
-            AssocItemContainer::Impl => tcx.trait_id_of_impl(container_id),
-            AssocItemContainer::Trait => Some(container_id),
+            AssocContainer::InherentImpl => None,
+            AssocContainer::TraitImpl(_) => tcx.trait_id_of_impl(container_id),
+            AssocContainer::Trait => Some(container_id),
         }
     });
 
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index c82043f0222..149f5e638b1 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -27,8 +27,8 @@ use rustc_middle::ty::print::{
     with_forced_trimmed_paths,
 };
 use rustc_middle::ty::{
-    self, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
-    Upcast,
+    self, GenericArgKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeVisitableExt, Upcast,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_span::{BytePos, DUMMY_SP, STDLIB_STABLE_CRATES, Span, Symbol, sym};
@@ -2316,7 +2316,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 cand
             })
             .collect();
-        impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref.to_string()));
+        impl_candidates.sort_by_key(|cand| {
+            // When suggesting array types, sort them by the length of the array, not lexicographically (#135098)
+            let len = if let GenericArgKind::Type(ty) = cand.trait_ref.args[0].kind()
+                && let ty::Array(_, len) = ty.kind()
+            {
+                // Deprioritize suggestions for parameterized arrays.
+                len.try_to_target_usize(self.tcx).unwrap_or(u64::MAX)
+            } else {
+                0
+            };
+
+            (cand.similarity, len, cand.trait_ref.to_string())
+        });
         let mut impl_candidates: Vec<_> =
             impl_candidates.into_iter().map(|cand| cand.trait_ref).collect();
         impl_candidates.dedup();
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index cb84d583e6e..f2f840581cf 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -421,7 +421,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 })
                 | hir::Node::ImplItem(hir::ImplItem {
                     generics,
-                    trait_item_def_id: None,
+                    impl_kind: hir::ImplItemImplKind::Inherent { .. },
                     kind: hir::ImplItemKind::Fn(..),
                     ..
                 }) if finder.can_suggest_bound(generics) => {
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index 19eb85506b6..4d0465777dd 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -387,7 +387,7 @@ pub(crate) fn assoc_def(
     if let Some(assoc_item) = ancestors.leaf_def(tcx, assoc_def_id) {
         // Ensure that the impl is constrained, otherwise projection may give us
         // bad unconstrained infer vars.
-        if assoc_item.item.container == ty::AssocItemContainer::Impl
+        if let ty::AssocContainer::TraitImpl(_) = assoc_item.item.container
             && let Some(impl_def_id) = assoc_item.item.container_id(tcx).as_local()
         {
             tcx.ensure_ok().enforce_impl_non_lifetime_params_are_constrained(impl_def_id)?;
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index e9629e31482..84f52e7fc9d 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -2,7 +2,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatorState};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{self as hir, ItemKind};
+use rustc_hir::{self as hir, ImplItemImplKind, ItemKind};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
 use rustc_middle::{bug, span_bug};
@@ -63,7 +63,7 @@ fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems {
 fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap<DefId> {
     tcx.associated_items(impl_id)
         .in_definition_order()
-        .filter_map(|item| item.trait_item_def_id.map(|trait_item| (trait_item, item.def_id)))
+        .filter_map(|item| item.trait_item_def_id().map(|trait_item| (trait_item, item.def_id)))
         .collect()
 }
 
@@ -97,12 +97,7 @@ fn associated_item_from_trait_item(
         }
     };
 
-    ty::AssocItem {
-        kind,
-        def_id: owner_id.to_def_id(),
-        trait_item_def_id: Some(owner_id.to_def_id()),
-        container: ty::AssocItemContainer::Trait,
-    }
+    ty::AssocItem { kind, def_id: owner_id.to_def_id(), container: ty::AssocContainer::Trait }
 }
 
 fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> ty::AssocItem {
@@ -118,12 +113,13 @@ fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>
         }
     };
 
-    ty::AssocItem {
-        kind,
-        def_id: owner_id.to_def_id(),
-        trait_item_def_id: impl_item.trait_item_def_id,
-        container: ty::AssocItemContainer::Impl,
-    }
+    let container = match impl_item.impl_kind {
+        ImplItemImplKind::Inherent { .. } => ty::AssocContainer::InherentImpl,
+        ImplItemImplKind::Trait { trait_item_def_id, .. } => {
+            ty::AssocContainer::TraitImpl(trait_item_def_id)
+        }
+    };
+    ty::AssocItem { kind, def_id: owner_id.to_def_id(), container }
 }
 struct RPITVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -190,7 +186,10 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
                     }
                     let did = item.owner_id.def_id.to_def_id();
                     let item = tcx.hir_impl_item(*item);
-                    let Some(trait_item_def_id) = item.trait_item_def_id else {
+                    let ImplItemImplKind::Trait {
+                        trait_item_def_id: Ok(trait_item_def_id), ..
+                    } = item.impl_kind
+                    else {
                         return Some((did, vec![]));
                     };
                     let iter = in_trait_def[&trait_item_def_id].iter().map(|&id| {
@@ -256,8 +255,7 @@ fn associated_type_for_impl_trait_in_trait(
             }),
         },
         def_id,
-        trait_item_def_id: None,
-        container: ty::AssocItemContainer::Trait,
+        container: ty::AssocContainer::Trait,
     });
 
     // Copy visility of the containing function.
@@ -322,8 +320,7 @@ fn associated_type_for_impl_trait_in_impl(
             }),
         },
         def_id,
-        trait_item_def_id: Some(trait_assoc_def_id),
-        container: ty::AssocItemContainer::Impl,
+        container: ty::AssocContainer::TraitImpl(Ok(trait_assoc_def_id)),
     });
 
     // Copy visility of the containing function.
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index cdfb93c4e7d..543f6a3ccf7 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -107,7 +107,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
                 // the assumed wf types of the trait's RPITIT GAT.
                 ty::ImplTraitInTraitData::Impl { .. } => {
                     let impl_def_id = tcx.local_parent(def_id);
-                    let rpitit_def_id = tcx.associated_item(def_id).trait_item_def_id.unwrap();
+                    let rpitit_def_id = tcx.trait_item_of(def_id).unwrap();
                     let args = ty::GenericArgs::identity_for_item(tcx, def_id).rebase_onto(
                         tcx,
                         impl_def_id.to_def_id(),
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 4a7263d0ccd..eb3236d3006 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -245,7 +245,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
 
                         for &assoc in self.tcx.associated_items(parent).in_definition_order() {
                             trace!(?assoc);
-                            if assoc.trait_item_def_id != Some(alias_ty.def_id) {
+                            if assoc.expect_trait_impl() != Ok(alias_ty.def_id) {
                                 continue;
                             }
 
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index b22c326b9f2..a5987757dc3 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -88,7 +88,10 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness {
                 }),
             ..
         })
-        | hir::Node::ImplItem(hir::ImplItem { defaultness, .. })
+        | hir::Node::ImplItem(hir::ImplItem {
+            impl_kind: hir::ImplItemImplKind::Trait { defaultness, .. },
+            ..
+        })
         | hir::Node::TraitItem(hir::TraitItem { defaultness, .. }) => *defaultness,
         node => {
             bug!("`defaultness` called on {:?}", node);
@@ -165,7 +168,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
 
     if tcx.def_kind(def_id) == DefKind::AssocFn
         && let assoc_item = tcx.associated_item(def_id)
-        && assoc_item.container == ty::AssocItemContainer::Trait
+        && assoc_item.container == ty::AssocContainer::Trait
         && assoc_item.defaultness(tcx).has_value()
     {
         let sig = tcx.fn_sig(def_id).instantiate_identity();
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 3a83b1739ff..cf58aec14a6 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -347,6 +347,7 @@ pub trait Interner:
         self_ty: Self::Ty,
         f: impl FnMut(Self::ImplId),
     );
+    fn for_each_blanket_impl(self, trait_def_id: Self::TraitId, f: impl FnMut(Self::ImplId));
 
     fn has_item_definition(self, def_id: Self::DefId) -> bool;
 
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 8b6d86a2888..98f11e2ea57 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -1433,7 +1433,6 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(btree_extract_if)]
     /// use std::collections::BTreeMap;
     ///
     /// // Splitting a map into even and odd keys, reusing the original map:
@@ -1450,7 +1449,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
     /// assert_eq!(low.keys().copied().collect::<Vec<_>>(), [0, 1, 2, 3]);
     /// assert_eq!(high.keys().copied().collect::<Vec<_>>(), [4, 5, 6, 7]);
     /// ```
-    #[unstable(feature = "btree_extract_if", issue = "70530")]
+    #[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
     pub fn extract_if<F, R>(&mut self, range: R, pred: F) -> ExtractIf<'_, K, V, R, F, A>
     where
         K: Ord,
@@ -1937,7 +1936,7 @@ impl<K, V> Default for Values<'_, K, V> {
 }
 
 /// An iterator produced by calling `extract_if` on BTreeMap.
-#[unstable(feature = "btree_extract_if", issue = "70530")]
+#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 pub struct ExtractIf<
     'a,
@@ -1970,7 +1969,7 @@ pub(super) struct ExtractIfInner<'a, K, V, R> {
     range: R,
 }
 
-#[unstable(feature = "btree_extract_if", issue = "70530")]
+#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, V, R, F, A> fmt::Debug for ExtractIf<'_, K, V, R, F, A>
 where
     K: fmt::Debug,
@@ -1982,7 +1981,7 @@ where
     }
 }
 
-#[unstable(feature = "btree_extract_if", issue = "70530")]
+#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, V, R, F, A: Allocator + Clone> Iterator for ExtractIf<'_, K, V, R, F, A>
 where
     K: PartialOrd,
@@ -2056,7 +2055,7 @@ impl<'a, K, V, R> ExtractIfInner<'a, K, V, R> {
     }
 }
 
-#[unstable(feature = "btree_extract_if", issue = "70530")]
+#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<K, V, R, F> FusedIterator for ExtractIf<'_, K, V, R, F>
 where
     K: PartialOrd,
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index d50ce02bda7..e6b0a1f6323 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1202,7 +1202,6 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(btree_extract_if)]
     /// use std::collections::BTreeSet;
     ///
     /// // Splitting a set into even and odd values, reusing the original set:
@@ -1219,7 +1218,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
     /// assert_eq!(low.into_iter().collect::<Vec<_>>(), [0, 1, 2, 3]);
     /// assert_eq!(high.into_iter().collect::<Vec<_>>(), [4, 5, 6, 7]);
     /// ```
-    #[unstable(feature = "btree_extract_if", issue = "70530")]
+    #[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
     pub fn extract_if<F, R>(&mut self, range: R, pred: F) -> ExtractIf<'_, T, R, F, A>
     where
         T: Ord,
@@ -1554,7 +1553,7 @@ impl<'a, T, A: Allocator + Clone> IntoIterator for &'a BTreeSet<T, A> {
 }
 
 /// An iterator produced by calling `extract_if` on BTreeSet.
-#[unstable(feature = "btree_extract_if", issue = "70530")]
+#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 pub struct ExtractIf<
     'a,
@@ -1569,7 +1568,7 @@ pub struct ExtractIf<
     alloc: A,
 }
 
-#[unstable(feature = "btree_extract_if", issue = "70530")]
+#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<T, R, F, A> fmt::Debug for ExtractIf<'_, T, R, F, A>
 where
     T: fmt::Debug,
@@ -1582,7 +1581,7 @@ where
     }
 }
 
-#[unstable(feature = "btree_extract_if", issue = "70530")]
+#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<T, R, F, A: Allocator + Clone> Iterator for ExtractIf<'_, T, R, F, A>
 where
     T: PartialOrd,
@@ -1602,7 +1601,7 @@ where
     }
 }
 
-#[unstable(feature = "btree_extract_if", issue = "70530")]
+#[stable(feature = "btree_extract_if", since = "CURRENT_RUSTC_VERSION")]
 impl<T, R, F, A: Allocator + Clone> FusedIterator for ExtractIf<'_, T, R, F, A>
 where
     T: PartialOrd,
diff --git a/library/alloctests/benches/lib.rs b/library/alloctests/benches/lib.rs
index 2633154318c..721d685527f 100644
--- a/library/alloctests/benches/lib.rs
+++ b/library/alloctests/benches/lib.rs
@@ -1,6 +1,5 @@
 // Disabling in Miri as these would take too long.
 #![cfg(not(miri))]
-#![feature(btree_extract_if)]
 #![feature(iter_next_chunk)]
 #![feature(repr_simd)]
 #![feature(slice_partition_dedup)]
diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs
index bf446ae1ba4..8c3ce156f3c 100644
--- a/library/alloctests/tests/lib.rs
+++ b/library/alloctests/tests/lib.rs
@@ -2,7 +2,6 @@
 #![feature(alloc_layout_extra)]
 #![feature(iter_array_chunks)]
 #![feature(assert_matches)]
-#![feature(btree_extract_if)]
 #![feature(wtf8_internals)]
 #![feature(char_max_len)]
 #![feature(cow_is_borrowed)]
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index e7d9763d46e..76ea2d18a82 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -705,7 +705,8 @@ impl dyn Any + Send + Sync {
 ///     std::mem::forget(fake_one_ring);
 /// }
 /// ```
-#[derive(Clone, Copy, Eq, PartialOrd, Ord)]
+#[derive(Copy, PartialOrd, Ord)]
+#[derive_const(Clone, Eq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "type_id"]
 pub struct TypeId {
diff --git a/library/core/src/array/equality.rs b/library/core/src/array/equality.rs
index 1ad2cca64a3..c2c7ccf0daa 100644
--- a/library/core/src/array/equality.rs
+++ b/library/core/src/array/equality.rs
@@ -1,9 +1,10 @@
 use crate::cmp::BytewiseEq;
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U; N]> for [T; N]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U; N]> for [T; N]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U; N]) -> bool {
@@ -16,9 +17,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U]> for [T; N]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U]> for [T; N]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U]) -> bool {
@@ -37,9 +39,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U; N]> for [T]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U; N]> for [T]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U; N]) -> bool {
@@ -58,9 +61,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<&[U]> for [T; N]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<&[U]> for [T; N]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &&[U]) -> bool {
@@ -73,9 +77,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U; N]> for &[T]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U; N]> for &[T]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U; N]) -> bool {
@@ -88,9 +93,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<&mut [U]> for [T; N]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<&mut [U]> for [T; N]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &&mut [U]) -> bool {
@@ -103,9 +109,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U; N]> for &mut [T]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U; N]> for &mut [T]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U; N]) -> bool {
@@ -122,14 +129,18 @@ where
 // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Eq, const N: usize> Eq for [T; N] {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] Eq, const N: usize> const Eq for [T; N] {}
 
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 trait SpecArrayEq<Other, const N: usize>: Sized {
     fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool;
     fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool;
 }
 
-impl<T: PartialEq<Other>, Other, const N: usize> SpecArrayEq<Other, N> for T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] PartialEq<Other>, Other, const N: usize> const SpecArrayEq<Other, N> for T {
     default fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool {
         a[..] == b[..]
     }
@@ -138,7 +149,8 @@ impl<T: PartialEq<Other>, Other, const N: usize> SpecArrayEq<Other, N> for T {
     }
 }
 
-impl<T: BytewiseEq<U>, U, const N: usize> SpecArrayEq<U, N> for T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] BytewiseEq<U>, U, const N: usize> const SpecArrayEq<U, N> for T {
     fn spec_eq(a: &[T; N], b: &[U; N]) -> bool {
         // SAFETY: Arrays are compared element-wise, and don't add any padding
         // between elements, so when the elements are `BytewiseEq`, we can
diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs
index 49d540314a2..178af2c0e3b 100644
--- a/library/core/src/ascii/ascii_char.rs
+++ b/library/core/src/ascii/ascii_char.rs
@@ -54,7 +54,8 @@ use crate::{assert_unsafe_precondition, fmt};
 /// [chart]: https://www.unicode.org/charts/PDF/U0000.pdf
 /// [NIST FIPS 1-2]: https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub1-2-1977.pdf
 /// [NamesList]: https://www.unicode.org/Public/15.0.0/ucd/NamesList.txt
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Copy, Hash)]
+#[derive_const(Clone, Eq, PartialEq, Ord, PartialOrd)]
 #[unstable(feature = "ascii_char", issue = "110998")]
 #[repr(u8)]
 pub enum AsciiChar {
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 0812322f3fb..94536f25b41 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -29,7 +29,7 @@ mod bytewise;
 pub(crate) use bytewise::BytewiseEq;
 
 use self::Ordering::*;
-use crate::marker::PointeeSized;
+use crate::marker::{Destruct, PointeeSized};
 use crate::ops::ControlFlow;
 
 /// Trait for comparisons using the equality operator.
@@ -334,7 +334,9 @@ pub macro PartialEq($item:item) {
 #[doc(alias = "!=")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Eq"]
-pub trait Eq: PartialEq<Self> + PointeeSized {
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub trait Eq: [const] PartialEq<Self> + PointeeSized {
     // this method is used solely by `impl Eq or #[derive(Eq)]` to assert that every component of a
     // type implements `Eq` itself. The current deriving infrastructure means doing this assertion
     // without using a method on this trait is nearly impossible.
@@ -380,8 +382,8 @@ pub struct AssertParamIsEq<T: Eq + PointeeSized> {
 ///
 /// assert_eq!(2.cmp(&1), Ordering::Greater);
 /// ```
-#[derive(Clone, Copy, Eq, PartialOrd, Ord, Debug, Hash)]
-#[derive_const(PartialEq)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(Clone, Eq, PartialOrd, Ord, PartialEq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 // This is a lang item only so that `BinOp::Cmp` in MIR can return it.
 // It has no special behavior, but does require that the three variants
@@ -635,7 +637,11 @@ impl Ordering {
     #[inline]
     #[must_use]
     #[stable(feature = "ordering_chaining", since = "1.17.0")]
-    pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    pub const fn then_with<F>(self, f: F) -> Ordering
+    where
+        F: [const] FnOnce() -> Ordering + [const] Destruct,
+    {
         match self {
             Equal => f(),
             _ => self,
@@ -659,13 +665,15 @@ impl Ordering {
 /// v.sort_by_key(|&num| (num > 3, Reverse(num)));
 /// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
 /// ```
-#[derive(PartialEq, Eq, Debug, Copy, Default, Hash)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(PartialEq, Eq, Default)]
 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
 #[repr(transparent)]
 pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
 
 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
-impl<T: PartialOrd> PartialOrd for Reverse<T> {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] PartialOrd> const PartialOrd for Reverse<T> {
     #[inline]
     fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
         other.0.partial_cmp(&self.0)
@@ -690,7 +698,8 @@ impl<T: PartialOrd> PartialOrd for Reverse<T> {
 }
 
 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
-impl<T: Ord> Ord for Reverse<T> {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] Ord> const Ord for Reverse<T> {
     #[inline]
     fn cmp(&self, other: &Reverse<T>) -> Ordering {
         other.0.cmp(&self.0)
@@ -957,7 +966,9 @@ impl<T: Clone> Clone for Reverse<T> {
 #[doc(alias = ">=")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Ord"]
-pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub trait Ord: [const] Eq + [const] PartialOrd<Self> + PointeeSized {
     /// This method returns an [`Ordering`] between `self` and `other`.
     ///
     /// By convention, `self.cmp(&other)` returns the ordering matching the expression
@@ -1011,7 +1022,7 @@ pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
     #[rustc_diagnostic_item = "cmp_ord_max"]
     fn max(self, other: Self) -> Self
     where
-        Self: Sized,
+        Self: Sized + [const] Destruct,
     {
         if other < self { self } else { other }
     }
@@ -1050,7 +1061,7 @@ pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
     #[rustc_diagnostic_item = "cmp_ord_min"]
     fn min(self, other: Self) -> Self
     where
-        Self: Sized,
+        Self: Sized + [const] Destruct,
     {
         if other < self { other } else { self }
     }
@@ -1076,7 +1087,7 @@ pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
     #[stable(feature = "clamp", since = "1.50.0")]
     fn clamp(self, min: Self, max: Self) -> Self
     where
-        Self: Sized,
+        Self: Sized + [const] Destruct,
     {
         assert!(min <= max);
         if self < min {
@@ -1341,6 +1352,8 @@ pub macro Ord($item:item) {
 )]
 #[rustc_diagnostic_item = "PartialOrd"]
 #[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
     /// This method returns an ordering between `self` and `other` values if one exists.
     ///
@@ -1481,13 +1494,14 @@ pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
     }
 }
 
-fn default_chaining_impl<T, U>(
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+const fn default_chaining_impl<T, U>(
     lhs: &T,
     rhs: &U,
-    p: impl FnOnce(Ordering) -> bool,
+    p: impl [const] FnOnce(Ordering) -> bool + [const] Destruct,
 ) -> ControlFlow<bool>
 where
-    T: PartialOrd<U> + PointeeSized,
+    T: [const] PartialOrd<U> + PointeeSized,
     U: PointeeSized,
 {
     // It's important that this only call `partial_cmp` once, not call `eq` then
@@ -1545,7 +1559,8 @@ pub macro PartialOrd($item:item) {
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "cmp_min"]
-pub fn min<T: Ord>(v1: T, v2: T) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn min<T: [const] Ord + [const] Destruct>(v1: T, v2: T) -> T {
     v1.min(v2)
 }
 
@@ -1575,7 +1590,12 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
-pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn min_by<T: [const] Destruct, F: [const] FnOnce(&T, &T) -> Ordering>(
+    v1: T,
+    v2: T,
+    compare: F,
+) -> T {
     if compare(&v1, &v2).is_le() { v1 } else { v2 }
 }
 
@@ -1600,7 +1620,13 @@ pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
-pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn min_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> T
+where
+    T: [const] Destruct,
+    F: [const] FnMut(&T) -> K + [const] Destruct,
+    K: [const] Ord + [const] Destruct,
+{
     if f(&v2) < f(&v1) { v2 } else { v1 }
 }
 
@@ -1640,7 +1666,8 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "cmp_max"]
-pub fn max<T: Ord>(v1: T, v2: T) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn max<T: [const] Ord + [const] Destruct>(v1: T, v2: T) -> T {
     v1.max(v2)
 }
 
@@ -1670,7 +1697,12 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
-pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn max_by<T: [const] Destruct, F: [const] FnOnce(&T, &T) -> Ordering>(
+    v1: T,
+    v2: T,
+    compare: F,
+) -> T {
     if compare(&v1, &v2).is_gt() { v1 } else { v2 }
 }
 
@@ -1695,7 +1727,13 @@ pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
-pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn max_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> T
+where
+    T: [const] Destruct,
+    F: [const] FnMut(&T) -> K + [const] Destruct,
+    K: [const] Ord + [const] Destruct,
+{
     if f(&v2) < f(&v1) { v1 } else { v2 }
 }
 
@@ -1739,9 +1777,10 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 #[inline]
 #[must_use]
 #[unstable(feature = "cmp_minmax", issue = "115939")]
-pub fn minmax<T>(v1: T, v2: T) -> [T; 2]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn minmax<T>(v1: T, v2: T) -> [T; 2]
 where
-    T: Ord,
+    T: [const] Ord,
 {
     if v2 < v1 { [v2, v1] } else { [v1, v2] }
 }
@@ -1773,9 +1812,10 @@ where
 #[inline]
 #[must_use]
 #[unstable(feature = "cmp_minmax", issue = "115939")]
-pub fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
 where
-    F: FnOnce(&T, &T) -> Ordering,
+    F: [const] FnOnce(&T, &T) -> Ordering,
 {
     if compare(&v1, &v2).is_le() { [v1, v2] } else { [v2, v1] }
 }
@@ -1801,10 +1841,11 @@ where
 #[inline]
 #[must_use]
 #[unstable(feature = "cmp_minmax", issue = "115939")]
-pub fn minmax_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> [T; 2]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn minmax_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> [T; 2]
 where
-    F: FnMut(&T) -> K,
-    K: Ord,
+    F: [const] FnMut(&T) -> K + [const] Destruct,
+    K: [const] Ord + [const] Destruct,
 {
     if f(&v2) < f(&v1) { [v2, v1] } else { [v1, v2] }
 }
@@ -1830,7 +1871,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl PartialEq for () {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialEq for () {
         #[inline]
         fn eq(&self, _other: &()) -> bool {
             true
@@ -1848,7 +1890,8 @@ mod impls {
     macro_rules! eq_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl Eq for $t {}
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl const Eq for $t {}
         )*)
     }
 
@@ -1896,7 +1939,8 @@ mod impls {
     macro_rules! partial_ord_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl PartialOrd for $t {
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl const PartialOrd for $t {
                 #[inline]
                 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
                     match (*self <= *other, *self >= *other) {
@@ -1913,7 +1957,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl PartialOrd for () {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialOrd for () {
         #[inline]
         fn partial_cmp(&self, _: &()) -> Option<Ordering> {
             Some(Equal)
@@ -1921,7 +1966,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl PartialOrd for bool {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialOrd for bool {
         #[inline]
         fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
             Some(self.cmp(other))
@@ -1935,7 +1981,8 @@ mod impls {
     macro_rules! ord_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl PartialOrd for $t {
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl const PartialOrd for $t {
                 #[inline]
                 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
                     Some(crate::intrinsics::three_way_compare(*self, *other))
@@ -1945,7 +1992,8 @@ mod impls {
             }
 
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl Ord for $t {
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl const Ord for $t {
                 #[inline]
                 fn cmp(&self, other: &Self) -> Ordering {
                     crate::intrinsics::three_way_compare(*self, *other)
@@ -1955,7 +2003,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Ord for () {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const Ord for () {
         #[inline]
         fn cmp(&self, _other: &()) -> Ordering {
             Equal
@@ -1963,7 +2012,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Ord for bool {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const Ord for bool {
         #[inline]
         fn cmp(&self, other: &bool) -> Ordering {
             // Casting to i8's and converting the difference to an Ordering generates
@@ -1998,7 +2048,8 @@ mod impls {
     ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
     #[unstable(feature = "never_type", issue = "35121")]
-    impl PartialEq for ! {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialEq for ! {
         #[inline]
         fn eq(&self, _: &!) -> bool {
             *self
@@ -2006,10 +2057,12 @@ mod impls {
     }
 
     #[unstable(feature = "never_type", issue = "35121")]
-    impl Eq for ! {}
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const Eq for ! {}
 
     #[unstable(feature = "never_type", issue = "35121")]
-    impl PartialOrd for ! {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialOrd for ! {
         #[inline]
         fn partial_cmp(&self, _: &!) -> Option<Ordering> {
             *self
@@ -2017,7 +2070,8 @@ mod impls {
     }
 
     #[unstable(feature = "never_type", issue = "35121")]
-    impl Ord for ! {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const Ord for ! {
         #[inline]
         fn cmp(&self, _: &!) -> Ordering {
             *self
@@ -2042,9 +2096,10 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized, B: PointeeSized> PartialOrd<&B> for &A
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized, B: PointeeSized> const PartialOrd<&B> for &A
     where
-        A: PartialOrd<B>,
+        A: [const] PartialOrd<B>,
     {
         #[inline]
         fn partial_cmp(&self, other: &&B) -> Option<Ordering> {
@@ -2084,9 +2139,10 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized> Ord for &A
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized> const Ord for &A
     where
-        A: Ord,
+        A: [const] Ord,
     {
         #[inline]
         fn cmp(&self, other: &Self) -> Ordering {
@@ -2094,7 +2150,8 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized> Eq for &A where A: Eq {}
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized> const Eq for &A where A: [const] Eq {}
 
     // &mut pointers
 
@@ -2114,9 +2171,10 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized, B: PointeeSized> PartialOrd<&mut B> for &mut A
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized, B: PointeeSized> const PartialOrd<&mut B> for &mut A
     where
-        A: PartialOrd<B>,
+        A: [const] PartialOrd<B>,
     {
         #[inline]
         fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> {
@@ -2156,9 +2214,10 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized> Ord for &mut A
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized> const Ord for &mut A
     where
-        A: Ord,
+        A: [const] Ord,
     {
         #[inline]
         fn cmp(&self, other: &Self) -> Ordering {
@@ -2166,7 +2225,8 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized> Eq for &mut A where A: Eq {}
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized> const Eq for &mut A where A: [const] Eq {}
 
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index a3cfd85974a..89cda30c030 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -963,17 +963,20 @@ impl const PartialEq for Infallible {
 }
 
 #[stable(feature = "convert_infallible", since = "1.34.0")]
-impl Eq for Infallible {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl const Eq for Infallible {}
 
 #[stable(feature = "convert_infallible", since = "1.34.0")]
-impl PartialOrd for Infallible {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl const PartialOrd for Infallible {
     fn partial_cmp(&self, _other: &Self) -> Option<crate::cmp::Ordering> {
         match *self {}
     }
 }
 
 #[stable(feature = "convert_infallible", since = "1.34.0")]
-impl Ord for Infallible {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl const Ord for Infallible {
     fn cmp(&self, _other: &Self) -> crate::cmp::Ordering {
         match *self {}
     }
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 0f38081c355..1b7c28bb95a 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -4,7 +4,7 @@ use super::{IntErrorKind, ParseIntError};
 use crate::clone::UseCloned;
 use crate::cmp::Ordering;
 use crate::hash::{Hash, Hasher};
-use crate::marker::{Freeze, StructuralPartialEq};
+use crate::marker::{Destruct, Freeze, StructuralPartialEq};
 use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
 use crate::panic::{RefUnwindSafe, UnwindSafe};
 use crate::str::FromStr;
@@ -220,12 +220,14 @@ where
 impl<T> StructuralPartialEq for NonZero<T> where T: ZeroablePrimitive + StructuralPartialEq {}
 
 #[stable(feature = "nonzero", since = "1.28.0")]
-impl<T> Eq for NonZero<T> where T: ZeroablePrimitive + Eq {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T> const Eq for NonZero<T> where T: ZeroablePrimitive + [const] Eq {}
 
 #[stable(feature = "nonzero", since = "1.28.0")]
-impl<T> PartialOrd for NonZero<T>
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T> const PartialOrd for NonZero<T>
 where
-    T: ZeroablePrimitive + PartialOrd,
+    T: ZeroablePrimitive + [const] PartialOrd,
 {
     #[inline]
     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
@@ -254,9 +256,12 @@ where
 }
 
 #[stable(feature = "nonzero", since = "1.28.0")]
-impl<T> Ord for NonZero<T>
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T> const Ord for NonZero<T>
 where
-    T: ZeroablePrimitive + Ord,
+    // FIXME(const_hack): the T: ~const Destruct should be inferred from the Self: ~const Destruct.
+    // See https://github.com/rust-lang/rust/issues/144207
+    T: ZeroablePrimitive + [const] Ord + [const] Destruct,
 {
     #[inline]
     fn cmp(&self, other: &Self) -> Ordering {
diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs
index 73b74d53323..b760a7c4e21 100644
--- a/library/core/src/ops/control_flow.rs
+++ b/library/core/src/ops/control_flow.rs
@@ -83,7 +83,8 @@ use crate::{convert, ops};
 #[must_use]
 // ControlFlow should not implement PartialOrd or Ord, per RFC 3058:
 // https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#traits-for-controlflow
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(Clone, PartialEq, Eq)]
 pub enum ControlFlow<B, C = ()> {
     /// Move on to the next phase of the operation as normal.
     #[stable(feature = "control_flow_enum_type", since = "1.55.0")]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 198636c67d0..886d581b0a6 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -585,7 +585,8 @@ use crate::{cmp, convert, hint, mem, slice};
 
 /// The `Option` type. See [the module level documentation](self) for more.
 #[doc(search_unbox)]
-#[derive(Copy, Eq, Debug, Hash)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(Eq)]
 #[rustc_diagnostic_item = "Option"]
 #[lang = "Option"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2363,7 +2364,8 @@ impl<T: [const] PartialEq> const PartialEq for Option<T> {
 // https://github.com/rust-lang/rust/issues/49892, although still
 // not optimal.
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: PartialOrd> PartialOrd for Option<T> {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] PartialOrd> const PartialOrd for Option<T> {
     #[inline]
     fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
         match (self, other) {
@@ -2376,7 +2378,8 @@ impl<T: PartialOrd> PartialOrd for Option<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Ord> Ord for Option<T> {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] Ord> const Ord for Option<T> {
     #[inline]
     fn cmp(&self, other: &Self) -> cmp::Ordering {
         match (self, other) {
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/core/src/range.rs b/library/core/src/range.rs
index 8c49123fdaf..a096a8ceafc 100644
--- a/library/core/src/range.rs
+++ b/library/core/src/range.rs
@@ -49,7 +49,8 @@ pub use crate::ops::{Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, R
 /// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum());
 /// ```
 #[lang = "RangeCopy"]
-#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
+#[derive(Copy, Hash)]
+#[derive_const(Clone, Default, PartialEq, Eq)]
 #[unstable(feature = "new_range_api", issue = "125687")]
 pub struct Range<Idx> {
     /// The lower bound of the range (inclusive).
@@ -424,7 +425,8 @@ impl<T> const From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
 /// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum());
 /// ```
 #[lang = "RangeFromCopy"]
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Copy, Hash)]
+#[derive_const(Clone, PartialEq, Eq)]
 #[unstable(feature = "new_range_api", issue = "125687")]
 pub struct RangeFrom<Idx> {
     /// The lower bound of the range (inclusive).
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 7dffab9b316..5c1f64bfe14 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -542,7 +542,8 @@ use crate::{convert, fmt, hint};
 ///
 /// See the [module documentation](self) for details.
 #[doc(search_unbox)]
-#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(PartialEq, PartialOrd, Eq, Ord)]
 #[must_use = "this `Result` may be an `Err` variant, which should be handled"]
 #[rustc_diagnostic_item = "Result"]
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs
index 0d801306984..103630aba0f 100644
--- a/library/core/src/slice/cmp.rs
+++ b/library/core/src/slice/cmp.rs
@@ -23,7 +23,8 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Eq> Eq for [T] {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] Eq> const Eq for [T] {}
 
 /// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison).
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -34,7 +35,7 @@ impl<T: Ord> Ord for [T] {
 }
 
 #[inline]
-fn as_underlying(x: ControlFlow<bool>) -> u8 {
+const fn as_underlying(x: ControlFlow<bool>) -> u8 {
     // SAFETY: This will only compile if `bool` and `ControlFlow<bool>` have the same
     // size (which isn't guaranteed but this is libcore). Because they have the same
     // size, it's a niched implementation, which in one byte means there can't be
@@ -154,12 +155,16 @@ where
 }
 
 #[doc(hidden)]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 // intermediate trait for specialization of slice's PartialOrd
 trait SlicePartialOrd: Sized {
     fn partial_compare(left: &[Self], right: &[Self]) -> Option<Ordering>;
 }
 
 #[doc(hidden)]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 // intermediate trait for specialization of slice's PartialOrd chaining methods
 trait SliceChain: Sized {
     fn chaining_lt(left: &[Self], right: &[Self]) -> ControlFlow<bool>;
@@ -231,14 +236,17 @@ where
 }
 */
 
-impl<A: AlwaysApplicableOrd> SlicePartialOrd for A {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<A: [const] AlwaysApplicableOrd> const SlicePartialOrd for A {
     fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
         Some(SliceOrd::compare(left, right))
     }
 }
 
 #[rustc_specialization_trait]
-trait AlwaysApplicableOrd: SliceOrd + Ord {}
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+trait AlwaysApplicableOrd: [const] SliceOrd + [const] Ord {}
 
 macro_rules! always_applicable_ord {
     ($([$($p:tt)*] $t:ty,)*) => {
@@ -257,6 +265,8 @@ always_applicable_ord! {
 }
 
 #[doc(hidden)]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 // intermediate trait for specialization of slice's Ord
 trait SliceOrd: Sized {
     fn compare(left: &[Self], right: &[Self]) -> Ordering;
@@ -282,17 +292,24 @@ impl<A: Ord> SliceOrd for A {
 /// * For every `x` and `y` of this type, `Ord(x, y)` must return the same
 ///   value as `Ord::cmp(transmute::<_, u8>(x), transmute::<_, u8>(y))`.
 #[rustc_specialization_trait]
-unsafe trait UnsignedBytewiseOrd: Ord {}
+#[const_trait]
+unsafe trait UnsignedBytewiseOrd: [const] Ord {}
 
-unsafe impl UnsignedBytewiseOrd for bool {}
-unsafe impl UnsignedBytewiseOrd for u8 {}
-unsafe impl UnsignedBytewiseOrd for NonZero<u8> {}
-unsafe impl UnsignedBytewiseOrd for Option<NonZero<u8>> {}
-unsafe impl UnsignedBytewiseOrd for ascii::Char {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for bool {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for u8 {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for NonZero<u8> {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for Option<NonZero<u8>> {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for ascii::Char {}
 
 // `compare_bytes` compares a sequence of unsigned bytes lexicographically, so
 // use it if the requirements for `UnsignedBytewiseOrd` are fulfilled.
-impl<A: Ord + UnsignedBytewiseOrd> SliceOrd for A {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<A: [const] Ord + [const] UnsignedBytewiseOrd> const SliceOrd for A {
     #[inline]
     fn compare(left: &[Self], right: &[Self]) -> Ordering {
         // Since the length of a slice is always less than or equal to
@@ -317,7 +334,9 @@ impl<A: Ord + UnsignedBytewiseOrd> SliceOrd for A {
 }
 
 // Don't generate our own chaining loops for `memcmp`-able things either.
-impl<A: PartialOrd + UnsignedBytewiseOrd> SliceChain for A {
+
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<A: [const] PartialOrd + [const] UnsignedBytewiseOrd> const SliceChain for A {
     #[inline]
     fn chaining_lt(left: &[Self], right: &[Self]) -> ControlFlow<bool> {
         match SliceOrd::compare(left, right) {
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index 5adae62b7e6..a7cc943994c 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -32,7 +32,8 @@ impl const PartialEq for str {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Eq for str {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl const Eq for str {}
 
 /// Implements comparison operations on strings.
 ///
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index 2cdee1803a9..3892f831076 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -23,7 +23,8 @@ macro_rules! tuple_impls {
         maybe_tuple_doc! {
             $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T: PartialEq),+> PartialEq for ($($T,)+) {
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl<$($T: [const] PartialEq),+> const PartialEq for ($($T,)+) {
                 #[inline]
                 fn eq(&self, other: &($($T,)+)) -> bool {
                     $( ${ignore($T)} self.${index()} == other.${index()} )&&+
@@ -38,7 +39,8 @@ macro_rules! tuple_impls {
         maybe_tuple_doc! {
             $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T: Eq),+> Eq for ($($T,)+)
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl<$($T: [const] Eq),+> const Eq for ($($T,)+)
             {}
         }
 
@@ -66,7 +68,8 @@ macro_rules! tuple_impls {
         maybe_tuple_doc! {
             $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl<$($T: [const] PartialOrd),+> const PartialOrd for ($($T,)+)
             {
                 #[inline]
                 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
@@ -110,7 +113,8 @@ macro_rules! tuple_impls {
         maybe_tuple_doc! {
             $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T: Ord),+> Ord for ($($T,)+)
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl<$($T: [const] Ord),+> const Ord for ($($T,)+)
             {
                 #[inline]
                 fn cmp(&self, other: &($($T,)+)) -> Ordering {
diff --git a/library/coretests/tests/alloc.rs b/library/coretests/tests/alloc.rs
index 72fdf82c1f8..a4af6fd32a1 100644
--- a/library/coretests/tests/alloc.rs
+++ b/library/coretests/tests/alloc.rs
@@ -56,6 +56,30 @@ fn layout_array_edge_cases() {
 }
 
 #[test]
+fn layout_errors() {
+    let layout = Layout::new::<[u8; 2]>();
+    // Should error if the alignment is not a power of two.
+    assert!(layout.align_to(3).is_err());
+
+    // The remaining assertions ensure that the methods error on arithmetic overflow as the
+    // alignment cannot overflow `isize`.
+    let size = layout.size();
+    let size_max = isize::MAX as usize;
+    let align_max = size_max / size;
+
+    assert!(layout.align_to(size_max + 1).is_err());
+
+    assert!(layout.repeat(align_max).is_ok());
+    assert!(layout.repeat(align_max + 1).is_err());
+
+    assert!(layout.repeat_packed(align_max).is_ok());
+    assert!(layout.repeat_packed(align_max + 1).is_err());
+
+    let next = Layout::from_size_align(size_max, 1).unwrap();
+    assert!(layout.extend(next).is_err());
+}
+
+#[test]
 fn layout_debug_shows_log2_of_alignment() {
     // `Debug` is not stable, but here's what it does right now
     let layout = Layout::from_size_align(24576, 8192).unwrap();
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/char.rs b/library/coretests/tests/char.rs
index 852f073bae1..6f94065b2d9 100644
--- a/library/coretests/tests/char.rs
+++ b/library/coretests/tests/char.rs
@@ -220,6 +220,7 @@ fn test_escape_default() {
     }
     assert_eq!(string('\n'), "\\n");
     assert_eq!(string('\r'), "\\r");
+    assert_eq!(string('\t'), "\\t");
     assert_eq!(string('\''), "\\'");
     assert_eq!(string('"'), "\\\"");
     assert_eq!(string(' '), " ");
@@ -417,3 +418,45 @@ fn eu_iterator_specializations() {
     check('\u{12340}');
     check('\u{10FFFF}');
 }
+
+#[test]
+#[should_panic]
+fn test_from_digit_radix_too_high() {
+    let _ = char::from_digit(0, 37);
+}
+
+#[test]
+fn test_from_digit_invalid_radix() {
+    assert!(char::from_digit(10, 9).is_none());
+}
+
+#[test]
+#[should_panic]
+fn test_to_digit_radix_too_low() {
+    let _ = 'a'.to_digit(1);
+}
+
+#[test]
+#[should_panic]
+fn test_to_digit_radix_too_high() {
+    let _ = 'a'.to_digit(37);
+}
+
+#[test]
+fn test_as_ascii_invalid() {
+    assert!('โค'.as_ascii().is_none());
+}
+
+#[test]
+#[should_panic]
+fn test_encode_utf8_raw_buffer_too_small() {
+    let mut buf = [0u8; 1];
+    let _ = char::encode_utf8_raw('รŸ'.into(), &mut buf);
+}
+
+#[test]
+#[should_panic]
+fn test_encode_utf16_raw_buffer_too_small() {
+    let mut buf = [0u16; 1];
+    let _ = char::encode_utf16_raw('๐ท'.into(), &mut buf);
+}
diff --git a/library/coretests/tests/cmp.rs b/library/coretests/tests/cmp.rs
index 6c4e2146f91..55e35a4a725 100644
--- a/library/coretests/tests/cmp.rs
+++ b/library/coretests/tests/cmp.rs
@@ -215,19 +215,18 @@ fn cmp_default() {
     assert_eq!(Fool(false), Fool(true));
 }
 
-/* FIXME(#110395)
 mod const_cmp {
     use super::*;
 
     struct S(i32);
 
-    impl PartialEq for S {
+    impl const PartialEq for S {
         fn eq(&self, other: &Self) -> bool {
             self.0 == other.0
         }
     }
 
-    impl PartialOrd for S {
+    impl const PartialOrd for S {
         fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
             let ret = match (self.0, other.0) {
                 (a, b) if a > b => Ordering::Greater,
@@ -247,4 +246,3 @@ mod const_cmp {
     const _: () = assert!(S(0) < S(1));
     const _: () = assert!(S(1) > S(0));
 }
-*/
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/hash/mod.rs b/library/coretests/tests/hash/mod.rs
index 1f10a4733b0..043a3ee7423 100644
--- a/library/coretests/tests/hash/mod.rs
+++ b/library/coretests/tests/hash/mod.rs
@@ -53,12 +53,14 @@ fn test_writer_hasher() {
     assert_eq!(hash(&5_u16), 5);
     assert_eq!(hash(&5_u32), 5);
     assert_eq!(hash(&5_u64), 5);
+    assert_eq!(hash(&5_u128), 5);
     assert_eq!(hash(&5_usize), 5);
 
     assert_eq!(hash(&5_i8), 5);
     assert_eq!(hash(&5_i16), 5);
     assert_eq!(hash(&5_i32), 5);
     assert_eq!(hash(&5_i64), 5);
+    assert_eq!(hash(&5_i128), 5);
     assert_eq!(hash(&5_isize), 5);
 
     assert_eq!(hash(&false), 0);
@@ -85,6 +87,17 @@ fn test_writer_hasher() {
     let ptr = ptr::without_provenance_mut::<i32>(5_usize);
     assert_eq!(hash(&ptr), 5);
 
+    // Use a newtype to test the `Hash::hash_slice` default implementation.
+    struct Byte(u8);
+
+    impl Hash for Byte {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_u8(self.0)
+        }
+    }
+
+    assert_eq!(hash(&[Byte(b'a')]), 97 + 1);
+
     if cfg!(miri) {
         // Miri cannot hash pointers
         return;
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index b5658a9970f..a246c806140 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -13,8 +13,10 @@
 #![feature(bool_to_result)]
 #![feature(bstr)]
 #![feature(cfg_target_has_reliable_f16_f128)]
+#![feature(char_internals)]
 #![feature(char_max_len)]
 #![feature(clone_to_uninit)]
+#![feature(const_cmp)]
 #![feature(const_convert)]
 #![feature(const_destruct)]
 #![feature(const_eval_select)]
@@ -81,6 +83,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/keyword_docs.rs b/library/std/src/keyword_docs.rs
index 1c55824ab90..7ff4af8ede8 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -1257,6 +1257,108 @@ mod ref_keyword {}
 /// [`async`]: ../std/keyword.async.html
 mod return_keyword {}
 
+#[doc(keyword = "become")]
+//
+/// Perform a tail-call of a function.
+///
+/// <div class="warning">
+///
+/// `feature(explicit_tail_calls)` is currently incomplete and may not work properly.
+/// </div>
+///
+/// When tail calling a function, instead of its stack frame being added to the
+/// stack, the stack frame of the caller is directly replaced with the callee's.
+/// This means that as long as a loop in a call graph only uses tail calls, the
+/// stack growth will be bounded.
+///
+/// This is useful for writing functional-style code (since it prevents recursion
+/// from exhausting resources) or for code optimization (since a tail call
+/// *might* be cheaper than a normal call, tail calls can be used in a similar
+/// manner to computed goto).
+///
+/// Example of using `become` to implement functional-style `fold`:
+/// ```
+/// #![feature(explicit_tail_calls)]
+/// #![expect(incomplete_features)]
+///
+/// fn fold<T: Copy, S>(slice: &[T], init: S, f: impl Fn(S, T) -> S) -> S {
+///     match slice {
+///         // without `become`, on big inputs this could easily overflow the
+///         // stack. using a tail call guarantees that the stack will not grow unboundedly
+///         [first, rest @ ..] => become fold(rest, f(init, *first), f),
+///         [] => init,
+///     }
+/// }
+/// ```
+///
+/// Compilers can already perform "tail call optimization" -- they can replace normal
+/// calls with tail calls, although there are no guarantees that this will be done.
+/// However, to perform TCO, the call needs to be the last thing that happens
+/// in the functions and be returned from it. This requirement is often broken
+/// by drop code for locals, which is run after computing the return expression:
+///
+/// ```
+/// fn example() {
+///     let string = "meow".to_owned();
+///     println!("{string}");
+///     return help(); // this is *not* the last thing that happens in `example`...
+/// }
+///
+/// // ... because it is desugared to this:
+/// fn example_desugared() {
+///     let string = "meow".to_owned();
+///     println!("{string}");
+///     let tmp = help();
+///     drop(string);
+///     return tmp;
+/// }
+///
+/// fn help() {}
+/// ```
+///
+/// For this reason, `become` also changes the drop order, such that locals are
+/// dropped *before* evaluating the call.
+///
+/// In order to guarantee that the compiler can perform a tail call, `become`
+/// currently has these requirements:
+/// 1. callee and caller must have the same ABI, arguments, and return type
+/// 2. callee and caller must not have varargs
+/// 3. caller must not be marked with `#[track_caller]`
+///    - callee is allowed to be marked with `#[track_caller]` as otherwise
+///      adding `#[track_caller]` would be a breaking change. if callee is
+///      marked with `#[track_caller]` a tail call is not guaranteed.
+/// 4. callee and caller cannot be a closure
+///    (unless it's coerced to a function pointer)
+///
+/// It is possible to tail-call a function pointer:
+/// ```
+/// #![feature(explicit_tail_calls)]
+/// #![expect(incomplete_features)]
+///
+/// #[derive(Copy, Clone)]
+/// enum Inst { Inc, Dec }
+///
+/// fn dispatch(stream: &[Inst], state: u32) -> u32 {
+///     const TABLE: &[fn(&[Inst], u32) -> u32] = &[increment, decrement];
+///     match stream {
+///         [inst, rest @ ..] => become TABLE[*inst as usize](rest, state),
+///         [] => state,
+///     }
+/// }
+///
+/// fn increment(stream: &[Inst], state: u32) -> u32 {
+///     become dispatch(stream, state + 1)
+/// }
+///
+/// fn decrement(stream: &[Inst], state: u32) -> u32 {
+///     become dispatch(stream, state - 1)
+/// }
+///
+/// let program = &[Inst::Inc, Inst::Inc, Inst::Dec, Inst::Inc];
+/// assert_eq!(dispatch(program, 0), 2);
+/// ```
+mod become_keyword {}
+
 #[doc(keyword = "self")]
 //
 /// The receiver of a method, or the current module.
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 97db0d6ab75..33e3bf0c085 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -284,7 +284,6 @@
 #![feature(core_float_math)]
 #![feature(decl_macro)]
 #![feature(deprecated_suggestion)]
-#![feature(derive_const)]
 #![feature(doc_cfg)]
 #![feature(doc_cfg_hide)]
 #![feature(doc_masked)]
@@ -332,11 +331,7 @@
 #![feature(cfg_select)]
 #![feature(char_internals)]
 #![feature(clone_to_uninit)]
-#![feature(const_cmp)]
 #![feature(const_convert)]
-#![feature(const_ops)]
-#![feature(const_option_ops)]
-#![feature(const_try)]
 #![feature(core_intrinsics)]
 #![feature(core_io_borrowed_buf)]
 #![feature(drop_guard)]
@@ -350,6 +345,7 @@
 #![feature(float_gamma)]
 #![feature(float_minimum_maximum)]
 #![feature(fmt_internals)]
+#![feature(fn_ptr_trait)]
 #![feature(generic_atomic)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
diff --git a/library/std/src/sync/nonpoison/condvar.rs b/library/std/src/sync/nonpoison/condvar.rs
index 49afdd87818..994fc6816a0 100644
--- a/library/std/src/sync/nonpoison/condvar.rs
+++ b/library/std/src/sync/nonpoison/condvar.rs
@@ -198,11 +198,10 @@ impl Condvar {
     /// the system time. This function is susceptible to spurious wakeups.
     /// Condition variables normally have a boolean predicate associated with
     /// them, and the predicate must always be checked each time this function
-    /// returns to protect against spurious wakeups. Additionally, it is
-    /// typically desirable for the timeout to not exceed some duration in
-    /// spite of spurious wakes, thus the sleep-duration is decremented by the
-    /// amount slept. Alternatively, use the `wait_timeout_while` method
-    /// to wait with a timeout while a predicate is true.
+    /// returns to protect against spurious wakeups.  Furthermore, since the timeout
+    /// is given relative to the moment this function is called, it needs to be adjusted
+    /// when this function is called in a loop. The [`wait_timeout_while`] method
+    /// lets you wait with a timeout while a predicate is true, taking care of all these concerns.
     ///
     /// The returned [`WaitTimeoutResult`] value indicates if the timeout is
     /// known to have elapsed.
diff --git a/library/std/src/sync/poison/condvar.rs b/library/std/src/sync/poison/condvar.rs
index 5dc2b510f3a..de625a6cc5f 100644
--- a/library/std/src/sync/poison/condvar.rs
+++ b/library/std/src/sync/poison/condvar.rs
@@ -269,11 +269,10 @@ impl Condvar {
     /// the system time. This function is susceptible to spurious wakeups.
     /// Condition variables normally have a boolean predicate associated with
     /// them, and the predicate must always be checked each time this function
-    /// returns to protect against spurious wakeups. Additionally, it is
-    /// typically desirable for the timeout to not exceed some duration in
-    /// spite of spurious wakes, thus the sleep-duration is decremented by the
-    /// amount slept. Alternatively, use the `wait_timeout_while` method
-    /// to wait with a timeout while a predicate is true.
+    /// returns to protect against spurious wakeups. Furthermore, since the timeout
+    /// is given relative to the moment this function is called, it needs to be adjusted
+    /// when this function is called in a loop. The [`wait_timeout_while`] method
+    /// lets you wait with a timeout while a predicate is true, taking care of all these concerns.
     ///
     /// The returned [`WaitTimeoutResult`] value indicates if the timeout is
     /// known to have elapsed.
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/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs
index 89a427ab88b..f76a5f96c87 100644
--- a/library/std/src/sys/pal/hermit/time.rs
+++ b/library/std/src/sys/pal/hermit/time.rs
@@ -25,15 +25,8 @@ impl Timespec {
         Timespec { t: timespec { tv_sec, tv_nsec } }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
-        // FIXME: const PartialOrd
-        let mut cmp = self.t.tv_sec - other.t.tv_sec;
-        if cmp == 0 {
-            cmp = self.t.tv_nsec as i64 - other.t.tv_nsec as i64;
-        }
-
-        if cmp >= 0 {
+    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        if self >= other {
             Ok(if self.t.tv_nsec >= other.t.tv_nsec {
                 Duration::new(
                     (self.t.tv_sec - other.t.tv_sec) as u64,
@@ -53,22 +46,20 @@ impl Timespec {
         }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
+    fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?;
 
         // Nano calculations can't overflow because nanos are <1B which fit
         // in a u32.
-        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
-        if nsec >= NSEC_PER_SEC as u32 {
-            nsec -= NSEC_PER_SEC as u32;
+        let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
+        if nsec >= NSEC_PER_SEC.try_into().unwrap() {
+            nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
             secs = secs.checked_add(1)?;
         }
         Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
+    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?;
 
         // Similar to above, nanos can't overflow.
@@ -222,18 +213,15 @@ impl SystemTime {
         SystemTime(time)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         self.0.sub_timespec(&other.0)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add_duration(other)?))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub_duration(other)?))
     }
 }
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/sgx/time.rs b/library/std/src/sys/pal/sgx/time.rs
index 603dae952ab..db4cf2804bf 100644
--- a/library/std/src/sys/pal/sgx/time.rs
+++ b/library/std/src/sys/pal/sgx/time.rs
@@ -32,22 +32,15 @@ impl SystemTime {
         SystemTime(usercalls::insecure_time())
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        // FIXME: ok_or_else with const closures
-        match self.0.checked_sub(other.0) {
-            Some(duration) => Ok(duration),
-            None => Err(other.0 - self.0),
-        }
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
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/solid/time.rs b/library/std/src/sys/pal/solid/time.rs
index e35e60df1a0..c39d715c6a6 100644
--- a/library/std/src/sys/pal/solid/time.rs
+++ b/library/std/src/sys/pal/solid/time.rs
@@ -39,8 +39,7 @@ impl SystemTime {
         Self(t)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         if self.0 >= other.0 {
             Ok(Duration::from_secs((self.0 as u64).wrapping_sub(other.0 as u64)))
         } else {
@@ -48,13 +47,11 @@ impl SystemTime {
         }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add_unsigned(other.as_secs())?))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub_unsigned(other.as_secs())?))
     }
 }
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/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs
index 36ce3f7ef96..c6636626fd5 100644
--- a/library/std/src/sys/pal/uefi/time.rs
+++ b/library/std/src/sys/pal/uefi/time.rs
@@ -80,32 +80,19 @@ impl SystemTime {
             .unwrap_or_else(|| panic!("time not implemented on this platform"))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        // FIXME: ok_or_else with const closures
-        match self.0.checked_sub(other.0) {
-            Some(duration) => Ok(duration),
-            None => Err(other.0 - self.0),
-        }
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        let temp = self.0.checked_add(*other)?;
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+        let temp = Self(self.0.checked_add(*other)?);
 
         // Check if can be represented in UEFI
-        // FIXME: const PartialOrd
-        let mut cmp = temp.as_secs() - MAX_UEFI_TIME.0.as_secs();
-        if cmp == 0 {
-            cmp = temp.subsec_nanos() as u64 - MAX_UEFI_TIME.0.subsec_nanos() as u64;
-        }
-
-        if cmp <= 0 { Some(SystemTime(temp)) } else { None }
+        if temp <= MAX_UEFI_TIME { Some(temp) } else { None }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
-        Some(SystemTime(self.0.checked_sub(*other)?))
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+        self.0.checked_sub(*other).map(Self)
     }
 }
 
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/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
index 328fe0bc960..bd7f74fea6a 100644
--- a/library/std/src/sys/pal/unix/time.rs
+++ b/library/std/src/sys/pal/unix/time.rs
@@ -38,18 +38,15 @@ impl SystemTime {
         SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         self.t.sub_timespec(&other.t)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime { t: self.t.checked_add_duration(other)? })
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime { t: self.t.checked_sub_duration(other)? })
     }
 }
@@ -136,15 +133,8 @@ impl Timespec {
         Timespec::new(t.tv_sec as i64, t.tv_nsec as i64).unwrap()
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
-        // FIXME: const PartialOrd
-        let mut cmp = self.tv_sec - other.tv_sec;
-        if cmp == 0 {
-            cmp = self.tv_nsec.as_inner() as i64 - other.tv_nsec.as_inner() as i64;
-        }
-
-        if cmp >= 0 {
+    pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        if self >= other {
             // NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
             // to optimize it into a branchless form (see also #75545):
             //
@@ -179,8 +169,7 @@ impl Timespec {
         }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.tv_sec.checked_add_unsigned(other.as_secs())?;
 
         // Nano calculations can't overflow because nanos are <1B which fit
@@ -190,11 +179,10 @@ impl Timespec {
             nsec -= NSEC_PER_SEC as u32;
             secs = secs.checked_add(1)?;
         }
-        Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) })
+        Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.tv_sec.checked_sub_unsigned(other.as_secs())?;
 
         // Similar to above, nanos can't overflow.
@@ -203,7 +191,7 @@ impl Timespec {
             nsec += NSEC_PER_SEC as i32;
             secs = secs.checked_sub(1)?;
         }
-        Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) })
+        Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
     }
 
     #[allow(dead_code)]
diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs
index c8cf75b876c..a3b980a3f3d 100644
--- a/library/std/src/sys/pal/unix/weak.rs
+++ b/library/std/src/sys/pal/unix/weak.rs
@@ -22,11 +22,24 @@
 #![allow(dead_code, unused_macros)]
 #![forbid(unsafe_op_in_unsafe_fn)]
 
-use crate::ffi::CStr;
-use crate::marker::PhantomData;
-use crate::sync::atomic::{self, Atomic, AtomicPtr, Ordering};
+use crate::ffi::{CStr, c_char, c_void};
+use crate::marker::{FnPtr, PhantomData};
+use crate::sync::atomic::{Atomic, AtomicPtr, Ordering};
 use crate::{mem, ptr};
 
+// We currently only test `dlsym!`, but that doesn't work on all platforms, so
+// we gate the tests to only the platforms where it is actually used.
+//
+// FIXME(joboet): add more tests, reorganise the whole module and get rid of
+//                `#[allow(dead_code, unused_macros)]`.
+#[cfg(any(
+    target_vendor = "apple",
+    all(target_os = "linux", target_env = "gnu"),
+    target_os = "freebsd",
+))]
+#[cfg(test)]
+mod tests;
+
 // We can use true weak linkage on ELF targets.
 #[cfg(all(unix, not(target_vendor = "apple")))]
 pub(crate) macro weak {
@@ -64,7 +77,7 @@ impl<F: Copy> ExternWeak<F> {
 
 pub(crate) macro dlsym {
     (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => (
-         dlsym!(
+        dlsym!(
             #[link_name = stringify!($name)]
             fn $name($($param : $t),*) -> $ret;
         );
@@ -73,21 +86,39 @@ pub(crate) macro dlsym {
         #[link_name = $sym:expr]
         fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;
     ) => (
-        static DLSYM: DlsymWeak<unsafe extern "C" fn($($t),*) -> $ret> =
-            DlsymWeak::new(concat!($sym, '\0'));
+        static DLSYM: DlsymWeak<unsafe extern "C" fn($($t),*) -> $ret> = {
+            let Ok(name) = CStr::from_bytes_with_nul(concat!($sym, '\0').as_bytes()) else {
+                panic!("symbol name may not contain NUL")
+            };
+
+            // SAFETY: Whoever calls the function pointer returned by `get()`
+            // is responsible for ensuring that the signature is correct. Just
+            // like with extern blocks, this is syntactically enforced by making
+            // the function pointer be unsafe.
+            unsafe { DlsymWeak::new(name) }
+        };
+
         let $name = &DLSYM;
     )
 }
+
 pub(crate) struct DlsymWeak<F> {
-    name: &'static str,
+    /// A pointer to the nul-terminated name of the symbol.
+    // Use a pointer instead of `&'static CStr` to save space.
+    name: *const c_char,
     func: Atomic<*mut libc::c_void>,
     _marker: PhantomData<F>,
 }
 
-impl<F> DlsymWeak<F> {
-    pub(crate) const fn new(name: &'static str) -> Self {
+impl<F: FnPtr> DlsymWeak<F> {
+    /// # Safety
+    ///
+    /// If the signature of `F` does not match the signature of the symbol (if
+    /// it exists), calling the function pointer returned by `get()` is
+    /// undefined behaviour.
+    pub(crate) const unsafe fn new(name: &'static CStr) -> Self {
         DlsymWeak {
-            name,
+            name: name.as_ptr(),
             func: AtomicPtr::new(ptr::without_provenance_mut(1)),
             _marker: PhantomData,
         }
@@ -95,62 +126,59 @@ impl<F> DlsymWeak<F> {
 
     #[inline]
     pub(crate) fn get(&self) -> Option<F> {
-        unsafe {
-            // Relaxed is fine here because we fence before reading through the
-            // pointer (see the comment below).
-            match self.func.load(Ordering::Relaxed) {
-                func if func.addr() == 1 => self.initialize(),
-                func if func.is_null() => None,
-                func => {
-                    let func = mem::transmute_copy::<*mut libc::c_void, F>(&func);
-                    // The caller is presumably going to read through this value
-                    // (by calling the function we've dlsymed). This means we'd
-                    // need to have loaded it with at least C11's consume
-                    // ordering in order to be guaranteed that the data we read
-                    // from the pointer isn't from before the pointer was
-                    // stored. Rust has no equivalent to memory_order_consume,
-                    // so we use an acquire fence (sorry, ARM).
-                    //
-                    // Now, in practice this likely isn't needed even on CPUs
-                    // where relaxed and consume mean different things. The
-                    // symbols we're loading are probably present (or not) at
-                    // init, and even if they aren't the runtime dynamic loader
-                    // is extremely likely have sufficient barriers internally
-                    // (possibly implicitly, for example the ones provided by
-                    // invoking `mprotect`).
-                    //
-                    // That said, none of that's *guaranteed*, and so we fence.
-                    atomic::fence(Ordering::Acquire);
-                    Some(func)
-                }
-            }
+        // The caller is presumably going to read through this value
+        // (by calling the function we've dlsymed). This means we'd
+        // need to have loaded it with at least C11's consume
+        // ordering in order to be guaranteed that the data we read
+        // from the pointer isn't from before the pointer was
+        // stored. Rust has no equivalent to memory_order_consume,
+        // so we use an acquire load (sorry, ARM).
+        //
+        // Now, in practice this likely isn't needed even on CPUs
+        // where relaxed and consume mean different things. The
+        // symbols we're loading are probably present (or not) at
+        // init, and even if they aren't the runtime dynamic loader
+        // is extremely likely have sufficient barriers internally
+        // (possibly implicitly, for example the ones provided by
+        // invoking `mprotect`).
+        //
+        // That said, none of that's *guaranteed*, so we use acquire.
+        match self.func.load(Ordering::Acquire) {
+            func if func.addr() == 1 => self.initialize(),
+            func if func.is_null() => None,
+            // SAFETY:
+            // `func` is not null and `F` implements `FnPtr`, thus this
+            // transmutation is well-defined. It is the responsibility of the
+            // creator of this `DlsymWeak` to ensure that calling the resulting
+            // function pointer does not result in undefined behaviour (though
+            // the `dlsym!` macro delegates this responsibility to the caller
+            // of the function by using `unsafe` function pointers).
+            // FIXME: use `transmute` once it stops complaining about generics.
+            func => Some(unsafe { mem::transmute_copy::<*mut c_void, F>(&func) }),
         }
     }
 
     // Cold because it should only happen during first-time initialization.
     #[cold]
-    unsafe fn initialize(&self) -> Option<F> {
-        assert_eq!(size_of::<F>(), size_of::<*mut libc::c_void>());
-
-        let val = unsafe { fetch(self.name) };
-        // This synchronizes with the acquire fence in `get`.
+    fn initialize(&self) -> Option<F> {
+        // SAFETY: `self.name` was created from a `&'static CStr` and is
+        // therefore a valid C string pointer.
+        let val = unsafe { libc::dlsym(libc::RTLD_DEFAULT, self.name) };
+        // This synchronizes with the acquire load in `get`.
         self.func.store(val, Ordering::Release);
 
         if val.is_null() {
             None
         } else {
+            // SAFETY: see the comment in `get`.
+            // FIXME: use `transmute` once it stops complaining about generics.
             Some(unsafe { mem::transmute_copy::<*mut libc::c_void, F>(&val) })
         }
     }
 }
 
-unsafe fn fetch(name: &str) -> *mut libc::c_void {
-    let name = match CStr::from_bytes_with_nul(name.as_bytes()) {
-        Ok(cstr) => cstr,
-        Err(..) => return ptr::null_mut(),
-    };
-    unsafe { libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) }
-}
+unsafe impl<F> Send for DlsymWeak<F> {}
+unsafe impl<F> Sync for DlsymWeak<F> {}
 
 #[cfg(not(any(target_os = "linux", target_os = "android")))]
 pub(crate) macro syscall {
diff --git a/library/std/src/sys/pal/unix/weak/tests.rs b/library/std/src/sys/pal/unix/weak/tests.rs
new file mode 100644
index 00000000000..d807ba64e35
--- /dev/null
+++ b/library/std/src/sys/pal/unix/weak/tests.rs
@@ -0,0 +1,32 @@
+use super::*;
+
+#[test]
+fn dlsym_existing() {
+    const TEST_STRING: &'static CStr = c"Ferris!";
+
+    // Try to find a symbol that definitely exists.
+    dlsym! {
+        fn strlen(cs: *const c_char) -> usize;
+    }
+
+    dlsym! {
+        #[link_name = "strlen"]
+        fn custom_name(cs: *const c_char) -> usize;
+    }
+
+    let strlen = strlen.get().unwrap();
+    assert_eq!(unsafe { strlen(TEST_STRING.as_ptr()) }, TEST_STRING.count_bytes());
+
+    let custom_name = custom_name.get().unwrap();
+    assert_eq!(unsafe { custom_name(TEST_STRING.as_ptr()) }, TEST_STRING.count_bytes());
+}
+
+#[test]
+fn dlsym_missing() {
+    // Try to find a symbol that definitely does not exist.
+    dlsym! {
+        fn test_symbol_that_does_not_exist() -> i32;
+    }
+
+    assert!(test_symbol_that_does_not_exist.get().is_none());
+}
diff --git a/library/std/src/sys/pal/unsupported/time.rs b/library/std/src/sys/pal/unsupported/time.rs
index 0c387917044..6d67b538a96 100644
--- a/library/std/src/sys/pal/unsupported/time.rs
+++ b/library/std/src/sys/pal/unsupported/time.rs
@@ -31,22 +31,15 @@ impl SystemTime {
         panic!("time not implemented on this platform")
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        // FIXME: ok_or_else with const closures
-        match self.0.checked_sub(other.0) {
-            Some(duration) => Ok(duration),
-            None => Err(other.0 - self.0),
-        }
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
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/wasip1/time.rs b/library/std/src/sys/pal/wasip1/time.rs
index 892661b312b..0d8d0b59ac1 100644
--- a/library/std/src/sys/pal/wasip1/time.rs
+++ b/library/std/src/sys/pal/wasip1/time.rs
@@ -43,34 +43,23 @@ impl SystemTime {
         SystemTime(current_time(wasi::CLOCKID_REALTIME))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
+    pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
         SystemTime(Duration::from_nanos(ts))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
-        // FIXME: const TryInto
-        let ns = self.0.as_nanos();
-        if ns <= u64::MAX as u128 { Some(ns as u64) } else { None }
+    pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
+        self.0.as_nanos().try_into().ok()
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        // FIXME: ok_or_else with const closures
-        match self.0.checked_sub(other.0) {
-            Some(duration) => Ok(duration),
-            None => Err(other.0 - self.0),
-        }
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
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..43489183994 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
     }
 }
@@ -36,34 +36,23 @@ impl SystemTime {
         SystemTime(Duration::new(now.seconds, now.nanoseconds))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
+    pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
         SystemTime(Duration::from_nanos(ts))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
-        // FIXME: const TryInto
-        let ns = self.0.as_nanos();
-        if ns <= u64::MAX as u128 { Some(ns as u64) } else { None }
+    pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
+        self.0.as_nanos().try_into().ok()
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        // FIXME: ok_or_else with const closures
-        match self.0.checked_sub(other.0) {
-            Some(duration) => Ok(duration),
-            None => Err(other.0 - self.0),
-        }
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
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..0d31b80e56a 100644
--- a/library/std/src/sys/pal/windows/time.rs
+++ b/library/std/src/sys/pal/windows/time.rs
@@ -72,8 +72,7 @@ impl SystemTime {
         }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    const fn from_intervals(intervals: i64) -> SystemTime {
+    fn from_intervals(intervals: i64) -> SystemTime {
         SystemTime {
             t: c::FILETIME {
                 dwLowDateTime: intervals as u32,
@@ -82,13 +81,11 @@ impl SystemTime {
         }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    const fn intervals(&self) -> i64 {
+    fn intervals(&self) -> i64 {
         (self.t.dwLowDateTime as i64) | ((self.t.dwHighDateTime as i64) << 32)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         let me = self.intervals();
         let other = other.intervals();
         if me >= other {
@@ -98,14 +95,12 @@ impl SystemTime {
         }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         let intervals = self.intervals().checked_add(checked_dur2intervals(other)?)?;
         Some(SystemTime::from_intervals(intervals))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?;
         Some(SystemTime::from_intervals(intervals))
     }
@@ -155,18 +150,15 @@ impl Hash for SystemTime {
     }
 }
 
-#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-const fn checked_dur2intervals(dur: &Duration) -> Option<i64> {
-    // FIXME: const TryInto
-    let secs = dur
-        .as_secs()
+fn checked_dur2intervals(dur: &Duration) -> Option<i64> {
+    dur.as_secs()
         .checked_mul(INTERVALS_PER_SEC)?
-        .checked_add(dur.subsec_nanos() as u64 / 100)?;
-    if secs <= i64::MAX as u64 { Some(secs.cast_signed()) } else { None }
+        .checked_add(dur.subsec_nanos() as u64 / 100)?
+        .try_into()
+        .ok()
 }
 
-#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-const fn intervals2dur(intervals: u64) -> Duration {
+fn intervals2dur(intervals: u64) -> Duration {
     Duration::new(intervals / INTERVALS_PER_SEC, ((intervals % INTERVALS_PER_SEC) * 100) as u32)
 }
 
@@ -232,7 +224,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/pal/xous/time.rs b/library/std/src/sys/pal/xous/time.rs
index d737416436e..ae8be81c0b7 100644
--- a/library/std/src/sys/pal/xous/time.rs
+++ b/library/std/src/sys/pal/xous/time.rs
@@ -43,22 +43,15 @@ impl SystemTime {
         SystemTime { 0: Duration::from_millis((upper as u64) << 32 | lower as u64) }
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        // FIXME: ok_or_else with const closures
-        match self.0.checked_sub(other.0) {
-            Some(duration) => Ok(duration),
-            None => Err(other.0 - self.0),
-        }
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
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/src/time.rs b/library/std/src/time.rs
index 84fbb4c2fe4..31187adb6fe 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -551,13 +551,8 @@ impl SystemTime {
     /// println!("{difference:?}");
     /// ```
     #[stable(feature = "time2", since = "1.8.0")]
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTimeError> {
-        // FIXME: map_err in const
-        match self.0.sub_time(&earlier.0) {
-            Ok(time) => Ok(time),
-            Err(err) => Err(SystemTimeError(err)),
-        }
+    pub fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTimeError> {
+        self.0.sub_time(&earlier.0).map_err(SystemTimeError)
     }
 
     /// Returns the difference from this system time to the
@@ -594,8 +589,7 @@ impl SystemTime {
     /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None`
     /// otherwise.
     #[stable(feature = "time_checked_add", since = "1.34.0")]
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
+    pub fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
         self.0.checked_add_duration(&duration).map(SystemTime)
     }
 
@@ -603,15 +597,13 @@ impl SystemTime {
     /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None`
     /// otherwise.
     #[stable(feature = "time_checked_add", since = "1.34.0")]
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
+    pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
         self.0.checked_sub_duration(&duration).map(SystemTime)
     }
 }
 
 #[stable(feature = "time2", since = "1.8.0")]
-#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
-impl const Add<Duration> for SystemTime {
+impl Add<Duration> for SystemTime {
     type Output = SystemTime;
 
     /// # Panics
@@ -624,16 +616,14 @@ impl const Add<Duration> for SystemTime {
 }
 
 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
-#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
-impl const AddAssign<Duration> for SystemTime {
+impl AddAssign<Duration> for SystemTime {
     fn add_assign(&mut self, other: Duration) {
         *self = *self + other;
     }
 }
 
 #[stable(feature = "time2", since = "1.8.0")]
-#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
-impl const Sub<Duration> for SystemTime {
+impl Sub<Duration> for SystemTime {
     type Output = SystemTime;
 
     fn sub(self, dur: Duration) -> SystemTime {
@@ -642,8 +632,7 @@ impl const Sub<Duration> for SystemTime {
 }
 
 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
-#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
-impl const SubAssign<Duration> for SystemTime {
+impl SubAssign<Duration> for SystemTime {
     fn sub_assign(&mut self, other: Duration) {
         *self = *self - other;
     }
@@ -710,8 +699,7 @@ impl SystemTimeError {
     /// ```
     #[must_use]
     #[stable(feature = "time2", since = "1.8.0")]
-    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
-    pub const fn duration(&self) -> Duration {
+    pub fn duration(&self) -> Duration {
         self.0
     }
 }
diff --git a/library/std/tests/sync/condvar.rs b/library/std/tests/sync/condvar.rs
index 1d712a64300..1b1c33efad5 100644
--- a/library/std/tests/sync/condvar.rs
+++ b/library/std/tests/sync/condvar.rs
@@ -17,7 +17,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads.
 nonpoison_and_poison_unwrap_test!(
     name: notify_one,
     test_body: {
@@ -38,7 +38,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads.
 nonpoison_and_poison_unwrap_test!(
     name: notify_all,
     test_body: {
@@ -79,7 +79,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads.
 nonpoison_and_poison_unwrap_test!(
     name: test_mutex_arc_condvar,
     test_body: {
@@ -116,7 +116,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads.
 nonpoison_and_poison_unwrap_test!(
     name: wait_while,
     test_body: {
@@ -141,7 +141,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads.
 nonpoison_and_poison_unwrap_test!(
     name: wait_timeout_wait,
     test_body: {
@@ -164,7 +164,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads.
 nonpoison_and_poison_unwrap_test!(
     name: wait_timeout_while_wait,
     test_body: {
@@ -180,7 +180,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads.
 nonpoison_and_poison_unwrap_test!(
     name: wait_timeout_while_instant_satisfy,
     test_body: {
@@ -197,7 +197,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads.
 nonpoison_and_poison_unwrap_test!(
     name: wait_timeout_while_wake,
     test_body: {
@@ -226,7 +226,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(any(target_os = "emscripten", target_os = "wasi"), ignore)] // no threads
+#[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] // No threads.
 nonpoison_and_poison_unwrap_test!(
     name: wait_timeout_wake,
     test_body: {
diff --git a/library/std/tests/sync/lib.rs b/library/std/tests/sync/lib.rs
index ac1dbebcc5c..23112e10284 100644
--- a/library/std/tests/sync/lib.rs
+++ b/library/std/tests/sync/lib.rs
@@ -58,6 +58,9 @@ fn result_unwrap<T, E: std::fmt::Debug>(x: Result<T, E>) -> T {
 /// a no-op (the identity function).
 ///
 /// The test names will be prefiex with `poison_` or `nonpoison_`.
+///
+/// Important: most attributes (except `cfg`) will not work properly! (They are only applied to the first test.)
+/// See <https://github.com/rust-lang/rust/pull/146433> for more information.
 macro_rules! nonpoison_and_poison_unwrap_test {
     (
         name: $name:ident,
diff --git a/library/std/tests/sync/mutex.rs b/library/std/tests/sync/mutex.rs
index 612c75c7aef..2445764001b 100644
--- a/library/std/tests/sync/mutex.rs
+++ b/library/std/tests/sync/mutex.rs
@@ -266,7 +266,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+#[cfg(panic = "unwind")] // Requires unwinding support.
 nonpoison_and_poison_unwrap_test!(
     name: test_panics,
     test_body: {
@@ -297,7 +297,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+#[cfg(panic = "unwind")] // Requires unwinding support.
 nonpoison_and_poison_unwrap_test!(
     name: test_mutex_arc_access_in_unwind,
     test_body: {
diff --git a/library/std/tests/sync/rwlock.rs b/library/std/tests/sync/rwlock.rs
index eca15d2a4ad..65d8bac7194 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: {
@@ -124,7 +124,7 @@ nonpoison_and_poison_unwrap_test!(
     }
 );
 
-#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+#[cfg(panic = "unwind")] // Requires unwinding support.
 nonpoison_and_poison_unwrap_test!(
     name: test_rw_arc_access_in_unwind,
     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/bootstrap/defaults/bootstrap.dist.toml b/src/bootstrap/defaults/bootstrap.dist.toml
index 9daf9faac14..b111a20f8d8 100644
--- a/src/bootstrap/defaults/bootstrap.dist.toml
+++ b/src/bootstrap/defaults/bootstrap.dist.toml
@@ -14,6 +14,10 @@ compiletest-use-stage0-libtest = false
 [llvm]
 download-ci-llvm = false
 
+# Most users installing from source want to build all parts of the project from source.
+[gcc]
+download-ci-gcc = false
+
 [rust]
 # We have several defaults in bootstrap that depend on whether the channel is `dev` (e.g. `omit-git-hash` and `download-ci-llvm`).
 # Make sure they don't get set when installing from source.
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 0b75e85772f..1458b0beefa 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1383,14 +1383,17 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS
         }
     }
 
-    // Build jemalloc on AArch64 with support for page sizes up to 64K
-    // See: https://github.com/rust-lang/rust/pull/135081
     // See also the "JEMALLOC_SYS_WITH_LG_PAGE" setting in the tool build step.
-    if builder.config.jemalloc(target)
-        && target.starts_with("aarch64")
-        && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none()
-    {
-        cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16");
+    if builder.config.jemalloc(target) && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() {
+        // Build jemalloc on AArch64 with support for page sizes up to 64K
+        // See: https://github.com/rust-lang/rust/pull/135081
+        if target.starts_with("aarch64") {
+            cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16");
+        }
+        // Build jemalloc on LoongArch with support for page sizes up to 16K
+        else if target.starts_with("loongarch") {
+            cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "14");
+        }
     }
 }
 
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index a5f0718bc01..99a1062109a 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -590,6 +590,8 @@ impl Step for Rustc {
             // Debugger scripts
             builder.ensure(DebuggerScripts { sysroot: image.to_owned(), target });
 
+            generate_target_spec_json_schema(builder, image);
+
             // HTML copyright files
             let file_list = builder.ensure(super::run::GenerateCopyright);
             for file in file_list {
@@ -618,6 +620,28 @@ impl Step for Rustc {
     }
 }
 
+fn generate_target_spec_json_schema(builder: &Builder<'_>, sysroot: &Path) {
+    // Since we run rustc in bootstrap, we need to ensure that we use the host compiler.
+    // We do this by using the stage 1 compiler, which is always compiled for the host,
+    // even in a cross build.
+    let stage1_host = builder.compiler(1, builder.host_target);
+    let mut rustc = command(builder.rustc(stage1_host)).fail_fast();
+    rustc
+        .env("RUSTC_BOOTSTRAP", "1")
+        .args(["--print=target-spec-json-schema", "-Zunstable-options"]);
+    let schema = rustc.run_capture(builder).stdout();
+
+    let schema_dir = tmpdir(builder);
+    t!(fs::create_dir_all(&schema_dir));
+    let schema_file = schema_dir.join("target-spec-json-schema.json");
+    t!(std::fs::write(&schema_file, schema));
+
+    let dst = sysroot.join("etc");
+    t!(fs::create_dir_all(&dst));
+
+    builder.install(&schema_file, &dst, FileType::Regular);
+}
+
 /// Copies debugger scripts for `target` into the given compiler `sysroot`.
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct DebuggerScripts {
diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs
index 77c9622a9bf..717dea37e9e 100644
--- a/src/bootstrap/src/core/build_steps/gcc.rs
+++ b/src/bootstrap/src/core/build_steps/gcc.rs
@@ -32,6 +32,10 @@ pub struct GccOutput {
 impl GccOutput {
     /// Install the required libgccjit library file(s) to the specified `path`.
     pub fn install_to(&self, builder: &Builder<'_>, directory: &Path) {
+        if builder.config.dry_run() {
+            return;
+        }
+
         // At build time, cg_gcc has to link to libgccjit.so (the unversioned symbol).
         // However, at runtime, it will by default look for libgccjit.so.0.
         // So when we install the built libgccjit.so file to the target `directory`, we add it there
@@ -39,8 +43,16 @@ impl GccOutput {
         let mut target_filename = self.libgccjit.file_name().unwrap().to_str().unwrap().to_string();
         target_filename.push_str(".0");
 
+        // If we build libgccjit ourselves, then `self.libgccjit` can actually be a symlink.
+        // In that case, we have to resolve it first, otherwise we'd create a symlink to a symlink,
+        // which wouldn't work.
+        let actual_libgccjit_path = t!(
+            self.libgccjit.canonicalize(),
+            format!("Cannot find libgccjit at {}", self.libgccjit.display())
+        );
+
         let dst = directory.join(target_filename);
-        builder.copy_link(&self.libgccjit, &dst, FileType::NativeLibrary);
+        builder.copy_link(&actual_libgccjit_path, &dst, FileType::NativeLibrary);
     }
 }
 
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 4f839bdf7b8..723ba80eaf8 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -2086,11 +2086,25 @@ HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?}
         }
 
         // Get paths from cmd args
-        let paths = match &builder.config.cmd {
+        let mut paths = match &builder.config.cmd {
             Subcommand::Test { .. } => &builder.config.paths[..],
             _ => &[],
         };
 
+        // in rustdoc-js mode, allow filters to be rs files or js files.
+        // use a late-initialized Vec to avoid cloning for other modes.
+        let mut paths_v;
+        if mode == "rustdoc-js" {
+            paths_v = paths.to_vec();
+            for p in &mut paths_v {
+                if let Some(ext) = p.extension()
+                    && ext == "js"
+                {
+                    p.set_extension("rs");
+                }
+            }
+            paths = &paths_v;
+        }
         // Get test-args by striping suite path
         let mut test_args: Vec<&str> = paths
             .iter()
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 6870bf3eddc..dcc4898cae1 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -228,12 +228,18 @@ pub fn prepare_tool_cargo(
     // own copy
     cargo.env("LZMA_API_STATIC", "1");
 
-    // Build jemalloc on AArch64 with support for page sizes up to 64K
-    // See: https://github.com/rust-lang/rust/pull/135081
     // Note that `miri` always uses jemalloc. As such, there is no checking of the jemalloc build flag.
     // See also the "JEMALLOC_SYS_WITH_LG_PAGE" setting in the compile build step.
-    if target.starts_with("aarch64") && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() {
-        cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16");
+    if env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() {
+        // Build jemalloc on AArch64 with support for page sizes up to 64K
+        // See: https://github.com/rust-lang/rust/pull/135081
+        if target.starts_with("aarch64") {
+            cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16");
+        }
+        // Build jemalloc on LoongArch with support for page sizes up to 16K
+        else if target.starts_with("loongarch") {
+            cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "14");
+        }
     }
 
     // CFG_RELEASE is needed by rustfmt (and possibly other tools) which
diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs
index 5999348a7fe..05a5dfc0bc5 100644
--- a/src/bootstrap/src/core/config/mod.rs
+++ b/src/bootstrap/src/core/config/mod.rs
@@ -422,10 +422,10 @@ impl std::str::FromStr for RustcLto {
 #[derive(Default, Clone)]
 pub enum GccCiMode {
     /// Build GCC from the local `src/gcc` submodule.
-    #[default]
     BuildLocally,
     /// Try to download GCC from CI.
     /// If it is not available on CI, it will be built locally instead.
+    #[default]
     DownloadFromCi,
 }
 
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 01309072927..03b39882e30 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -541,4 +541,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "Added a new option `rust.break-on-ice` to control if internal compiler errors cause a debug break on Windows.",
     },
+    ChangeInfo {
+        change_id: 146435,
+        severity: ChangeSeverity::Info,
+        summary: "The default value of the `gcc.download-ci-gcc` option has been changed to `true`.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs
index 777c8601aa1..db2369097d6 100644
--- a/src/bootstrap/src/utils/proc_macro_deps.rs
+++ b/src/bootstrap/src/utils/proc_macro_deps.rs
@@ -43,6 +43,7 @@ pub static CRATES: &[&str] = &[
     "rustc-hash",
     "self_cell",
     "serde",
+    "serde_derive_internals",
     "sha2",
     "smallvec",
     "stable_deref_trait",
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
index 7e6a59aaf89..54b13c4397f 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile
@@ -38,7 +38,7 @@ ENV RUST_CONFIGURE_ARGS \
       --build=x86_64-unknown-linux-gnu \
       --enable-debug \
       --enable-lld \
-      --set rust.debuginfo-level-tests=1 \
+      --set rust.debuginfo-level-tests=2 \
       --set llvm.use-linker=lld \
       --set target.x86_64-unknown-linux-gnu.linker=clang \
       --set target.x86_64-unknown-linux-gnu.cc=clang \
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 8e378e53e51..e4bf33dd8a0 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -48,6 +48,7 @@
     - [\*-apple-visionos](platform-support/apple-visionos.md)
     - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
     - [aarch64-unknown-linux-musl](platform-support/aarch64-unknown-linux-musl.md)
+    - [aarch64-unknown-none*](platform-support/aarch64-unknown-none.md)
     - [aarch64_be-unknown-none-softfloat](platform-support/aarch64_be-unknown-none-softfloat.md)
     - [aarch64_be-unknown-linux-musl](platform-support/aarch64_be-unknown-linux-musl.md)
     - [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md)
@@ -55,7 +56,9 @@
     - [arm-none-eabi](platform-support/arm-none-eabi.md)
       - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)
       - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md)
-      - [armv7r-none-eabi](platform-support/armv7r-none-eabi.md)
+      - [armv7a-none-eabi{,hf}](platform-support/armv7a-none-eabi.md)
+      - [armv7r-none-eabi{,hf}](platform-support/armv7r-none-eabi.md)
+      - [armebv7r-none-eabi{,hf}](platform-support/armebv7r-none-eabi.md)
       - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md)
       - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md)
       - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md)
diff --git a/src/doc/rustc/src/check-cfg.md b/src/doc/rustc/src/check-cfg.md
index 00add2651ae..4caeaa106b4 100644
--- a/src/doc/rustc/src/check-cfg.md
+++ b/src/doc/rustc/src/check-cfg.md
@@ -134,7 +134,7 @@ As of `2025-01-02T`, the list of known names is as follows:
  - `unix`
  - `windows`
 
-> Starting with 1.85.0, the `test` cfg is consider to be a "userspace" config
+> Starting with 1.85.0, the `test` cfg is considered to be a "userspace" config
 > despite being also set by `rustc` and should be managed by the build system itself.
 
 Like with `values(any())`, well known names checking can be disabled by passing `cfg(any())`
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 6c5b48d8c8f..e5e46f72637 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)
@@ -149,22 +149,22 @@ target | std | notes
 [`aarch64-apple-ios-sim`](platform-support/apple-ios.md) | โœ“ | Apple iOS Simulator on ARM64
 [`aarch64-linux-android`](platform-support/android.md) | โœ“ | ARM64 Android
 [`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | โœ“ | ARM64 Fuchsia
-`aarch64-unknown-none` | * | Bare ARM64, hardfloat
-`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
+[`aarch64-unknown-none`](platform-support/aarch64-unknown-none.md) | * | Bare ARM64, hardfloat
+[`aarch64-unknown-none-softfloat`](platform-support/aarch64-unknown-none.md) | * | Bare ARM64, softfloat
 [`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI
 [`arm-linux-androideabi`](platform-support/android.md) | โœ“ | Armv6 Android
 `arm-unknown-linux-musleabi` | โœ“ | Armv6 Linux with musl 1.2.3
 `arm-unknown-linux-musleabihf` | โœ“ | Armv6 Linux with musl 1.2.3, hardfloat
 [`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | โœ“ | Arm64EC Windows MSVC
-[`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian
-[`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat
+[`armebv7r-none-eabi`](platform-support/armebv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian
+[`armebv7r-none-eabihf`](platform-support/armebv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat
 [`armv5te-unknown-linux-gnueabi`](platform-support/armv5te-unknown-linux-gnueabi.md) | โœ“ | Armv5TE Linux (kernel 4.4+, glibc 2.23)
 `armv5te-unknown-linux-musleabi` | โœ“ | Armv5TE Linux with musl 1.2.3
 [`armv7-linux-androideabi`](platform-support/android.md) | โœ“ | Armv7-A Android
 `armv7-unknown-linux-gnueabi` | โœ“ | Armv7-A Linux (kernel 4.15+, glibc 2.27)
 `armv7-unknown-linux-musleabi` | โœ“ | Armv7-A Linux with musl 1.2.3
 `armv7-unknown-linux-musleabihf` | โœ“ | Armv7-A Linux with musl 1.2.3, hardfloat
-[`armv7a-none-eabi`](platform-support/arm-none-eabi.md) | * | Bare Armv7-A
+[`armv7a-none-eabi`](platform-support/armv7a-none-eabi.md) | * | Bare Armv7-A
 [`armv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R
 [`armv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, hardfloat
 `i586-unknown-linux-gnu` | โœ“ | 32-bit Linux (kernel 3.2+, glibc 2.17, original Pentium) [^x86_32-floats-x87]
diff --git a/src/doc/rustc/src/platform-support/aarch64-unknown-none.md b/src/doc/rustc/src/platform-support/aarch64-unknown-none.md
new file mode 100644
index 00000000000..7e18e8c157f
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/aarch64-unknown-none.md
@@ -0,0 +1,78 @@
+# `aarch64-unknown-none` and `aarch64-unknown-none-softfloat`
+
+* **Tier: 2**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
+
+Bare-metal targets for CPUs in the Armv8-A architecture family, running in AArch64 mode.
+
+For the AArch32 mode carried over from Armv7-A, see
+[`armv7a-none-eabi`](armv7a-none-eabi.md) instead.
+
+Processors in this family include the [Arm Cortex-A35, 53, 76, etc][aarch64-cpus].
+
+[aarch64-cpus]: https://en.wikipedia.org/wiki/Comparison_of_ARM_processors#ARMv8-A
+
+## Target maintainers
+
+[Rust Embedded Devices Working Group Arm Team]
+
+[Rust Embedded Devices Working Group Arm Team]: https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team
+
+## Target CPU and Target Feature options
+
+All AArch64 processors include an FPU. The difference between the `-none` and
+`-none-softfloat` targets is whether the FPU is used for passing function arguments.
+You may prefer the `-softfloat` target when writing a kernel or interfacing with
+pre-compiled binaries that use the soft-float ABI.
+
+When using the hardfloat targets, the minimum floating-point features assumed
+are those of the `fp-armv8`, which excludes NEON SIMD support. If your
+processor supports a different set of floating-point features than the default
+expectations of `fp-armv8`, then these should also be enabled or disabled as
+needed with `-C target-feature=(+/-)`. It is also possible to tell Rust (or
+LLVM) that you have a specific model of Arm processor, using the
+[`-Ctarget-cpu`][target-cpu] option. Doing so may change the default set of
+target-features enabled.
+
+[target-cpu]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-cpu
+[target-feature]: https://doc.rust-lang.org/rustc/codegen-options/index.html#target-feature
+
+## Requirements
+
+These targets are cross-compiled and use static linking.
+
+By default, the `lld` linker included with Rust will be used; however, you may
+want to use the GNU linker instead. This can be obtained for Windows/Mac/Linux
+from the [Arm Developer Website][arm-gnu-toolchain], or possibly from your OS's
+package manager. To use it, add the following to your `.cargo/config.toml`:
+
+```toml
+[target.aarch64-unknown-none]
+linker = "aarch64-none-elf-ld"
+```
+
+The GNU linker can also be used by specifying `aarch64-none-elf-gcc` as the
+linker. This is needed when using GCC's link time optimization.
+
+These targets don't provide a linker script, so you'll need to bring your own
+according to the specific device you are using. Pass
+`-Clink-arg=-Tyour_script.ld` as a rustc argument to make the linker use
+`your_script.ld` during linking.
+
+[arm-gnu-toolchain]: https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain
+
+## Cross-compilation toolchains and C code
+
+This target supports C code compiled with the `aarch64-none-elf` target
+triple and a suitable `-march` or `-mcpu` flag.
+
+## Start-up and Low-Level Code
+
+The [Rust Embedded Devices Working Group Arm Team] maintain the
+[`aarch64-cpu`] crate, which may be useful for writing bare-metal code using
+this target.
+
+The *TrustedFirmware* group also maintain [Rust crates for this
+target](https://github.com/ArmFirmwareCrates).
+
+[`aarch64-cpu`]: https://docs.rs/aarch64-cpu
diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md
index 9732df4be7f..aaa80e42971 100644
--- a/src/doc/rustc/src/platform-support/arm-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md
@@ -12,10 +12,10 @@ their own document.
 ### Tier 2 Target List
 
 - Arm A-Profile Architectures
-  - `armv7a-none-eabi`
+  - [`armv7a-none-eabi`](armv7a-none-eabi.md)
 - Arm R-Profile Architectures
   - [`armv7r-none-eabi` and `armv7r-none-eabihf`](armv7r-none-eabi.md)
-  - [`armebv7r-none-eabi` and `armebv7r-none-eabihf`](armv7r-none-eabi.md)
+  - [`armebv7r-none-eabi` and `armebv7r-none-eabihf`](armebv7r-none-eabi.md)
 - Arm M-Profile Architectures
   - [`thumbv6m-none-eabi`](thumbv6m-none-eabi.md)
   - [`thumbv7m-none-eabi`](thumbv7m-none-eabi.md)
@@ -28,7 +28,7 @@ their own document.
 ### Tier 3 Target List
 
 - Arm A-Profile Architectures
-  - `armv7a-none-eabihf`
+  - [`armv7a-none-eabihf`](armv7a-none-eabi.md)
 - Arm R-Profile Architectures
   - [`armv8r-none-eabihf`](armv8r-none-eabihf.md)
 - Arm M-Profile Architectures
diff --git a/src/doc/rustc/src/platform-support/armebv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armebv7r-none-eabi.md
new file mode 100644
index 00000000000..3e90319c373
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armebv7r-none-eabi.md
@@ -0,0 +1,55 @@
+# `armebv7r-none-eabi` and `armebv7r-none-eabihf`
+
+* **Tier: 2**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
+
+Bare-metal target for CPUs in the Armv7-R architecture family running in Big
+Endian mode. These processors support dual ARM/Thumb mode, with ARM mode as
+the default.
+
+**NOTE:** You should almost always prefer the [little-endian
+versions](armv7r-none-eabi.md) of these target. Big Endian Arm systems are
+highly unusual.
+
+Processors in this family include the [Arm Cortex-R4, 5, 7, and 8][cortex-r].
+
+See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
+`arm-none-eabi` targets.
+
+[cortex-r]: https://en.wikipedia.org/wiki/ARM_Cortex-R
+
+## Target maintainers
+
+[@chrisnc](https://github.com/chrisnc)
+
+## Requirements
+
+Note that some variants of the Cortex-R have both big-endian instructions and
+data. This configuration is known as BE-32, while data-only big-endianness is
+known as BE-8. To build programs for BE-32 processors, the GNU linker must be
+used with the `-mbe32` option. See [ARM Cortex-R Series Programmer's Guide:
+Endianness][endianness] for more details about different endian modes.
+
+When using the hardfloat targets, the minimum floating-point features assumed
+are those of the `vfpv3-d16`, which includes single- and double-precision, with
+16 double-precision registers. This floating-point unit appears in Cortex-R4F
+and Cortex-R5F processors. See [VFP in the Cortex-R processors][vfp]
+for more details on the possible FPU variants.
+
+If your processor supports a different set of floating-point features than the
+default expectations of `vfpv3-d16`, then these should also be enabled or
+disabled as needed with `-C target-feature=(+/-)`.
+
+[endianness]: https://developer.arm.com/documentation/den0042/a/Coding-for-Cortex-R-Processors/Endianness
+
+[vfp]: https://developer.arm.com/documentation/den0042/a/Floating-Point/Floating-point-basics-and-the-IEEE-754-standard/VFP-in-the-Cortex-R-processors
+
+## Start-up and Low-Level Code
+
+The [Rust Embedded Devices Working Group Arm Team] maintain the [`cortex-ar`]
+and [`cortex-r-rt`] crates, which may be useful for writing bare-metal code
+using this target. Those crates include several examples which run in QEMU and
+build using these targets.
+
+[`cortex-ar`]: https://docs.rs/cortex-ar
+[`cortex-r-rt`]: https://docs.rs/cortex-r-rt
diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
index 56f919e2a12..c6d88762fb1 100644
--- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md
@@ -1,6 +1,7 @@
 # armv4t-none-eabi / thumbv4t-none-eabi
 
-Tier 3
+* **Tier:  3**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
 
 These two targets are part of the [`arm-none-eabi`](arm-none-eabi.md) target
 group, and all the information there applies.
diff --git a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md
index 22287972b7e..e9f34d4ede8 100644
--- a/src/doc/rustc/src/platform-support/armv5te-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/armv5te-none-eabi.md
@@ -1,6 +1,7 @@
 # `armv5te-none-eabi`
 
-**Tier: 3**
+* **Tier: 3**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
 
 Bare-metal target for any cpu in the Armv5TE architecture family, supporting
 ARM/Thumb code interworking (aka `A32`/`T32`), with `A32` code as the default code
diff --git a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md
new file mode 100644
index 00000000000..3dadda86a5f
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md
@@ -0,0 +1,70 @@
+# `armv7a-none-eabi` and `armv7a-none-eabihf`
+
+* **Tier: 2** for `armv7a-none-eabi`
+* **Tier: 3** for `armv7a-none-eabihf`
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
+
+Bare-metal target for CPUs in the Armv7-A architecture family, supporting
+dual ARM/Thumb mode, with ARM mode as the default.
+
+Note, this is for processors running in AArch32 mode. For the AArch64 mode
+added in Armv8-A, see [`aarch64-unknown-none`](aarch64-unknown-none.md) instead.
+
+Processors in this family include the [Arm Cortex-A5, 8, 32, etc][cortex-a].
+
+See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
+`arm-none-eabi` targets.
+
+[cortex-a]: https://en.wikipedia.org/wiki/ARM_Cortex-A
+
+## Target maintainers
+
+[Rust Embedded Devices Working Group Arm Team]
+
+[Rust Embedded Devices Working Group Arm Team]: https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team
+
+## Requirements
+
+Almost all Armv7-A processors include an FPU (a VFPv3 or a VFPv4). The
+difference between the `-eabi` and `-eabihf` targets is whether the FPU is
+used for passing function arguments. You may prefer the `-eabi` soft-float
+target when the processor does not have a floating point unit or the compiled
+code should not use the floating point unit.
+
+When using the hardfloat targets, the minimum floating-point features assumed
+are those of the VFPv3-D16, which includes single- and double-precision, with
+16 double-precision registers. This floating-point unit appears in Cortex-A8
+and Cortex-A9 processors. See [VFP in the Cortex-A processors][vfp] for more
+details on the possible FPU variants.
+
+If your processor supports a different set of floating-point features than the
+default expectations of VFPv3-D16, then these should also be enabled or
+disabled as needed with `-C target-feature=(+/-)`.
+
+In general, the following four combinations are possible:
+
+- VFPv3-D16, target feature `+vfp3` and `-d32`
+- VFPv3-D32, target feature `+vfp3` and `+d32`
+- VFPv4-D16, target feature `+vfp4` and `-d32`
+- VFPv4-D32, target feature `+vfp4` and `+d32`
+
+An Armv7-A processor may optionally include a NEON hardware unit which
+provides Single Instruction Multiple Data (SIMD) operations. The
+implementation of this unit implies VFPv3-D32. The target feature `+neon` may
+be added to inform the compiler about the availability of NEON.
+
+You can refer to the [arm-none-eabi](arm-none-eabi.md) documentation for a
+generic guide on target feature and target CPU specification and how to enable
+and disable them via `.cargo/config.toml` file.
+
+[vfp]: https://developer.arm.com/documentation/den0013/0400/Floating-Point/Floating-point-basics-and-the-IEEE-754-standard/ARM-VFP
+
+## Start-up and Low-Level Code
+
+The [Rust Embedded Devices Working Group Arm Team] maintain the [`cortex-ar`]
+and [`cortex-a-rt`] crates, which may be useful for writing bare-metal code
+using this target. The [`cortex-ar` repository](https://github.com/rust-embedded/cortex-ar)
+includes several examples which run in QEMU and build using these targets.
+
+[`cortex-ar`]: https://docs.rs/cortex-ar
+[`cortex-a-rt`]: https://docs.rs/cortex-a-rt
diff --git a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md
index 88b2689dcf0..c1252b4a4bf 100644
--- a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md
@@ -1,14 +1,13 @@
-# `arm(eb)?v7r-none-eabi(hf)?`
+# `armv7r-none-eabi` and `armv7r-none-eabihf`
 
-**Tier: 2**
+* **Tier: 2**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
 
 Bare-metal target for CPUs in the Armv7-R architecture family, supporting
 dual ARM/Thumb mode, with ARM mode as the default.
 
 Processors in this family include the [Arm Cortex-R4, 5, 7, and 8][cortex-r].
 
-The `eb` versions of this target generate code for big-endian processors.
-
 See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
 `arm-none-eabi` targets.
 
@@ -17,15 +16,11 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
 ## Target maintainers
 
 [@chrisnc](https://github.com/chrisnc)
+[Rust Embedded Devices Working Group Arm Team]
 
-## Requirements
+[Rust Embedded Devices Working Group Arm Team]: https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team
 
-When using the big-endian version of this target, note that some variants of
-the Cortex-R have both big-endian instructions and data. This configuration is
-known as BE-32, while data-only big-endianness is known as BE-8. To build
-programs for BE-32 processors, the GNU linker must be used with the `-mbe32`
-option. See [ARM Cortex-R Series Programmer's Guide: Endianness][endianness]
-for more details about different endian modes.
+## Requirements
 
 When using the hardfloat targets, the minimum floating-point features assumed
 are those of the `vfpv3-d16`, which includes single- and double-precision, with
@@ -41,7 +36,12 @@ disabled as needed with `-C target-feature=(+/-)`.
 
 [vfp]: https://developer.arm.com/documentation/den0042/a/Floating-Point/Floating-point-basics-and-the-IEEE-754-standard/VFP-in-the-Cortex-R-processors
 
-## Cross-compilation toolchains and C code
+## Start-up and Low-Level Code
+
+The [Rust Embedded Devices Working Group Arm Team] maintain the [`cortex-ar`]
+and [`cortex-r-rt`] crates, which may be useful for writing bare-metal code
+using this target. Those crates include several examples which run in QEMU and
+build using these targets.
 
-This target supports C code compiled with the `arm-none-eabi` target triple and
-`-march=armv7-r` or a suitable `-mcpu` flag.
+[`cortex-ar`]: https://docs.rs/cortex-ar
+[`cortex-r-rt`]: https://docs.rs/cortex-r-rt
diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
index 569d8802ebe..0d5a36c3ee2 100644
--- a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
+++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
@@ -1,6 +1,7 @@
 # `armv8r-none-eabihf`
 
-**Tier: 3**
+* **Tier: 3**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
 
 Bare-metal target for CPUs in the Armv8-R architecture family, supporting
 dual ARM/Thumb mode, with ARM mode as the default.
@@ -17,6 +18,9 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
 ## Target maintainers
 
 [@chrisnc](https://github.com/chrisnc)
+[Rust Embedded Devices Working Group Arm Team]
+
+[Rust Embedded Devices Working Group Arm Team]: https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team
 
 ## Requirements
 
@@ -34,7 +38,14 @@ Technical Reference Manual for more details.
 
 [fpu]: https://developer.arm.com/documentation/100026/0104/Advanced-SIMD-and-floating-point-support/About-the-Advanced-SIMD-and-floating-point-support
 
-## Cross-compilation toolchains and C code
-
-This target supports C code compiled with the `arm-none-eabi` target triple and
-`-march=armv8-r` or a suitable `-mcpu` flag.
+### Table of supported CPUs for `armv8r-none-eabihf`
+
+| CPU         | FPU | Neon | Target CPU       | Target Features    |
+|:----------- | --- |:---- |:---------------- |:------------------ |
+| Any         | SP  | No   | None             | None               |
+| Cortex-R52  | SP  | No   | `cortex-r52`     | `-fp64,-d32,-neon` |
+| Cortex-R52  | DP  | No   | `cortex-r52`     | `-neon`            |
+| Cortex-R52  | DP  | Yes  | `cortex-r52`     | None               |
+| Cortex-R52+ | SP  | No   | `cortex-r52plus` | `-fp64,-d32,-neon` |
+| Cortex-R52+ | DP  | No   | `cortex-r52plus` | `-neon`            |
+| Cortex-R52+ | DP  | Yes  | `cortex-r52plus` | None               |
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/doc/rustc/src/platform-support/thumbv6m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md
index 746b8443547..d4bd0b0945a 100644
--- a/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv6m-none-eabi.md
@@ -1,6 +1,7 @@
 # `thumbv6m-none-eabi`
 
-**Tier: 2**
+* **Tier: 2**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
 
 Bare-metal target for CPUs in the [Armv6-M] architecture family, supporting a
 subset of the [T32 ISA][t32-isa].
@@ -26,7 +27,7 @@ only option because there is no FPU support in [Armv6-M].
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
+[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
index 12e28265678..98dcf9bd396 100644
--- a/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv7em-none-eabi.md
@@ -1,6 +1,7 @@
 # `thumbv7em-none-eabi` and `thumbv7em-none-eabihf`
 
-**Tier: 2**
+* **Tier: 2**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
 
 Bare-metal target for CPUs in the [Armv7E-M] architecture family, supporting a
 subset of the [T32 ISA][t32-isa].
@@ -21,7 +22,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
+[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md
index 03324b341d0..d8f3970c8bf 100644
--- a/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv7m-none-eabi.md
@@ -1,6 +1,7 @@
 # `thumbv7m-none-eabi`
 
-**Tier: 2**
+* **Tier: 2**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
 
 Bare-metal target for CPUs in the [Armv7-M] architecture family, supporting a
 subset of the [T32 ISA][t32-isa].
@@ -22,7 +23,7 @@ only option because there is no FPU support in [Armv7-M].
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
+[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md
index 4a92e856466..b16d450275d 100644
--- a/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv8m.base-none-eabi.md
@@ -1,6 +1,7 @@
 # `thumbv8m.base-none-eabi`
 
-**Tier: 2**
+* **Tier: 2**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
 
 Bare-metal target for CPUs in the Baseline [Armv8-M] architecture family,
 supporting a subset of the [T32 ISA][t32-isa].
@@ -22,7 +23,7 @@ only option because there is no FPU support in [Armv8-M] Baseline.
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
+[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
index 9f85d08fa0a..a2d515d07ea 100644
--- a/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/thumbv8m.main-none-eabi.md
@@ -1,6 +1,7 @@
 # `thumbv8m.main-none-eabi` and `thumbv8m.main-none-eabihf`
 
-**Tier: 2**
+* **Tier: 2**
+* **Library Support:** core and alloc (bare-metal, `#![no_std]`)
 
 Bare-metal target for CPUs in the Mainline [Armv8-M] architecture family,
 supporting a subset of the [T32 ISA][t32-isa].
@@ -25,7 +26,7 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
 
 ## Target maintainers
 
-* [Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
+[Rust Embedded Devices Working Group Arm Team](https://github.com/rust-embedded/wg?tab=readme-ov-file#the-arm-team)
 
 ## Target CPU and Target Feature options
 
diff --git a/src/doc/rustc/src/targets/custom.md b/src/doc/rustc/src/targets/custom.md
index 6c1494186a4..e1750e27f0b 100644
--- a/src/doc/rustc/src/targets/custom.md
+++ b/src/doc/rustc/src/targets/custom.md
@@ -16,6 +16,21 @@ rustc +nightly -Z unstable-options --target=wasm32-unknown-unknown --print targe
 
 To use a custom target, see the (unstable) [`build-std` feature](../../cargo/reference/unstable.html#build-std) of `cargo`.
 
+<div class="warning">
+
+The target JSON properties are not stable and subject to change.
+Always pin your compiler version when using custom targets!
+
+</div>
+
+## JSON Schema
+
+`rustc` provides a JSON schema for the custom target JSON specification.
+Because the schema is subject to change, you should always use the schema from the version of rustc which you are passing the target to.
+
+It can be found in `etc/target-spec-json-schema.json` in the sysroot (`rustc --print sysroot`) or printed with `rustc +nightly -Zunstable-options --print target-spec-json-schema`.
+The existence and name of this schema is, just like the properties of the JSON specification, not stable and subject to change.
+
 ## Custom Target Lookup Path
 
 When `rustc` is given an option `--target=TARGET` (where `TARGET` is any string), it uses the following logic:
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 93932936a2e..5ccacafea01 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1256,7 +1256,10 @@ pub(crate) fn clean_impl_item<'tcx>(
             })),
             hir::ImplItemKind::Fn(ref sig, body) => {
                 let m = clean_function(cx, sig, impl_.generics, ParamsSrc::Body(body));
-                let defaultness = cx.tcx.defaultness(impl_.owner_id);
+                let defaultness = match impl_.impl_kind {
+                    hir::ImplItemImplKind::Inherent { .. } => hir::Defaultness::Final,
+                    hir::ImplItemImplKind::Trait { defaultness, .. } => defaultness,
+                };
                 MethodItem(m, Some(defaultness))
             }
             hir::ImplItemKind::Type(hir_ty) => {
@@ -1295,12 +1298,14 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
             simplify::move_bounds_to_generic_parameters(&mut generics);
 
             match assoc_item.container {
-                ty::AssocItemContainer::Impl => ImplAssocConstItem(Box::new(Constant {
-                    generics,
-                    kind: ConstantKind::Extern { def_id: assoc_item.def_id },
-                    type_: ty,
-                })),
-                ty::AssocItemContainer::Trait => {
+                ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
+                    ImplAssocConstItem(Box::new(Constant {
+                        generics,
+                        kind: ConstantKind::Extern { def_id: assoc_item.def_id },
+                        type_: ty,
+                    }))
+                }
+                ty::AssocContainer::Trait => {
                     if tcx.defaultness(assoc_item.def_id).has_value() {
                         ProvidedAssocConstItem(Box::new(Constant {
                             generics,
@@ -1318,10 +1323,10 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
 
             if has_self {
                 let self_ty = match assoc_item.container {
-                    ty::AssocItemContainer::Impl => {
+                    ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {
                         tcx.type_of(assoc_item.container_id(tcx)).instantiate_identity()
                     }
-                    ty::AssocItemContainer::Trait => tcx.types.self_param,
+                    ty::AssocContainer::Trait => tcx.types.self_param,
                 };
                 let self_param_ty =
                     tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder();
@@ -1338,13 +1343,13 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
             }
 
             let provided = match assoc_item.container {
-                ty::AssocItemContainer::Impl => true,
-                ty::AssocItemContainer::Trait => assoc_item.defaultness(tcx).has_value(),
+                ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true,
+                ty::AssocContainer::Trait => assoc_item.defaultness(tcx).has_value(),
             };
             if provided {
                 let defaultness = match assoc_item.container {
-                    ty::AssocItemContainer::Impl => Some(assoc_item.defaultness(tcx)),
-                    ty::AssocItemContainer::Trait => None,
+                    ty::AssocContainer::TraitImpl(_) => Some(assoc_item.defaultness(tcx)),
+                    ty::AssocContainer::InherentImpl | ty::AssocContainer::Trait => None,
                 };
                 MethodItem(item, defaultness)
             } else {
@@ -1375,7 +1380,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
             }
 
             let mut predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates;
-            if let ty::AssocItemContainer::Trait = assoc_item.container {
+            if let ty::AssocContainer::Trait = assoc_item.container {
                 let bounds = tcx.explicit_item_bounds(assoc_item.def_id).iter_identity_copied();
                 predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied()));
             }
@@ -1386,7 +1391,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
             );
             simplify::move_bounds_to_generic_parameters(&mut generics);
 
-            if let ty::AssocItemContainer::Trait = assoc_item.container {
+            if let ty::AssocContainer::Trait = assoc_item.container {
                 // Move bounds that are (likely) directly attached to the associated type
                 // from the where-clause to the associated type.
                 // There is no guarantee that this is what the user actually wrote but we have
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index dcd67cb7ebc..bd3f4e9a6f2 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -690,16 +690,13 @@ impl Item {
                 // rustc's `is_const_fn` returns `true` for associated functions that have an `impl const` parent
                 // or that have a `const trait` parent. Do not display those as `const` in rustdoc because we
                 // won't be printing correct syntax plus the syntax is unstable.
-                match tcx.opt_associated_item(def_id) {
-                    Some(ty::AssocItem {
-                        container: ty::AssocItemContainer::Impl,
-                        trait_item_def_id: Some(_),
-                        ..
-                    })
-                    | Some(ty::AssocItem { container: ty::AssocItemContainer::Trait, .. }) => {
-                        hir::Constness::NotConst
-                    }
-                    None | Some(_) => hir::Constness::Const,
+                if let Some(assoc) = tcx.opt_associated_item(def_id)
+                    && let ty::AssocContainer::Trait | ty::AssocContainer::TraitImpl(_) =
+                        assoc.container
+                {
+                    hir::Constness::NotConst
+                } else {
+                    hir::Constness::Const
                 }
             } else {
                 hir::Constness::NotConst
@@ -779,17 +776,13 @@ impl Item {
             | RequiredAssocTypeItem(..)
             | RequiredMethodItem(..)
             | MethodItem(..) => {
-                let assoc_item = tcx.associated_item(def_id);
-                let is_trait_item = match assoc_item.container {
-                    ty::AssocItemContainer::Trait => true,
-                    ty::AssocItemContainer::Impl => {
-                        // Trait impl items always inherit the impl's visibility --
-                        // we don't want to show `pub`.
-                        tcx.impl_trait_ref(tcx.parent(assoc_item.def_id)).is_some()
+                match tcx.associated_item(def_id).container {
+                    // Trait impl items always inherit the impl's visibility --
+                    // we don't want to show `pub`.
+                    ty::AssocContainer::Trait | ty::AssocContainer::TraitImpl(_) => {
+                        return None;
                     }
-                };
-                if is_trait_item {
-                    return None;
+                    ty::AssocContainer::InherentImpl => {}
                 }
             }
             _ => {}
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index b01b596da68..3b84ae2bed0 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -3639,7 +3639,7 @@ class DocSearch {
             if (contains.length === 0) {
                 return 0;
             }
-            const maxPathEditDistance = Math.floor(
+            const maxPathEditDistance = parsedQuery.literalSearch ? 0 : Math.floor(
                 contains.reduce((acc, next) => acc + next.length, 0) / 3,
             );
             let ret_dist = maxPathEditDistance + 1;
@@ -3650,7 +3650,9 @@ class DocSearch {
                 let dist_total = 0;
                 for (let x = 0; x < clength; ++x) {
                     const [p, c] = [path[i + x], contains[x]];
-                    if (Math.floor((p.length - c.length) / 3) <= maxPathEditDistance &&
+                    if (parsedQuery.literalSearch && p !== c) {
+                        continue pathiter;
+                    } else if (Math.floor((p.length - c.length) / 3) <= maxPathEditDistance &&
                         p.indexOf(c) !== -1
                     ) {
                         // discount distance on substring match
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 719b7c6ab89..0da42f38251 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -210,7 +210,7 @@ impl UrlFragment {
             &UrlFragment::Item(def_id) => {
                 let kind = match tcx.def_kind(def_id) {
                     DefKind::AssocFn => {
-                        if tcx.defaultness(def_id).has_value() {
+                        if tcx.associated_item(def_id).defaultness(tcx).has_value() {
                             "method."
                         } else {
                             "tymethod."
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/llvm-project b/src/llvm-project
-Subproject 19f0a49c5c3f4ba88b5e7ac620b9a0d8574c09c
+Subproject 333793696b0a08002acac6af983adc7a5233fc5
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 761c4658d0079d607e6d33cf0c060e61a617cad
+Subproject 24bb93c388fb8c211a37986539f24a819dc669d
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
index 23e7c7251cf..49cd2671dc0 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
@@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefIdMap;
 use rustc_hir::{
-    AmbigArg, Expr, ExprKind, ForeignItem, HirId, ImplItem, Item, ItemKind, OwnerId, Pat, Path, Stmt, TraitItem, Ty,
+    AmbigArg, Expr, ExprKind, ForeignItem, HirId, ImplItem, ImplItemImplKind, Item, ItemKind, OwnerId, Pat, Path, Stmt, TraitItem, Ty,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TyCtxt;
@@ -177,7 +177,9 @@ impl LateLintPass<'_> for DisallowedMacros {
 
     fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &ImplItem<'_>) {
         self.check(cx, item.span, None);
-        self.check(cx, item.vis_span, None);
+        if let ImplItemImplKind::Inherent { vis_span, .. } = item.impl_kind {
+            self.check(cx, vis_span, None);
+        }
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
index f8e8f5544b9..e25611d4881 100644
--- a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_errors::{Applicability, MultiSpan};
-use rustc_hir::def_id::{DefId, DefIdSet};
-use rustc_hir::hir_id::OwnerId;
+use rustc_hir::def_id::DefIdSet;
 use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node, TraitRef};
 use rustc_lint::LateContext;
 use rustc_span::Span;
@@ -19,7 +18,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored
             of_trait: Some(of_trait),
             ..
         }) = &parent_item.kind
-        && let Some(did) = trait_item_def_id_of_impl(cx, item.owner_id)
+        && let Some(did) = cx.tcx.trait_item_of(item.owner_id)
         && !is_from_ignored_trait(&of_trait.trait_ref, ignored_traits)
     {
         let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id);
@@ -87,11 +86,6 @@ impl RenamedFnArgs {
     }
 }
 
-/// Get the [`trait_item_def_id`](ImplItemRef::trait_item_def_id) of a relevant impl item.
-fn trait_item_def_id_of_impl(cx: &LateContext<'_>, target: OwnerId) -> Option<DefId> {
-    cx.tcx.associated_item(target).trait_item_def_id
-}
-
 fn is_from_ignored_trait(of_trait: &TraitRef<'_>, ignored_traits: &DefIdSet) -> bool {
     of_trait
         .trait_def_id()
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index ba1ad599e11..bee3b19b597 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -4,7 +4,7 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
-    FnRetTy, GenericBound, ImplItem, Item, Node, OpaqueTy, TraitRef, Ty, TyKind,
+    FnRetTy, GenericBound, Node, OpaqueTy, TraitRef, Ty, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
@@ -60,8 +60,11 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
             && let ExprKind::Block(block, _) = body.value.kind
             && block.stmts.is_empty()
             && let Some(closure_body) = desugared_async_block(cx, block)
-            && let Node::Item(Item {vis_span, ..}) | Node::ImplItem(ImplItem {vis_span, ..}) =
-                cx.tcx.hir_node_by_def_id(fn_def_id)
+            && let Some(vis_span_opt) = match cx.tcx.hir_node_by_def_id(fn_def_id) {
+                Node::Item(item) => Some(Some(item.vis_span)),
+                Node::ImplItem(impl_item) => Some(impl_item.vis_span()),
+                _ => None,
+            }
             && !span.from_expansion()
         {
             let header_span = span.with_hi(ret_ty.span.hi());
@@ -72,7 +75,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
                 header_span,
                 "this function can be simplified using the `async fn` syntax",
                 |diag| {
-                    if let Some(vis_snip) = vis_span.get_source_text(cx)
+                    if let Some(vis_span) = vis_span_opt
+                        && let Some(vis_snip) = vis_span.get_source_text(cx)
                         && let Some(header_snip) = header_span.get_source_text(cx)
                         && let Some(ret_pos) = position_before_rarrow(&header_snip)
                         && let Some((_, ret_snip)) = suggested_ret(cx, output)
diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
index dbce29a8631..6258e408217 100644
--- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
@@ -5,8 +5,8 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{Visitor, walk_item, walk_trait_item};
 use rustc_hir::{
-    GenericParamKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, TraitItem,
-    UsePath,
+    GenericParamKind, HirId, Impl, ImplItem, ImplItemImplKind, ImplItemKind, Item, ItemKind, ItemLocalId, Node, Pat,
+    PatKind, TraitItem, UsePath,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
@@ -256,7 +256,7 @@ fn is_not_in_trait_impl(cx: &LateContext<'_>, pat: &Pat<'_>, ident: Ident) -> bo
 }
 
 fn get_param_name(impl_item: &ImplItem<'_>, cx: &LateContext<'_>, ident: Ident) -> Option<Symbol> {
-    if let Some(trait_item_def_id) = impl_item.trait_item_def_id {
+    if let ImplItemImplKind::Trait { trait_item_def_id: Ok(trait_item_def_id), .. } = impl_item.impl_kind {
         let trait_param_names = cx.tcx.fn_arg_idents(trait_item_def_id);
 
         let ImplItemKind::Fn(_, body_id) = impl_item.kind else {
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/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index a6be7581c9a..a63ad978626 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -158,13 +158,23 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
         let mir = cx.tcx.optimized_mir(def_id);
 
         if let Ok(()) = is_min_const_fn(cx, mir, self.msrv)
-            && let hir::Node::Item(hir::Item { vis_span, .. }) | hir::Node::ImplItem(hir::ImplItem { vis_span, .. }) =
-                cx.tcx.hir_node_by_def_id(def_id)
+            && let node = cx.tcx.hir_node_by_def_id(def_id)
+            && let Some((item_span, vis_span_opt)) = match node {
+                hir::Node::Item(item) => Some((item.span, Some(item.vis_span))),
+                hir::Node::ImplItem(impl_item) => Some((impl_item.span, impl_item.vis_span())),
+                _ => None,
+            }
         {
-            let suggestion = if vis_span.is_empty() { "const " } else { " const" };
+            let (sugg_span, suggestion) = if let Some(vis_span) = vis_span_opt
+                && !vis_span.is_empty()
+            {
+                (vis_span.shrink_to_hi(), " const")
+            } else {
+                (item_span.shrink_to_lo(), "const ")
+            };
             span_lint_and_then(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`", |diag| {
                 diag.span_suggestion_verbose(
-                    vis_span.shrink_to_hi(),
+                    sugg_span,
                     "make the function `const`",
                     suggestion,
                     Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 7772051eb5c..39b5964bd87 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -16,7 +16,7 @@ use rustc_hir::Attribute;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty::Visibility;
+use rustc_middle::ty::{AssocContainer, Visibility};
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::CRATE_DEF_ID;
 use rustc_span::symbol::kw;
@@ -246,12 +246,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
         // If the method is an impl for a trait, don't doc.
-        if let Some(cid) = cx.tcx.associated_item(impl_item.owner_id).impl_container(cx.tcx) {
-            if cx.tcx.impl_trait_ref(cid).is_some() {
+        match cx.tcx.associated_item(impl_item.owner_id).container {
+            AssocContainer::Trait | AssocContainer::TraitImpl(_) => {
                 note_prev_span_then_ret!(self.prev_span, impl_item.span);
-            }
-        } else {
-            note_prev_span_then_ret!(self.prev_span, impl_item.span);
+            },
+            AssocContainer::InherentImpl => {}
         }
 
         let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id());
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index 28555a61090..6323e728666 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -3,7 +3,7 @@ use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, Attribute, find_attr};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty::AssocItemContainer;
+use rustc_middle::ty::AssocContainer;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 
@@ -166,8 +166,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
         let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
         let container_id = assoc_item.container_id(cx.tcx);
         let trait_def_id = match assoc_item.container {
-            AssocItemContainer::Trait => Some(container_id),
-            AssocItemContainer::Impl => cx.tcx.impl_trait_ref(container_id).map(|t| t.skip_binder().def_id),
+            AssocContainer::Trait => Some(container_id),
+            AssocContainer::TraitImpl(_) => cx.tcx.impl_trait_ref(container_id).map(|t| t.skip_binder().def_id),
+            AssocContainer::InherentImpl => None,
         };
 
         if let Some(trait_def_id) = trait_def_id
diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
index 9cc93bf0653..8e9400e9d58 100644
--- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
@@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
                 .tcx
                 .associated_items(item.owner_id)
                 .in_definition_order()
-                .filter_map(|assoc_item| assoc_item.trait_item_def_id)
+                .filter_map(|assoc_item| assoc_item.expect_trait_impl().ok())
                 .collect();
 
             for assoc in cx
diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
index 809a6728e12..c4cad592e36 100644
--- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
@@ -248,7 +248,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
                         .tcx
                         .impl_trait_ref(item.owner_id)
                         .map(EarlyBinder::instantiate_identity)
-                    && let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id
+                    && let Some(trait_item_id) = cx.tcx.trait_item_of(owner_id)
                 {
                     (
                         trait_item_id,
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index aeda864b7eb..8252e6d4869 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -151,8 +151,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             // trait, not in the impl of the trait.
             let trait_method = cx
                 .tcx
-                .associated_item(impl_item.owner_id)
-                .trait_item_def_id
+                .trait_item_of(impl_item.owner_id)
                 .expect("impl method matches a trait method");
             let trait_method_sig = cx.tcx.fn_sig(trait_method).instantiate_identity();
             let trait_method_sig = cx.tcx.instantiate_bound_regions_with_erased(trait_method_sig);
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index c4a759e919b..1a25c90d735 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -19,7 +19,7 @@ use rustc_ast::token::CommentKind;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, FnRetTy, HirId, Impl,
-    ImplItem, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource, MatchSource, MutTy, Node, Path, QPath, Safety,
+    ImplItem, ImplItemImplKind, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource, MatchSource, MutTy, Node, Path, QPath, Safety,
     TraitImplHeader, TraitItem, TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource,
 };
 use rustc_lint::{EarlyContext, LateContext, LintContext};
@@ -280,16 +280,17 @@ fn trait_item_search_pat(item: &TraitItem<'_>) -> (Pat, Pat) {
 }
 
 fn impl_item_search_pat(item: &ImplItem<'_>) -> (Pat, Pat) {
-    let (start_pat, end_pat) = match &item.kind {
+    let (mut start_pat, end_pat) = match &item.kind {
         ImplItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
         ImplItemKind::Type(..) => (Pat::Str("type"), Pat::Str(";")),
         ImplItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
     };
-    if item.vis_span.is_empty() {
-        (start_pat, end_pat)
-    } else {
-        (Pat::Str("pub"), end_pat)
-    }
+    if let ImplItemImplKind::Inherent { vis_span, .. } = item.impl_kind
+        && !vis_span.is_empty()
+    {
+        start_pat = Pat::Str("pub");
+    };
+    (start_pat, end_pat)
 }
 
 fn field_def_search_pat(def: &FieldDef<'_>) -> (Pat, Pat) {
@@ -313,21 +314,20 @@ fn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) {
 }
 
 fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirId) -> (Pat, Pat) {
-    let (start_pat, end_pat) = match kind {
+    let (mut start_pat, end_pat) = match kind {
         FnKind::ItemFn(.., header) => (fn_header_search_pat(*header), Pat::Str("")),
         FnKind::Method(.., sig) => (fn_header_search_pat(sig.header), Pat::Str("")),
         FnKind::Closure => return (Pat::Str(""), expr_search_pat(tcx, body.value).1),
     };
-    let start_pat = match tcx.hir_node(hir_id) {
-        Node::Item(Item { vis_span, .. }) | Node::ImplItem(ImplItem { vis_span, .. }) => {
-            if vis_span.is_empty() {
-                start_pat
-            } else {
-                Pat::Str("pub")
+    match tcx.hir_node(hir_id) {
+        Node::Item(Item { vis_span, .. })
+        | Node::ImplItem(ImplItem { impl_kind: ImplItemImplKind::Inherent { vis_span, .. }, .. }) => {
+            if !vis_span.is_empty() {
+                start_pat = Pat::Str("pub")
             }
         },
-        Node::TraitItem(_) => start_pat,
-        _ => Pat::Str(""),
+        Node::ImplItem(_) | Node::TraitItem(_) => {},
+        _ => start_pat = Pat::Str(""),
     };
     (start_pat, end_pat)
 }
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 14b64eb4d54..120ab2e717d 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -2133,17 +2133,11 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {
 }
 
 pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
-    cx.tcx
-        .hir_attrs(hir::CRATE_HIR_ID)
-        .iter()
-        .any(|attr| attr.has_name(sym::no_std))
+    find_attr!(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), AttributeKind::NoStd(..))
 }
 
 pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
-    cx.tcx
-        .hir_attrs(hir::CRATE_HIR_ID)
-        .iter()
-        .any(|attr| attr.has_name(sym::no_core))
+    find_attr!(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), AttributeKind::NoCore(..))
 }
 
 /// Check if parent of a hir node is a trait implementation block.
@@ -3250,8 +3244,8 @@ pub fn get_path_from_caller_to_method_type<'tcx>(
     let assoc_item = tcx.associated_item(method);
     let def_id = assoc_item.container_id(tcx);
     match assoc_item.container {
-        rustc_ty::AssocItemContainer::Trait => get_path_to_callee(tcx, from, def_id),
-        rustc_ty::AssocItemContainer::Impl => {
+        rustc_ty::AssocContainer::Trait => get_path_to_callee(tcx, from, def_id),
+        rustc_ty::AssocContainer::InherentImpl | rustc_ty::AssocContainer::TraitImpl(_) => {
             let ty = tcx.type_of(def_id).instantiate_identity();
             get_path_to_ty(tcx, from, ty, args)
         },
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/miri/tests/pass/btreemap.rs b/src/tools/miri/tests/pass/btreemap.rs
index 1d65e69bf72..7af6d7b5551 100644
--- a/src/tools/miri/tests/pass/btreemap.rs
+++ b/src/tools/miri/tests/pass/btreemap.rs
@@ -1,7 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
 //@compile-flags: -Zmiri-strict-provenance
-#![feature(btree_extract_if)]
 use std::collections::{BTreeMap, BTreeSet};
 use std::mem;
 
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 60347b2ea64..a9804761400 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -267,6 +267,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "digest",
     "displaydoc",
     "dissimilar",
+    "dyn-clone",
     "either",
     "elsa",
     "ena",
@@ -346,6 +347,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "rand_xorshift", // dependency for doc-tests in rustc_thread_pool
     "rand_xoshiro",
     "redox_syscall",
+    "ref-cast",
+    "ref-cast-impl",
     "regex",
     "regex-automata",
     "regex-syntax",
@@ -357,11 +360,14 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "rustix",
     "ruzstd", // via object in thorin-dwp
     "ryu",
+    "schemars",
+    "schemars_derive",
     "scoped-tls",
     "scopeguard",
     "self_cell",
     "serde",
     "serde_derive",
+    "serde_derive_internals",
     "serde_json",
     "serde_path_to_error",
     "sha1",
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/src/tools/tidy/src/fluent_lowercase.rs b/src/tools/tidy/src/fluent_lowercase.rs
new file mode 100644
index 00000000000..13f0319909e
--- /dev/null
+++ b/src/tools/tidy/src/fluent_lowercase.rs
@@ -0,0 +1,64 @@
+//! Checks that the error messages start with a lowercased letter (except when allowed to).
+
+use std::path::Path;
+
+use fluent_syntax::ast::{Entry, Message, PatternElement};
+
+use crate::walk::{filter_dirs, walk};
+
+#[rustfmt::skip]
+const ALLOWED_CAPITALIZED_WORDS: &[&str] = &[
+    // tidy-alphabetical-start
+    "ABI",
+    "ABIs",
+    "ADT",
+    "C",
+    "CGU",
+    "Ferris",
+    "MIR",
+    "OK",
+    "Rust",
+    "VS", // VS Code
+    // tidy-alphabetical-end
+];
+
+fn filter_fluent(path: &Path) -> bool {
+    if let Some(ext) = path.extension() { ext.to_str() != Some("ftl") } else { true }
+}
+
+fn is_allowed_capitalized_word(msg: &str) -> bool {
+    ALLOWED_CAPITALIZED_WORDS.iter().any(|word| {
+        msg.strip_prefix(word)
+            .map(|tail| tail.chars().next().map(|c| c == '-' || c.is_whitespace()).unwrap_or(true))
+            .unwrap_or_default()
+    })
+}
+
+fn check_lowercase(filename: &str, contents: &str, bad: &mut bool) {
+    let (Ok(parse) | Err((parse, _))) = fluent_syntax::parser::parse(contents);
+
+    for entry in &parse.body {
+        if let Entry::Message(msg) = entry
+            && let Message { value: Some(pattern), .. } = msg
+            && let [first_pattern, ..] = &pattern.elements[..]
+            && let PatternElement::TextElement { value } = first_pattern
+            && value.chars().next().is_some_and(char::is_uppercase)
+            && !is_allowed_capitalized_word(value)
+        {
+            tidy_error!(
+                bad,
+                "{filename}: message `{value}` starts with an uppercase letter. Fix it or add it to `ALLOWED_CAPITALIZED_WORDS`"
+            );
+        }
+    }
+}
+
+pub fn check(path: &Path, bad: &mut bool) {
+    walk(
+        path,
+        |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)),
+        &mut |ent, contents| {
+            check_lowercase(ent.path().to_str().unwrap(), contents, bad);
+        },
+    );
+}
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 37713cbf75e..2a9c3963d2d 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -257,6 +257,7 @@ pub mod extra_checks;
 pub mod features;
 pub mod filenames;
 pub mod fluent_alphabetical;
+pub mod fluent_lowercase;
 pub mod fluent_period;
 mod fluent_used;
 pub mod gcc_submodule;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index bfe30258915..f9e82341b7a 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -121,6 +121,7 @@ fn main() {
         check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose, &ci_info);
         check!(fluent_alphabetical, &compiler_path, bless);
         check!(fluent_period, &compiler_path);
+        check!(fluent_lowercase, &compiler_path);
         check!(target_policy, &root_path);
         check!(gcc_submodule, &root_path, &compiler_path);
 
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/run-make/print-request-help-stable-unstable/help-diff.diff b/tests/run-make/print-request-help-stable-unstable/help-diff.diff
index 07eafca3271..044302a19a0 100644
--- a/tests/run-make/print-request-help-stable-unstable/help-diff.diff
+++ b/tests/run-make/print-request-help-stable-unstable/help-diff.diff
@@ -2,6 +2,6 @@
  error: unknown print request: `xxx`
    |
 -  = help: valid print requests are: `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `tls-models`
-+  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
++  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
    = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
  
diff --git a/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err b/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err
index 50ef340e3dd..cc6c3c909b3 100644
--- a/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err
+++ b/tests/run-make/print-request-help-stable-unstable/unstable-invalid-print-request-help.err
@@ -1,5 +1,5 @@
 error: unknown print request: `xxx`
   |
-  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
+  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
   = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
 
diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout
index 3fc297fb08e..cd161c51ee3 100644
--- a/tests/run-make/rustc-help/help-v.stdout
+++ b/tests/run-make/rustc-help/help-v.stdout
@@ -43,7 +43,7 @@ Options:
         --print <INFO>[=<FILE>]
                         Compiler information to print on stdout (or to a file)
                         INFO may be one of
-                        <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models>.
+                        <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
     -g                  Equivalent to -C debuginfo=2
     -O                  Equivalent to -C opt-level=3
     -o <FILENAME>       Write output to FILENAME
diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout
index caffe28f498..74ec083bdee 100644
--- a/tests/run-make/rustc-help/help.stdout
+++ b/tests/run-make/rustc-help/help.stdout
@@ -43,7 +43,7 @@ Options:
         --print <INFO>[=<FILE>]
                         Compiler information to print on stdout (or to a file)
                         INFO may be one of
-                        <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models>.
+                        <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
     -g                  Equivalent to -C debuginfo=2
     -O                  Equivalent to -C opt-level=3
     -o <FILENAME>       Write output to FILENAME
diff --git a/tests/rustdoc-js/literal-path.js b/tests/rustdoc-js/literal-path.js
new file mode 100644
index 00000000000..ea999ea1a6f
--- /dev/null
+++ b/tests/rustdoc-js/literal-path.js
@@ -0,0 +1,23 @@
+// exact-check
+
+// This test ensures that literal search is always applied on elements of the path.
+
+const EXPECTED = [
+    {
+        'query': '"some::path"',
+        'others': [
+            { 'path': 'literal_path::some', 'name': 'Path' },
+        ],
+    },
+    {
+        'query': '"somea::path"',
+        'others': [
+            { 'path': 'literal_path::somea', 'name': 'Path' },
+        ],
+    },
+    {
+        'query': '"soma::path"',
+        'others': [
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/literal-path.rs b/tests/rustdoc-js/literal-path.rs
new file mode 100644
index 00000000000..fa7685fd966
--- /dev/null
+++ b/tests/rustdoc-js/literal-path.rs
@@ -0,0 +1,7 @@
+pub mod some {
+    pub struct Path;
+}
+
+pub mod somea {
+    pub struct Path;
+}
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/issues/issue-56806.rs b/tests/ui/abi/invalid-self-parameter-type-56806.rs
index b1dac26d65a..60229df3005 100644
--- a/tests/ui/issues/issue-56806.rs
+++ b/tests/ui/abi/invalid-self-parameter-type-56806.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/56806
 pub trait Trait {
     fn dyn_instead_of_self(self: Box<dyn Trait>);
     //~^ ERROR invalid `self` parameter type
diff --git a/tests/ui/issues/issue-56806.stderr b/tests/ui/abi/invalid-self-parameter-type-56806.stderr
index ec50d863758..ac249b8f108 100644
--- a/tests/ui/issues/issue-56806.stderr
+++ b/tests/ui/abi/invalid-self-parameter-type-56806.stderr
@@ -1,5 +1,5 @@
 error[E0307]: invalid `self` parameter type: `Box<(dyn Trait + 'static)>`
-  --> $DIR/issue-56806.rs:2:34
+  --> $DIR/invalid-self-parameter-type-56806.rs:3:34
    |
 LL |     fn dyn_instead_of_self(self: Box<dyn Trait>);
    |                                  ^^^^^^^^^^^^^^
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/issues/issue-56870.rs b/tests/ui/associated-consts/traits-associated-consts-ice-56870.rs
index fc6deedd029..0c5a2b84773 100644
--- a/tests/ui/issues/issue-56870.rs
+++ b/tests/ui/associated-consts/traits-associated-consts-ice-56870.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/56870
 //@ build-pass
 // Regression test for #56870: Internal compiler error (traits & associated consts)
 
diff --git a/tests/ui/issues/issue-59326.rs b/tests/ui/associated-types/duplicate-associated-type-resolution-59326.rs
index e9634ad9fd8..0439e229e14 100644
--- a/tests/ui/issues/issue-59326.rs
+++ b/tests/ui/associated-types/duplicate-associated-type-resolution-59326.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/59326
 //@ check-pass
 trait Service {
     type S;
diff --git a/tests/ui/issues/issue-57399-self-return-impl-trait.rs b/tests/ui/associated-types/impl-trait-member-type-resolution-57399.rs
index bcf1b18a9ff..3342dd0631a 100644
--- a/tests/ui/issues/issue-57399-self-return-impl-trait.rs
+++ b/tests/ui/associated-types/impl-trait-member-type-resolution-57399.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/57399
 //@ check-pass
 
 trait T {
@@ -12,7 +13,6 @@ struct S<A> {
     a: A,
 }
 
-
 impl From<u32> for S<<i32 as T>::T> {
     fn from(a: u32) -> Self {
         Self { a }
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/async-await/future-sizes/async-awaiting-fut.rs b/tests/ui/async-await/future-sizes/async-awaiting-fut.rs
index b5f59069f85..7113f591630 100644
--- a/tests/ui/async-await/future-sizes/async-awaiting-fut.rs
+++ b/tests/ui/async-await/future-sizes/async-awaiting-fut.rs
@@ -1,3 +1,5 @@
+// FIXME(#61117): Respect debuginfo-level-tests, do not force debuginfo=0
+//@ compile-flags: -C debuginfo=0
 //@ compile-flags: -C panic=abort -Z print-type-sizes --crate-type lib
 //@ needs-deterministic-layouts
 //@ edition:2021
diff --git a/tests/ui/async-await/future-sizes/large-arg.rs b/tests/ui/async-await/future-sizes/large-arg.rs
index 809f7cf1f93..b05a2b71915 100644
--- a/tests/ui/async-await/future-sizes/large-arg.rs
+++ b/tests/ui/async-await/future-sizes/large-arg.rs
@@ -1,3 +1,5 @@
+// FIXME(#61117): Respect debuginfo-level-tests, do not force debuginfo=0
+//@ compile-flags: -C debuginfo=0
 //@ compile-flags: -C panic=abort -Z print-type-sizes --crate-type=lib
 //@ needs-deterministic-layouts
 //@ edition: 2021
diff --git a/tests/ui/attributes/malformed-no-std.rs b/tests/ui/attributes/malformed-no-std.rs
new file mode 100644
index 00000000000..528ecb549b0
--- /dev/null
+++ b/tests/ui/attributes/malformed-no-std.rs
@@ -0,0 +1,25 @@
+#![feature(no_core)]
+// these all still apply no_std and then later error
+#![no_std = "foo"]
+//~^ ERROR malformed `no_std` attribute input
+#![no_std("bar")]
+//~^ ERROR malformed `no_std` attribute input
+#![no_std(foo = "bar")]
+//~^ ERROR malformed `no_std` attribute input
+#![no_core = "foo"]
+//~^ ERROR malformed `no_core` attribute input
+#![no_core("bar")]
+//~^ ERROR malformed `no_core` attribute input
+#![no_core(foo = "bar")]
+//~^ ERROR malformed `no_core` attribute input
+
+#[deny(unused_attributes)]
+#[no_std]
+//~^ ERROR crate-level attribute should be an inner attribute: add an exclamation mark:
+#[no_core]
+//~^ ERROR crate-level attribute should be an inner attribute: add an exclamation mark:
+// to fix compilation
+extern crate core;
+extern crate std;
+
+fn main() {}
diff --git a/tests/ui/attributes/malformed-no-std.stderr b/tests/ui/attributes/malformed-no-std.stderr
new file mode 100644
index 00000000000..322d5f03e41
--- /dev/null
+++ b/tests/ui/attributes/malformed-no-std.stderr
@@ -0,0 +1,86 @@
+error[E0565]: malformed `no_std` attribute input
+  --> $DIR/malformed-no-std.rs:3:1
+   |
+LL | #![no_std = "foo"]
+   | ^^^^^^^^^^-------^
+   | |         |
+   | |         didn't expect any arguments here
+   | help: must be of the form: `#![no_std]`
+
+error[E0565]: malformed `no_std` attribute input
+  --> $DIR/malformed-no-std.rs:5:1
+   |
+LL | #![no_std("bar")]
+   | ^^^^^^^^^-------^
+   | |        |
+   | |        didn't expect any arguments here
+   | help: must be of the form: `#![no_std]`
+
+error[E0565]: malformed `no_std` attribute input
+  --> $DIR/malformed-no-std.rs:7:1
+   |
+LL | #![no_std(foo = "bar")]
+   | ^^^^^^^^^-------------^
+   | |        |
+   | |        didn't expect any arguments here
+   | help: must be of the form: `#![no_std]`
+
+error[E0565]: malformed `no_core` attribute input
+  --> $DIR/malformed-no-std.rs:9:1
+   |
+LL | #![no_core = "foo"]
+   | ^^^^^^^^^^^-------^
+   | |          |
+   | |          didn't expect any arguments here
+   | help: must be of the form: `#![no_core]`
+
+error[E0565]: malformed `no_core` attribute input
+  --> $DIR/malformed-no-std.rs:11:1
+   |
+LL | #![no_core("bar")]
+   | ^^^^^^^^^^-------^
+   | |         |
+   | |         didn't expect any arguments here
+   | help: must be of the form: `#![no_core]`
+
+error[E0565]: malformed `no_core` attribute input
+  --> $DIR/malformed-no-std.rs:13:1
+   |
+LL | #![no_core(foo = "bar")]
+   | ^^^^^^^^^^-------------^
+   | |         |
+   | |         didn't expect any arguments here
+   | help: must be of the form: `#![no_core]`
+
+error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/malformed-no-std.rs:17:1
+   |
+LL | #[no_std]
+   | ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this extern crate
+  --> $DIR/malformed-no-std.rs:22:1
+   |
+LL | extern crate core;
+   | ^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/malformed-no-std.rs:16:8
+   |
+LL | #[deny(unused_attributes)]
+   |        ^^^^^^^^^^^^^^^^^
+
+error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_core]`
+  --> $DIR/malformed-no-std.rs:19:1
+   |
+LL | #[no_core]
+   | ^^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this extern crate
+  --> $DIR/malformed-no-std.rs:22:1
+   |
+LL | extern crate core;
+   | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0565`.
diff --git a/tests/ui/issues/issue-59488.rs b/tests/ui/binop/function-comparison-errors-59488.rs
index 384501e3e5d..8ded781ef95 100644
--- a/tests/ui/issues/issue-59488.rs
+++ b/tests/ui/binop/function-comparison-errors-59488.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/59488
 fn foo() -> i32 {
     42
 }
diff --git a/tests/ui/issues/issue-59488.stderr b/tests/ui/binop/function-comparison-errors-59488.stderr
index b6611ad63a8..615458bc45b 100644
--- a/tests/ui/issues/issue-59488.stderr
+++ b/tests/ui/binop/function-comparison-errors-59488.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}`
-  --> $DIR/issue-59488.rs:14:9
+  --> $DIR/function-comparison-errors-59488.rs:15:9
    |
 LL |     foo > 12;
    |     --- ^ -- {integer}
@@ -12,7 +12,7 @@ LL |     foo() > 12;
    |        ++
 
 error[E0308]: mismatched types
-  --> $DIR/issue-59488.rs:14:11
+  --> $DIR/function-comparison-errors-59488.rs:15:11
    |
 LL |     foo > 12;
    |           ^^ expected fn item, found `i32`
@@ -21,7 +21,7 @@ LL |     foo > 12;
                  found type `i32`
 
 error[E0369]: binary operation `>` cannot be applied to type `fn(i64) -> i64 {bar}`
-  --> $DIR/issue-59488.rs:18:9
+  --> $DIR/function-comparison-errors-59488.rs:19:9
    |
 LL |     bar > 13;
    |     --- ^ -- {integer}
@@ -34,7 +34,7 @@ LL |     bar(/* i64 */) > 13;
    |        +++++++++++
 
 error[E0308]: mismatched types
-  --> $DIR/issue-59488.rs:18:11
+  --> $DIR/function-comparison-errors-59488.rs:19:11
    |
 LL |     bar > 13;
    |           ^^ expected fn item, found `i64`
@@ -43,7 +43,7 @@ LL |     bar > 13;
                  found type `i64`
 
 error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}`
-  --> $DIR/issue-59488.rs:22:9
+  --> $DIR/function-comparison-errors-59488.rs:23:9
    |
 LL |     foo > foo;
    |     --- ^ --- fn() -> i32 {foo}
@@ -56,7 +56,7 @@ LL |     foo() > foo();
    |        ++      ++
 
 error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}`
-  --> $DIR/issue-59488.rs:25:9
+  --> $DIR/function-comparison-errors-59488.rs:26:9
    |
 LL |     foo > bar;
    |     --- ^ --- fn(i64) -> i64 {bar}
@@ -64,7 +64,7 @@ LL |     foo > bar;
    |     fn() -> i32 {foo}
 
 error[E0308]: mismatched types
-  --> $DIR/issue-59488.rs:25:11
+  --> $DIR/function-comparison-errors-59488.rs:26:11
    |
 LL |     foo > bar;
    |           ^^^ expected fn item, found a different fn item
@@ -73,7 +73,7 @@ LL |     foo > bar;
               found fn item `fn(i64) -> i64 {bar}`
 
 error[E0369]: binary operation `==` cannot be applied to type `fn(usize) -> Foo {Foo::Bar}`
-  --> $DIR/issue-59488.rs:30:5
+  --> $DIR/function-comparison-errors-59488.rs:31:5
    |
 LL |     assert_eq!(Foo::Bar, i);
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +84,7 @@ LL |     assert_eq!(Foo::Bar, i);
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug`
-  --> $DIR/issue-59488.rs:30:5
+  --> $DIR/function-comparison-errors-59488.rs:31:5
    |
 LL |     assert_eq!(Foo::Bar, i);
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}`
@@ -92,7 +92,7 @@ LL |     assert_eq!(Foo::Bar, i);
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug`
-  --> $DIR/issue-59488.rs:30:5
+  --> $DIR/function-comparison-errors-59488.rs:31:5
    |
 LL |     assert_eq!(Foo::Bar, i);
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}`
diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.rs b/tests/ui/box/boxed-value-matching-57741.rs
index d0aae23b2fc..7e2f089dad8 100644
--- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.rs
+++ b/tests/ui/box/boxed-value-matching-57741.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/57741
 #![allow(warnings)]
 
 // This tests that the `help: consider dereferencing the boxed value` suggestion isn't made
diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.stderr b/tests/ui/box/boxed-value-matching-57741.stderr
index 76f03bab6d1..33d7a6759ad 100644
--- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741-1.stderr
+++ b/tests/ui/box/boxed-value-matching-57741.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-57741-1.rs:14:9
+  --> $DIR/boxed-value-matching-57741.rs:15:9
    |
 LL |     let y = match x {
    |                   - this expression has type `Box<u32>`
@@ -10,7 +10,7 @@ LL |         S::A { a } | S::B { b: a } => a,
                 found enum `S`
 
 error[E0308]: mismatched types
-  --> $DIR/issue-57741-1.rs:14:22
+  --> $DIR/boxed-value-matching-57741.rs:15:22
    |
 LL |     let y = match x {
    |                   - this expression has type `Box<u32>`
diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.fixed b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.fixed
index 1823f0d3d4c..ee796b56272 100644
--- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.fixed
+++ b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.fixed
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/57741
 //@ run-rustfix
 
 #![allow(warnings)]
diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.rs b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.rs
index 47ab91177e0..3a45a8b56ff 100644
--- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.rs
+++ b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/57741
 //@ run-rustfix
 
 #![allow(warnings)]
diff --git a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.stderr
index 62d83a54614..c07387b21bd 100644
--- a/tests/ui/issues/issue-57741-dereference-boxed-value/issue-57741.stderr
+++ b/tests/ui/box/dereferencing-boxed-enum-in-match-57741.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-57741.rs:20:9
+  --> $DIR/dereferencing-boxed-enum-in-match-57741.rs:21:9
    |
 LL |     let y = match x {
    |                   - this expression has type `Box<T>`
@@ -14,7 +14,7 @@ LL |     let y = match *x {
    |                   +
 
 error[E0308]: mismatched types
-  --> $DIR/issue-57741.rs:20:19
+  --> $DIR/dereferencing-boxed-enum-in-match-57741.rs:21:19
    |
 LL |     let y = match x {
    |                   - this expression has type `Box<T>`
@@ -29,7 +29,7 @@ LL |     let y = match *x {
    |                   +
 
 error[E0308]: mismatched types
-  --> $DIR/issue-57741.rs:27:9
+  --> $DIR/dereferencing-boxed-enum-in-match-57741.rs:28:9
    |
 LL |     let y = match x {
    |                   - this expression has type `Box<S>`
@@ -44,7 +44,7 @@ LL |     let y = match *x {
    |                   +
 
 error[E0308]: mismatched types
-  --> $DIR/issue-57741.rs:27:22
+  --> $DIR/dereferencing-boxed-enum-in-match-57741.rs:28:22
    |
 LL |     let y = match x {
    |                   - this expression has type `Box<S>`
diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs b/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs
index afb16cf58e8..4ae77ab6439 100644
--- a/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs
+++ b/tests/ui/closures/2229_closure_analysis/run_pass/lit-pattern-matching-with-methods.rs
@@ -2,7 +2,6 @@
 //@check-pass
 #![warn(unused)]
 #![feature(rustc_attrs)]
-#![feature(btree_extract_if)]
 
 use std::collections::BTreeMap;
 use std::panic::{catch_unwind, AssertUnwindSafe};
diff --git a/tests/ui/issues/issue-59494.rs b/tests/ui/closures/generic-typed-nested-closures-59494.rs
index b4d50bd4ce7..04d7b00ff7f 100644
--- a/tests/ui/issues/issue-59494.rs
+++ b/tests/ui/closures/generic-typed-nested-closures-59494.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/59494
 fn t7p<A, B, C>(f: impl Fn(B) -> C, g: impl Fn(A) -> B) -> impl Fn(A) -> C {
     move |a: A| -> C { f(g(a)) }
 }
diff --git a/tests/ui/issues/issue-59494.stderr b/tests/ui/closures/generic-typed-nested-closures-59494.stderr
index 33d3e48c1aa..9706fea82a3 100644
--- a/tests/ui/issues/issue-59494.stderr
+++ b/tests/ui/closures/generic-typed-nested-closures-59494.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-59494.rs:20:40
+  --> $DIR/generic-typed-nested-closures-59494.rs:21:40
    |
 LL |     let t7 = |env| |a| |b| t7p(f, g)(((env, a), b));
    |                                        ^^^ cyclic type of infinite size
diff --git a/tests/ui/issues/issue-58375-monomorphize-default-impls.rs b/tests/ui/codegen/mono-item-collector-default-impl-58375.rs
index 769a1176edd..f00e79e0dc5 100644
--- a/tests/ui/issues/issue-58375-monomorphize-default-impls.rs
+++ b/tests/ui/codegen/mono-item-collector-default-impl-58375.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/58375
 // Make sure that the mono-item collector does not crash when trying to
 // instantiate a default impl for DecodeUtf16<<u8 as A>::Item>
 // See https://github.com/rust-lang/rust/issues/58375
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/issues/issue-57162.rs b/tests/ui/coherence/trait-implementation-coherence-check-57162.rs
index 5e62d0eb010..a57e827ca8b 100644
--- a/tests/ui/issues/issue-57162.rs
+++ b/tests/ui/coherence/trait-implementation-coherence-check-57162.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/57162
 //@ check-pass
 
 trait Foo {}
diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs
index 478fa3706e8..9af351ec59f 100644
--- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs
+++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.rs
@@ -11,7 +11,6 @@ where
 {
     fn unimplemented(self, _: &Foo) -> Self::Output {
         //~^ ERROR method `unimplemented` is not a member of trait `std::ops::Add`
-        //~| ERROR type annotations needed
         loop {}
     }
 }
diff --git a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr
index 29bbd23a469..37eb895f9a8 100644
--- a/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/post-analysis-user-facing-param-env.stderr
@@ -3,7 +3,6 @@ error[E0407]: method `unimplemented` is not a member of trait `std::ops::Add`
    |
 LL | /     fn unimplemented(self, _: &Foo) -> Self::Output {
 LL | |
-LL | |
 LL | |         loop {}
 LL | |     }
    | |_____^ not a member of trait `std::ops::Add`
@@ -39,21 +38,7 @@ LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
    = note: expressions using a const parameter must map each value to a distinct output value
    = note: proving the result of expressions other than the parameter are unique is not supported
 
-error[E0284]: type annotations needed
-  --> $DIR/post-analysis-user-facing-param-env.rs:12:40
-   |
-LL |     fn unimplemented(self, _: &Foo) -> Self::Output {
-   |                                        ^^^^^^^^^^^^ cannot infer the value of const parameter `NUM`
-   |
-note: required for `Foo` to implement `Add<&'a Foo>`
-  --> $DIR/post-analysis-user-facing-param-env.rs:6:28
-   |
-LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
-   |          ----------------  ^^^^^^^^^^^^^^^^^^^^^^     ^^^
-   |          |
-   |          unsatisfied trait bound introduced here
-
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0046, E0207, E0284, E0407.
+Some errors have detailed explanations: E0046, E0207, E0407.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs
index ff44876c5c4..dc0701d3b1d 100644
--- a/tests/ui/consts/const_cmp_type_id.rs
+++ b/tests/ui/consts/const_cmp_type_id.rs
@@ -9,8 +9,7 @@ fn main() {
         assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
         assert!(TypeId::of::<()>() != TypeId::of::<u8>());
         let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
-        //~^ ERROR: cannot call non-const operator in constants
-        // can't assert `_a` because it is not deterministic
-        // FIXME(const_trait_impl) make it pass
+        //~^ ERROR: the trait bound `TypeId: const PartialOrd` is not satisfied
+        // FIXME(const_trait_impl) make it pass; requires const comparison of pointers (#53020)
     }
 }
diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr
index 05b94caef79..62a1677c0d9 100644
--- a/tests/ui/consts/const_cmp_type_id.stderr
+++ b/tests/ui/consts/const_cmp_type_id.stderr
@@ -1,13 +1,9 @@
-error[E0015]: cannot call non-const operator in constants
+error[E0277]: the trait bound `TypeId: const PartialOrd` is not satisfied
   --> $DIR/const_cmp_type_id.rs:11:18
    |
 LL |         let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: impl defined here, but it is not `const`
-  --> $SRC_DIR/core/src/any.rs:LL:COL
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
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/consts/fn_trait_refs.rs b/tests/ui/consts/fn_trait_refs.rs
index e475c0a1b6f..e4a62e18c7b 100644
--- a/tests/ui/consts/fn_trait_refs.rs
+++ b/tests/ui/consts/fn_trait_refs.rs
@@ -1,6 +1,5 @@
-//@ known-bug: #110395
+//@ check-pass
 
-#![feature(const_fn_trait_ref_impls)]
 #![feature(fn_traits)]
 #![feature(unboxed_closures)]
 #![feature(const_trait_impl)]
diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr
deleted file mode 100644
index bbe0714801c..00000000000
--- a/tests/ui/consts/fn_trait_refs.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0635]: unknown feature `const_fn_trait_ref_impls`
-  --> $DIR/fn_trait_refs.rs:3:12
-   |
-LL | #![feature(const_fn_trait_ref_impls)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0277]: the trait bound `(i32, i32, i32): const PartialEq` is not satisfied
-  --> $DIR/fn_trait_refs.rs:71:17
-   |
-LL |         assert!(test_one == (1, 1, 1));
-   |                 ^^^^^^^^^^^^^^^^^^^^^
-
-error[E0277]: the trait bound `(i32, i32): const PartialEq` is not satisfied
-  --> $DIR/fn_trait_refs.rs:74:17
-   |
-LL |         assert!(test_two == (2, 2));
-   |                 ^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0277, E0635.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/missing-larger-array-impl.stderr b/tests/ui/consts/missing-larger-array-impl.stderr
index ff4fa36d684..33d7a46339b 100644
--- a/tests/ui/consts/missing-larger-array-impl.stderr
+++ b/tests/ui/consts/missing-larger-array-impl.stderr
@@ -8,11 +8,11 @@ LL |     <[X; 35] as Default>::default();
              &[T]
              &mut [T]
              [T; 0]
-             [T; 10]
-             [T; 11]
-             [T; 12]
-             [T; 13]
-             [T; 14]
+             [T; 1]
+             [T; 2]
+             [T; 3]
+             [T; 4]
+             [T; 5]
            and 27 others
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/issues/issue-57781.rs b/tests/ui/consts/oncecell-const-init-57781.rs
index 7f0d2eda9bb..27426ef2549 100644
--- a/tests/ui/issues/issue-57781.rs
+++ b/tests/ui/consts/oncecell-const-init-57781.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/57781
 //@ run-pass
 
 use std::cell::UnsafeCell;
diff --git a/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr b/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr
index 67f5009c4ff..c1ae42b3939 100644
--- a/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr
+++ b/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr
@@ -1,17 +1,17 @@
 error[E0080]: evaluation panicked: explicit panic
-  --> $DIR/collect-in-promoted-const.rs:9:19
+  --> $DIR/collect-in-promoted-const.rs:11:19
    |
 LL |     const C: () = panic!();
    |                   ^^^^^^^^ evaluation of `Fail::<i32>::C` failed here
 
 note: erroneous constant encountered
-  --> $DIR/collect-in-promoted-const.rs:20:21
+  --> $DIR/collect-in-promoted-const.rs:22:21
    |
 LL |         let _val = &Fail::<T>::C;
    |                     ^^^^^^^^^^^^
 
 note: the above error was encountered while instantiating `fn f::<i32>`
-  --> $DIR/collect-in-promoted-const.rs:25:5
+  --> $DIR/collect-in-promoted-const.rs:27:5
    |
 LL |     f::<i32>();
    |     ^^^^^^^^^^
diff --git a/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr b/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr
index 5c3edf68d95..0d7ac48172c 100644
--- a/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr
+++ b/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr
@@ -1,23 +1,23 @@
 error[E0080]: evaluation panicked: explicit panic
-  --> $DIR/collect-in-promoted-const.rs:9:19
+  --> $DIR/collect-in-promoted-const.rs:11:19
    |
 LL |     const C: () = panic!();
    |                   ^^^^^^^^ evaluation of `Fail::<T>::C` failed here
 
 note: erroneous constant encountered
-  --> $DIR/collect-in-promoted-const.rs:20:21
+  --> $DIR/collect-in-promoted-const.rs:22:21
    |
 LL |         let _val = &Fail::<T>::C;
    |                     ^^^^^^^^^^^^
 
 error[E0080]: evaluation panicked: explicit panic
-  --> $DIR/collect-in-promoted-const.rs:9:19
+  --> $DIR/collect-in-promoted-const.rs:11:19
    |
 LL |     const C: () = panic!();
    |                   ^^^^^^^^ evaluation of `Fail::<i32>::C` failed here
 
 note: erroneous constant encountered
-  --> $DIR/collect-in-promoted-const.rs:20:21
+  --> $DIR/collect-in-promoted-const.rs:22:21
    |
 LL |         let _val = &Fail::<T>::C;
    |                     ^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |         let _val = &Fail::<T>::C;
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 note: the above error was encountered while instantiating `fn f::<i32>`
-  --> $DIR/collect-in-promoted-const.rs:25:5
+  --> $DIR/collect-in-promoted-const.rs:27:5
    |
 LL |     f::<i32>();
    |     ^^^^^^^^^^
diff --git a/tests/ui/consts/required-consts/collect-in-promoted-const.rs b/tests/ui/consts/required-consts/collect-in-promoted-const.rs
index 25c8cb7e804..498328abe21 100644
--- a/tests/ui/consts/required-consts/collect-in-promoted-const.rs
+++ b/tests/ui/consts/required-consts/collect-in-promoted-const.rs
@@ -1,6 +1,8 @@
 //@revisions: noopt opt
 //@ build-fail
 //@[noopt] compile-flags: -Copt-level=0
+// FIXME(#61117): Respect debuginfo-level-tests, do not force debuginfo=0
+//@[opt] compile-flags: -C debuginfo=0
 //@[opt] compile-flags: -O
 //! Make sure we error on erroneous consts even if they get promoted.
 
diff --git a/tests/ui/issues/issue-58463.rs b/tests/ui/debuginfo/impl-copy-function-debuginfo-58463.rs
index 6e4b909bc38..72388c36ce4 100644
--- a/tests/ui/issues/issue-58463.rs
+++ b/tests/ui/debuginfo/impl-copy-function-debuginfo-58463.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/58463
 //@ run-pass
 //@ compile-flags:-C debuginfo=2
 
diff --git a/tests/ui/issues/issue-58734.rs b/tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.rs
index e5b371f5530..3e9ebb497a2 100644
--- a/tests/ui/issues/issue-58734.rs
+++ b/tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/58734
 trait Trait {
     fn exists(self) -> ();
 
diff --git a/tests/ui/issues/issue-58734.stderr b/tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.stderr
index 2336a94f150..140461283f3 100644
--- a/tests/ui/issues/issue-58734.stderr
+++ b/tests/ui/dyn-compatibility/spurious-dyn-compat-errors-58734.stderr
@@ -1,5 +1,5 @@
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/issue-58734.rs:20:5
+  --> $DIR/spurious-dyn-compat-errors-58734.rs:21:5
    |
 LL |     Trait::nonexistent(());
    |     ^^^^^
@@ -13,14 +13,14 @@ LL |     <dyn Trait>::nonexistent(());
    |     ++++      +
 
 error[E0038]: the trait `Trait` is not dyn compatible
-  --> $DIR/issue-58734.rs:20:5
+  --> $DIR/spurious-dyn-compat-errors-58734.rs:21:5
    |
 LL |     Trait::nonexistent(());
    |     ^^^^^ `Trait` is not dyn compatible
    |
 note: for a trait to be dyn compatible it needs to allow building a vtable
       for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
-  --> $DIR/issue-58734.rs:4:8
+  --> $DIR/spurious-dyn-compat-errors-58734.rs:5:8
    |
 LL | trait Trait {
    |       ----- this trait is not dyn compatible...
diff --git a/tests/ui/feature-gates/feature-gate-sanitize.rs b/tests/ui/feature-gates/feature-gate-sanitize.rs
index 40098d93272..768417cfae8 100644
--- a/tests/ui/feature-gates/feature-gate-sanitize.rs
+++ b/tests/ui/feature-gates/feature-gate-sanitize.rs
@@ -1,4 +1,3 @@
-//@ normalize-stderr: "you are using [0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?( \([^)]*\))?" -> "you are using $$RUSTC_VERSION"
 #![feature(no_sanitize)] //~ ERROR feature has been removed
 
 #[sanitize(address = "on")]
diff --git a/tests/ui/feature-gates/feature-gate-sanitize.stderr b/tests/ui/feature-gates/feature-gate-sanitize.stderr
index 7c38b351916..513999636a9 100644
--- a/tests/ui/feature-gates/feature-gate-sanitize.stderr
+++ b/tests/ui/feature-gates/feature-gate-sanitize.stderr
@@ -1,5 +1,5 @@
 error[E0557]: feature has been removed
-  --> $DIR/feature-gate-sanitize.rs:2:12
+  --> $DIR/feature-gate-sanitize.rs:1:12
    |
 LL | #![feature(no_sanitize)]
    |            ^^^^^^^^^^^ feature has been removed
@@ -8,7 +8,7 @@ LL | #![feature(no_sanitize)]
    = note: renamed to sanitize(xyz = "on|off")
 
 error[E0658]: the `#[sanitize]` attribute is an experimental feature
-  --> $DIR/feature-gate-sanitize.rs:4:1
+  --> $DIR/feature-gate-sanitize.rs:3:1
    |
 LL | #[sanitize(address = "on")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
index c2653dd82a9..546aa4052d3 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
@@ -539,26 +539,26 @@ mod macro_escape {
 
 #[no_std]
 //~^ WARN crate-level attribute should be an inner attribute
-//~| HELP add a `!`
 mod no_std {
+    //~^ NOTE This attribute does not have an `!`, which means it is applied to this module
     mod inner { #![no_std] }
-//~^ WARN crate-level attribute should be in the root module
+//~^ WARN the `#![no_std]` attribute can only be used at the crate root
 
     #[no_std] fn f() { }
     //~^ WARN crate-level attribute should be an inner attribute
-    //~| HELP add a `!`
+    //~| NOTE This attribute does not have an `!`, which means it is applied to this function
 
     #[no_std] struct S;
     //~^ WARN crate-level attribute should be an inner attribute
-    //~| HELP add a `!`
+    //~| NOTE This attribute does not have an `!`, which means it is applied to this struct
 
     #[no_std] type T = S;
     //~^ WARN crate-level attribute should be an inner attribute
-    //~| HELP add a `!`
+    //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias
 
     #[no_std] impl S { }
     //~^ WARN crate-level attribute should be an inner attribute
-    //~| HELP add a `!`
+    //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block
 }
 
 // At time of authorship, #[proc_macro_derive = "2500"] signals error
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
index 4a3520972bf..3c835be5cff 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
@@ -209,17 +209,6 @@ help: add a `!`
 LL | #![reexport_test_harness_main = "2900"]
    |  +
 
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:1
-   |
-LL | #[no_std]
-   | ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL | #![no_std]
-   |  +
-
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:1
    |
@@ -387,56 +376,6 @@ help: add a `!`
 LL |     #![reexport_test_harness_main = "2900"] impl S { }
    |      +
 
-warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:17
-   |
-LL |     mod inner { #![no_std] }
-   |                 ^^^^^^^^^^
-
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5
-   |
-LL |     #[no_std] fn f() { }
-   |     ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL |     #![no_std] fn f() { }
-   |      +
-
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:5
-   |
-LL |     #[no_std] struct S;
-   |     ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL |     #![no_std] struct S;
-   |      +
-
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5
-   |
-LL |     #[no_std] type T = S;
-   |     ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL |     #![no_std] type T = S;
-   |      +
-
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5
-   |
-LL |     #[no_std] impl S { }
-   |     ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL |     #![no_std] impl S { }
-   |      +
-
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17
    |
@@ -1095,6 +1034,76 @@ LL |     #[macro_escape] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = help: `#[macro_escape]` can be applied to modules, extern crates, and crates
 
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:1
+   |
+LL | #[no_std]
+   | ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this module
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:542:1
+   |
+LL | / mod no_std {
+LL | |
+LL | |     mod inner { #![no_std] }
+...  |
+LL | | }
+   | |_^
+
+warning: the `#![no_std]` attribute can only be used at the crate root
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:17
+   |
+LL |     mod inner { #![no_std] }
+   |                 ^^^^^^^^^^
+
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5
+   |
+LL |     #[no_std] fn f() { }
+   |     ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this function
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:15
+   |
+LL |     #[no_std] fn f() { }
+   |               ^^^^^^^^^^
+
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:5
+   |
+LL |     #[no_std] struct S;
+   |     ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this struct
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:15
+   |
+LL |     #[no_std] struct S;
+   |               ^^^^^^^^^
+
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5
+   |
+LL |     #[no_std] type T = S;
+   |     ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this type alias
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:15
+   |
+LL |     #[no_std] type T = S;
+   |               ^^^^^^^^^^^
+
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5
+   |
+LL |     #[no_std] impl S { }
+   |     ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this implementation block
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:15
+   |
+LL |     #[no_std] impl S { }
+   |               ^^^^^^^^^^
+
 warning: `#[cold]` attribute cannot be used on modules
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:581:1
    |
diff --git a/tests/ui/issues/issue-56237.rs b/tests/ui/generics/generic-associated-type-deref-target-56237.rs
index 3c0a235f3ec..2050ca377e8 100644
--- a/tests/ui/issues/issue-56237.rs
+++ b/tests/ui/generics/generic-associated-type-deref-target-56237.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/56237
 //@ run-pass
 
 use std::ops::Deref;
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/issues/issue-55731.rs b/tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.rs
index 7b4f4e2cd3b..978abd9fcf5 100644
--- a/tests/ui/issues/issue-55731.rs
+++ b/tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/55731
 use std::marker::PhantomData;
 
 trait DistributedIterator {
diff --git a/tests/ui/issues/issue-55731.stderr b/tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.stderr
index 2c38041642d..40ac1d9d041 100644
--- a/tests/ui/issues/issue-55731.stderr
+++ b/tests/ui/higher-ranked/hrtb-associated-type-leak-check-55731.stderr
@@ -1,5 +1,5 @@
 error: implementation of `DistributedIteratorMulti` is not general enough
-  --> $DIR/issue-55731.rs:48:5
+  --> $DIR/hrtb-associated-type-leak-check-55731.rs:49:5
    |
 LL | /     multi(Map {
 LL | |         i: Cloned(PhantomData),
diff --git a/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-2.next.stderr b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-2.next.stderr
new file mode 100644
index 00000000000..86ac1bdad04
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-2.next.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/avoid-inference-constraints-from-blanket-2.rs:27:18
+   |
+LL |     let _: u32 = x;
+   |            ---   ^ expected `u32`, found `u64`
+   |            |
+   |            expected due to this
+   |
+help: you can convert a `u64` to a `u32` and panic if the converted value doesn't fit
+   |
+LL |     let _: u32 = x.try_into().unwrap();
+   |                   ++++++++++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-2.rs b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-2.rs
new file mode 100644
index 00000000000..b4f853de4aa
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-2.rs
@@ -0,0 +1,31 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[current] check-pass
+
+// Regression test for trait-system-refactor-initiative#205. Avoid
+// constraining other impl arguments when applying blanket impls.
+
+// FIXME(-Znext-solver): This currently incompletely constrains the
+// argument of `opaque: Trait<?x>` using the blanket impl of trait.
+// Ideally we don't do that.
+
+trait Trait<T> {}
+
+impl<T> Trait<u64> for T {}
+impl Trait<u32> for u64 {}
+
+fn impls_trait<T: Trait<U>, U>(_: U) -> T {
+    todo!()
+}
+
+fn foo() -> impl Sized {
+    let x = Default::default();
+    if false {
+        return impls_trait::<_, _>(x);
+    }
+    let _: u32 = x;
+    //[next]~^ ERROR mismatched types
+    1u64
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-3.rs b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-3.rs
new file mode 100644
index 00000000000..2f29cb4ee6b
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-3.rs
@@ -0,0 +1,25 @@
+//@ compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+#![allow(unconditional_recursion)]
+
+// Regression test for trait-system-refactor-initiative#205. Avoid
+// constraining other impl arguments when applying blanket impls,
+// especially if the nested where-bounds of the blanket impl don't
+// actually apply for the opaque.
+
+// FIXME(-Znext-solver): This currently incompletely constrains the
+// argument of `opaque: Trait<?x>` using the blanket impl of trait.
+// Ideally we don't do that.
+
+trait Trait<T> {}
+
+impl<T: Copy> Trait<u32> for T {}
+impl Trait<u64> for String {}
+fn impls_trait<T: Trait<U>, U>(_: T) {}
+
+fn test() -> impl Sized {
+    let x = test();
+    impls_trait(x); //~ ERROR the trait bound `String: Trait<u32>` is not satisfied
+    String::new()
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-3.stderr b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-3.stderr
new file mode 100644
index 00000000000..a5d19b48481
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket-3.stderr
@@ -0,0 +1,25 @@
+error[E0277]: the trait bound `String: Trait<u32>` is not satisfied
+  --> $DIR/avoid-inference-constraints-from-blanket-3.rs:22:5
+   |
+LL |     impls_trait(x);
+   |     ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+   = help: the trait `Trait<u32>` is not implemented for `String`
+           but trait `Trait<u64>` is implemented for it
+   = help: for that trait implementation, expected `u64`, found `u32`
+note: required for `String` to implement `Trait<u32>`
+  --> $DIR/avoid-inference-constraints-from-blanket-3.rs:16:15
+   |
+LL | impl<T: Copy> Trait<u32> for T {}
+   |         ----  ^^^^^^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required by a bound in `impls_trait`
+  --> $DIR/avoid-inference-constraints-from-blanket-3.rs:18:19
+   |
+LL | fn impls_trait<T: Trait<U>, U>(_: T) {}
+   |                   ^^^^^^^^ required by this bound in `impls_trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket.rs b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket.rs
new file mode 100644
index 00000000000..bb3acfde5bc
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/avoid-inference-constraints-from-blanket.rs
@@ -0,0 +1,25 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#205. Avoid constraining
+// the opaque type when applying blanket impls.
+
+trait Trait<T> {}
+
+impl<T> Trait<T> for T {}
+impl Trait<u32> for u64 {}
+
+fn impls_trait<T: Trait<U>, U>() -> T {
+    todo!()
+}
+
+fn foo() -> impl Sized {
+    if false {
+        // `opaque: Trait<u32>` shouldn't constrain `opaque` to `u32` via the blanket impl
+        return impls_trait::<_, u32>();
+    }
+    1u64
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/multiple-opaques-ambig.rs b/tests/ui/impl-trait/non-defining-uses/multiple-opaques-ambig.rs
new file mode 100644
index 00000000000..e7aaf6fa135
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/multiple-opaques-ambig.rs
@@ -0,0 +1,23 @@
+//@ compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+#![allow(unconditional_recursion)]
+
+// Regression test for trait-system-refactor-initiative#182. If multiple
+// opaque types result in different item bounds, do not apply them.
+
+trait Trait<T> {}
+impl<T, U> Trait<T> for U {}
+
+fn impls_trait<T: Trait<U>, U>(_: T) -> U {
+    todo!()
+}
+
+fn overlap<T, U>() -> (impl Trait<T>, impl Trait<U>) {
+    let mut x = overlap::<T, U>().0;
+    x = overlap::<T, U>().1;
+    let u = impls_trait(x);
+    let _: u32 = u;
+    ((), ())
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/multiple-opaques-ok.rs b/tests/ui/impl-trait/non-defining-uses/multiple-opaques-ok.rs
new file mode 100644
index 00000000000..d91efe181e3
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/multiple-opaques-ok.rs
@@ -0,0 +1,37 @@
+//@ compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+#![allow(unconditional_recursion)]
+
+// Regression test for trait-system-refactor-initiative#18, making sure
+// we support being sub unified with more than 1 opaque type.
+
+trait Id {
+    type This;
+}
+impl Id for &'static str {
+    type This = &'static str;
+}
+fn to_assoc<T: Id>(x: T) -> <T as Id>::This {
+    todo!()
+}
+
+fn mirror1() -> (impl Id<This = &'static str>, impl Sized) {
+    let mut opaque = mirror1().0;
+    opaque = mirror1().1;
+    let x = to_assoc(opaque);
+    // `?x` equals both opaques, make sure we still use the applicable
+    // item bound.
+    x.len();
+    (x, x)
+}
+fn mirror2() -> (impl Sized, impl Id<This = &'static str>) {
+    let mut opaque = mirror2().0;
+    opaque = mirror2().1;
+    let x = to_assoc(opaque);
+    // `?x` equals both opaques, make sure we still use the applicable
+    // item bound.
+    x.len();
+    (x, x)
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/no-rigid-alias.rs b/tests/ui/impl-trait/non-defining-uses/no-rigid-alias.rs
new file mode 100644
index 00000000000..fca5db3e20f
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/no-rigid-alias.rs
@@ -0,0 +1,27 @@
+//@ compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+#![allow(unconditional_recursion)]
+
+// Test for trait-system-refactor-initiative#182 making sure
+// that we don't incorrectly normalize to rigid aliases if the
+// opaque type only has a trait bound.
+
+trait Id {
+    type This;
+}
+impl<T> Id for Vec<T> {
+    type This = Vec<T>;
+}
+fn to_assoc<T: Id>(x: T) -> <T as Id>::This {
+    todo!()
+}
+
+fn mirror<T>(x: Vec<T>) -> impl Id {
+    let x = to_assoc(mirror(x));
+    // `?x` equals `<opaque::<T> as Id>::This`. We should not infer `?x`
+    // to be a rigid alias here.
+    let _: Vec<u32> = x;
+    x
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/use-blanket-impl.rs b/tests/ui/impl-trait/non-defining-uses/use-blanket-impl.rs
new file mode 100644
index 00000000000..50bb3995b94
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/use-blanket-impl.rs
@@ -0,0 +1,19 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#196.
+fn iterator(b: bool) -> impl Iterator<Item = String> {
+    if b {
+        // We need to eagerly figure out the type of `i` here by using
+        // the `<opaque as IntoIterator>::Item` obligation. This means
+        // we not only have to consider item bounds, but also blanket impls.
+        for i in iterator(false) {
+            i.len();
+        }
+    }
+
+    vec![].into_iter()
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/use-item-bound-over-blanket-impl.rs b/tests/ui/impl-trait/non-defining-uses/use-item-bound-over-blanket-impl.rs
new file mode 100644
index 00000000000..7c2766ade3f
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/use-item-bound-over-blanket-impl.rs
@@ -0,0 +1,30 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+#![allow(unconditional_recursion)]
+
+// Regression test for trait-system-refactor-initiative#182.
+
+trait Id {
+    type This;
+}
+impl<T> Id for T {
+    type This = T;
+}
+fn to_assoc<T>(x: T) -> <T as Id>::This {
+    x
+}
+
+fn mirror<T>(x: Vec<T>) -> impl Id<This = Vec<T>> {
+    let x = to_assoc(mirror(x));
+    // `?x` equals `<opaque::<T> as Id>::This`. We need to eagerly infer the
+    // type of `?x` to prevent this method call from resulting in an error.
+    //
+    // We could use both the item bound to normalize to `Vec<T>`, or the
+    // blanket impl to normalize to `opaque::<T>`. We have to go with the
+    // item bound.
+    x.len();
+    x
+}
+fn main() {}
diff --git a/tests/ui/impl-trait/non-defining-uses/use-item-bound.rs b/tests/ui/impl-trait/non-defining-uses/use-item-bound.rs
new file mode 100644
index 00000000000..36dcbacbe6f
--- /dev/null
+++ b/tests/ui/impl-trait/non-defining-uses/use-item-bound.rs
@@ -0,0 +1,25 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ check-pass
+#![allow(unconditional_recursion)]
+// Regression test for trait-system-refactor-initiative#182.
+
+trait Id {
+    type This;
+}
+impl<T> Id for Vec<T> {
+    type This = Vec<T>;
+}
+fn to_assoc<T: Id>(x: T) -> <T as Id>::This {
+    todo!()
+}
+
+fn mirror<T>(x: Vec<T>) -> impl Id<This = Vec<T>> {
+    let x = to_assoc(mirror(x));
+    // `?x` equals `<opaque::<T> as Id>::This`. We need to eagerly infer the
+    // type of `?x` to prevent this method call from resulting in an error.
+    x.len();
+    x
+}
+fn main() {}
diff --git a/tests/ui/imports/auxiliary/reexported-trait-56175.rs b/tests/ui/imports/auxiliary/reexported-trait-56175.rs
new file mode 100644
index 00000000000..51a991bef59
--- /dev/null
+++ b/tests/ui/imports/auxiliary/reexported-trait-56175.rs
@@ -0,0 +1,17 @@
+mod private {
+    pub trait Trait {
+        fn trait_method(&self) {
+        }
+    }
+    pub trait TraitB {
+        fn trait_method_b(&self) {
+        }
+    }
+}
+
+pub struct FooStruct;
+pub use crate::private::Trait;
+impl crate::private::Trait for FooStruct {}
+
+pub use crate::private::TraitB as TraitBRename;
+impl crate::private::TraitB for FooStruct {}
diff --git a/tests/ui/issues/issue-56175.rs b/tests/ui/imports/private-types-suggested-without-extern-crate-56175.rs
index daffe806a90..ce001edad1b 100644
--- a/tests/ui/issues/issue-56175.rs
+++ b/tests/ui/imports/private-types-suggested-without-extern-crate-56175.rs
@@ -1,5 +1,6 @@
+// https://github.com/rust-lang/rust/issues/56175
 //@ edition:2018
-//@ aux-crate:reexported_trait=reexported-trait.rs
+//@ aux-crate:reexported_trait=reexported-trait-56175.rs
 
 fn main() {
     reexported_trait::FooStruct.trait_method();
diff --git a/tests/ui/issues/issue-56175.stderr b/tests/ui/imports/private-types-suggested-without-extern-crate-56175.stderr
index df4cd6ce8a7..1e8285c80ac 100644
--- a/tests/ui/issues/issue-56175.stderr
+++ b/tests/ui/imports/private-types-suggested-without-extern-crate-56175.stderr
@@ -1,10 +1,10 @@
 error[E0599]: no method named `trait_method` found for struct `FooStruct` in the current scope
-  --> $DIR/issue-56175.rs:5:33
+  --> $DIR/private-types-suggested-without-extern-crate-56175.rs:6:33
    |
 LL |     reexported_trait::FooStruct.trait_method();
    |                                 ^^^^^^^^^^^^
    |
-  ::: $DIR/auxiliary/reexported-trait.rs:3:12
+  ::: $DIR/auxiliary/reexported-trait-56175.rs:3:12
    |
 LL |         fn trait_method(&self) {
    |            ------------ the method is available for `FooStruct` here
@@ -12,7 +12,7 @@ LL |         fn trait_method(&self) {
    = help: items from traits can only be used if the trait is in scope
 help: trait `Trait` which provides `trait_method` is implemented but not in scope; perhaps you want to import it
    |
-LL + use reexported_trait::Trait;
+LL + use reexported_trait_56175::Trait;
    |
 help: there is a method `trait_method_b` with a similar name
    |
@@ -20,12 +20,12 @@ LL |     reexported_trait::FooStruct.trait_method_b();
    |                                             ++
 
 error[E0599]: no method named `trait_method_b` found for struct `FooStruct` in the current scope
-  --> $DIR/issue-56175.rs:7:33
+  --> $DIR/private-types-suggested-without-extern-crate-56175.rs:8:33
    |
 LL |     reexported_trait::FooStruct.trait_method_b();
    |                                 ^^^^^^^^^^^^^^
    |
-  ::: $DIR/auxiliary/reexported-trait.rs:7:12
+  ::: $DIR/auxiliary/reexported-trait-56175.rs:7:12
    |
 LL |         fn trait_method_b(&self) {
    |            -------------- the method is available for `FooStruct` here
@@ -33,7 +33,7 @@ LL |         fn trait_method_b(&self) {
    = help: items from traits can only be used if the trait is in scope
 help: trait `TraitB` which provides `trait_method_b` is implemented but not in scope; perhaps you want to import it
    |
-LL + use reexported_trait::TraitBRename;
+LL + use reexported_trait_56175::TraitBRename;
    |
 help: there is a method `trait_method` with a similar name
    |
diff --git a/tests/ui/issues/auxiliary/issue-57271-lib.rs b/tests/ui/infinite/auxiliary/aux-57271-lib.rs
index ff625668a9d..ff625668a9d 100644
--- a/tests/ui/issues/auxiliary/issue-57271-lib.rs
+++ b/tests/ui/infinite/auxiliary/aux-57271-lib.rs
diff --git a/tests/ui/issues/issue-57271.rs b/tests/ui/infinite/mutually-recursive-infinite-types-57271.rs
index 20d081ecb3c..cb20770b486 100644
--- a/tests/ui/issues/issue-57271.rs
+++ b/tests/ui/infinite/mutually-recursive-infinite-types-57271.rs
@@ -1,8 +1,9 @@
-//@ aux-build:issue-57271-lib.rs
+// https://github.com/rust-lang/rust/issues/57271
+//@ aux-build:aux-57271-lib.rs
 
-extern crate issue_57271_lib;
+extern crate aux_57271_lib;
 
-use issue_57271_lib::BaseType;
+use aux_57271_lib::BaseType;
 
 pub enum ObjectType { //~ ERROR recursive types `ObjectType` and `TypeSignature` have infinite size
     Class(ClassTypeSignature),
diff --git a/tests/ui/issues/issue-57271.stderr b/tests/ui/infinite/mutually-recursive-infinite-types-57271.stderr
index a61419c61d7..8bf1b470062 100644
--- a/tests/ui/issues/issue-57271.stderr
+++ b/tests/ui/infinite/mutually-recursive-infinite-types-57271.stderr
@@ -1,5 +1,5 @@
 error[E0072]: recursive types `ObjectType` and `TypeSignature` have infinite size
-  --> $DIR/issue-57271.rs:7:1
+  --> $DIR/mutually-recursive-infinite-types-57271.rs:8:1
    |
 LL | pub enum ObjectType {
    | ^^^^^^^^^^^^^^^^^^^
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/invalid-compile-flags/print-without-arg.stderr b/tests/ui/invalid-compile-flags/print-without-arg.stderr
index 3048a59d0d0..4163d4e0602 100644
--- a/tests/ui/invalid-compile-flags/print-without-arg.stderr
+++ b/tests/ui/invalid-compile-flags/print-without-arg.stderr
@@ -3,5 +3,5 @@ error: Argument to option 'print' missing
            --print <INFO>[=<FILE>]
                                Compiler information to print on stdout (or to a file)
                                INFO may be one of
-                               <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models>.
+                               <all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|target-spec-json-schema|tls-models>.
 
diff --git a/tests/ui/invalid-compile-flags/print.stderr b/tests/ui/invalid-compile-flags/print.stderr
index e3374eb1e6e..e8adbfd87d7 100644
--- a/tests/ui/invalid-compile-flags/print.stderr
+++ b/tests/ui/invalid-compile-flags/print.stderr
@@ -1,5 +1,5 @@
 error: unknown print request: `yyyy`
   |
-  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
+  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
   = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
 
diff --git a/tests/ui/issues/issue-56943.rs b/tests/ui/issues/issue-56943.rs
deleted file mode 100644
index 9664567ec9e..00000000000
--- a/tests/ui/issues/issue-56943.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ aux-build:issue-56943.rs
-
-extern crate issue_56943;
-
-fn main() {
-    let _: issue_56943::S = issue_56943::S2;
-    //~^ ERROR mismatched types [E0308]
-}
diff --git a/tests/ui/issues/issue-57198-pass.rs b/tests/ui/keyword/raw-identifier-for-function-57198.rs
index 06f30603c31..41a0cbf4619 100644
--- a/tests/ui/issues/issue-57198-pass.rs
+++ b/tests/ui/keyword/raw-identifier-for-function-57198.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/57198
 //@ run-pass
 
 mod m {
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs
index 92cb60bb16d..dac878c1cd9 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs
@@ -20,4 +20,4 @@ pub fn lib_main() {
     unsafe { f(42); }
 }
 
-//~? ERROR Dlltool could not create import library with
+//~? ERROR dlltool could not create import library with
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr
index 90cca83d1c1..5f3c29c3a21 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr
@@ -1,4 +1,4 @@
-error: Dlltool could not create import library with $DLLTOOL -d $DEF_FILE -D foo.dll -l $LIB_FILE $TARGET_MACHINE $ASM_FLAGS --no-leading-underscore $TEMP_PREFIX:
+error: dlltool could not create import library with $DLLTOOL -d $DEF_FILE -D foo.dll -l $LIB_FILE $TARGET_MACHINE $ASM_FLAGS --no-leading-underscore $TEMP_PREFIX:
        
        $DLLTOOL: Syntax error in def file $DEF_FILE:1โ
 
diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr
index 076a08ac6f2..3a3b450f3c5 100644
--- a/tests/ui/lint/unused/unused-attr-duplicate.stderr
+++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr
@@ -29,18 +29,6 @@ LL | #[no_link]
    | ^^^^^^^^^^
 
 error: unused attribute
-  --> $DIR/unused-attr-duplicate.rs:27:1
-   |
-LL | #![no_std]
-   | ^^^^^^^^^^ help: remove this attribute
-   |
-note: attribute also specified here
-  --> $DIR/unused-attr-duplicate.rs:26:1
-   |
-LL | #![no_std]
-   | ^^^^^^^^^^
-
-error: unused attribute
   --> $DIR/unused-attr-duplicate.rs:31:1
    |
 LL | #![windows_subsystem = "windows"]
@@ -305,6 +293,18 @@ LL | #![type_length_limit = "1048576"]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 error: unused attribute
+  --> $DIR/unused-attr-duplicate.rs:27:1
+   |
+LL | #![no_std]
+   | ^^^^^^^^^^ help: remove this attribute
+   |
+note: attribute also specified here
+  --> $DIR/unused-attr-duplicate.rs:26:1
+   |
+LL | #![no_std]
+   | ^^^^^^^^^^
+
+error: unused attribute
   --> $DIR/unused-attr-duplicate.rs:29:1
    |
 LL | #![no_implicit_prelude]
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/issues/auxiliary/issue-56943.rs b/tests/ui/mismatched_types/auxiliary/aux-56943.rs
index 65b9beb91f9..65b9beb91f9 100644
--- a/tests/ui/issues/auxiliary/issue-56943.rs
+++ b/tests/ui/mismatched_types/auxiliary/aux-56943.rs
diff --git a/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.rs b/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.rs
new file mode 100644
index 00000000000..9970b27c847
--- /dev/null
+++ b/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.rs
@@ -0,0 +1,9 @@
+// https://github.com/rust-lang/rust/issues/56943
+//@ aux-build:aux-56943.rs
+
+extern crate aux_56943;
+
+fn main() {
+    let _: aux_56943::S = aux_56943::S2;
+    //~^ ERROR mismatched types [E0308]
+}
diff --git a/tests/ui/issues/issue-56943.stderr b/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.stderr
index 60a2e92dc71..2315267701d 100644
--- a/tests/ui/issues/issue-56943.stderr
+++ b/tests/ui/mismatched_types/type-mismatch-in-extern-crate-56943.stderr
@@ -1,8 +1,8 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-56943.rs:6:29
+  --> $DIR/type-mismatch-in-extern-crate-56943.rs:7:27
    |
-LL |     let _: issue_56943::S = issue_56943::S2;
-   |            --------------   ^^^^^^^^^^^^^^^ expected `S`, found `S2`
+LL |     let _: aux_56943::S = aux_56943::S2;
+   |            ------------   ^^^^^^^^^^^^^ expected `S`, found `S2`
    |            |
    |            expected due to this
 
diff --git a/tests/ui/issues/issue-56128.rs b/tests/ui/modules/pub-use-handling-in-modules-56128.rs
index cc170f60250..cc170f60250 100644
--- a/tests/ui/issues/issue-56128.rs
+++ b/tests/ui/modules/pub-use-handling-in-modules-56128.rs
diff --git a/tests/ui/issues/issue-55587.rs b/tests/ui/parser/invalid-variable-definition-55587.rs
index d9100cf555b..f2c7c0a8e6c 100644
--- a/tests/ui/issues/issue-55587.rs
+++ b/tests/ui/parser/invalid-variable-definition-55587.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/55587
 use std::path::Path;
 
 fn main() {
diff --git a/tests/ui/issues/issue-55587.stderr b/tests/ui/parser/invalid-variable-definition-55587.stderr
index 7a5d0e28100..08c951582e3 100644
--- a/tests/ui/issues/issue-55587.stderr
+++ b/tests/ui/parser/invalid-variable-definition-55587.stderr
@@ -1,5 +1,5 @@
 error[E0164]: expected tuple struct or tuple variant, found associated function `Path::new`
-  --> $DIR/issue-55587.rs:4:9
+  --> $DIR/invalid-variable-definition-55587.rs:5:9
    |
 LL |     let Path::new();
    |         ^^^^^^^^^^^ `fn` calls are not allowed in patterns
diff --git a/tests/ui/print-request/print-lints-help.stderr b/tests/ui/print-request/print-lints-help.stderr
index bc48b2fa73c..297a3aa79e1 100644
--- a/tests/ui/print-request/print-lints-help.stderr
+++ b/tests/ui/print-request/print-lints-help.stderr
@@ -1,6 +1,6 @@
 error: unknown print request: `lints`
   |
-  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
+  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `crate-root-lint-levels`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `target-spec-json-schema`, `tls-models`
   = help: use `-Whelp` to print a list of lints
   = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
 
diff --git a/tests/ui/print_type_sizes/async.rs b/tests/ui/print_type_sizes/async.rs
index 951e7cd1012..b6ec8842634 100644
--- a/tests/ui/print_type_sizes/async.rs
+++ b/tests/ui/print_type_sizes/async.rs
@@ -1,3 +1,5 @@
+// FIXME(#61117): Respect debuginfo-level-tests, do not force debuginfo=0
+//@ compile-flags: -C debuginfo=0
 //@ compile-flags: -C panic=abort -Z print-type-sizes --crate-type lib
 //@ needs-deterministic-layouts
 //@ edition:2021
diff --git a/tests/ui/issues/issue-58712.rs b/tests/ui/resolve/missing-type-in-scope-58712.rs
index 930bec6889b..b9ff74e426d 100644
--- a/tests/ui/issues/issue-58712.rs
+++ b/tests/ui/resolve/missing-type-in-scope-58712.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/58712
 struct AddrVec<H, A> {
     h: H,
     a: A,
diff --git a/tests/ui/issues/issue-58712.stderr b/tests/ui/resolve/missing-type-in-scope-58712.stderr
index f4bd4d1e826..d7e06eee856 100644
--- a/tests/ui/issues/issue-58712.stderr
+++ b/tests/ui/resolve/missing-type-in-scope-58712.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `DeviceId` in this scope
-  --> $DIR/issue-58712.rs:6:20
+  --> $DIR/missing-type-in-scope-58712.rs:7:20
    |
 LL | impl<H> AddrVec<H, DeviceId> {
    |                    ^^^^^^^^ not found in this scope
@@ -10,7 +10,7 @@ LL | impl<H, DeviceId> AddrVec<H, DeviceId> {
    |       ++++++++++
 
 error[E0412]: cannot find type `DeviceId` in this scope
-  --> $DIR/issue-58712.rs:8:29
+  --> $DIR/missing-type-in-scope-58712.rs:9:29
    |
 LL |     pub fn device(&self) -> DeviceId {
    |                             ^^^^^^^^ not found in this scope
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/issues/issue-59020.rs b/tests/ui/std/park-timeout-wakeup-59020.rs
index 2a34ba52b88..af530bb586c 100644
--- a/tests/ui/issues/issue-59020.rs
+++ b/tests/ui/std/park-timeout-wakeup-59020.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/59020
 //@ edition:2018
 //@ run-pass
 //@ needs-threads
diff --git a/tests/ui/issues/issue-56835.rs b/tests/ui/structs/invalid-self-constructor-56835.rs
index 7132d15ee5f..fd8763443f0 100644
--- a/tests/ui/issues/issue-56835.rs
+++ b/tests/ui/structs/invalid-self-constructor-56835.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/56835
 pub struct Foo {}
 
 impl Foo {
diff --git a/tests/ui/issues/issue-56835.stderr b/tests/ui/structs/invalid-self-constructor-56835.stderr
index e949ae7b324..045781ec42b 100644
--- a/tests/ui/issues/issue-56835.stderr
+++ b/tests/ui/structs/invalid-self-constructor-56835.stderr
@@ -1,11 +1,11 @@
 error: the `Self` constructor can only be used with tuple or unit structs
-  --> $DIR/issue-56835.rs:4:12
+  --> $DIR/invalid-self-constructor-56835.rs:5:12
    |
 LL |     fn bar(Self(foo): Self) {}
    |            ^^^^^^^^^ help: use curly brackets: `Self { /* fields */ }`
 
 error[E0164]: expected tuple struct or tuple variant, found self constructor `Self`
-  --> $DIR/issue-56835.rs:4:12
+  --> $DIR/invalid-self-constructor-56835.rs:5:12
    |
 LL |     fn bar(Self(foo): Self) {}
    |            ^^^^^^^^^ not a tuple struct or tuple variant
diff --git a/tests/ui/issues/issue-59756.fixed b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.fixed
index 954ba917626..954ba917626 100644
--- a/tests/ui/issues/issue-59756.fixed
+++ b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.fixed
diff --git a/tests/ui/issues/issue-59756.rs b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.rs
index de349f43f46..570aa7d373b 100644
--- a/tests/ui/issues/issue-59756.rs
+++ b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/59756
 //@ run-rustfix
 //@ ignore-test (rustfix needs multiple suggestions)
 //
diff --git a/tests/ui/issues/issue-59756.stderr b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.stderr
index 27c07fecd5b..7182109b5a0 100644
--- a/tests/ui/issues/issue-59756.stderr
+++ b/tests/ui/suggestions/incompatible-types-in-try-expression-59756.stderr
@@ -1,5 +1,5 @@
 error[E0308]: try expression alternatives have incompatible types
-  --> $DIR/issue-59756.rs:13:5
+  --> $DIR/incompatible-types-in-try-expression-59756.rs:13:5
    |
 LL |     foo()?
    |     ^^^^^^ expected enum `std::result::Result`, found struct `A`
diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr
index 31f8f1d455a..9e068c311ae 100644
--- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr
+++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr
@@ -5,14 +5,14 @@ LL |     let _: &[i8] = data.into();
    |                         ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]`
    |
    = help: the following other types implement trait `From<T>`:
-             `[T; 10]` implements `From<(T, T, T, T, T, T, T, T, T, T)>`
-             `[T; 11]` implements `From<(T, T, T, T, T, T, T, T, T, T, T)>`
-             `[T; 12]` implements `From<(T, T, T, T, T, T, T, T, T, T, T, T)>`
              `[T; 1]` implements `From<(T,)>`
              `[T; 2]` implements `From<(T, T)>`
              `[T; 3]` implements `From<(T, T, T)>`
              `[T; 4]` implements `From<(T, T, T, T)>`
              `[T; 5]` implements `From<(T, T, T, T, T)>`
+             `[T; 6]` implements `From<(T, T, T, T, T, T)>`
+             `[T; 7]` implements `From<(T, T, T, T, T, T, T)>`
+             `[T; 8]` implements `From<(T, T, T, T, T, T, T, T)>`
            and 6 others
    = note: required for `&[u8]` to implement `Into<&[i8]>`
 
diff --git a/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs b/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs
index 29799624d78..fbede7c41cb 100644
--- a/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs
+++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.rs
@@ -32,4 +32,33 @@ fn missing_format_specifiers_multiple_unused_args() {
     //~| NOTE consider adding 2 format specifiers
 }
 
+fn unicode_unused_args() {
+    panic!("๐Ÿ‘†", "๐Ÿ‘†", 1);
+    //~^ ERROR multiple unused formatting arguments
+    //~| NOTE multiple missing formatting specifiers
+    //~| NOTE argument never used
+    //~| NOTE argument never used
+    //~| HELP format specifiers use curly braces, consider adding 2 format specifiers
+}
+
+fn raw_str_unused_arg() {
+    format_args!(r##"lJ๐ฟร†๏ฟฝ.๐ฟ๏ฟฝ"##, r#"r}J๐ฟร†" {}"#, 1);
+    //~^ ERROR multiple unused formatting arguments
+    //~| NOTE multiple missing formatting specifiers
+    //~| NOTE argument never used
+    //~| NOTE argument never used
+    //~| HELP format specifiers use curly braces, consider adding 2 format specifiers
+}
+
+fn valid_new_lines_unused_args() {
+    panic!("Expect 2 newlines
+
+", "๐Ÿ‘†", 1);
+    //~^ ERROR multiple unused formatting arguments
+    //~| NOTE argument never used
+    //~| NOTE argument never used
+    //~^^^^^^ NOTE multiple missing formatting specifiers
+    //~| HELP format specifiers use curly braces, consider adding 2 format specifiers
+}
+
 fn main() { }
diff --git a/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr b/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr
index 081409789f5..7e997241698 100644
--- a/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr
+++ b/tests/ui/suggestions/missing-format-specifiers-issue-68293.stderr
@@ -45,5 +45,52 @@ LL |     println!("list: {}", 1, 2, 3);
    |
    = note: consider adding 2 format specifiers
 
-error: aborting due to 4 previous errors
+error: multiple unused formatting arguments
+  --> $DIR/missing-format-specifiers-issue-68293.rs:36:17
+   |
+LL |     panic!("๐Ÿ‘†", "๐Ÿ‘†", 1);
+   |            ----  ^^^^  ^ argument never used
+   |            |     |
+   |            |     argument never used
+   |            multiple missing formatting specifiers
+   |
+help: format specifiers use curly braces, consider adding 2 format specifiers
+   |
+LL |     panic!("๐Ÿ‘†{}{}", "๐Ÿ‘†", 1);
+   |               ++++
+
+error: multiple unused formatting arguments
+  --> $DIR/missing-format-specifiers-issue-68293.rs:45:35
+   |
+LL |     format_args!(r##"lJ๐ฟร†๏ฟฝ.๐ฟ๏ฟฝ"##, r#"r}J๐ฟร†" {}"#, 1);
+   |                  ---------------  ^^^^^^^^^^^^^^  ^ argument never used
+   |                  |                |
+   |                  |                argument never used
+   |                  multiple missing formatting specifiers
+   |
+help: format specifiers use curly braces, consider adding 2 format specifiers
+   |
+LL |     format_args!(r##"lJ๐ฟร†๏ฟฝ.๐ฟ๏ฟฝ{}{}"##, r#"r}J๐ฟร†" {}"#, 1);
+   |                              ++++
+
+error: multiple unused formatting arguments
+  --> $DIR/missing-format-specifiers-issue-68293.rs:56:4
+   |
+LL |       panic!("Expect 2 newlines
+   |  ____________-
+LL | |
+LL | | ", "๐Ÿ‘†", 1);
+   | | -  ^^^^  ^ argument never used
+   | | |  |
+   | |_|  argument never used
+   |   multiple missing formatting specifiers
+   |
+help: format specifiers use curly braces, consider adding 2 format specifiers
+   |
+LL |     panic!("Expect 2 newlines
+LL |
+LL ~ {}{}", "๐Ÿ‘†", 1);
+   |
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/issues/issue-58857.rs b/tests/ui/trait-bounds/negative-bound-not-supported-58857.rs
index 4350d7e5b40..0a0b70a216b 100644
--- a/tests/ui/issues/issue-58857.rs
+++ b/tests/ui/trait-bounds/negative-bound-not-supported-58857.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/58857
 struct Conj<A> {a : A}
 trait Valid {}
 
diff --git a/tests/ui/issues/issue-58857.stderr b/tests/ui/trait-bounds/negative-bound-not-supported-58857.stderr
index ac70bc725e2..05347a891b4 100644
--- a/tests/ui/issues/issue-58857.stderr
+++ b/tests/ui/trait-bounds/negative-bound-not-supported-58857.stderr
@@ -1,5 +1,5 @@
 error: negative bounds are not supported
-  --> $DIR/issue-58857.rs:4:9
+  --> $DIR/negative-bound-not-supported-58857.rs:5:9
    |
 LL | impl<A: !Valid> Conj<A>{}
    |         ^
diff --git a/tests/ui/traits/const-traits/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs
index da28d9a47c3..c89aaa62d99 100644
--- a/tests/ui/traits/const-traits/const-impl-trait.rs
+++ b/tests/ui/traits/const-traits/const-impl-trait.rs
@@ -1,7 +1,5 @@
+//@ check-pass
 //@ compile-flags: -Znext-solver
-//@ known-bug: #110395
-
-// Broken until `(): const PartialEq`
 
 #![allow(incomplete_features)]
 #![feature(const_trait_impl, const_cmp, const_destruct)]
diff --git a/tests/ui/traits/const-traits/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr
deleted file mode 100644
index cbb68d8c983..00000000000
--- a/tests/ui/traits/const-traits/const-impl-trait.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0277]: the trait bound `(): const PartialEq` is not satisfied
-  --> $DIR/const-impl-trait.rs:34:17
-   |
-LL |     assert!(cmp(&()));
-   |             --- ^^^
-   |             |
-   |             required by a bound introduced by this call
-   |
-note: required by a bound in `cmp`
-  --> $DIR/const-impl-trait.rs:11:23
-   |
-LL | const fn cmp(a: &impl [const] PartialEq) -> bool {
-   |                       ^^^^^^^^^^^^^^^^^ required by this bound in `cmp`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.rs b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
index 1a3012de06f..78c25ccd6e5 100644
--- a/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
@@ -1,5 +1,4 @@
-//@ known-bug: #110395
-
+//@ check-pass
 #![feature(const_trait_impl, const_default, const_cmp, derive_const)]
 
 pub struct A;
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
deleted file mode 100644
index 4ea11a0c7ed..00000000000
--- a/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0277]: the trait bound `(): [const] PartialEq` is not satisfied
-  --> $DIR/derive-const-use.rs:16:14
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                         --------- in this derive macro expansion
-LL | pub struct S((), A);
-   |              ^^
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
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/issues/issue-58212.rs b/tests/ui/traits/generic-trait-impl-aliased-array-58212.rs
index f266db603bf..a71194ba806 100644
--- a/tests/ui/issues/issue-58212.rs
+++ b/tests/ui/traits/generic-trait-impl-aliased-array-58212.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/58212
 //@ check-pass
 
 trait FromUnchecked {
diff --git a/tests/ui/issues/issue-57156.rs b/tests/ui/traits/trait-object-lifetime-bounds-57156.rs
index 12251509abd..8f5bef7fe13 100644
--- a/tests/ui/issues/issue-57156.rs
+++ b/tests/ui/traits/trait-object-lifetime-bounds-57156.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/57156
 //@ check-pass
 
 trait Foo<Args> {
diff --git a/tests/ui/issues/issue-56229.rs b/tests/ui/traits/trait-objects-with-supertraits-56229.rs
index 1c6dd72ed2d..27cae968a6a 100644
--- a/tests/ui/issues/issue-56229.rs
+++ b/tests/ui/traits/trait-objects-with-supertraits-56229.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/56229
 //@ check-pass
 
 trait Mirror {
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
diff --git a/tests/ui/issues/issue-57924.rs b/tests/ui/typeck/self-constructor-type-args-not-allowed-57924.rs
index 8846912a8ff..2b3b11c3f38 100644
--- a/tests/ui/issues/issue-57924.rs
+++ b/tests/ui/typeck/self-constructor-type-args-not-allowed-57924.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/57924
 pub struct Gcm<E>(E);
 
 impl<E> Gcm<E> {
diff --git a/tests/ui/issues/issue-57924.stderr b/tests/ui/typeck/self-constructor-type-args-not-allowed-57924.stderr
index 40435fd0f0a..b5be5b39eb8 100644
--- a/tests/ui/issues/issue-57924.stderr
+++ b/tests/ui/typeck/self-constructor-type-args-not-allowed-57924.stderr
@@ -1,5 +1,5 @@
 error[E0109]: type arguments are not allowed on self constructor
-  --> $DIR/issue-57924.rs:5:16
+  --> $DIR/self-constructor-type-args-not-allowed-57924.rs:6:16
    |
 LL |         Self::<E>(e)
    |         ----   ^ type argument not allowed
diff --git a/tests/ui/issues/issue-56199.rs b/tests/ui/typeck/self-constructor-type-error-56199.rs
index ba11582a9d5..b08d6918980 100644
--- a/tests/ui/issues/issue-56199.rs
+++ b/tests/ui/typeck/self-constructor-type-error-56199.rs
@@ -1,3 +1,4 @@
+// https://github.com/rust-lang/rust/issues/56199
 enum Foo {}
 struct Bar {}
 
diff --git a/tests/ui/issues/issue-56199.stderr b/tests/ui/typeck/self-constructor-type-error-56199.stderr
index eb6d7005979..6e9d0fcd90c 100644
--- a/tests/ui/issues/issue-56199.stderr
+++ b/tests/ui/typeck/self-constructor-type-error-56199.stderr
@@ -1,5 +1,5 @@
 error: the `Self` constructor can only be used with tuple or unit structs
-  --> $DIR/issue-56199.rs:6:17
+  --> $DIR/self-constructor-type-error-56199.rs:7:17
    |
 LL |         let _ = Self;
    |                 ^^^^
@@ -7,7 +7,7 @@ LL |         let _ = Self;
    = help: did you mean to use one of the enum's variants?
 
 error: the `Self` constructor can only be used with tuple or unit structs
-  --> $DIR/issue-56199.rs:8:17
+  --> $DIR/self-constructor-type-error-56199.rs:9:17
    |
 LL |         let _ = Self();
    |                 ^^^^^^
@@ -15,13 +15,13 @@ LL |         let _ = Self();
    = help: did you mean to use one of the enum's variants?
 
 error: the `Self` constructor can only be used with tuple or unit structs
-  --> $DIR/issue-56199.rs:15:17
+  --> $DIR/self-constructor-type-error-56199.rs:16:17
    |
 LL |         let _ = Self;
    |                 ^^^^ help: use curly brackets: `Self { /* fields */ }`
 
 error: the `Self` constructor can only be used with tuple or unit structs
-  --> $DIR/issue-56199.rs:17:17
+  --> $DIR/self-constructor-type-error-56199.rs:18:17
    |
 LL |         let _ = Self();
    |                 ^^^^^^ help: use curly brackets: `Self { /* fields */ }`
diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout
index 924fb98ae18..96d85d1e7c1 100644
--- a/tests/ui/unpretty/exhaustive.hir.stdout
+++ b/tests/ui/unpretty/exhaustive.hir.stdout
@@ -55,7 +55,7 @@ use self::prelude::*;
      */
 #[doc = "inner doc attribute"]
 #[allow(dead_code, unused_variables)]
-#[no_std]
+#[attr = NoStd]
 mod attributes {
 
     /// outer single-line doc comment