about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock513
-rw-r--r--Cargo.toml2
-rw-r--r--compiler/rustc/Cargo.toml1
-rw-r--r--compiler/rustc_ast/src/ast.rs35
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs1
-rw-r--r--compiler/rustc_ast/src/visit.rs14
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs1
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs16
-rw-r--r--compiler/rustc_attr/src/builtin.rs68
-rw-r--r--compiler/rustc_baked_icu_data/Cargo.toml7
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs368
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs71
-rw-r--r--compiler/rustc_builtin_macros/src/cfg_eval.rs137
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/archive.rs12
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs13
-rw-r--r--compiler/rustc_codegen_gcc/src/archive.rs25
-rw-r--r--compiler/rustc_codegen_gcc/src/debuginfo.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs10
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs130
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/debuginfo.rs1
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs78
-rw-r--r--compiler/rustc_const_eval/src/check_consts/mod.rs20
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs15
-rw-r--r--compiler/rustc_data_structures/Cargo.toml9
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/marker.rs341
-rw-r--r--compiler/rustc_data_structures/src/owned_slice.rs2
-rw-r--r--compiler/rustc_data_structures/src/sharded.rs21
-rw-r--r--compiler/rustc_data_structures/src/sync.rs282
-rw-r--r--compiler/rustc_data_structures/src/sync/freeze.rs5
-rw-r--r--compiler/rustc_data_structures/src/sync/lock.rs309
-rw-r--r--compiler/rustc_data_structures/src/sync/parallel.rs236
-rw-r--r--compiler/rustc_data_structures/src/sync/vec.rs21
-rw-r--r--compiler/rustc_data_structures/src/sync/worker_local.rs44
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml5
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs7
-rw-r--r--compiler/rustc_error_messages/Cargo.toml5
-rw-r--r--compiler/rustc_error_messages/src/lib.rs27
-rw-r--r--compiler/rustc_errors/Cargo.toml5
-rw-r--r--compiler/rustc_errors/src/emitter.rs716
-rw-r--r--compiler/rustc_errors/src/json.rs7
-rw-r--r--compiler/rustc_errors/src/lib.rs19
-rw-r--r--compiler/rustc_errors/src/tests.rs5
-rw-r--r--compiler/rustc_expand/src/base.rs4
-rw-r--r--compiler/rustc_hir/src/lang_items.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs98
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs95
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs34
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs20
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs64
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs4
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs136
-rw-r--r--compiler/rustc_interface/Cargo.toml10
-rw-r--r--compiler/rustc_interface/src/passes.rs2
-rw-r--r--compiler/rustc_interface/src/util.rs14
-rw-r--r--compiler/rustc_lint/messages.ftl1
-rw-r--r--compiler/rustc_lint/src/builtin.rs18
-rw-r--r--compiler/rustc_lint/src/impl_trait_overcaptures.rs54
-rw-r--r--compiler/rustc_lint/src/lints.rs3
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp15
-rw-r--r--compiler/rustc_metadata/src/creader.rs3
-rw-r--r--compiler/rustc_metadata/src/locator.rs84
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs4
-rw-r--r--compiler/rustc_middle/Cargo.toml3
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs23
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs11
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs18
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs2
-rw-r--r--compiler/rustc_middle/src/thir.rs17
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs59
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs36
-rw-r--r--compiler/rustc_middle/src/ty/context.rs10
-rw-r--r--compiler/rustc_middle/src/ty/context/tls.rs10
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs2
-rw-r--r--compiler/rustc_middle/src/ty/generics.rs4
-rw-r--r--compiler/rustc_middle/src/ty/list.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs20
-rw-r--r--compiler/rustc_mir_build/src/build/matches/match_pair.rs8
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs14
-rw-r--r--compiler/rustc_mir_build/src/errors.rs8
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs56
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs62
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs42
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs7
-rw-r--r--compiler/rustc_mir_transform/messages.ftl2
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs100
-rw-r--r--compiler/rustc_mir_transform/src/cross_crate_inline.rs10
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs6
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs204
-rw-r--r--compiler/rustc_mir_transform/src/pass_manager.rs34
-rw-r--r--compiler/rustc_monomorphize/messages.ftl11
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs45
-rw-r--r--compiler/rustc_monomorphize/src/errors.rs14
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs2
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/abi_check.rs (renamed from compiler/rustc_monomorphize/src/collector/abi_check.rs)101
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/mod.rs23
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/move_check.rs (renamed from compiler/rustc_monomorphize/src/collector/move_check.rs)111
-rw-r--r--compiler/rustc_next_trait_solver/src/delegate.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs2
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs4
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs1231
-rw-r--r--compiler/rustc_passes/messages.ftl3
-rw-r--r--compiler/rustc_passes/src/check_attr.rs27
-rw-r--r--compiler/rustc_passes/src/errors.rs7
-rw-r--r--compiler/rustc_passes/src/stability.rs199
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs20
-rw-r--r--compiler/rustc_query_impl/Cargo.toml5
-rw-r--r--compiler/rustc_query_system/Cargo.toml7
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs13
-rw-r--r--compiler/rustc_query_system/src/query/job.rs49
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs19
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs9
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs29
-rw-r--r--compiler/rustc_session/src/config.rs138
-rw-r--r--compiler/rustc_session/src/filesearch.rs39
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_session/src/search_paths.rs59
-rw-r--r--compiler/rustc_session/src/session.rs34
-rw-r--r--compiler/rustc_span/src/hygiene.rs14
-rw-r--r--compiler/rustc_span/src/lib.rs18
-rw-r--r--compiler/rustc_span/src/source_map.rs2
-rw-r--r--compiler/rustc_span/src/span_encoding.rs14
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs11
-rw-r--r--compiler/rustc_target/src/target_features.rs34
-rw-r--r--compiler/rustc_trait_selection/messages.ftl6
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs139
-rw-r--r--compiler/rustc_trait_selection/src/solve/delegate.rs23
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs31
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs52
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs225
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs21
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_normalize.rs2
-rw-r--r--config.example.toml12
-rw-r--r--library/Cargo.lock12
-rw-r--r--library/alloc/src/alloc.rs5
-rw-r--r--library/alloc/src/boxed.rs3
-rw-r--r--library/alloc/src/collections/btree/map.rs40
-rw-r--r--library/alloc/src/collections/btree/mod.rs8
-rw-r--r--library/alloc/src/collections/btree/set.rs7
-rw-r--r--library/alloc/src/collections/btree/set_val.rs4
-rw-r--r--library/alloc/src/rc.rs7
-rw-r--r--library/alloc/src/sync.rs7
-rw-r--r--library/alloc/src/task.rs8
-rw-r--r--library/core/benches/fmt.rs14
-rw-r--r--library/core/src/cell.rs4
-rw-r--r--library/core/src/char/methods.rs50
-rw-r--r--library/core/src/clone.rs29
-rw-r--r--library/core/src/fmt/float.rs2
-rw-r--r--library/core/src/fmt/num.rs8
-rw-r--r--library/core/src/future/future.rs1
-rw-r--r--library/core/src/intrinsics/mod.rs2109
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/num/dec2flt/mod.rs2
-rw-r--r--library/core/src/num/f128.rs114
-rw-r--r--library/core/src/num/f16.rs111
-rw-r--r--library/core/src/num/f32.rs99
-rw-r--r--library/core/src/num/f64.rs99
-rw-r--r--library/core/src/num/int_macros.rs8
-rw-r--r--library/core/src/num/mod.rs5
-rw-r--r--library/core/src/num/nonzero.rs2
-rw-r--r--library/core/src/num/uint_macros.rs127
-rw-r--r--library/core/src/ops/deref.rs88
-rw-r--r--library/core/src/ops/mod.rs3
-rw-r--r--library/core/src/option.rs9
-rw-r--r--library/core/src/panic.rs9
-rw-r--r--library/core/src/primitive_docs.rs32
-rw-r--r--library/core/src/ptr/mod.rs14
-rw-r--r--library/core/src/ptr/non_null.rs2
-rw-r--r--library/core/src/result.rs1
-rw-r--r--library/core/src/slice/mod.rs26
-rw-r--r--library/core/src/str/mod.rs2
-rw-r--r--library/core/src/unicode/unicode_data.rs3
-rw-r--r--library/core/tests/clone.rs12
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/profiler_builtins/Cargo.toml3
-rw-r--r--library/std/src/collections/hash/set.rs449
-rw-r--r--library/std/src/f128.rs98
-rw-r--r--library/std/src/f16.rs97
-rw-r--r--library/std/src/f32.rs84
-rw-r--r--library/std/src/f64.rs84
-rw-r--r--library/std/src/ffi/os_str.rs8
-rw-r--r--library/std/src/ffi/os_str/tests.rs4
-rw-r--r--library/std/src/fs.rs217
-rw-r--r--library/std/src/fs/tests.rs146
-rw-r--r--library/std/src/io/mod.rs45
-rw-r--r--library/std/src/io/tests.rs14
-rw-r--r--library/std/src/os/nuttx/raw.rs2
-rw-r--r--library/std/src/path.rs8
-rw-r--r--library/std/src/path/tests.rs4
-rw-r--r--library/std/src/sync/mpmc/mod.rs2
-rw-r--r--library/std/src/sync/mpsc/mod.rs2
-rw-r--r--library/std/src/sys/os_str/bytes.rs6
-rw-r--r--library/std/src/sys/os_str/wtf8.rs6
-rw-r--r--library/std/src/sys/pal/hermit/fs.rs20
-rw-r--r--library/std/src/sys/pal/hermit/io.rs7
-rw-r--r--library/std/src/sys/pal/solid/fs.rs20
-rw-r--r--library/std/src/sys/pal/solid/io.rs7
-rw-r--r--library/std/src/sys/pal/unix/fs.rs117
-rw-r--r--library/std/src/sys/pal/unix/io.rs7
-rw-r--r--library/std/src/sys/pal/unix/pipe.rs1
-rw-r--r--library/std/src/sys/pal/unsupported/fs.rs20
-rw-r--r--library/std/src/sys/pal/unsupported/io.rs7
-rw-r--r--library/std/src/sys/pal/wasi/fs.rs20
-rw-r--r--library/std/src/sys/pal/wasi/io.rs7
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt4
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs5
-rw-r--r--library/std/src/sys/pal/windows/fs.rs114
-rw-r--r--library/std/src/sys/pal/windows/io.rs7
-rw-r--r--library/std/src/sys_common/wtf8.rs6
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/bootstrap_test.py47
-rw-r--r--src/bootstrap/defaults/config.compiler.toml1
-rw-r--r--src/bootstrap/defaults/config.library.toml1
-rw-r--r--src/bootstrap/src/core/build_steps/clean.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/clippy.rs130
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs10
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs4
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs9
-rw-r--r--src/bootstrap/src/core/builder/mod.rs1
-rw-r--r--src/bootstrap/src/core/config/config.rs80
-rw-r--r--src/bootstrap/src/core/config/tests.rs42
-rw-r--r--src/bootstrap/src/lib.rs6
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/helpers.rs2
-rw-r--r--src/build_helper/Cargo.toml (renamed from src/tools/build_helper/Cargo.toml)0
-rw-r--r--src/build_helper/README.md (renamed from src/tools/build_helper/README.md)0
-rw-r--r--src/build_helper/src/ci.rs (renamed from src/tools/build_helper/src/ci.rs)0
-rw-r--r--src/build_helper/src/drop_bomb/mod.rs (renamed from src/tools/build_helper/src/drop_bomb/mod.rs)0
-rw-r--r--src/build_helper/src/drop_bomb/tests.rs (renamed from src/tools/build_helper/src/drop_bomb/tests.rs)0
-rw-r--r--src/build_helper/src/git.rs (renamed from src/tools/build_helper/src/git.rs)0
-rw-r--r--src/build_helper/src/lib.rs (renamed from src/tools/build_helper/src/lib.rs)0
-rw-r--r--src/build_helper/src/metrics.rs (renamed from src/tools/build_helper/src/metrics.rs)0
-rw-r--r--src/build_helper/src/stage0_parser.rs (renamed from src/tools/build_helper/src/stage0_parser.rs)2
-rw-r--r--src/build_helper/src/util.rs (renamed from src/tools/build_helper/src/util.rs)0
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile4
-rwxr-xr-xsrc/ci/docker/run.sh4
-rwxr-xr-xsrc/ci/run.sh12
m---------src/doc/rust-by-example0
-rw-r--r--src/doc/rustdoc/src/read-documentation/search.md12
-rw-r--r--src/doc/unstable-book/src/language-features/asm-experimental-arch.md32
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/clean/inline.rs18
-rw-r--r--src/librustdoc/clean/mod.rs15
-rw-r--r--src/librustdoc/clean/types.rs2
-rw-r--r--src/librustdoc/clean/utils.rs55
-rw-r--r--src/librustdoc/core.rs9
-rw-r--r--src/librustdoc/doctest.rs5
-rw-r--r--src/librustdoc/html/format.rs41
-rw-r--r--src/librustdoc/html/highlight.rs7
-rw-r--r--src/librustdoc/html/markdown.rs46
-rw-r--r--src/librustdoc/html/markdown/footnotes.rs77
-rw-r--r--src/librustdoc/html/render/context.rs4
-rw-r--r--src/librustdoc/html/render/mod.rs5
-rw-r--r--src/librustdoc/html/render/print_item.rs9
-rw-r--r--src/librustdoc/html/render/search_index.rs119
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css21
-rw-r--r--src/librustdoc/html/static/js/externs.js7
-rw-r--r--src/librustdoc/html/static/js/search.js1938
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/tools/bump-stage0/Cargo.toml2
-rw-r--r--src/tools/clippy/CHANGELOG.md1
-rw-r--r--src/tools/clippy/clippy_dev/src/setup/vscode.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/utils.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/box_default.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/comparison_chain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/copies.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/missing_headers.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/drop_forget_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/infinite_iter.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/item_name_repetitions.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_const_arrays.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/large_include_file.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_find.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/same_item_push.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/utils.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_clamp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/try_err.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_next.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_next_back.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_clone.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/str_splitn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs131
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/useless_asref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_continue.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/identity_op.rs190
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs172
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_slicing.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/types/borrowed_box.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/vec_init_then_push.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs31
-rw-r--r--src/tools/clippy/clippy_utils/src/numeric_literal.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs12
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs10
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr30
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/empty.txt0
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs6
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed1
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs1
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr12
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr20
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr18
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes.stderr10
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr2
-rw-r--r--src/tools/clippy/tests/ui/identity_op.fixed46
-rw-r--r--src/tools/clippy/tests/ui/identity_op.rs44
-rw-r--r--src/tools/clippy/tests/ui/identity_op.stderr70
-rw-r--r--src/tools/clippy/tests/ui/question_mark.fixed56
-rw-r--r--src/tools/clippy/tests/ui/question_mark.rs71
-rw-r--r--src/tools/clippy/tests/ui/question_mark.stderr63
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr2
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.fixed64
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.rs67
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.stderr99
-rw-r--r--src/tools/compiletest/Cargo.toml2
-rw-r--r--src/tools/compiletest/src/directive-list.rs3
-rw-r--r--src/tools/compiletest/src/header.rs27
-rw-r--r--src/tools/compiletest/src/header/tests.rs24
-rw-r--r--src/tools/opt-dist/Cargo.toml2
-rw-r--r--src/tools/run-make-support/Cargo.toml2
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs23
-rw-r--r--src/tools/run-make-support/src/lib.rs2
-rw-r--r--src/tools/run-make-support/src/targets.rs6
-rw-r--r--src/tools/rust-analyzer/.github/workflows/autopublish.yaml1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/data.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs13
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs97
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs144
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs37
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs34
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/file_structure.rs59
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs4
-rw-r--r--src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs18
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs1
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs30
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/minicore.rs10
-rw-r--r--src/tools/rust-analyzer/docs/dev/README.md2
-rw-r--r--src/tools/rust-analyzer/docs/dev/lsp-extensions.md2
-rw-r--r--src/tools/rust-analyzer/editors/code/package-lock.json44
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json16
-rw-r--r--src/tools/rust-analyzer/editors/code/src/client.ts2
-rw-r--r--src/tools/rust-analyzer/triagebot.toml2
-rw-r--r--src/tools/rustbook/.gitignore1
-rw-r--r--src/tools/rustbook/Cargo.lock291
-rw-r--r--src/tools/rustdoc-gui-test/Cargo.toml2
-rw-r--r--src/tools/rustdoc-js/tester.js55
-rw-r--r--src/tools/suggest-tests/Cargo.toml2
-rw-r--r--src/tools/tidy/Cargo.toml2
-rw-r--r--src/tools/tidy/src/deps.rs3
-rw-r--r--src/tools/tidy/src/known_bug.rs18
-rw-r--r--src/tools/unicode-table-generator/src/range_search.rs1
-rw-r--r--src/tools/unicode-table-generator/src/raw_emitter.rs4
-rw-r--r--tests/assembly/asm/aarch64-types.rs2
-rw-r--r--tests/assembly/riscv-soft-abi-with-float-features.rs2
-rw-r--r--tests/assembly/x86_64-cmp.rs2
-rw-r--r--tests/codegen/asm/arm64ec-clobbers.rs2
-rw-r--r--tests/codegen/branch-protection-old-llvm.rs2
-rw-r--r--tests/codegen/call-metadata.rs2
-rw-r--r--tests/codegen/float/f16-f128-inline.rs29
-rw-r--r--tests/codegen/integer-cmp.rs2
-rw-r--r--tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs19
-rw-r--r--tests/codegen/try_question_mark_nop.rs3
-rw-r--r--tests/coverage-run-rustdoc/doctest.coverage4
-rw-r--r--tests/coverage/abort.cov-map8
-rw-r--r--tests/coverage/abort.coverage4
-rw-r--r--tests/coverage/assert.cov-map4
-rw-r--r--tests/coverage/async2.cov-map8
-rw-r--r--tests/coverage/async2.coverage4
-rw-r--r--tests/coverage/branch/if.cov-map18
-rw-r--r--tests/coverage/branch/if.coverage4
-rw-r--r--tests/coverage/closure.cov-map38
-rw-r--r--tests/coverage/closure.coverage4
-rw-r--r--tests/coverage/closure_bug.cov-map10
-rw-r--r--tests/coverage/closure_bug.coverage8
-rw-r--r--tests/coverage/conditions.cov-map22
-rw-r--r--tests/coverage/conditions.coverage8
-rw-r--r--tests/coverage/dead_code.cov-map12
-rw-r--r--tests/coverage/dead_code.coverage2
-rw-r--r--tests/coverage/if.cov-map4
-rw-r--r--tests/coverage/if.coverage2
-rw-r--r--tests/coverage/if_not.cov-map6
-rw-r--r--tests/coverage/inner_items.cov-map6
-rw-r--r--tests/coverage/inner_items.coverage4
-rw-r--r--tests/coverage/lazy_boolean.cov-map8
-rw-r--r--tests/coverage/lazy_boolean.coverage2
-rw-r--r--tests/coverage/loop-break.cov-map4
-rw-r--r--tests/coverage/loops_branches.cov-map12
-rw-r--r--tests/coverage/match_or_pattern.cov-map10
-rw-r--r--tests/coverage/match_or_pattern.coverage8
-rw-r--r--tests/coverage/mcdc/condition-limit.cov-map4
-rw-r--r--tests/coverage/mcdc/if.cov-map4
-rw-r--r--tests/coverage/nested_loops.cov-map4
-rw-r--r--tests/coverage/overflow.cov-map8
-rw-r--r--tests/coverage/panic_unwind.cov-map4
-rw-r--r--tests/coverage/simple_loop.cov-map4
-rw-r--r--tests/coverage/simple_loop.coverage2
-rw-r--r--tests/coverage/simple_match.cov-map4
-rw-r--r--tests/coverage/simple_match.coverage2
-rw-r--r--tests/coverage/sort_groups.cov-map20
-rw-r--r--tests/coverage/sort_groups.coverage2
-rw-r--r--tests/coverage/unicode.cov-map4
-rw-r--r--tests/coverage/unicode.coverage2
-rw-r--r--tests/coverage/unused.cov-map12
-rw-r--r--tests/coverage/uses_crate.coverage2
-rw-r--r--tests/coverage/uses_inline_crate.cov-map4
-rw-r--r--tests/coverage/uses_inline_crate.coverage4
-rw-r--r--tests/crashes/118545.rs8
-rw-r--r--tests/crashes/128232.rs15
-rw-r--r--tests/crashes/131915.rs13
-rw-r--r--tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff13
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff3
-rw-r--r--tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff11
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff11
-rw-r--r--tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff11
-rw-r--r--tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs18
-rw-r--r--tests/run-make/simd-ffi/simd.rs10
-rw-r--r--tests/rustdoc-gui/search-about-this-result.goml42
-rw-r--r--tests/rustdoc-gui/search-corrections.goml12
-rw-r--r--tests/rustdoc-js-std/bufread-fill-buf.js11
-rw-r--r--tests/rustdoc-js-std/deduplication.js1
-rw-r--r--tests/rustdoc-js-std/option-type-signatures.js157
-rw-r--r--tests/rustdoc-js-std/parser-bindings.js52
-rw-r--r--tests/rustdoc-js-std/parser-errors.js159
-rw-r--r--tests/rustdoc-js-std/parser-filter.js27
-rw-r--r--tests/rustdoc-js-std/parser-generics.js18
-rw-r--r--tests/rustdoc-js-std/parser-hof.js86
-rw-r--r--tests/rustdoc-js-std/parser-ident.js37
-rw-r--r--tests/rustdoc-js-std/parser-literal.js7
-rw-r--r--tests/rustdoc-js-std/parser-paths.js31
-rw-r--r--tests/rustdoc-js-std/parser-quote.js21
-rw-r--r--tests/rustdoc-js-std/parser-reference.js55
-rw-r--r--tests/rustdoc-js-std/parser-returned.js33
-rw-r--r--tests/rustdoc-js-std/parser-separators.js24
-rw-r--r--tests/rustdoc-js-std/parser-slice-array.js56
-rw-r--r--tests/rustdoc-js-std/parser-tuple.js65
-rw-r--r--tests/rustdoc-js-std/parser-weird-queries.js18
-rw-r--r--tests/rustdoc-js-std/path-maxeditdistance.js12
-rw-r--r--tests/rustdoc-js-std/simd-type-signatures.js20
-rw-r--r--tests/rustdoc-js-std/transmute-fail.js13
-rw-r--r--tests/rustdoc-js-std/transmute.js12
-rw-r--r--tests/rustdoc-js-std/vec-type-signatures.js12
-rw-r--r--tests/rustdoc-js-std/write.js24
-rw-r--r--tests/rustdoc-js/assoc-type-backtrack.js48
-rw-r--r--tests/rustdoc-js/assoc-type-backtrack.rs4
-rw-r--r--tests/rustdoc-js/assoc-type-unbound.js39
-rw-r--r--tests/rustdoc-js/assoc-type-unbound.rs4
-rw-r--r--tests/rustdoc-js/assoc-type.js48
-rw-r--r--tests/rustdoc-js/assoc-type.rs12
-rw-r--r--tests/rustdoc-js/case.js17
-rw-r--r--tests/rustdoc-js/case.rs7
-rw-r--r--tests/rustdoc-js/generics-impl.js8
-rw-r--r--tests/rustdoc-js/generics-impl.rs4
-rw-r--r--tests/rustdoc-js/generics-match-ambiguity-no-unbox.js68
-rw-r--r--tests/rustdoc-js/generics-match-ambiguity-no-unbox.rs18
-rw-r--r--tests/rustdoc-js/generics-match-ambiguity.js12
-rw-r--r--tests/rustdoc-js/generics-match-ambiguity.rs6
-rw-r--r--tests/rustdoc-js/generics-nested.js5
-rw-r--r--tests/rustdoc-js/generics-trait.js48
-rw-r--r--tests/rustdoc-js/generics-unbox.js4
-rw-r--r--tests/rustdoc-js/generics-unbox.rs8
-rw-r--r--tests/rustdoc-js/generics.js16
-rw-r--r--tests/rustdoc-js/hof.js25
-rw-r--r--tests/rustdoc-js/impl-trait.js6
-rw-r--r--tests/rustdoc-js/looks-like-rustc-interner.js18
-rw-r--r--tests/rustdoc-js/nested-unboxed.js9
-rw-r--r--tests/rustdoc-js/nested-unboxed.rs3
-rw-r--r--tests/rustdoc-js/non-english-identifier.js60
-rw-r--r--tests/rustdoc-js/path-maxeditdistance.js25
-rw-r--r--tests/rustdoc-js/prototype.js4
-rw-r--r--tests/rustdoc-js/reference.js15
-rw-r--r--tests/rustdoc-js/tuple-unit.js4
-rw-r--r--tests/rustdoc-js/type-parameters.js6
-rw-r--r--tests/rustdoc-ui/invalid-syntax.stderr2
-rw-r--r--tests/rustdoc/decl_macro.rs2
-rw-r--r--tests/rustdoc/footnote-ids.rs41
-rw-r--r--tests/rustdoc/footnote-reference-in-footnote-def.rs20
-rw-r--r--tests/rustdoc/heterogeneous-concat.rs11
-rw-r--r--tests/rustdoc/macro_rules-matchers.rs28
-rw-r--r--tests/ui-fulldeps/internal-lints/bad_opt_access.rs2
-rw-r--r--tests/ui-fulldeps/internal-lints/bad_opt_access.stderr2
-rw-r--r--tests/ui/asan-odr-win/asan_odr_windows.rs18
-rw-r--r--tests/ui/asan-odr-win/auxiliary/asan_odr_win-2.rs11
-rw-r--r--tests/ui/asm/aarch64/arm64ec-sve.rs2
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-3.stderr4
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-4.stderr4
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-5.stderr4
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-6.rs1
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-param-6.stderr18
-rw-r--r--tests/ui/check-cfg/mix.stderr2
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/bad-pattern.stderr13
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr4
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr4
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr4
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr4
-rw-r--r--tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg (renamed from tests/ui/codemap_tests/huge_multispan_highlight.svg)14
-rw-r--r--tests/ui/codemap_tests/huge_multispan_highlight.rs5
-rw-r--r--tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg116
-rw-r--r--tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-1.rs12
-rw-r--r--tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-1.stderr10
-rw-r--r--tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs19
-rw-r--r--tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr39
-rw-r--r--tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.rs20
-rw-r--r--tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr39
-rw-r--r--tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs366
-rw-r--r--tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.rs21
-rw-r--r--tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.stderr31
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs36
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr93
-rw-r--r--tests/ui/consts/const-pattern-irrefutable.rs27
-rw-r--r--tests/ui/consts/const-pattern-irrefutable.stderr73
-rw-r--r--tests/ui/consts/const-unstable-intrinsic.rs6
-rw-r--r--tests/ui/consts/const-unstable-intrinsic.stderr30
-rw-r--r--tests/ui/consts/const_in_pattern/incomplete-slice.stderr12
-rw-r--r--tests/ui/consts/min_const_fn/auxiliary/unmarked_const_fn_crate.rs1
-rw-r--r--tests/ui/consts/min_const_fn/auxiliary/unstable_if_unmarked_const_fn_crate.rs8
-rw-r--r--tests/ui/consts/min_const_fn/recursive_const_stab_unmarked_crate_imports.rs21
-rw-r--r--tests/ui/consts/min_const_fn/recursive_const_stab_unmarked_crate_imports.stderr28
-rw-r--r--tests/ui/consts/min_const_fn/recursive_const_stab_unstable_if_unmarked.rs24
-rw-r--r--tests/ui/consts/min_const_fn/recursive_const_stab_unstable_if_unmarked.stderr37
-rw-r--r--tests/ui/consts/rustc-const-stability-require-const.rs6
-rw-r--r--tests/ui/consts/rustc-const-stability-require-const.stderr14
-rw-r--r--tests/ui/diagnostic-width/E0271.ascii.stderr (renamed from tests/ui/diagnostic-width/E0271.stderr)4
-rw-r--r--tests/ui/diagnostic-width/E0271.rs6
-rw-r--r--tests/ui/diagnostic-width/E0271.unicode.stderr22
-rw-r--r--tests/ui/diagnostic-width/flag-human.ascii.stderr (renamed from tests/ui/diagnostic-width/flag-human.stderr)2
-rw-r--r--tests/ui/diagnostic-width/flag-human.rs6
-rw-r--r--tests/ui/diagnostic-width/flag-human.unicode.stderr11
-rw-r--r--tests/ui/diagnostic-width/long-E0308.ascii.stderr (renamed from tests/ui/diagnostic-width/long-E0308.stderr)16
-rw-r--r--tests/ui/diagnostic-width/long-E0308.rs4
-rw-r--r--tests/ui/diagnostic-width/long-E0308.unicode.stderr82
-rw-r--r--tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr (renamed from tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.stderr)2
-rw-r--r--tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs4
-rw-r--r--tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr18
-rw-r--r--tests/ui/diagnostic-width/non-whitespace-trimming-2.ascii.stderr (renamed from tests/ui/diagnostic-width/non-whitespace-trimming-2.stderr)2
-rw-r--r--tests/ui/diagnostic-width/non-whitespace-trimming-2.rs4
-rw-r--r--tests/ui/diagnostic-width/non-whitespace-trimming-2.unicode.stderr11
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.fixed52
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.stderr29
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2024.stderr31
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.rs14
-rw-r--r--tests/ui/error-emitter/highlighting.svg2
-rw-r--r--tests/ui/error-emitter/highlighting.windows.svg2
-rw-r--r--tests/ui/error-emitter/unicode-output.rs21
-rw-r--r--tests/ui/error-emitter/unicode-output.svg72
-rw-r--r--tests/ui/extern-flag/auxiliary/panic_handler.rs14
-rw-r--r--tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr42
-rw-r--r--tests/ui/feature-gates/feature-gate-coroutines.rs8
-rw-r--r--tests/ui/feature-gates/feature-gate-rustdoc_internals.rs3
-rw-r--r--tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr12
-rw-r--r--tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr22
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr4
-rw-r--r--tests/ui/impl-trait/precise-capturing/migration-note.rs15
-rw-r--r--tests/ui/impl-trait/precise-capturing/migration-note.stderr58
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.fixed13
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.rs13
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.stderr26
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed13
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs13
-rw-r--r--tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr87
-rw-r--r--tests/ui/inline-const/cross_const_control_flow.rs46
-rw-r--r--tests/ui/inline-const/cross_const_control_flow.stderr78
-rw-r--r--tests/ui/lifetimes/temporary-lifetime-extension.edition2021.run.stdout1
-rw-r--r--tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout1
-rw-r--r--tests/ui/lifetimes/temporary-lifetime-extension.rs25
-rw-r--r--tests/ui/lint/unreachable_pub.fixed116
-rw-r--r--tests/ui/lint/unreachable_pub.rs46
-rw-r--r--tests/ui/lint/unreachable_pub.stderr140
-rw-r--r--tests/ui/match/intended-binding-pattern-is-const.rs10
-rw-r--r--tests/ui/match/intended-binding-pattern-is-const.stderr27
-rw-r--r--tests/ui/mir/enable_passes_validation.all_unknown.stderr14
-rw-r--r--tests/ui/mir/enable_passes_validation.empty.stderr2
-rw-r--r--tests/ui/mir/enable_passes_validation.mixed.stderr8
-rw-r--r--tests/ui/mir/enable_passes_validation.rs21
-rw-r--r--tests/ui/mir/enable_passes_validation.unprefixed.stderr2
-rw-r--r--tests/ui/mir/issue-112269.stderr24
-rw-r--r--tests/ui/moves/auxiliary/suggest-borrow-for-generic-arg-aux.rs20
-rw-r--r--tests/ui/moves/borrow-closures-instead-of-move.rs2
-rw-r--r--tests/ui/moves/borrow-closures-instead-of-move.stderr22
-rw-r--r--tests/ui/moves/moved-value-on-as-ref-arg.stderr8
-rw-r--r--tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr4
-rw-r--r--tests/ui/moves/suggest-borrow-for-generic-arg.fixed46
-rw-r--r--tests/ui/moves/suggest-borrow-for-generic-arg.rs46
-rw-r--r--tests/ui/moves/suggest-borrow-for-generic-arg.stderr93
-rw-r--r--tests/ui/not-copy-closure.stderr4
-rw-r--r--tests/ui/parser/bad-char-literals.stderr2
-rw-r--r--tests/ui/parser/unnecessary-let.stderr8
-rw-r--r--tests/ui/pattern/usefulness/match-arm-statics-2.stderr12
-rw-r--r--tests/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr72
-rw-r--r--tests/ui/proc-macro/auxiliary/helper-attr.rs12
-rw-r--r--tests/ui/proc-macro/helper-attr-builtin-derive.rs19
-rw-r--r--tests/ui/simd-abi-checks-empty-list.rs19
-rw-r--r--tests/ui/simd-abi-checks-empty-list.stderr12
-rw-r--r--tests/ui/simd-abi-checks.rs18
-rw-r--r--tests/ui/simd-abi-checks.stderr18
-rw-r--r--tests/ui/sse-abi-checks.rs2
-rw-r--r--tests/ui/sse-abi-checks.stderr2
-rw-r--r--tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs2
-rw-r--r--tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr13
-rw-r--r--tests/ui/suggestions/no-method-found-suggest-trait-args.rs30
-rw-r--r--tests/ui/suggestions/no-method-found-suggest-trait-args.stderr63
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds.rs32
-rw-r--r--tests/ui/traits/const-traits/const-trait-bounds.stderr29
-rw-r--r--tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.current.stderr (renamed from tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.stderr)2
-rw-r--r--tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.next.stderr11
-rw-r--r--tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.rs3
-rw-r--r--tests/ui/wasm/wasm-stable-target-features.rs49
-rw-r--r--triagebot.toml46
691 files changed, 16119 insertions, 7348 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 9cca91c25df..b98c4fd0642 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -41,7 +41,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
 dependencies = [
  "cfg-if",
- "getrandom",
  "once_cell",
  "version_check",
  "zerocopy",
@@ -112,9 +111,9 @@ dependencies = [
 
 [[package]]
 name = "anstream"
-version = "0.6.15"
+version = "0.6.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
+checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338"
 dependencies = [
  "anstyle",
  "anstyle-parse",
@@ -127,65 +126,65 @@ dependencies = [
 
 [[package]]
 name = "anstyle"
-version = "1.0.8"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
 
 [[package]]
 name = "anstyle-lossy"
-version = "1.1.2"
+version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f45c79b3b9413932fc255f2c19ca0d48eaab72c4ea1913bafaebf289cbc099f2"
+checksum = "934ff8719effd2023a48cf63e69536c1c3ced9d3895068f6f5cc9a4ff845e59b"
 dependencies = [
  "anstyle",
 ]
 
 [[package]]
 name = "anstyle-parse"
-version = "0.2.5"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
 dependencies = [
  "utf8parse",
 ]
 
 [[package]]
 name = "anstyle-query"
-version = "1.1.1"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
 dependencies = [
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
 name = "anstyle-svg"
-version = "0.1.5"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "962f6d5681926dbe5503b71057202d6723a33abe464c983b1d160bca3095a3bb"
+checksum = "d3607949e9f6de49ea4bafe12f5e4fd73613ebf24795e48587302a8cc0e4bb35"
 dependencies = [
  "anstream",
  "anstyle",
  "anstyle-lossy",
  "html-escape",
- "unicode-width 0.1.14",
+ "unicode-width 0.2.0",
 ]
 
 [[package]]
 name = "anstyle-wincon"
-version = "3.0.4"
+version = "3.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
+checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
 dependencies = [
  "anstyle",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
 name = "anyhow"
-version = "1.0.89"
+version = "1.0.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
+checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13"
 dependencies = [
  "backtrace",
 ]
@@ -196,14 +195,14 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4"
 dependencies = [
- "object 0.36.4",
+ "object 0.36.5",
 ]
 
 [[package]]
 name = "arrayref"
-version = "0.3.7"
+version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
+checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
 
 [[package]]
 name = "arrayvec"
@@ -270,9 +269,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
 
 [[package]]
 name = "blake3"
-version = "1.5.2"
+version = "1.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d08263faac5cde2a4d52b513dadb80846023aade56fcd8fc99ba73ba8050e92"
+checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7"
 dependencies = [
  "arrayref",
  "arrayvec",
@@ -297,7 +296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
 dependencies = [
  "memchr",
- "regex-automata 0.4.7",
+ "regex-automata 0.4.8",
  "serde",
 ]
 
@@ -357,9 +356,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "bytes"
-version = "1.7.2"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
+checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da"
 
 [[package]]
 name = "camino"
@@ -412,9 +411,9 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.1.23"
+version = "1.1.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bbb537bb4a30b90362caddba8f360c0a56bc13d3a5570028e7197204cb54a17"
+checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9"
 dependencies = [
  "shlex",
 ]
@@ -477,9 +476,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.5.18"
+version = "4.5.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3"
+checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -497,9 +496,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.18"
+version = "4.5.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b"
+checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
 dependencies = [
  "anstream",
  "anstyle",
@@ -510,9 +509,9 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.29"
+version = "4.5.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8937760c3f4c60871870b8c3ee5f9b30771f792a7045c48bcbba999d7d6b3b8e"
+checksum = "86bc73de94bc81e52f3bebec71bc4463e9748f7a59166663e32044669577b0e2"
 dependencies = [
  "clap",
 ]
@@ -526,7 +525,7 @@ dependencies = [
  "heck 0.5.0",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -557,7 +556,7 @@ dependencies = [
  "rustc_tools_util",
  "serde",
  "serde_json",
- "syn 2.0.79",
+ "syn 2.0.87",
  "tempfile",
  "termize",
  "tokio",
@@ -600,7 +599,7 @@ dependencies = [
  "itertools",
  "quine-mc_cluskey",
  "regex",
- "regex-syntax 0.8.4",
+ "regex-syntax 0.8.5",
  "semver",
  "serde",
  "serde_json",
@@ -665,7 +664,7 @@ dependencies = [
  "nom",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -682,9 +681,9 @@ dependencies = [
 
 [[package]]
 name = "colorchoice"
-version = "1.0.2"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
 
 [[package]]
 name = "colored"
@@ -745,9 +744,9 @@ dependencies = [
 
 [[package]]
 name = "constant_time_eq"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
+checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
 
 [[package]]
 name = "core-foundation-sys"
@@ -841,9 +840,9 @@ dependencies = [
 
 [[package]]
 name = "curl"
-version = "0.4.46"
+version = "0.4.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e2161dd6eba090ff1594084e95fd67aeccf04382ffea77999ea94ed42ec67b6"
+checksum = "d9fb4d13a1be2b58f14d60adba57c9834b78c62fd86c3e76a148f732686e9265"
 dependencies = [
  "curl-sys",
  "libc",
@@ -856,9 +855,9 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.76+curl-8.10.1"
+version = "0.4.77+curl-8.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00462dbe9cbb9344e1b2be34d9094d74e3b8aac59a883495b335eafd02e25120"
+checksum = "f469e8a5991f277a208224f6c7ad72ecb5f986e36d09ae1f2c1bb9259478a480"
 dependencies = [
  "cc",
  "libc",
@@ -890,7 +889,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "strsim",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -901,7 +900,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
 dependencies = [
  "darling_core",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -938,38 +937,38 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
 name = "derive_builder"
-version = "0.20.1"
+version = "0.20.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b"
+checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947"
 dependencies = [
  "derive_builder_macro",
 ]
 
 [[package]]
 name = "derive_builder_core"
-version = "0.20.1"
+version = "0.20.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38"
+checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8"
 dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
 name = "derive_builder_macro"
-version = "0.20.1"
+version = "0.20.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc"
+checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
 dependencies = [
  "derive_builder_core",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -981,7 +980,7 @@ dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -1059,7 +1058,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -1261,6 +1260,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
 [[package]]
+name = "foldhash"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
+
+[[package]]
 name = "form_urlencoded"
 version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1296,9 +1301,9 @@ dependencies = [
 
 [[package]]
 name = "futures"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
+checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1311,9 +1316,9 @@ dependencies = [
 
 [[package]]
 name = "futures-channel"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -1321,15 +1326,15 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
+checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -1338,38 +1343,38 @@ dependencies = [
 
 [[package]]
 name = "futures-io"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
 
 [[package]]
 name = "futures-macro"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
+checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
 name = "futures-sink"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
 
 [[package]]
 name = "futures-task"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
 
 [[package]]
 name = "futures-util"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -1451,9 +1456,9 @@ dependencies = [
 
 [[package]]
 name = "gimli"
-version = "0.31.0"
+version = "0.31.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
 dependencies = [
  "fallible-iterator",
  "indexmap",
@@ -1475,8 +1480,8 @@ dependencies = [
  "aho-corasick",
  "bstr",
  "log",
- "regex-automata 0.4.7",
- "regex-syntax 0.8.4",
+ "regex-automata 0.4.8",
+ "regex-syntax 0.8.5",
 ]
 
 [[package]]
@@ -1514,6 +1519,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "hashbrown"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
+dependencies = [
+ "foldhash",
+]
+
+[[package]]
 name = "heck"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1574,7 +1588,7 @@ dependencies = [
  "markup5ever",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -1706,7 +1720,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -1747,7 +1761,7 @@ dependencies = [
  "globset",
  "log",
  "memchr",
- "regex-automata 0.4.7",
+ "regex-automata 0.4.8",
  "same-file",
  "walkdir",
  "winapi-util",
@@ -1761,12 +1775,12 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
 
 [[package]]
 name = "indexmap"
-version = "2.5.0"
+version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
+checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
 dependencies = [
  "equivalent",
- "hashbrown",
+ "hashbrown 0.15.0",
  "rustc-rayon",
  "serde",
 ]
@@ -1882,9 +1896,9 @@ dependencies = [
 
 [[package]]
 name = "js-sys"
-version = "0.3.70"
+version = "0.3.72"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
+checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -1951,9 +1965,9 @@ checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
 
 [[package]]
 name = "libc"
-version = "0.2.159"
+version = "0.2.161"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
 
 [[package]]
 name = "libdbus-sys"
@@ -1996,9 +2010,9 @@ dependencies = [
 
 [[package]]
 name = "libm"
-version = "0.2.8"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
+checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
 
 [[package]]
 name = "libredox"
@@ -2223,12 +2237,9 @@ dependencies = [
 
 [[package]]
 name = "minifier"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aa3f302fe0f8de065d4a2d1ed64f60204623cac58b80cd3c2a83a25d5a7d437"
-dependencies = [
- "clap",
-]
+checksum = "bd559bbf5d350ac7f2c1cf92ed71a869b847a92bce0c1318b47932a5b5f65cdd"
 
 [[package]]
 name = "minimal-lexical"
@@ -2454,17 +2465,17 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.36.4"
+version = "0.36.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
+checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
 dependencies = [
  "crc32fast",
  "flate2",
- "hashbrown",
+ "hashbrown 0.15.0",
  "indexmap",
  "memchr",
  "ruzstd",
- "wasmparser 0.216.0",
+ "wasmparser 0.218.0",
 ]
 
 [[package]]
@@ -2478,21 +2489,9 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.19.0"
+version = "1.20.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
-
-[[package]]
-name = "once_map"
-version = "0.4.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30c7f82d6d446dd295845094f3a76bcdc5e6183b66667334e169f019cd05e5a0"
-dependencies = [
- "ahash",
- "hashbrown",
- "parking_lot",
- "stable_deref_trait",
-]
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
 
 [[package]]
 name = "opener"
@@ -2514,9 +2513,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.103"
+version = "0.9.104"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6"
+checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"
 dependencies = [
  "cc",
  "libc",
@@ -2620,9 +2619,9 @@ dependencies = [
 
 [[package]]
 name = "pathdiff"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361"
 
 [[package]]
 name = "percent-encoding"
@@ -2641,9 +2640,9 @@ dependencies = [
 
 [[package]]
 name = "pest"
-version = "2.7.13"
+version = "2.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9"
+checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442"
 dependencies = [
  "memchr",
  "thiserror",
@@ -2652,9 +2651,9 @@ dependencies = [
 
 [[package]]
 name = "pest_derive"
-version = "2.7.13"
+version = "2.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0"
+checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd"
 dependencies = [
  "pest",
  "pest_generator",
@@ -2662,22 +2661,22 @@ dependencies = [
 
 [[package]]
 name = "pest_generator"
-version = "2.7.13"
+version = "2.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e"
+checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e"
 dependencies = [
  "pest",
  "pest_meta",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
 name = "pest_meta"
-version = "2.7.13"
+version = "2.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f"
+checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d"
 dependencies = [
  "once_cell",
  "pest",
@@ -2743,9 +2742,9 @@ dependencies = [
 
 [[package]]
 name = "pin-project-lite"
-version = "0.2.14"
+version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
+checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
 
 [[package]]
 name = "pin-utils"
@@ -2815,9 +2814,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.86"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
 dependencies = [
  "unicode-ident",
 ]
@@ -2960,9 +2959,9 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.6"
+version = "0.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b"
+checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
 dependencies = [
  "bitflags 2.6.0",
 ]
@@ -2980,14 +2979,14 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.10.6"
+version = "1.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
 dependencies = [
  "aho-corasick",
  "memchr",
- "regex-automata 0.4.7",
- "regex-syntax 0.8.4",
+ "regex-automata 0.4.8",
+ "regex-syntax 0.8.5",
 ]
 
 [[package]]
@@ -3010,13 +3009,13 @@ dependencies = [
 
 [[package]]
 name = "regex-automata"
-version = "0.4.7"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
+checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
 dependencies = [
  "aho-corasick",
  "memchr",
- "regex-syntax 0.8.4",
+ "regex-syntax 0.8.5",
 ]
 
 [[package]]
@@ -3033,9 +3032,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
 
 [[package]]
 name = "regex-syntax"
-version = "0.8.4"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
 
 [[package]]
 name = "remote-test-client"
@@ -3055,41 +3054,39 @@ dependencies = [
 
 [[package]]
 name = "rinja"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f28580fecce391f3c0e65a692e5f2b5db258ba2346ee04f355ae56473ab973dc"
+checksum = "3dc4940d00595430b3d7d5a01f6222b5e5b51395d1120bdb28d854bb8abb17a5"
 dependencies = [
  "humansize",
  "itoa",
- "num-traits",
  "percent-encoding",
  "rinja_derive",
 ]
 
 [[package]]
 name = "rinja_derive"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f1ae91455a4c82892d9513fcfa1ac8faff6c523602d0041536341882714aede"
+checksum = "08d9ed0146aef6e2825f1b1515f074510549efba38d71f4554eec32eb36ba18b"
 dependencies = [
  "basic-toml",
  "memchr",
  "mime",
  "mime_guess",
- "once_map",
  "proc-macro2",
  "quote",
  "rinja_parser",
  "rustc-hash 2.0.0",
  "serde",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
 name = "rinja_parser"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06ea17639e1f35032e1c67539856e498c04cd65fe2a45f55ec437ec55e4be941"
+checksum = "93f9a866e2e00a7a1fb27e46e9e324a6f7c0e7edc4543cae1d38f4e4a100c610"
 dependencies = [
  "memchr",
  "nom",
@@ -3109,9 +3106,9 @@ version = "0.2.0"
 dependencies = [
  "bstr",
  "build_helper",
- "gimli 0.31.0",
+ "gimli 0.31.1",
  "libc",
- "object 0.36.4",
+ "object 0.36.5",
  "regex",
  "serde_json",
  "similar",
@@ -3410,7 +3407,7 @@ dependencies = [
  "itertools",
  "libc",
  "measureme",
- "object 0.36.4",
+ "object 0.36.5",
  "rustc-demangle",
  "rustc_abi",
  "rustc_ast",
@@ -3450,7 +3447,7 @@ dependencies = [
  "itertools",
  "jobserver",
  "libc",
- "object 0.36.4",
+ "object 0.36.5",
  "pathdiff",
  "regex",
  "rustc_abi",
@@ -3698,7 +3695,7 @@ dependencies = [
  "fluent-syntax",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
  "unic-langid",
 ]
 
@@ -3833,7 +3830,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -3981,7 +3978,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
  "synstructure",
 ]
 
@@ -4446,7 +4443,7 @@ name = "rustc_target"
 version = "0.0.0"
 dependencies = [
  "bitflags 2.6.0",
- "object 0.36.4",
+ "object 0.36.5",
  "rustc_abi",
  "rustc_data_structures",
  "rustc_fs_util",
@@ -4568,7 +4565,7 @@ version = "0.0.0"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
  "synstructure",
 ]
 
@@ -4657,7 +4654,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "serde",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -4691,9 +4688,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.37"
+version = "0.38.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
+checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a"
 dependencies = [
  "bitflags 2.6.0",
  "errno",
@@ -4704,9 +4701,9 @@ dependencies = [
 
 [[package]]
 name = "rustversion"
-version = "1.0.17"
+version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
+checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
 
 [[package]]
 name = "ruzstd"
@@ -4734,9 +4731,9 @@ dependencies = [
 
 [[package]]
 name = "schannel"
-version = "0.1.24"
+version = "0.1.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b"
+checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1"
 dependencies = [
  "windows-sys 0.59.0",
 ]
@@ -4779,29 +4776,29 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.210"
+version = "1.0.214"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
+checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.210"
+version = "1.0.214"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
+checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.128"
+version = "1.0.132"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
+checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
 dependencies = [
  "indexmap",
  "itoa",
@@ -5052,9 +5049,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.79"
+version = "2.0.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
+checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -5069,7 +5066,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -5095,9 +5092,9 @@ dependencies = [
 
 [[package]]
 name = "tar"
-version = "0.4.42"
+version = "0.4.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020"
+checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6"
 dependencies = [
  "filetime",
  "libc",
@@ -5150,12 +5147,12 @@ dependencies = [
 
 [[package]]
 name = "terminal_size"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
+checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef"
 dependencies = [
  "rustix",
- "windows-sys 0.48.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -5187,22 +5184,22 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b"
 
 [[package]]
 name = "thiserror"
-version = "1.0.64"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
+checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.64"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
+checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -5212,8 +5209,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "813ba76597db32dc4f6992fd8bf8f394715b88d352fd97401da67dab6283b4c6"
 dependencies = [
  "gimli 0.30.0",
- "hashbrown",
- "object 0.36.4",
+ "hashbrown 0.14.5",
+ "object 0.36.5",
  "tracing",
 ]
 
@@ -5315,9 +5312,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.40.0"
+version = "1.41.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
+checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb"
 dependencies = [
  "backtrace",
  "bytes",
@@ -5393,7 +5390,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -5495,9 +5492,9 @@ dependencies = [
 
 [[package]]
 name = "ucd-trie"
-version = "0.1.6"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
+checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
 
 [[package]]
 name = "ui_test"
@@ -5564,24 +5561,21 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b"
 dependencies = [
  "proc-macro-hack",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
  "unic-langid-impl",
 ]
 
 [[package]]
 name = "unicase"
-version = "2.7.0"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
-dependencies = [
- "version_check",
-]
+checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df"
 
 [[package]]
 name = "unicode-bidi"
-version = "0.3.15"
+version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
+checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
 
 [[package]]
 name = "unicode-ident"
@@ -5600,9 +5594,9 @@ dependencies = [
 
 [[package]]
 name = "unicode-properties"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524"
+checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
 
 [[package]]
 name = "unicode-script"
@@ -5699,9 +5693,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 
 [[package]]
 name = "uuid"
-version = "1.10.0"
+version = "1.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
+checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
 dependencies = [
  "getrandom",
 ]
@@ -5742,15 +5736,15 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasi-preview1-component-adapter-provider"
-version = "24.0.0"
+version = "24.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36e6cadfa74538edd5409b6f8c79628436529138e9618b7373bec7aae7805835"
+checksum = "0f76d9fa52234153eeb40b088de91a8c13dc28a912cf6f31cd89ca4bac9024e0"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
+checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -5759,24 +5753,24 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
+checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
 dependencies = [
  "bumpalo",
  "log",
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
+checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -5784,22 +5778,22 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
+checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
+checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
 
 [[package]]
 name = "wasm-component-ld"
@@ -5812,7 +5806,7 @@ dependencies = [
  "lexopt",
  "tempfile",
  "wasi-preview1-component-adapter-provider",
- "wasmparser 0.219.0",
+ "wasmparser 0.219.1",
  "wat",
  "wit-component",
  "wit-parser",
@@ -5836,19 +5830,19 @@ dependencies = [
 
 [[package]]
 name = "wasm-encoder"
-version = "0.219.0"
+version = "0.219.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2b1b95711b3ad655656a341e301cc64e33cbee94de9a99a1c5a2ab88efab79d"
+checksum = "29cbbd772edcb8e7d524a82ee8cef8dd046fc14033796a754c3ad246d019fa54"
 dependencies = [
  "leb128",
- "wasmparser 0.219.0",
+ "wasmparser 0.219.1",
 ]
 
 [[package]]
 name = "wasm-metadata"
-version = "0.219.0"
+version = "0.219.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96132fe00dd17d092d2be289eeed5a0a68ad3cf30b68e8875bc953b96f55f0be"
+checksum = "2af5a8e37a5e996861e1813f8de30911c47609c9ff51a7284f7dbd754dc3a9f3"
 dependencies = [
  "anyhow",
  "indexmap",
@@ -5856,8 +5850,8 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "spdx",
- "wasm-encoder 0.219.0",
- "wasmparser 0.219.0",
+ "wasm-encoder 0.219.1",
+ "wasmparser 0.219.1",
 ]
 
 [[package]]
@@ -5872,13 +5866,22 @@ dependencies = [
 
 [[package]]
 name = "wasmparser"
-version = "0.219.0"
+version = "0.218.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b09e46c7fceceaa72b2dd1a8a137ea7fd8f93dfaa69806010a709918e496c5dc"
+dependencies = [
+ "bitflags 2.6.0",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.219.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "324b4e56d24439495b88cd81439dad5e97f3c7b1eedc3c7e10455ed1e045e9a2"
+checksum = "5c771866898879073c53b565a6c7b49953795159836714ac56a5befb581227c5"
 dependencies = [
  "ahash",
  "bitflags 2.6.0",
- "hashbrown",
+ "hashbrown 0.14.5",
  "indexmap",
  "semver",
  "serde",
@@ -5886,22 +5889,22 @@ dependencies = [
 
 [[package]]
 name = "wast"
-version = "219.0.0"
+version = "219.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06880ecb25662bc21db6a83f4fcc27c41f71fbcba4f1980b650c88ada92728e1"
+checksum = "4f79a9d9df79986a68689a6b40bcc8d5d40d807487b235bebc2ac69a242b54a1"
 dependencies = [
  "bumpalo",
  "leb128",
  "memchr",
  "unicode-width 0.1.14",
- "wasm-encoder 0.219.0",
+ "wasm-encoder 0.219.1",
 ]
 
 [[package]]
 name = "wat"
-version = "1.219.0"
+version = "1.219.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11e56dbf9fc89111b0d97c91e683d7895b1a6e5633a729f2ccad2303724005b6"
+checksum = "8bc3cf014fb336883a411cd662f987abf6a1d2a27f2f0008616a0070bbf6bd0d"
 dependencies = [
  "wast",
 ]
@@ -5957,7 +5960,7 @@ dependencies = [
  "rayon",
  "serde",
  "serde_json",
- "syn 2.0.79",
+ "syn 2.0.87",
  "windows-metadata",
 ]
 
@@ -5990,7 +5993,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -6001,7 +6004,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -6178,9 +6181,9 @@ dependencies = [
 
 [[package]]
 name = "wit-component"
-version = "0.219.0"
+version = "0.219.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99a76111c20444a814019de20499d30940ecd219b9512ee296f034a5edb18a2d"
+checksum = "ad1673163c0cb14a6a19ddbf44dd4efe6f015ec1ebb8156710ac32501f19fba2"
 dependencies = [
  "anyhow",
  "bitflags 2.6.0",
@@ -6189,17 +6192,17 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
- "wasm-encoder 0.219.0",
+ "wasm-encoder 0.219.1",
  "wasm-metadata",
- "wasmparser 0.219.0",
+ "wasmparser 0.219.1",
  "wit-parser",
 ]
 
 [[package]]
 name = "wit-parser"
-version = "0.219.0"
+version = "0.219.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23102e180c0c464f36e293d31a27b524e3ece930d7b5527d2f33f9d2c963de64"
+checksum = "4a86f669283257e8e424b9a4fc3518e3ade0b95deb9fbc0f93a1876be3eda598"
 dependencies = [
  "anyhow",
  "id-arena",
@@ -6210,7 +6213,7 @@ dependencies = [
  "serde_derive",
  "serde_json",
  "unicode-xid",
- "wasmparser 0.219.0",
+ "wasmparser 0.219.1",
 ]
 
 [[package]]
@@ -6268,7 +6271,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
  "synstructure",
 ]
 
@@ -6290,7 +6293,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
 
 [[package]]
@@ -6310,7 +6313,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
  "synstructure",
 ]
 
@@ -6333,5 +6336,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.79",
+ "syn 2.0.87",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index e1d667bf015..b773030b4ca 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,12 +2,12 @@
 resolver = "2"
 members = [
   "compiler/rustc",
+  "src/build_helper",
   "src/etc/test-float-parse",
   "src/rustc-std-workspace/rustc-std-workspace-core",
   "src/rustc-std-workspace/rustc-std-workspace-alloc",
   "src/rustc-std-workspace/rustc-std-workspace-std",
   "src/rustdoc-json-types",
-  "src/tools/build_helper",
   "src/tools/cargotest",
   "src/tools/clippy",
   "src/tools/clippy/clippy_dev",
diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml
index a2fc9d5c408..f85c30ac7ec 100644
--- a/compiler/rustc/Cargo.toml
+++ b/compiler/rustc/Cargo.toml
@@ -31,5 +31,4 @@ jemalloc = ['dep:jemalloc-sys']
 llvm = ['rustc_driver_impl/llvm']
 max_level_info = ['rustc_driver_impl/max_level_info']
 rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts']
-rustc_use_parallel_compiler = ['rustc_driver_impl/rustc_use_parallel_compiler']
 # tidy-alphabetical-end
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 997c44cffff..5f71fb97d76 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1194,7 +1194,7 @@ impl Expr {
     ///
     /// Does not ensure that the path resolves to a const param, the caller should check this.
     pub fn is_potential_trivial_const_arg(&self, strip_identity_block: bool) -> bool {
-        let this = if strip_identity_block { self.maybe_unwrap_block().1 } else { self };
+        let this = if strip_identity_block { self.maybe_unwrap_block() } else { self };
 
         if let ExprKind::Path(None, path) = &this.kind
             && path.is_potential_trivial_const_arg()
@@ -1206,14 +1206,41 @@ impl Expr {
     }
 
     /// Returns an expression with (when possible) *one* outter brace removed
-    pub fn maybe_unwrap_block(&self) -> (bool, &Expr) {
+    pub fn maybe_unwrap_block(&self) -> &Expr {
         if let ExprKind::Block(block, None) = &self.kind
             && let [stmt] = block.stmts.as_slice()
             && let StmtKind::Expr(expr) = &stmt.kind
         {
-            (true, expr)
+            expr
         } else {
-            (false, self)
+            self
+        }
+    }
+
+    /// Determines whether this expression is a macro call optionally wrapped in braces . If
+    /// `already_stripped_block` is set then we do not attempt to peel off a layer of braces.
+    ///
+    /// Returns the [`NodeId`] of the macro call and whether a layer of braces has been peeled
+    /// either before, or part of, this function.
+    pub fn optionally_braced_mac_call(
+        &self,
+        already_stripped_block: bool,
+    ) -> Option<(bool, NodeId)> {
+        match &self.kind {
+            ExprKind::Block(block, None)
+                if let [stmt] = &*block.stmts
+                    && !already_stripped_block =>
+            {
+                match &stmt.kind {
+                    StmtKind::MacCall(_) => Some((true, stmt.id)),
+                    StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
+                        Some((true, expr.id))
+                    }
+                    _ => None,
+                }
+            }
+            ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
+            _ => None,
         }
     }
 
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index d5c2bc1c7f6..0b4bfc0b36a 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -38,7 +38,6 @@ pub enum TokenTree {
 }
 
 // Ensure all fields of `TokenTree` are `DynSend` and `DynSync`.
-#[cfg(parallel_compiler)]
 fn _dummy()
 where
     Token: sync::DynSend + sync::DynSync,
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 2f8115441de..58497d70a24 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -200,8 +200,8 @@ pub trait Visitor<'ast>: Sized {
     fn visit_param_bound(&mut self, bounds: &'ast GenericBound, _ctxt: BoundKind) -> Self::Result {
         walk_param_bound(self, bounds)
     }
-    fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) {
-        walk_precise_capturing_arg(self, arg);
+    fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) -> Self::Result {
+        walk_precise_capturing_arg(self, arg)
     }
     fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result {
         walk_poly_trait_ref(self, t)
@@ -730,14 +730,10 @@ pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericB
 pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>(
     visitor: &mut V,
     arg: &'a PreciseCapturingArg,
-) {
+) -> V::Result {
     match arg {
-        PreciseCapturingArg::Lifetime(lt) => {
-            visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg);
-        }
-        PreciseCapturingArg::Arg(path, id) => {
-            visitor.visit_path(path, *id);
-        }
+        PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg),
+        PreciseCapturingArg::Arg(path, id) => visitor.visit_path(path, *id),
     }
 }
 
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 3acca94a54b..215e6d84d0f 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -45,6 +45,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     | asm::InlineAsmArch::X86_64
                     | asm::InlineAsmArch::Arm
                     | asm::InlineAsmArch::AArch64
+                    | asm::InlineAsmArch::Arm64EC
                     | asm::InlineAsmArch::RiscV32
                     | asm::InlineAsmArch::RiscV64
                     | asm::InlineAsmArch::LoongArch64
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index d646150a620..be6f2c152a4 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -204,6 +204,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                     "meant for internal use only" {
                         keyword => rustdoc_internals
                         fake_variadic => rustdoc_internals
+                        search_unbox => rustdoc_internals
                     }
                 );
             }
@@ -522,9 +523,18 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
         "consider removing `for<...>`"
     );
     gate_all!(more_qualified_paths, "usage of qualified paths in this context is experimental");
-    for &span in spans.get(&sym::yield_expr).iter().copied().flatten() {
-        if !span.at_least_rust_2024() {
-            gate!(&visitor, coroutines, span, "yield syntax is experimental");
+    // yield can be enabled either by `coroutines` or `gen_blocks`
+    if let Some(spans) = spans.get(&sym::yield_expr) {
+        for span in spans {
+            if (!visitor.features.coroutines() && !span.allows_unstable(sym::coroutines))
+                && (!visitor.features.gen_blocks() && !span.allows_unstable(sym::gen_blocks))
+            {
+                #[allow(rustc::untranslatable_diagnostic)]
+                // Don't know which of the two features to include in the
+                // error message, so I am arbitrarily picking one.
+                feature_err(&visitor.sess, sym::coroutines, *span, "yield syntax is experimental")
+                    .emit();
+            }
         }
     }
     gate_all!(gen_blocks, "gen blocks are experimental");
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 2753ac529d1..94f9727eb7f 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -16,9 +16,9 @@ use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::lint::builtin::UNEXPECTED_CFGS;
 use rustc_session::parse::feature_err;
 use rustc_session::{RustcVersion, Session};
+use rustc_span::Span;
 use rustc_span::hygiene::Transparency;
 use rustc_span::symbol::{Symbol, kw, sym};
-use rustc_span::{DUMMY_SP, Span};
 
 use crate::fluent_generated;
 use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
@@ -92,9 +92,7 @@ impl Stability {
 #[derive(HashStable_Generic)]
 pub struct ConstStability {
     pub level: StabilityLevel,
-    /// This can be `None` for functions that do not have an explicit const feature.
-    /// We still track them for recursive const stability checks.
-    pub feature: Option<Symbol>,
+    pub feature: Symbol,
     /// This is true iff the `const_stable_indirect` attribute is present.
     pub const_stable_indirect: bool,
     /// whether the function has a `#[rustc_promotable]` attribute
@@ -272,22 +270,19 @@ pub fn find_stability(
 
 /// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
 /// attributes in `attrs`. Returns `None` if no stability attributes are found.
-///
-/// `is_const_fn` indicates whether this is a function marked as `const`.
 pub fn find_const_stability(
     sess: &Session,
     attrs: &[Attribute],
     item_sp: Span,
-    is_const_fn: bool,
 ) -> Option<(ConstStability, Span)> {
     let mut const_stab: Option<(ConstStability, Span)> = None;
     let mut promotable = false;
-    let mut const_stable_indirect = None;
+    let mut const_stable_indirect = false;
 
     for attr in attrs {
         match attr.name_or_empty() {
             sym::rustc_promotable => promotable = true,
-            sym::rustc_const_stable_indirect => const_stable_indirect = Some(attr.span),
+            sym::rustc_const_stable_indirect => const_stable_indirect = true,
             sym::rustc_const_unstable => {
                 if const_stab.is_some() {
                     sess.dcx()
@@ -299,7 +294,7 @@ pub fn find_const_stability(
                     const_stab = Some((
                         ConstStability {
                             level,
-                            feature: Some(feature),
+                            feature,
                             const_stable_indirect: false,
                             promotable: false,
                         },
@@ -317,7 +312,7 @@ pub fn find_const_stability(
                     const_stab = Some((
                         ConstStability {
                             level,
-                            feature: Some(feature),
+                            feature,
                             const_stable_indirect: false,
                             promotable: false,
                         },
@@ -340,7 +335,7 @@ pub fn find_const_stability(
             }
         }
     }
-    if const_stable_indirect.is_some() {
+    if const_stable_indirect {
         match &mut const_stab {
             Some((stab, _)) => {
                 if stab.is_const_unstable() {
@@ -351,36 +346,37 @@ pub fn find_const_stability(
                     })
                 }
             }
-            _ => {}
+            _ => {
+                // This function has no const stability attribute, but has `const_stable_indirect`.
+                // We ignore that; unmarked functions are subject to recursive const stability
+                // checks by default so we do carry out the user's intent.
+            }
         }
     }
-    // Make sure if `const_stable_indirect` is present, that is recorded. Also make sure all `const
-    // fn` get *some* marker, since we are a staged_api crate and therefore will do recursive const
-    // stability checks for them. We need to do this because the default for whether an unmarked
-    // function enforces recursive stability differs between staged-api crates and force-unmarked
-    // crates: in force-unmarked crates, only functions *explicitly* marked `const_stable_indirect`
-    // enforce recursive stability. Therefore when `lookup_const_stability` is `None`, we have to
-    // assume the function does not have recursive stability. All functions that *do* have recursive
-    // stability must explicitly record this, and so that's what we do for all `const fn` in a
-    // staged_api crate.
-    if (is_const_fn || const_stable_indirect.is_some()) && const_stab.is_none() {
-        let c = ConstStability {
-            feature: None,
-            const_stable_indirect: const_stable_indirect.is_some(),
-            promotable: false,
-            level: StabilityLevel::Unstable {
-                reason: UnstableReason::Default,
-                issue: None,
-                is_soft: false,
-                implied_by: None,
-            },
-        };
-        const_stab = Some((c, const_stable_indirect.unwrap_or(DUMMY_SP)));
-    }
 
     const_stab
 }
 
+/// Calculates the const stability for a const function in a `-Zforce-unstable-if-unmarked` crate
+/// without the `staged_api` feature.
+pub fn unmarked_crate_const_stab(
+    _sess: &Session,
+    attrs: &[Attribute],
+    regular_stab: Stability,
+) -> ConstStability {
+    assert!(regular_stab.level.is_unstable());
+    // The only attribute that matters here is `rustc_const_stable_indirect`.
+    // We enforce recursive const stability rules for those functions.
+    let const_stable_indirect =
+        attrs.iter().any(|a| a.name_or_empty() == sym::rustc_const_stable_indirect);
+    ConstStability {
+        feature: regular_stab.feature,
+        const_stable_indirect,
+        promotable: false,
+        level: regular_stab.level,
+    }
+}
+
 /// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`.
 /// Returns `None` if no stability attributes are found.
 pub fn find_body_stability(
diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml
index e6cfb4887c9..c35556dcf5b 100644
--- a/compiler/rustc_baked_icu_data/Cargo.toml
+++ b/compiler/rustc_baked_icu_data/Cargo.toml
@@ -8,11 +8,6 @@ edition = "2021"
 icu_list = "1.2"
 icu_locid = "1.2"
 icu_locid_transform = "1.3.2"
-icu_provider = "1.2"
+icu_provider = { version = "1.2", features = ["sync"] }
 zerovec = "0.10.0"
 # tidy-alphabetical-end
-
-[features]
-# tidy-alphabetical-start
-rustc_use_parallel_compiler = ['icu_provider/sync']
-# tidy-alphabetical-end
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index e5b28289faa..454fd14ea74 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -27,7 +27,7 @@ use rustc_middle::mir::{
 };
 use rustc_middle::ty::print::PrintTraitRefExt as _;
 use rustc_middle::ty::{
-    self, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast,
+    self, ClauseKind, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast,
     suggest_constraining_type_params,
 };
 use rustc_middle::util::CallKind;
@@ -39,6 +39,7 @@ use rustc_span::{BytePos, Span, Symbol};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
 use rustc_trait_selection::infer::InferCtxtExt;
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt};
 use tracing::{debug, instrument};
 
@@ -201,16 +202,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
 
                 let mut has_suggest_reborrow = false;
                 if !seen_spans.contains(&move_span) {
-                    if !closure {
-                        self.suggest_ref_or_clone(
-                            mpi,
-                            &mut err,
-                            &mut in_pattern,
-                            move_spans,
-                            moved_place.as_ref(),
-                            &mut has_suggest_reborrow,
-                        );
-                    }
+                    self.suggest_ref_or_clone(
+                        mpi,
+                        &mut err,
+                        &mut in_pattern,
+                        move_spans,
+                        moved_place.as_ref(),
+                        &mut has_suggest_reborrow,
+                        closure,
+                    );
 
                     let msg_opt = CapturedMessageOpt {
                         is_partial_move,
@@ -266,27 +266,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 }
             }
 
-            let opt_name = self.describe_place_with_options(place.as_ref(), DescribePlaceOpt {
-                including_downcast: true,
-                including_tuple_field: true,
-            });
-            let note_msg = match opt_name {
-                Some(name) => format!("`{name}`"),
-                None => "value".to_owned(),
-            };
-            if self.suggest_borrow_fn_like(&mut err, ty, &move_site_vec, &note_msg)
-                || if let UseSpans::FnSelfUse { kind, .. } = use_spans
-                    && let CallKind::FnCall { fn_trait_id, self_ty } = kind
-                    && let ty::Param(_) = self_ty.kind()
-                    && ty == self_ty
-                    && self.infcx.tcx.is_lang_item(fn_trait_id, LangItem::FnOnce)
-                {
-                    // this is a type parameter `T: FnOnce()`, don't suggest `T: FnOnce() + Clone`.
-                    true
-                } else {
-                    false
-                }
-            {
+            if self.param_env.caller_bounds().iter().any(|c| {
+                c.as_trait_clause().is_some_and(|pred| {
+                    pred.skip_binder().self_ty() == ty && self.infcx.tcx.is_fn_trait(pred.def_id())
+                })
+            }) {
                 // Suppress the next suggestion since we don't want to put more bounds onto
                 // something that already has `Fn`-like bounds (or is a closure), so we can't
                 // restrict anyways.
@@ -295,6 +279,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 self.suggest_adding_bounds(&mut err, ty, copy_did, span);
             }
 
+            let opt_name = self.describe_place_with_options(place.as_ref(), DescribePlaceOpt {
+                including_downcast: true,
+                including_tuple_field: true,
+            });
+            let note_msg = match opt_name {
+                Some(name) => format!("`{name}`"),
+                None => "value".to_owned(),
+            };
             if needs_note {
                 if let Some(local) = place.as_local() {
                     let span = self.body.local_decls[local].source_info.span;
@@ -341,6 +333,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         move_spans: UseSpans<'tcx>,
         moved_place: PlaceRef<'tcx>,
         has_suggest_reborrow: &mut bool,
+        moved_or_invoked_closure: bool,
     ) {
         let move_span = match move_spans {
             UseSpans::ClosureUse { capture_kind_span, .. } => capture_kind_span,
@@ -428,104 +421,76 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 }
                 let typeck = self.infcx.tcx.typeck(self.mir_def_id());
                 let parent = self.infcx.tcx.parent_hir_node(expr.hir_id);
-                let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
+                let (def_id, call_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
                     && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
                 {
-                    (typeck.type_dependent_def_id(parent_expr.hir_id), args, 1)
+                    let def_id = typeck.type_dependent_def_id(parent_expr.hir_id);
+                    (def_id, Some(parent_expr.hir_id), args, 1)
                 } else if let hir::Node::Expr(parent_expr) = parent
                     && let hir::ExprKind::Call(call, args) = parent_expr.kind
                     && let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
                 {
-                    (Some(*def_id), args, 0)
+                    (Some(*def_id), Some(call.hir_id), args, 0)
                 } else {
-                    (None, &[][..], 0)
+                    (None, None, &[][..], 0)
                 };
+                let ty = place.ty(self.body, self.infcx.tcx).ty;
 
-                // If the moved value is a mut reference, it is used in a
-                // generic function and it's type is a generic param, it can be
-                // reborrowed to avoid moving.
-                // for example:
-                // struct Y(u32);
-                // x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`.
+                let mut can_suggest_clone = true;
                 if let Some(def_id) = def_id
-                    && self.infcx.tcx.def_kind(def_id).is_fn_like()
                     && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
-                    && let Some(arg) = self
-                        .infcx
-                        .tcx
-                        .fn_sig(def_id)
-                        .skip_binder()
-                        .skip_binder()
-                        .inputs()
-                        .get(pos + offset)
-                    && let ty::Param(_) = arg.kind()
                 {
-                    let place = &self.move_data.move_paths[mpi].place;
-                    let ty = place.ty(self.body, self.infcx.tcx).ty;
-                    if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
+                    // The move occurred as one of the arguments to a function call. Is that
+                    // argument generic? `def_id` can't be a closure here, so using `fn_sig` is fine
+                    let arg_param = if self.infcx.tcx.def_kind(def_id).is_fn_like()
+                        && let sig =
+                            self.infcx.tcx.fn_sig(def_id).instantiate_identity().skip_binder()
+                        && let Some(arg_ty) = sig.inputs().get(pos + offset)
+                        && let ty::Param(arg_param) = arg_ty.kind()
+                    {
+                        Some(arg_param)
+                    } else {
+                        None
+                    };
+
+                    // If the moved value is a mut reference, it is used in a
+                    // generic function and it's type is a generic param, it can be
+                    // reborrowed to avoid moving.
+                    // for example:
+                    // struct Y(u32);
+                    // x's type is '& mut Y' and it is used in `fn generic<T>(x: T) {}`.
+                    if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind()
+                        && arg_param.is_some()
+                    {
                         *has_suggest_reborrow = true;
                         self.suggest_reborrow(err, expr.span, moved_place);
                         return;
                     }
-                }
 
-                let mut can_suggest_clone = true;
-                if let Some(def_id) = def_id
-                    && let Some(local_def_id) = def_id.as_local()
-                    && let node = self.infcx.tcx.hir_node_by_def_id(local_def_id)
-                    && let Some(fn_sig) = node.fn_sig()
-                    && let Some(ident) = node.ident()
-                    && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
-                    && let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
-                {
-                    let mut is_mut = false;
-                    if let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = arg.kind
-                        && let Res::Def(DefKind::TyParam, param_def_id) = path.res
-                        && self
-                            .infcx
-                            .tcx
-                            .predicates_of(def_id)
-                            .instantiate_identity(self.infcx.tcx)
-                            .predicates
-                            .into_iter()
-                            .any(|pred| {
-                                if let ty::ClauseKind::Trait(predicate) = pred.kind().skip_binder()
-                                    && [
-                                        self.infcx.tcx.get_diagnostic_item(sym::AsRef),
-                                        self.infcx.tcx.get_diagnostic_item(sym::AsMut),
-                                        self.infcx.tcx.get_diagnostic_item(sym::Borrow),
-                                        self.infcx.tcx.get_diagnostic_item(sym::BorrowMut),
-                                    ]
-                                    .contains(&Some(predicate.def_id()))
-                                    && let ty::Param(param) = predicate.self_ty().kind()
-                                    && let generics = self.infcx.tcx.generics_of(def_id)
-                                    && let param = generics.type_param(*param, self.infcx.tcx)
-                                    && param.def_id == param_def_id
-                                {
-                                    if [
-                                        self.infcx.tcx.get_diagnostic_item(sym::AsMut),
-                                        self.infcx.tcx.get_diagnostic_item(sym::BorrowMut),
-                                    ]
-                                    .contains(&Some(predicate.def_id()))
-                                    {
-                                        is_mut = true;
-                                    }
-                                    true
-                                } else {
-                                    false
-                                }
-                            })
+                    // If the moved place is used generically by the callee and a reference to it
+                    // would still satisfy any bounds on its type, suggest borrowing.
+                    if let Some(&param) = arg_param
+                        && let Some(generic_args) = call_id.and_then(|id| typeck.node_args_opt(id))
+                        && let Some(ref_mutability) = self.suggest_borrow_generic_arg(
+                            err,
+                            def_id,
+                            generic_args,
+                            param,
+                            moved_place,
+                            pos + offset,
+                            ty,
+                            expr.span,
+                        )
                     {
-                        // The type of the argument corresponding to the expression that got moved
-                        // is a type parameter `T`, which is has a `T: AsRef` obligation.
-                        err.span_suggestion_verbose(
-                            expr.span.shrink_to_lo(),
-                            "borrow the value to avoid moving it",
-                            format!("&{}", if is_mut { "mut " } else { "" }),
-                            Applicability::MachineApplicable,
-                        );
-                        can_suggest_clone = is_mut;
-                    } else {
+                        can_suggest_clone = ref_mutability.is_mut();
+                    } else if let Some(local_def_id) = def_id.as_local()
+                        && let node = self.infcx.tcx.hir_node_by_def_id(local_def_id)
+                        && let Some(fn_decl) = node.fn_decl()
+                        && let Some(ident) = node.ident()
+                        && let Some(arg) = fn_decl.inputs.get(pos + offset)
+                    {
+                        // If we can't suggest borrowing in the call, but the function definition
+                        // is local, instead offer changing the function to borrow that argument.
                         let mut span: MultiSpan = arg.span.into();
                         span.push_span_label(
                             arg.span,
@@ -546,8 +511,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         );
                     }
                 }
-                let place = &self.move_data.move_paths[mpi].place;
-                let ty = place.ty(self.body, self.infcx.tcx).ty;
                 if let hir::Node::Expr(parent_expr) = parent
                     && let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
                     && let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IntoIterIntoIter, _)) =
@@ -557,6 +520,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 } else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans
                 {
                     // We already suggest cloning for these cases in `explain_captures`.
+                } else if moved_or_invoked_closure {
+                    // Do not suggest `closure.clone()()`.
                 } else if let UseSpans::ClosureUse {
                     closure_kind:
                         ClosureKind::Coroutine(CoroutineKind::Desugared(_, CoroutineSource::Block)),
@@ -665,6 +630,113 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         );
     }
 
+    /// If a place is used after being moved as an argument to a function, the function is generic
+    /// in that argument, and a reference to the argument's type would still satisfy the function's
+    /// bounds, suggest borrowing. This covers, e.g., borrowing an `impl Fn()` argument being passed
+    /// in an `impl FnOnce()` position.
+    /// Returns `Some(mutability)` when suggesting to borrow with mutability `mutability`, or `None`
+    /// if no suggestion is made.
+    fn suggest_borrow_generic_arg(
+        &self,
+        err: &mut Diag<'_>,
+        callee_did: DefId,
+        generic_args: ty::GenericArgsRef<'tcx>,
+        param: ty::ParamTy,
+        moved_place: PlaceRef<'tcx>,
+        moved_arg_pos: usize,
+        moved_arg_ty: Ty<'tcx>,
+        place_span: Span,
+    ) -> Option<ty::Mutability> {
+        let tcx = self.infcx.tcx;
+        let sig = tcx.fn_sig(callee_did).instantiate_identity().skip_binder();
+        let clauses = tcx.predicates_of(callee_did).instantiate_identity(self.infcx.tcx).predicates;
+
+        // First, is there at least one method on one of `param`'s trait bounds?
+        // This keeps us from suggesting borrowing the argument to `mem::drop`, e.g.
+        if !clauses.iter().any(|clause| {
+            clause.as_trait_clause().is_some_and(|tc| {
+                tc.self_ty().skip_binder().is_param(param.index)
+                    && tc.polarity() == ty::PredicatePolarity::Positive
+                    && tcx
+                        .supertrait_def_ids(tc.def_id())
+                        .flat_map(|trait_did| tcx.associated_items(trait_did).in_definition_order())
+                        .any(|item| item.fn_has_self_parameter)
+            })
+        }) {
+            return None;
+        }
+
+        // Try borrowing a shared reference first, then mutably.
+        if let Some(mutbl) = [ty::Mutability::Not, ty::Mutability::Mut].into_iter().find(|&mutbl| {
+            let re = self.infcx.tcx.lifetimes.re_erased;
+            let ref_ty = Ty::new_ref(self.infcx.tcx, re, moved_arg_ty, mutbl);
+
+            // Ensure that substituting `ref_ty` in the callee's signature doesn't break
+            // other inputs or the return type.
+            let new_args = tcx.mk_args_from_iter(generic_args.iter().enumerate().map(
+                |(i, arg)| {
+                    if i == param.index as usize { ref_ty.into() } else { arg }
+                },
+            ));
+            let can_subst = |ty: Ty<'tcx>| {
+                // Normalize before comparing to see through type aliases and projections.
+                let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args);
+                let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_args);
+                if let Ok(old_ty) = tcx.try_normalize_erasing_regions(self.param_env, old_ty)
+                    && let Ok(new_ty) = tcx.try_normalize_erasing_regions(self.param_env, new_ty)
+                {
+                    old_ty == new_ty
+                } else {
+                    false
+                }
+            };
+            if !can_subst(sig.output())
+                || sig
+                    .inputs()
+                    .iter()
+                    .enumerate()
+                    .any(|(i, &input_ty)| i != moved_arg_pos && !can_subst(input_ty))
+            {
+                return false;
+            }
+
+            // Test the callee's predicates, substituting a reference in for the self ty
+            // in bounds on `param`.
+            clauses.iter().all(|&clause| {
+                let clause_for_ref = clause.kind().map_bound(|kind| match kind {
+                    ClauseKind::Trait(c) if c.self_ty().is_param(param.index) => {
+                        ClauseKind::Trait(c.with_self_ty(tcx, ref_ty))
+                    }
+                    ClauseKind::Projection(c) if c.self_ty().is_param(param.index) => {
+                        ClauseKind::Projection(c.with_self_ty(tcx, ref_ty))
+                    }
+                    _ => kind,
+                });
+                self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
+                    tcx,
+                    ObligationCause::dummy(),
+                    self.param_env,
+                    ty::EarlyBinder::bind(clause_for_ref).instantiate(tcx, generic_args),
+                ))
+            })
+        }) {
+            let place_desc = if let Some(desc) = self.describe_place(moved_place) {
+                format!("`{desc}`")
+            } else {
+                "here".to_owned()
+            };
+            err.span_suggestion_verbose(
+                place_span.shrink_to_lo(),
+                format!("consider {}borrowing {place_desc}", mutbl.mutably_str()),
+                mutbl.ref_prefix_str(),
+                Applicability::MaybeIncorrect,
+            );
+            Some(mutbl)
+        } else {
+            None
+        }
+    }
+
     fn report_use_of_uninitialized(
         &self,
         mpi: MovePathIndex,
@@ -845,74 +917,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         );
     }
 
-    fn suggest_borrow_fn_like(
-        &self,
-        err: &mut Diag<'_>,
-        ty: Ty<'tcx>,
-        move_sites: &[MoveSite],
-        value_name: &str,
-    ) -> bool {
-        let tcx = self.infcx.tcx;
-
-        // Find out if the predicates show that the type is a Fn or FnMut
-        let find_fn_kind_from_did = |(pred, _): (ty::Clause<'tcx>, _)| {
-            if let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
-                && pred.self_ty() == ty
-            {
-                if tcx.is_lang_item(pred.def_id(), LangItem::Fn) {
-                    return Some(hir::Mutability::Not);
-                } else if tcx.is_lang_item(pred.def_id(), LangItem::FnMut) {
-                    return Some(hir::Mutability::Mut);
-                }
-            }
-            None
-        };
-
-        // If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably)
-        // borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`.
-        // These types seem reasonably opaque enough that they could be instantiated with their
-        // borrowed variants in a function body when we see a move error.
-        let borrow_level = match *ty.kind() {
-            ty::Param(_) => tcx
-                .explicit_predicates_of(self.mir_def_id().to_def_id())
-                .predicates
-                .iter()
-                .copied()
-                .find_map(find_fn_kind_from_did),
-            ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => tcx
-                .explicit_item_super_predicates(def_id)
-                .iter_instantiated_copied(tcx, args)
-                .find_map(|(clause, span)| find_fn_kind_from_did((clause, span))),
-            ty::Closure(_, args) => match args.as_closure().kind() {
-                ty::ClosureKind::Fn => Some(hir::Mutability::Not),
-                ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
-                _ => None,
-            },
-            _ => None,
-        };
-
-        let Some(borrow_level) = borrow_level else {
-            return false;
-        };
-        let sugg = move_sites
-            .iter()
-            .map(|move_site| {
-                let move_out = self.move_data.moves[(*move_site).moi];
-                let moved_place = &self.move_data.move_paths[move_out.path].place;
-                let move_spans = self.move_spans(moved_place.as_ref(), move_out.source);
-                let move_span = move_spans.args_or_use();
-                let suggestion = borrow_level.ref_prefix_str().to_owned();
-                (move_span.shrink_to_lo(), suggestion)
-            })
-            .collect();
-        err.multipart_suggestion_verbose(
-            format!("consider {}borrowing {value_name}", borrow_level.mutably_str()),
-            sugg,
-            Applicability::MaybeIncorrect,
-        );
-        true
-    }
-
     /// In a move error that occurs on a call within a loop, we try to identify cases where cloning
     /// the value would lead to a logic error. We infer these cases by seeing if the moved value is
     /// part of the logic to break the loop, either through an explicit `break` or if the expression
diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs
index bfd7e83501c..d77c53a3984 100644
--- a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs
@@ -4,15 +4,16 @@
 use std::ops::ControlFlow;
 
 use either::Either;
+use itertools::Itertools as _;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{Applicability, Diag};
+use rustc_errors::{Diag, Subdiagnostic};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::mir::{self, ConstraintCategory, Location};
 use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
-use rustc_span::Symbol;
+use rustc_trait_selection::errors::impl_trait_overcapture_suggestion;
 
 use crate::MirBorrowckCtxt;
 use crate::borrow_set::BorrowData;
@@ -61,6 +62,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             // *does* mention. We'll use that for the `+ use<'a>` suggestion below.
             let mut visitor = CheckExplicitRegionMentionAndCollectGenerics {
                 tcx,
+                generics: tcx.generics_of(opaque_def_id),
                 offending_region_idx,
                 seen_opaques: [opaque_def_id].into_iter().collect(),
                 seen_lifetimes: Default::default(),
@@ -83,34 +85,50 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                         "this call may capture more lifetimes than intended, \
                         because Rust 2024 has adjusted the `impl Trait` lifetime capture rules",
                     );
-                    let mut seen_generics: Vec<_> =
-                        visitor.seen_lifetimes.iter().map(ToString::to_string).collect();
-                    // Capture all in-scope ty/const params.
-                    seen_generics.extend(
-                        ty::GenericArgs::identity_for_item(tcx, opaque_def_id)
-                            .iter()
-                            .filter(|arg| {
-                                matches!(
-                                    arg.unpack(),
-                                    ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_)
-                                )
-                            })
-                            .map(|arg| arg.to_string()),
-                    );
-                    if opaque_def_id.is_local() {
-                        diag.span_suggestion_verbose(
-                            tcx.def_span(opaque_def_id).shrink_to_hi(),
-                            "add a precise capturing bound to avoid overcapturing",
-                            format!(" + use<{}>", seen_generics.join(", ")),
-                            Applicability::MaybeIncorrect,
-                        );
+                    let mut captured_args = visitor.seen_lifetimes;
+                    // Add in all of the type and const params, too.
+                    // Ordering here is kinda strange b/c we're walking backwards,
+                    // but we're trying to provide *a* suggestion, not a nice one.
+                    let mut next_generics = Some(visitor.generics);
+                    let mut any_synthetic = false;
+                    while let Some(generics) = next_generics {
+                        for param in &generics.own_params {
+                            if param.kind.is_ty_or_const() {
+                                captured_args.insert(param.def_id);
+                            }
+                            if param.kind.is_synthetic() {
+                                any_synthetic = true;
+                            }
+                        }
+                        next_generics = generics.parent.map(|def_id| tcx.generics_of(def_id));
+                    }
+
+                    if let Some(opaque_def_id) = opaque_def_id.as_local()
+                        && let hir::OpaqueTyOrigin::FnReturn { parent, .. } =
+                            tcx.hir().expect_opaque_ty(opaque_def_id).origin
+                    {
+                        if let Some(sugg) = impl_trait_overcapture_suggestion(
+                            tcx,
+                            opaque_def_id,
+                            parent,
+                            captured_args,
+                        ) {
+                            sugg.add_to_diag(diag);
+                        }
                     } else {
                         diag.span_help(
                             tcx.def_span(opaque_def_id),
                             format!(
                                 "if you can modify this crate, add a precise \
                                 capturing bound to avoid overcapturing: `+ use<{}>`",
-                                seen_generics.join(", ")
+                                if any_synthetic {
+                                    "/* Args */".to_string()
+                                } else {
+                                    captured_args
+                                        .into_iter()
+                                        .map(|def_id| tcx.item_name(def_id))
+                                        .join(", ")
+                                }
                             ),
                         );
                     }
@@ -182,9 +200,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindOpaqueRegion<'_, 'tcx> {
 
 struct CheckExplicitRegionMentionAndCollectGenerics<'tcx> {
     tcx: TyCtxt<'tcx>,
+    generics: &'tcx ty::Generics,
     offending_region_idx: usize,
     seen_opaques: FxIndexSet<DefId>,
-    seen_lifetimes: FxIndexSet<Symbol>,
+    seen_lifetimes: FxIndexSet<DefId>,
 }
 
 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for CheckExplicitRegionMentionAndCollectGenerics<'tcx> {
@@ -214,7 +233,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for CheckExplicitRegionMentionAndCollectGen
                 if param.index as usize == self.offending_region_idx {
                     ControlFlow::Break(())
                 } else {
-                    self.seen_lifetimes.insert(param.name);
+                    self.seen_lifetimes.insert(self.generics.region_param(param, self.tcx).def_id);
                     ControlFlow::Continue(())
                 }
             }
diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs
index b686a8cf935..f419c1e776b 100644
--- a/compiler/rustc_builtin_macros/src/cfg_eval.rs
+++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs
@@ -39,50 +39,10 @@ pub(crate) fn cfg_eval(
     let features = Some(features);
     CfgEval(StripUnconfigured { sess, features, config_tokens: true, lint_node_id })
         .configure_annotatable(annotatable)
-        // Since the item itself has already been configured by the `InvocationCollector`,
-        // we know that fold result vector will contain exactly one element.
-        .unwrap()
 }
 
 struct CfgEval<'a>(StripUnconfigured<'a>);
 
-fn flat_map_annotatable(
-    vis: &mut impl MutVisitor,
-    annotatable: Annotatable,
-) -> Option<Annotatable> {
-    match annotatable {
-        Annotatable::Item(item) => vis.flat_map_item(item).pop().map(Annotatable::Item),
-        Annotatable::AssocItem(item, ctxt) => {
-            Some(Annotatable::AssocItem(vis.flat_map_assoc_item(item, ctxt).pop()?, ctxt))
-        }
-        Annotatable::ForeignItem(item) => {
-            vis.flat_map_foreign_item(item).pop().map(Annotatable::ForeignItem)
-        }
-        Annotatable::Stmt(stmt) => {
-            vis.flat_map_stmt(stmt.into_inner()).pop().map(P).map(Annotatable::Stmt)
-        }
-        Annotatable::Expr(mut expr) => {
-            vis.visit_expr(&mut expr);
-            Some(Annotatable::Expr(expr))
-        }
-        Annotatable::Arm(arm) => vis.flat_map_arm(arm).pop().map(Annotatable::Arm),
-        Annotatable::ExprField(field) => {
-            vis.flat_map_expr_field(field).pop().map(Annotatable::ExprField)
-        }
-        Annotatable::PatField(fp) => vis.flat_map_pat_field(fp).pop().map(Annotatable::PatField),
-        Annotatable::GenericParam(param) => {
-            vis.flat_map_generic_param(param).pop().map(Annotatable::GenericParam)
-        }
-        Annotatable::Param(param) => vis.flat_map_param(param).pop().map(Annotatable::Param),
-        Annotatable::FieldDef(sf) => vis.flat_map_field_def(sf).pop().map(Annotatable::FieldDef),
-        Annotatable::Variant(v) => vis.flat_map_variant(v).pop().map(Annotatable::Variant),
-        Annotatable::Crate(mut krate) => {
-            vis.visit_crate(&mut krate);
-            Some(Annotatable::Crate(krate))
-        }
-    }
-}
-
 fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
     struct CfgFinder;
 
@@ -106,14 +66,7 @@ fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
         Annotatable::ForeignItem(item) => CfgFinder.visit_foreign_item(item),
         Annotatable::Stmt(stmt) => CfgFinder.visit_stmt(stmt),
         Annotatable::Expr(expr) => CfgFinder.visit_expr(expr),
-        Annotatable::Arm(arm) => CfgFinder.visit_arm(arm),
-        Annotatable::ExprField(field) => CfgFinder.visit_expr_field(field),
-        Annotatable::PatField(field) => CfgFinder.visit_pat_field(field),
-        Annotatable::GenericParam(param) => CfgFinder.visit_generic_param(param),
-        Annotatable::Param(param) => CfgFinder.visit_param(param),
-        Annotatable::FieldDef(field) => CfgFinder.visit_field_def(field),
-        Annotatable::Variant(variant) => CfgFinder.visit_variant(variant),
-        Annotatable::Crate(krate) => CfgFinder.visit_crate(krate),
+        _ => unreachable!(),
     };
     res.is_break()
 }
@@ -123,11 +76,11 @@ impl CfgEval<'_> {
         self.0.configure(node)
     }
 
-    fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Option<Annotatable> {
+    fn configure_annotatable(mut self, annotatable: Annotatable) -> Annotatable {
         // Tokenizing and re-parsing the `Annotatable` can have a significant
         // performance impact, so try to avoid it if possible
         if !has_cfg_or_cfg_attr(&annotatable) {
-            return Some(annotatable);
+            return annotatable;
         }
 
         // The majority of parsed attribute targets will never need to have early cfg-expansion
@@ -140,39 +93,6 @@ impl CfgEval<'_> {
         // the location of `#[cfg]` and `#[cfg_attr]` in the token stream. The tokenization
         // process is lossless, so this process is invisible to proc-macros.
 
-        let parse_annotatable_with: for<'a> fn(&mut Parser<'a>) -> PResult<'a, _> =
-            match annotatable {
-                Annotatable::Item(_) => {
-                    |parser| Ok(Annotatable::Item(parser.parse_item(ForceCollect::Yes)?.unwrap()))
-                }
-                Annotatable::AssocItem(_, AssocCtxt::Trait) => |parser| {
-                    Ok(Annotatable::AssocItem(
-                        parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap(),
-                        AssocCtxt::Trait,
-                    ))
-                },
-                Annotatable::AssocItem(_, AssocCtxt::Impl) => |parser| {
-                    Ok(Annotatable::AssocItem(
-                        parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap(),
-                        AssocCtxt::Impl,
-                    ))
-                },
-                Annotatable::ForeignItem(_) => |parser| {
-                    Ok(Annotatable::ForeignItem(
-                        parser.parse_foreign_item(ForceCollect::Yes)?.unwrap().unwrap(),
-                    ))
-                },
-                Annotatable::Stmt(_) => |parser| {
-                    Ok(Annotatable::Stmt(P(parser
-                        .parse_stmt_without_recovery(false, ForceCollect::Yes)?
-                        .unwrap())))
-                },
-                Annotatable::Expr(_) => {
-                    |parser| Ok(Annotatable::Expr(parser.parse_expr_force_collect()?))
-                }
-                _ => unreachable!(),
-            };
-
         // 'Flatten' all nonterminals (i.e. `TokenKind::Interpolated`)
         // to `None`-delimited groups containing the corresponding tokens. This
         // is normally delayed until the proc-macro server actually needs to
@@ -191,19 +111,56 @@ impl CfgEval<'_> {
         // Re-parse the tokens, setting the `capture_cfg` flag to save extra information
         // to the captured `AttrTokenStream` (specifically, we capture
         // `AttrTokenTree::AttrsTarget` for all occurrences of `#[cfg]` and `#[cfg_attr]`)
+        //
+        // After that we have our re-parsed `AttrTokenStream`, recursively configuring
+        // our attribute target will correctly configure the tokens as well.
         let mut parser = Parser::new(&self.0.sess.psess, orig_tokens, None);
         parser.capture_cfg = true;
-        match parse_annotatable_with(&mut parser) {
-            Ok(a) => annotatable = a,
+        let res: PResult<'_, Annotatable> = try {
+            match annotatable {
+                Annotatable::Item(_) => {
+                    let item = parser.parse_item(ForceCollect::Yes)?.unwrap();
+                    Annotatable::Item(self.flat_map_item(item).pop().unwrap())
+                }
+                Annotatable::AssocItem(_, AssocCtxt::Trait) => {
+                    let item = parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap();
+                    Annotatable::AssocItem(
+                        self.flat_map_assoc_item(item, AssocCtxt::Trait).pop().unwrap(),
+                        AssocCtxt::Trait,
+                    )
+                }
+                Annotatable::AssocItem(_, AssocCtxt::Impl) => {
+                    let item = parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap();
+                    Annotatable::AssocItem(
+                        self.flat_map_assoc_item(item, AssocCtxt::Impl).pop().unwrap(),
+                        AssocCtxt::Impl,
+                    )
+                }
+                Annotatable::ForeignItem(_) => {
+                    let item = parser.parse_foreign_item(ForceCollect::Yes)?.unwrap().unwrap();
+                    Annotatable::ForeignItem(self.flat_map_foreign_item(item).pop().unwrap())
+                }
+                Annotatable::Stmt(_) => {
+                    let stmt =
+                        parser.parse_stmt_without_recovery(false, ForceCollect::Yes)?.unwrap();
+                    Annotatable::Stmt(P(self.flat_map_stmt(stmt).pop().unwrap()))
+                }
+                Annotatable::Expr(_) => {
+                    let mut expr = parser.parse_expr_force_collect()?;
+                    self.visit_expr(&mut expr);
+                    Annotatable::Expr(expr)
+                }
+                _ => unreachable!(),
+            }
+        };
+
+        match res {
+            Ok(ann) => ann,
             Err(err) => {
                 err.emit();
-                return Some(annotatable);
+                annotatable
             }
         }
-
-        // Now that we have our re-parsed `AttrTokenStream`, recursively configuring
-        // our attribute target will correctly configure the tokens as well.
-        flat_map_annotatable(self, annotatable)
     }
 }
 
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 82baaca9a46..79c198ed2d0 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -680,6 +680,12 @@ impl<'a> TraitDef<'a> {
                     param_clone
                 }
             })
+            .map(|mut param| {
+                // Remove all attributes, because there might be helper attributes
+                // from other macros that will not be valid in the expanded implementation.
+                param.attrs.clear();
+                param
+            })
             .collect();
 
         // and similarly for where clauses
diff --git a/compiler/rustc_codegen_cranelift/src/archive.rs b/compiler/rustc_codegen_cranelift/src/archive.rs
deleted file mode 100644
index c7725e49c94..00000000000
--- a/compiler/rustc_codegen_cranelift/src/archive.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-use rustc_codegen_ssa::back::archive::{
-    ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
-};
-use rustc_session::Session;
-
-pub(crate) struct ArArchiveBuilderBuilder;
-
-impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
-    fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
-        Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
-    }
-}
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index 19a1de53d1d..b506b1f5731 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -43,7 +43,6 @@ use rustc_codegen_ssa::CodegenResults;
 use rustc_codegen_ssa::back::versioned_llvm_target;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::profiling::SelfProfilerRef;
-use rustc_errors::ErrorGuaranteed;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_session::Session;
@@ -56,7 +55,6 @@ use crate::prelude::*;
 mod abi;
 mod allocator;
 mod analyze;
-mod archive;
 mod base;
 mod cast;
 mod codegen_i128;
@@ -249,17 +247,6 @@ impl CodegenBackend for CraneliftCodegenBackend {
             self.config.borrow().as_ref().unwrap(),
         )
     }
-
-    fn link(
-        &self,
-        sess: &Session,
-        codegen_results: CodegenResults,
-        outputs: &OutputFilenames,
-    ) -> Result<(), ErrorGuaranteed> {
-        use rustc_codegen_ssa::back::link::link_binary;
-
-        link_binary(sess, &crate::archive::ArArchiveBuilderBuilder, &codegen_results, outputs)
-    }
 }
 
 fn target_triple(sess: &Session) -> target_lexicon::Triple {
diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs
deleted file mode 100644
index 82e98370b37..00000000000
--- a/compiler/rustc_codegen_gcc/src/archive.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use std::path::Path;
-
-use rustc_codegen_ssa::back::archive::{
-    ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder, DEFAULT_OBJECT_READER,
-    ImportLibraryItem,
-};
-use rustc_session::Session;
-
-pub(crate) struct ArArchiveBuilderBuilder;
-
-impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
-    fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
-        Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
-    }
-
-    fn create_dll_import_lib(
-        &self,
-        _sess: &Session,
-        _lib_name: &str,
-        _items: Vec<ImportLibraryItem>,
-        _output_path: &Path,
-    ) {
-        unimplemented!("creating dll imports is not yet supported");
-    }
-}
diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs
index 9d62ccc95d5..5d8c5c199b1 100644
--- a/compiler/rustc_codegen_gcc/src/debuginfo.rs
+++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs
@@ -52,6 +52,10 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> {
     fn clear_dbg_loc(&mut self) {
         self.location = None;
     }
+
+    fn get_dbg_loc(&self) -> Option<Self::DILocation> {
+        self.location
+    }
 }
 
 /// Generate the `debug_context` in an MIR Body.
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index f70dc94b267..452e92bffa2 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -58,7 +58,6 @@ extern crate rustc_driver;
 
 mod abi;
 mod allocator;
-mod archive;
 mod asm;
 mod attributes;
 mod back;
@@ -103,7 +102,7 @@ use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBacken
 use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::IntoDynSyncSend;
-use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed};
+use rustc_errors::DiagCtxtHandle;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_middle::ty::TyCtxt;
@@ -261,17 +260,6 @@ impl CodegenBackend for GccCodegenBackend {
             .join(sess)
     }
 
-    fn link(
-        &self,
-        sess: &Session,
-        codegen_results: CodegenResults,
-        outputs: &OutputFilenames,
-    ) -> Result<(), ErrorGuaranteed> {
-        use rustc_codegen_ssa::back::link::link_binary;
-
-        link_binary(sess, &crate::archive::ArArchiveBuilderBuilder, &codegen_results, outputs)
-    }
-
     fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
         target_features(sess, allow_unstable, &self.target_info)
     }
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 751b2235dc8..ac76b781218 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1574,6 +1574,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
                 cfi::typeid_for_fnabi(self.tcx, fn_abi, options)
             };
             let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap();
+            let dbg_loc = self.get_dbg_loc();
 
             // Test whether the function pointer is associated with the type identifier.
             let cond = self.type_test(llfn, typeid_metadata);
@@ -1582,10 +1583,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
             self.cond_br(cond, bb_pass, bb_fail);
 
             self.switch_to_block(bb_fail);
+            if let Some(dbg_loc) = dbg_loc {
+                self.set_dbg_loc(dbg_loc);
+            }
             self.abort();
             self.unreachable();
 
             self.switch_to_block(bb_pass);
+            if let Some(dbg_loc) = dbg_loc {
+                self.set_dbg_loc(dbg_loc);
+            }
         }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index ba863d9d74b..3a7c7efe03b 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -274,8 +274,12 @@ pub(crate) unsafe fn create_module<'ll>(
         }
     }
 
-    // Control Flow Guard is currently only supported by the MSVC linker on Windows.
-    if sess.target.is_like_msvc {
+    // Control Flow Guard is currently only supported by MSVC and LLVM on Windows.
+    if sess.target.is_like_msvc
+        || (sess.target.options.os == "windows"
+            && sess.target.options.env == "gnu"
+            && sess.target.options.abi == "llvm")
+    {
         match sess.opts.cg.control_flow_guard {
             CFGuard::Disabled => {}
             CFGuard::NoChecks => {
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
index feac97f3e2b..a6e07ea2a60 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
@@ -1,5 +1,7 @@
 use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId, SourceRegion};
 
+use crate::coverageinfo::mapgen::LocalFileId;
+
 /// Must match the layout of `LLVMRustCounterKind`.
 #[derive(Copy, Clone, Debug)]
 #[repr(C)]
@@ -137,8 +139,12 @@ pub(crate) struct CoverageSpan {
 }
 
 impl CoverageSpan {
-    pub(crate) fn from_source_region(file_id: u32, code_region: &SourceRegion) -> Self {
-        let &SourceRegion { file_name: _, start_line, start_col, end_line, end_col } = code_region;
+    pub(crate) fn from_source_region(
+        local_file_id: LocalFileId,
+        code_region: &SourceRegion,
+    ) -> Self {
+        let file_id = local_file_id.as_u32();
+        let &SourceRegion { start_line, start_col, end_line, end_col } = code_region;
         // Internally, LLVM uses the high bit of `end_col` to distinguish between
         // code regions and gap regions, so it can't be used by the column number.
         assert!(end_col & (1u32 << 31) == 0, "high bit of `end_col` must be unset: {end_col:#X}");
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
index 5ed640b840e..e3c0df27883 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
@@ -6,7 +6,6 @@ use rustc_middle::mir::coverage::{
     SourceRegion,
 };
 use rustc_middle::ty::Instance;
-use rustc_span::Symbol;
 use tracing::{debug, instrument};
 
 use crate::coverageinfo::ffi::{Counter, CounterExpression, ExprKind};
@@ -180,7 +179,7 @@ impl<'tcx> FunctionCoverageCollector<'tcx> {
 }
 
 pub(crate) struct FunctionCoverage<'tcx> {
-    function_coverage_info: &'tcx FunctionCoverageInfo,
+    pub(crate) function_coverage_info: &'tcx FunctionCoverageInfo,
     is_used: bool,
 
     counters_seen: BitSet<CounterId>,
@@ -199,11 +198,6 @@ impl<'tcx> FunctionCoverage<'tcx> {
         if self.is_used { self.function_coverage_info.function_source_hash } else { 0 }
     }
 
-    /// Returns an iterator over all filenames used by this function's mappings.
-    pub(crate) fn all_file_names(&self) -> impl Iterator<Item = Symbol> + Captures<'_> {
-        self.function_coverage_info.mappings.iter().map(|mapping| mapping.source_region.file_name)
-    }
-
     /// Convert this function's coverage expression data into a form that can be
     /// passed through FFI to LLVM.
     pub(crate) fn counter_expressions(
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index bb2f634cb25..b582dd967a7 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -12,8 +12,10 @@ use rustc_index::IndexVec;
 use rustc_middle::mir::coverage::MappingKind;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_middle::{bug, mir};
-use rustc_span::Symbol;
+use rustc_session::RemapFileNameExt;
+use rustc_session::config::RemapPathScopeComponents;
 use rustc_span::def_id::DefIdSet;
+use rustc_span::{Span, Symbol};
 use rustc_target::spec::HasTargetSpec;
 use tracing::debug;
 
@@ -70,8 +72,10 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
         .map(|(instance, function_coverage)| (instance, function_coverage.into_finished()))
         .collect::<Vec<_>>();
 
-    let all_file_names =
-        function_coverage_entries.iter().flat_map(|(_, fn_cov)| fn_cov.all_file_names());
+    let all_file_names = function_coverage_entries
+        .iter()
+        .map(|(_, fn_cov)| fn_cov.function_coverage_info.body_span)
+        .map(|span| span_file_name(tcx, span));
     let global_file_table = GlobalFileTable::new(all_file_names);
 
     // Encode all filenames referenced by coverage mappings in this CGU.
@@ -96,7 +100,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
         let is_used = function_coverage.is_used();
 
         let coverage_mapping_buffer =
-            encode_mappings_for_function(&global_file_table, &function_coverage);
+            encode_mappings_for_function(tcx, &global_file_table, &function_coverage);
 
         if coverage_mapping_buffer.is_empty() {
             if function_coverage.is_used() {
@@ -164,13 +168,13 @@ impl GlobalFileTable {
         Self { raw_file_table }
     }
 
-    fn global_file_id_for_file_name(&self, file_name: Symbol) -> u32 {
+    fn global_file_id_for_file_name(&self, file_name: Symbol) -> GlobalFileId {
         let raw_id = self.raw_file_table.get_index_of(&file_name).unwrap_or_else(|| {
             bug!("file name not found in prepared global file table: {file_name}");
         });
         // The raw file table doesn't include an entry for the working dir
         // (which has ID 0), so add 1 to get the correct ID.
-        (raw_id + 1) as u32
+        GlobalFileId::from_usize(raw_id + 1)
     }
 
     fn make_filenames_buffer(&self, tcx: TyCtxt<'_>) -> Vec<u8> {
@@ -196,19 +200,27 @@ impl GlobalFileTable {
 }
 
 rustc_index::newtype_index! {
-    struct LocalFileId {}
+    /// An index into the CGU's overall list of file paths. The underlying paths
+    /// will be embedded in the `__llvm_covmap` linker section.
+    struct GlobalFileId {}
+}
+rustc_index::newtype_index! {
+    /// An index into a function's list of global file IDs. That underlying list
+    /// of local-to-global mappings will be embedded in the function's record in
+    /// the `__llvm_covfun` linker section.
+    pub(crate) struct LocalFileId {}
 }
 
 /// Holds a mapping from "local" (per-function) file IDs to "global" (per-CGU)
 /// file IDs.
 #[derive(Default)]
 struct VirtualFileMapping {
-    local_to_global: IndexVec<LocalFileId, u32>,
-    global_to_local: FxIndexMap<u32, LocalFileId>,
+    local_to_global: IndexVec<LocalFileId, GlobalFileId>,
+    global_to_local: FxIndexMap<GlobalFileId, LocalFileId>,
 }
 
 impl VirtualFileMapping {
-    fn local_id_for_global(&mut self, global_file_id: u32) -> LocalFileId {
+    fn local_id_for_global(&mut self, global_file_id: GlobalFileId) -> LocalFileId {
         *self
             .global_to_local
             .entry(global_file_id)
@@ -216,16 +228,26 @@ impl VirtualFileMapping {
     }
 
     fn into_vec(self) -> Vec<u32> {
-        self.local_to_global.raw
+        // This conversion should be optimized away to ~zero overhead.
+        // In any case, it's probably not hot enough to worry about.
+        self.local_to_global.into_iter().map(|global| global.as_u32()).collect()
     }
 }
 
+fn span_file_name(tcx: TyCtxt<'_>, span: Span) -> Symbol {
+    let source_file = tcx.sess.source_map().lookup_source_file(span.lo());
+    let name =
+        source_file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy();
+    Symbol::intern(&name)
+}
+
 /// Using the expressions and counter regions collected for a single function,
 /// generate the variable-sized payload of its corresponding `__llvm_covfun`
 /// entry. The payload is returned as a vector of bytes.
 ///
 /// Newly-encountered filenames will be added to the global file table.
 fn encode_mappings_for_function(
+    tcx: TyCtxt<'_>,
     global_file_table: &GlobalFileTable,
     function_coverage: &FunctionCoverage<'_>,
 ) -> Vec<u8> {
@@ -242,53 +264,45 @@ fn encode_mappings_for_function(
     let mut mcdc_branch_regions = vec![];
     let mut mcdc_decision_regions = vec![];
 
-    // Group mappings into runs with the same filename, preserving the order
-    // yielded by `FunctionCoverage`.
-    // Prepare file IDs for each filename, and prepare the mapping data so that
-    // we can pass it through FFI to LLVM.
-    for (file_name, counter_regions_for_file) in
-        &counter_regions.group_by(|(_, region)| region.file_name)
-    {
-        // Look up the global file ID for this filename.
-        let global_file_id = global_file_table.global_file_id_for_file_name(file_name);
-
-        // Associate that global file ID with a local file ID for this function.
-        let local_file_id = virtual_file_mapping.local_id_for_global(global_file_id);
-        debug!("  file id: {local_file_id:?} => global {global_file_id} = '{file_name:?}'");
-
-        // For each counter/region pair in this function+file, convert it to a
-        // form suitable for FFI.
-        for (mapping_kind, region) in counter_regions_for_file {
-            debug!("Adding counter {mapping_kind:?} to map for {region:?}");
-            let span = ffi::CoverageSpan::from_source_region(local_file_id.as_u32(), region);
-            match mapping_kind {
-                MappingKind::Code(term) => {
-                    code_regions
-                        .push(ffi::CodeRegion { span, counter: ffi::Counter::from_term(term) });
-                }
-                MappingKind::Branch { true_term, false_term } => {
-                    branch_regions.push(ffi::BranchRegion {
-                        span,
-                        true_counter: ffi::Counter::from_term(true_term),
-                        false_counter: ffi::Counter::from_term(false_term),
-                    });
-                }
-                MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => {
-                    mcdc_branch_regions.push(ffi::MCDCBranchRegion {
-                        span,
-                        true_counter: ffi::Counter::from_term(true_term),
-                        false_counter: ffi::Counter::from_term(false_term),
-                        mcdc_branch_params: ffi::mcdc::BranchParameters::from(mcdc_params),
-                    });
-                }
-                MappingKind::MCDCDecision(mcdc_decision_params) => {
-                    mcdc_decision_regions.push(ffi::MCDCDecisionRegion {
-                        span,
-                        mcdc_decision_params: ffi::mcdc::DecisionParameters::from(
-                            mcdc_decision_params,
-                        ),
-                    });
-                }
+    // Currently a function's mappings must all be in the same file as its body span.
+    let file_name = span_file_name(tcx, function_coverage.function_coverage_info.body_span);
+
+    // Look up the global file ID for that filename.
+    let global_file_id = global_file_table.global_file_id_for_file_name(file_name);
+
+    // Associate that global file ID with a local file ID for this function.
+    let local_file_id = virtual_file_mapping.local_id_for_global(global_file_id);
+    debug!("  file id: {local_file_id:?} => {global_file_id:?} = '{file_name:?}'");
+
+    // For each counter/region pair in this function+file, convert it to a
+    // form suitable for FFI.
+    for (mapping_kind, region) in counter_regions {
+        debug!("Adding counter {mapping_kind:?} to map for {region:?}");
+        let span = ffi::CoverageSpan::from_source_region(local_file_id, region);
+        match mapping_kind {
+            MappingKind::Code(term) => {
+                code_regions.push(ffi::CodeRegion { span, counter: ffi::Counter::from_term(term) });
+            }
+            MappingKind::Branch { true_term, false_term } => {
+                branch_regions.push(ffi::BranchRegion {
+                    span,
+                    true_counter: ffi::Counter::from_term(true_term),
+                    false_counter: ffi::Counter::from_term(false_term),
+                });
+            }
+            MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => {
+                mcdc_branch_regions.push(ffi::MCDCBranchRegion {
+                    span,
+                    true_counter: ffi::Counter::from_term(true_term),
+                    false_counter: ffi::Counter::from_term(false_term),
+                    mcdc_branch_params: ffi::mcdc::BranchParameters::from(mcdc_params),
+                });
+            }
+            MappingKind::MCDCDecision(mcdc_decision_params) => {
+                mcdc_decision_regions.push(ffi::MCDCDecisionRegion {
+                    span,
+                    mcdc_decision_params: ffi::mcdc::DecisionParameters::from(mcdc_decision_params),
+                });
             }
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 9e1e5127e80..89492e4b9fe 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -206,6 +206,10 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
         }
     }
 
+    fn get_dbg_loc(&self) -> Option<&'ll DILocation> {
+        unsafe { llvm::LLVMGetCurrentDebugLocation2(self.llbuilder) }
+    }
+
     fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) {
         gdb::insert_reference_to_gdb_debug_scripts_section_global(self)
     }
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index 49e616b5371..3dfb86d422d 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -382,7 +382,7 @@ impl CodegenBackend for LlvmCodegenBackend {
 
         // Run the linker on any artifacts that resulted from the LLVM run.
         // This should produce either a finished executable or library.
-        link_binary(sess, &LlvmArchiveBuilderBuilder, &codegen_results, outputs)
+        link_binary(sess, &LlvmArchiveBuilderBuilder, codegen_results, outputs)
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 75a5ec44c22..7f59264824e 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1063,6 +1063,7 @@ unsafe extern "C" {
 
     // Metadata
     pub fn LLVMSetCurrentDebugLocation2<'a>(Builder: &Builder<'a>, Loc: *const Metadata);
+    pub fn LLVMGetCurrentDebugLocation2<'a>(Builder: &Builder<'a>) -> Option<&'a Metadata>;
 
     // Terminators
     pub fn LLVMBuildRetVoid<'a>(B: &Builder<'a>) -> &'a Value;
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index c382242d8d0..db2b03d9aed 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -344,15 +344,23 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
         })
     {
         if enabled {
+            // Also add all transitively implied features.
             features.extend(sess.target.implied_target_features(std::iter::once(feature)));
         } else {
+            // Remove transitively reverse-implied features.
+
             // We don't care about the order in `features` since the only thing we use it for is the
             // `features.contains` below.
             #[allow(rustc::potential_query_instability)]
             features.retain(|f| {
-                // Keep a feature if it does not imply `feature`. Or, equivalently,
-                // remove the reverse-dependencies of `feature`.
-                !sess.target.implied_target_features(std::iter::once(*f)).contains(&feature)
+                if sess.target.implied_target_features(std::iter::once(*f)).contains(&feature) {
+                    // If `f` if implies `feature`, then `!feature` implies `!f`, so we have to
+                    // remove `f`. (This is the standard logical contraposition principle.)
+                    false
+                } else {
+                    // We can keep `f`.
+                    true
+                }
             });
         }
     }
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index e83bfa7b70d..d4836eb7a1d 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -304,6 +304,14 @@ pub trait ArchiveBuilder {
     fn build(self: Box<Self>, output: &Path) -> bool;
 }
 
+pub struct ArArchiveBuilderBuilder;
+
+impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
+    fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder + 'a> {
+        Box::new(ArArchiveBuilder::new(sess, &DEFAULT_OBJECT_READER))
+    }
+}
+
 #[must_use = "must call build() to finish building the archive"]
 pub struct ArArchiveBuilder<'a> {
     sess: &'a Session,
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 3120b5bf0af..fd1126e8528 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -69,7 +69,7 @@ pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) {
 pub fn link_binary(
     sess: &Session,
     archive_builder_builder: &dyn ArchiveBuilderBuilder,
-    codegen_results: &CodegenResults,
+    codegen_results: CodegenResults,
     outputs: &OutputFilenames,
 ) -> Result<(), ErrorGuaranteed> {
     let _timer = sess.timer("link_binary");
@@ -116,7 +116,7 @@ pub fn link_binary(
                     link_rlib(
                         sess,
                         archive_builder_builder,
-                        codegen_results,
+                        &codegen_results,
                         RlibFlavor::Normal,
                         &path,
                     )?
@@ -126,7 +126,7 @@ pub fn link_binary(
                     link_staticlib(
                         sess,
                         archive_builder_builder,
-                        codegen_results,
+                        &codegen_results,
                         &out_filename,
                         &path,
                     )?;
@@ -137,7 +137,7 @@ pub fn link_binary(
                         archive_builder_builder,
                         crate_type,
                         &out_filename,
-                        codegen_results,
+                        &codegen_results,
                         path.as_ref(),
                     )?;
                 }
@@ -1647,7 +1647,7 @@ fn get_object_file_path(sess: &Session, name: &str, self_contained: bool) -> Pat
             return file_path;
         }
     }
-    for search_path in sess.target_filesearch(PathKind::Native).search_paths() {
+    for search_path in sess.target_filesearch().search_paths(PathKind::Native) {
         let file_path = search_path.dir.join(name);
         if file_path.exists() {
             return file_path;
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 676fb181d67..cbf214763b4 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -16,6 +16,8 @@ use rustc_span::symbol::Symbol;
 
 use super::CodegenObject;
 use super::write::WriteBackendMethods;
+use crate::back::archive::ArArchiveBuilderBuilder;
+use crate::back::link::link_binary;
 use crate::back::write::TargetMachineFactoryFn;
 use crate::{CodegenResults, ModuleCodegen};
 
@@ -87,7 +89,9 @@ pub trait CodegenBackend {
         sess: &Session,
         codegen_results: CodegenResults,
         outputs: &OutputFilenames,
-    ) -> Result<(), ErrorGuaranteed>;
+    ) -> Result<(), ErrorGuaranteed> {
+        link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, outputs)
+    }
 
     /// Returns `true` if this backend can be safely called from multiple threads.
     ///
diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
index 670433a6c33..fe135e911fb 100644
--- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
@@ -81,6 +81,7 @@ pub trait DebugInfoBuilderMethods: BackendTypes {
     );
     fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation);
     fn clear_dbg_loc(&mut self);
+    fn get_dbg_loc(&self) -> Option<Self::DILocation>;
     fn insert_reference_to_gdb_debug_scripts_section_global(&mut self);
     fn set_var_name(&mut self, value: Self::Value, name: &str);
 }
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 8cd0ecb3e4e..ffe32acb316 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -3,6 +3,7 @@
 use std::assert_matches::assert_matches;
 use std::borrow::Cow;
 use std::mem;
+use std::num::NonZero;
 use std::ops::Deref;
 
 use rustc_attr::{ConstStability, StabilityLevel};
@@ -271,9 +272,18 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
     /// context.
     pub fn check_op_spanned<O: NonConstOp<'tcx>>(&mut self, op: O, span: Span) {
         let gate = match op.status_in_item(self.ccx) {
-            Status::Unstable { gate, safe_to_expose_on_stable, is_function_call }
-                if self.tcx.features().enabled(gate) =>
-            {
+            Status::Unstable {
+                gate,
+                safe_to_expose_on_stable,
+                is_function_call,
+                gate_already_checked,
+            } if gate_already_checked || self.tcx.features().enabled(gate) => {
+                if gate_already_checked {
+                    assert!(
+                        !safe_to_expose_on_stable,
+                        "setting `gate_already_checked` without `safe_to_expose_on_stable` makes no sense"
+                    );
+                }
                 // Generally this is allowed since the feature gate is enabled -- except
                 // if this function wants to be safe-to-expose-on-stable.
                 if !safe_to_expose_on_stable
@@ -709,6 +719,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
                 // Intrinsics are language primitives, not regular calls, so treat them separately.
                 if let Some(intrinsic) = tcx.intrinsic(callee) {
+                    if !tcx.is_const_fn(callee) {
+                        // Non-const intrinsic.
+                        self.check_op(ops::IntrinsicNonConst { name: intrinsic.name });
+                        // If we allowed this, we're in miri-unleashed mode, so we might
+                        // as well skip the remaining checks.
+                        return;
+                    }
                     // We use `intrinsic.const_stable` to determine if this can be safely exposed to
                     // stable code, rather than `const_stable_indirect`. This is to make
                     // `#[rustc_const_stable_indirect]` an attribute that is always safe to add.
@@ -716,17 +733,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     // fallback body is safe to expose on stable.
                     let is_const_stable = intrinsic.const_stable
                         || (!intrinsic.must_be_overridden
-                            && tcx.is_const_fn(callee)
                             && is_safe_to_expose_on_stable_const_fn(tcx, callee));
                     match tcx.lookup_const_stability(callee) {
                         None => {
-                            // Non-const intrinsic.
-                            self.check_op(ops::IntrinsicNonConst { name: intrinsic.name });
-                        }
-                        Some(ConstStability { feature: None, .. }) => {
-                            // Intrinsic does not need a separate feature gate (we rely on the
-                            // regular stability checker). However, we have to worry about recursive
-                            // const stability.
+                            // This doesn't need a separate const-stability check -- const-stability equals
+                            // regular stability, and regular stability is checked separately.
+                            // However, we *do* have to worry about *recursive* const stability.
                             if !is_const_stable && self.enforce_recursive_const_stability() {
                                 self.dcx().emit_err(errors::UnmarkedIntrinsicExposed {
                                     span: self.span,
@@ -735,14 +747,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                             }
                         }
                         Some(ConstStability {
-                            feature: Some(feature),
                             level: StabilityLevel::Unstable { .. },
+                            feature,
                             ..
                         }) => {
                             self.check_op(ops::IntrinsicUnstable {
                                 name: intrinsic.name,
                                 feature,
-                                const_stable: is_const_stable,
+                                const_stable_indirect: is_const_stable,
                             });
                         }
                         Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
@@ -773,7 +785,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
                         // All good.
                     }
-                    None | Some(ConstStability { feature: None, .. }) => {
+                    None => {
                         // This doesn't need a separate const-stability check -- const-stability equals
                         // regular stability, and regular stability is checked separately.
                         // However, we *do* have to worry about *recursive* const stability.
@@ -787,8 +799,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                         }
                     }
                     Some(ConstStability {
-                        feature: Some(feature),
-                        level: StabilityLevel::Unstable { implied_by: implied_feature, .. },
+                        level: StabilityLevel::Unstable { implied_by: implied_feature, issue, .. },
+                        feature,
                         ..
                     }) => {
                         // An unstable const fn with a feature gate.
@@ -797,6 +809,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
                         // We only honor `span.allows_unstable` aka `#[allow_internal_unstable]` if
                         // the callee is safe to expose, to avoid bypassing recursive stability.
+                        // This is not ideal since it means the user sees an error, not the macro
+                        // author, but that's also the case if one forgets to set
+                        // `#[allow_internal_unstable]` in the first place. Note that this cannot be
+                        // integrated in the check below since we want to enforce
+                        // `callee_safe_to_expose_on_stable` even if
+                        // `!self.enforce_recursive_const_stability()`.
                         if (self.span.allows_unstable(feature)
                             || implied_feature.is_some_and(|f| self.span.allows_unstable(f)))
                             && callee_safe_to_expose_on_stable
@@ -810,16 +828,30 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                         // to allow this.
                         let feature_enabled = callee.is_local()
                             || tcx.features().enabled(feature)
-                            || implied_feature.is_some_and(|f| tcx.features().enabled(f));
-                        // We do *not* honor this if we are in the "danger zone": we have to enforce
-                        // recursive const-stability and the callee is not safe-to-expose. In that
-                        // case we need `check_op` to do the check.
-                        let danger_zone = !callee_safe_to_expose_on_stable
-                            && self.enforce_recursive_const_stability();
-                        if danger_zone || !feature_enabled {
+                            || implied_feature.is_some_and(|f| tcx.features().enabled(f))
+                            || {
+                                // When we're compiling the compiler itself we may pull in
+                                // crates from crates.io, but those crates may depend on other
+                                // crates also pulled in from crates.io. We want to ideally be
+                                // able to compile everything without requiring upstream
+                                // modifications, so in the case that this looks like a
+                                // `rustc_private` crate (e.g., a compiler crate) and we also have
+                                // the `-Z force-unstable-if-unmarked` flag present (we're
+                                // compiling a compiler crate), then let this missing feature
+                                // annotation slide.
+                                // This matches what we do in `eval_stability_allow_unstable` for
+                                // regular stability.
+                                feature == sym::rustc_private
+                                    && issue == NonZero::new(27812)
+                                    && self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
+                            };
+                        // Even if the feature is enabled, we still need check_op to double-check
+                        // this if the callee is not safe to expose on stable.
+                        if !feature_enabled || !callee_safe_to_expose_on_stable {
                             self.check_op(ops::FnCallUnstable {
                                 def_id: callee,
                                 feature,
+                                feature_enabled,
                                 safe_to_expose_on_stable: callee_safe_to_expose_on_stable,
                             });
                         }
diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs
index dcdaafaecc2..ebdd55a4f70 100644
--- a/compiler/rustc_const_eval/src/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/check_consts/mod.rs
@@ -53,10 +53,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
     }
 
     pub fn enforce_recursive_const_stability(&self) -> bool {
-        // We can skip this if `staged_api` is not enabled, since in such crates
-        // `lookup_const_stability` will always be `None`.
+        // We can skip this if neither `staged_api` nor `-Zforce-unstable-if-unmarked` are enabled,
+        // since in such crates `lookup_const_stability` will always be `None`.
         self.const_kind == Some(hir::ConstContext::ConstFn)
-            && self.tcx.features().staged_api()
+            && (self.tcx.features().staged_api()
+                || self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked)
             && is_safe_to_expose_on_stable_const_fn(self.tcx, self.def_id().to_def_id())
     }
 
@@ -109,14 +110,15 @@ pub fn is_safe_to_expose_on_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> b
 
     match tcx.lookup_const_stability(def_id) {
         None => {
-            // Only marked functions can be trusted. Note that this may be a function in a
-            // non-staged-API crate where no recursive checks were done!
-            false
+            // In a `staged_api` crate, we do enforce recursive const stability for all unmarked
+            // functions, so we can trust local functions. But in another crate we don't know which
+            // rules were applied, so we can't trust that.
+            def_id.is_local() && tcx.features().staged_api()
         }
         Some(stab) => {
-            // We consider things safe-to-expose if they are stable, if they don't have any explicit
-            // const stability attribute, or if they are marked as `const_stable_indirect`.
-            stab.is_const_stable() || stab.feature.is_none() || stab.const_stable_indirect
+            // We consider things safe-to-expose if they are stable or if they are marked as
+            // `const_stable_indirect`.
+            stab.is_const_stable() || stab.const_stable_indirect
         }
     }
 }
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 036ca763280..ca95e42dd2b 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -28,6 +28,9 @@ pub enum Status {
     Unstable {
         /// The feature that must be enabled to use this operation.
         gate: Symbol,
+        /// Whether the feature gate was already checked (because the logic is a bit more
+        /// complicated than just checking a single gate).
+        gate_already_checked: bool,
         /// Whether it is allowed to use this operation from stable `const fn`.
         /// This will usually be `false`.
         safe_to_expose_on_stable: bool,
@@ -82,6 +85,7 @@ impl<'tcx> NonConstOp<'tcx> for ConditionallyConstCall<'tcx> {
         // We use the `const_trait_impl` gate for all conditionally-const calls.
         Status::Unstable {
             gate: sym::const_trait_impl,
+            gate_already_checked: false,
             safe_to_expose_on_stable: false,
             // We don't want the "mark the callee as `#[rustc_const_stable_indirect]`" hint
             is_function_call: false,
@@ -330,6 +334,9 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
 pub(crate) struct FnCallUnstable {
     pub def_id: DefId,
     pub feature: Symbol,
+    /// If this is true, then the feature is enabled, but we need to still check if it is safe to
+    /// expose on stable.
+    pub feature_enabled: bool,
     pub safe_to_expose_on_stable: bool,
 }
 
@@ -337,12 +344,14 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
     fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
         Status::Unstable {
             gate: self.feature,
+            gate_already_checked: self.feature_enabled,
             safe_to_expose_on_stable: self.safe_to_expose_on_stable,
             is_function_call: true,
         }
     }
 
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
+        assert!(!self.feature_enabled);
         let mut err = ccx.dcx().create_err(errors::UnstableConstFn {
             span,
             def_path: ccx.tcx.def_path_str(self.def_id),
@@ -376,14 +385,15 @@ impl<'tcx> NonConstOp<'tcx> for IntrinsicNonConst {
 pub(crate) struct IntrinsicUnstable {
     pub name: Symbol,
     pub feature: Symbol,
-    pub const_stable: bool,
+    pub const_stable_indirect: bool,
 }
 
 impl<'tcx> NonConstOp<'tcx> for IntrinsicUnstable {
     fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
         Status::Unstable {
             gate: self.feature,
-            safe_to_expose_on_stable: self.const_stable,
+            gate_already_checked: false,
+            safe_to_expose_on_stable: self.const_stable_indirect,
             // We do *not* want to suggest to mark the intrinsic as `const_stable_indirect`,
             // that's not a trivial change!
             is_function_call: false,
@@ -410,6 +420,7 @@ impl<'tcx> NonConstOp<'tcx> for Coroutine {
         {
             Status::Unstable {
                 gate: sym::const_async_blocks,
+                gate_already_checked: false,
                 safe_to_expose_on_stable: false,
                 is_function_call: false,
             }
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 5a477143a62..c8ecddb046c 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -10,11 +10,11 @@ bitflags = "2.4.1"
 either = "1.0"
 elsa = "=1.7.1"
 ena = "0.14.3"
-indexmap = { version = "2.4.0" }
+indexmap = { version = "2.4.0", features = ["rustc-rayon"] }
 jobserver_crate = { version = "0.1.28", package = "jobserver" }
 measureme = "11"
 rustc-hash = "2.0.0"
-rustc-rayon = { version = "0.5.0", optional = true }
+rustc-rayon = "0.5.0"
 rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
 rustc_arena = { path = "../rustc_arena" }
 rustc_graphviz = { path = "../rustc_graphviz" }
@@ -53,8 +53,3 @@ memmap2 = "0.2.1"
 
 [target.'cfg(not(target_has_atomic = "64"))'.dependencies]
 portable-atomic = "1.5.1"
-
-[features]
-# tidy-alphabetical-start
-rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "dep:rustc-rayon"]
-# tidy-alphabetical-end
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index afac08ae6f8..bede4c49703 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -10,7 +10,6 @@
 #![allow(internal_features)]
 #![allow(rustc::default_hash_types)]
 #![allow(rustc::potential_query_instability)]
-#![cfg_attr(not(parallel_compiler), feature(cell_leak))]
 #![deny(unsafe_op_in_unsafe_fn)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs
index 83fdaff515b..2b629024bfe 100644
--- a/compiler/rustc_data_structures/src/marker.rs
+++ b/compiler/rustc_data_structures/src/marker.rs
@@ -1,194 +1,162 @@
-cfg_match! {
-    cfg(not(parallel_compiler)) => {
-        pub auto trait DynSend {}
-        pub auto trait DynSync {}
-
-        impl<T> DynSend for T {}
-        impl<T> DynSync for T {}
-    }
-    _ => {
-        #[rustc_on_unimplemented(
-            message = "`{Self}` doesn't implement `DynSend`. \
-            Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`"
-        )]
-        // This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()`
-        // is true. These types can be wrapped in a `FromDyn` to get a `Send` type. Wrapping a
-        // `Send` type in `IntoDynSyncSend` will create a `DynSend` type.
-        pub unsafe auto trait DynSend {}
-
-        #[rustc_on_unimplemented(
-            message = "`{Self}` doesn't implement `DynSync`. \
-            Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Sync`"
-        )]
-        // This is an auto trait for types which can be shared across threads if `sync::is_dyn_thread_safe()`
-        // is true. These types can be wrapped in a `FromDyn` to get a `Sync` type. Wrapping a
-        // `Sync` type in `IntoDynSyncSend` will create a `DynSync` type.
-        pub unsafe auto trait DynSync {}
-
-        // Same with `Sync` and `Send`.
-        unsafe impl<T: DynSync + ?Sized> DynSend for &T {}
-
-        macro_rules! impls_dyn_send_neg {
-            ($([$t1: ty $(where $($generics1: tt)*)?])*) => {
-                $(impl$(<$($generics1)*>)? !DynSend for $t1 {})*
-            };
-        }
-
-        // Consistent with `std`
-        impls_dyn_send_neg!(
-            [std::env::Args]
-            [std::env::ArgsOs]
-            [*const T where T: ?Sized]
-            [*mut T where T: ?Sized]
-            [std::ptr::NonNull<T> where T: ?Sized]
-            [std::rc::Rc<T> where T: ?Sized]
-            [std::rc::Weak<T> where T: ?Sized]
-            [std::sync::MutexGuard<'_, T> where T: ?Sized]
-            [std::sync::RwLockReadGuard<'_, T> where T: ?Sized]
-            [std::sync::RwLockWriteGuard<'_, T> where T: ?Sized]
-            [std::io::StdoutLock<'_>]
-            [std::io::StderrLock<'_>]
-        );
-
-        #[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))]
-        // Consistent with `std`, `os_imp::Env` is `!Sync` in these platforms
-        impl !DynSend for std::env::VarsOs {}
-
-        macro_rules! already_send {
-            ($([$ty: ty])*) => {
-                $(unsafe impl DynSend for $ty where $ty: Send {})*
-            };
-        }
-
-        // These structures are already `Send`.
-        already_send!(
-            [std::backtrace::Backtrace]
-            [std::io::Stdout]
-            [std::io::Stderr]
-            [std::io::Error]
-            [std::fs::File]
-            [rustc_arena::DroplessArena]
-            [crate::memmap::Mmap]
-            [crate::profiling::SelfProfiler]
-            [crate::owned_slice::OwnedSlice]
-        );
-
-        macro_rules! impl_dyn_send {
-            ($($($attr: meta)* [$ty: ty where $($generics2: tt)*])*) => {
-                $(unsafe impl<$($generics2)*> DynSend for $ty {})*
-            };
-        }
-
-        impl_dyn_send!(
-            [std::sync::atomic::AtomicPtr<T> where T]
-            [std::sync::Mutex<T> where T: ?Sized+ DynSend]
-            [std::sync::mpsc::Sender<T> where T: DynSend]
-            [std::sync::Arc<T> where T: ?Sized + DynSync + DynSend]
-            [std::sync::LazyLock<T, F> where T: DynSend, F: DynSend]
-            [std::collections::HashSet<K, S> where K: DynSend, S: DynSend]
-            [std::collections::HashMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend]
-            [std::collections::BTreeMap<K, V, A> where K: DynSend, V: DynSend, A: std::alloc::Allocator + Clone + DynSend]
-            [Vec<T, A> where T: DynSend, A: std::alloc::Allocator + DynSend]
-            [Box<T, A> where T: ?Sized + DynSend, A: std::alloc::Allocator + DynSend]
-            [crate::sync::RwLock<T> where T: DynSend]
-            [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Send + crate::tagged_ptr::Pointer, T: Send + crate::tagged_ptr::Tag, const CP: bool]
-            [rustc_arena::TypedArena<T> where T: DynSend]
-            [indexmap::IndexSet<V, S> where V: DynSend, S: DynSend]
-            [indexmap::IndexMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend]
-            [thin_vec::ThinVec<T> where T: DynSend]
-            [smallvec::SmallVec<A> where A: smallvec::Array + DynSend]
-        );
-
-        macro_rules! impls_dyn_sync_neg {
-            ($([$t1: ty $(where $($generics1: tt)*)?])*) => {
-                $(impl$(<$($generics1)*>)? !DynSync for $t1 {})*
-            };
-        }
-
-        // Consistent with `std`
-        impls_dyn_sync_neg!(
-            [std::env::Args]
-            [std::env::ArgsOs]
-            [*const T where T: ?Sized]
-            [*mut T where T: ?Sized]
-            [std::cell::Cell<T> where T: ?Sized]
-            [std::cell::RefCell<T> where T: ?Sized]
-            [std::cell::UnsafeCell<T> where T: ?Sized]
-            [std::ptr::NonNull<T> where T: ?Sized]
-            [std::rc::Rc<T> where T: ?Sized]
-            [std::rc::Weak<T> where T: ?Sized]
-            [std::cell::OnceCell<T> where T]
-            [std::sync::mpsc::Receiver<T> where T]
-            [std::sync::mpsc::Sender<T> where T]
-        );
-
-        #[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))]
-        // Consistent with `std`, `os_imp::Env` is `!Sync` in these platforms
-        impl !DynSync for std::env::VarsOs {}
-
-        macro_rules! already_sync {
-            ($([$ty: ty])*) => {
-                $(unsafe impl DynSync for $ty where $ty: Sync {})*
-            };
-        }
+#[rustc_on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \
+            Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`")]
+// This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()`
+// is true. These types can be wrapped in a `FromDyn` to get a `Send` type. Wrapping a
+// `Send` type in `IntoDynSyncSend` will create a `DynSend` type.
+pub unsafe auto trait DynSend {}
+
+#[rustc_on_unimplemented(message = "`{Self}` doesn't implement `DynSync`. \
+            Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Sync`")]
+// This is an auto trait for types which can be shared across threads if `sync::is_dyn_thread_safe()`
+// is true. These types can be wrapped in a `FromDyn` to get a `Sync` type. Wrapping a
+// `Sync` type in `IntoDynSyncSend` will create a `DynSync` type.
+pub unsafe auto trait DynSync {}
+
+// Same with `Sync` and `Send`.
+unsafe impl<T: DynSync + ?Sized> DynSend for &T {}
+
+macro_rules! impls_dyn_send_neg {
+    ($([$t1: ty $(where $($generics1: tt)*)?])*) => {
+        $(impl$(<$($generics1)*>)? !DynSend for $t1 {})*
+    };
+}
 
-        // These structures are already `Sync`.
-        already_sync!(
-            [std::sync::atomic::AtomicBool]
-            [std::sync::atomic::AtomicUsize]
-            [std::sync::atomic::AtomicU8]
-            [std::sync::atomic::AtomicU32]
-            [std::backtrace::Backtrace]
-            [std::io::Error]
-            [std::fs::File]
-            [jobserver_crate::Client]
-            [crate::memmap::Mmap]
-            [crate::profiling::SelfProfiler]
-            [crate::owned_slice::OwnedSlice]
-        );
+// Consistent with `std`
+impls_dyn_send_neg!(
+    [std::env::Args]
+    [std::env::ArgsOs]
+    [*const T where T: ?Sized]
+    [*mut T where T: ?Sized]
+    [std::ptr::NonNull<T> where T: ?Sized]
+    [std::rc::Rc<T> where T: ?Sized]
+    [std::rc::Weak<T> where T: ?Sized]
+    [std::sync::MutexGuard<'_, T> where T: ?Sized]
+    [std::sync::RwLockReadGuard<'_, T> where T: ?Sized]
+    [std::sync::RwLockWriteGuard<'_, T> where T: ?Sized]
+    [std::io::StdoutLock<'_>]
+    [std::io::StderrLock<'_>]
+);
+
+#[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))]
+// Consistent with `std`, `os_imp::Env` is `!Sync` in these platforms
+impl !DynSend for std::env::VarsOs {}
+
+macro_rules! already_send {
+    ($([$ty: ty])*) => {
+        $(unsafe impl DynSend for $ty where $ty: Send {})*
+    };
+}
 
-        // Use portable AtomicU64 for targets without native 64-bit atomics
-        #[cfg(target_has_atomic = "64")]
-        already_sync!(
-            [std::sync::atomic::AtomicU64]
-        );
+// These structures are already `Send`.
+already_send!(
+    [std::backtrace::Backtrace][std::io::Stdout][std::io::Stderr][std::io::Error][std::fs::File]
+        [rustc_arena::DroplessArena][crate::memmap::Mmap][crate::profiling::SelfProfiler]
+        [crate::owned_slice::OwnedSlice]
+);
+
+macro_rules! impl_dyn_send {
+    ($($($attr: meta)* [$ty: ty where $($generics2: tt)*])*) => {
+        $(unsafe impl<$($generics2)*> DynSend for $ty {})*
+    };
+}
 
-        #[cfg(not(target_has_atomic = "64"))]
-        already_sync!(
-            [portable_atomic::AtomicU64]
-        );
+impl_dyn_send!(
+    [std::sync::atomic::AtomicPtr<T> where T]
+    [std::sync::Mutex<T> where T: ?Sized+ DynSend]
+    [std::sync::mpsc::Sender<T> where T: DynSend]
+    [std::sync::Arc<T> where T: ?Sized + DynSync + DynSend]
+    [std::sync::LazyLock<T, F> where T: DynSend, F: DynSend]
+    [std::collections::HashSet<K, S> where K: DynSend, S: DynSend]
+    [std::collections::HashMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend]
+    [std::collections::BTreeMap<K, V, A> where K: DynSend, V: DynSend, A: std::alloc::Allocator + Clone + DynSend]
+    [Vec<T, A> where T: DynSend, A: std::alloc::Allocator + DynSend]
+    [Box<T, A> where T: ?Sized + DynSend, A: std::alloc::Allocator + DynSend]
+    [crate::sync::RwLock<T> where T: DynSend]
+    [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Send + crate::tagged_ptr::Pointer, T: Send + crate::tagged_ptr::Tag, const CP: bool]
+    [rustc_arena::TypedArena<T> where T: DynSend]
+    [indexmap::IndexSet<V, S> where V: DynSend, S: DynSend]
+    [indexmap::IndexMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend]
+    [thin_vec::ThinVec<T> where T: DynSend]
+    [smallvec::SmallVec<A> where A: smallvec::Array + DynSend]
+);
+
+macro_rules! impls_dyn_sync_neg {
+    ($([$t1: ty $(where $($generics1: tt)*)?])*) => {
+        $(impl$(<$($generics1)*>)? !DynSync for $t1 {})*
+    };
+}
 
-        macro_rules! impl_dyn_sync {
-            ($($($attr: meta)* [$ty: ty where $($generics2: tt)*])*) => {
-                $(unsafe impl<$($generics2)*> DynSync for $ty {})*
-            };
-        }
+// Consistent with `std`
+impls_dyn_sync_neg!(
+    [std::env::Args]
+    [std::env::ArgsOs]
+    [*const T where T: ?Sized]
+    [*mut T where T: ?Sized]
+    [std::cell::Cell<T> where T: ?Sized]
+    [std::cell::RefCell<T> where T: ?Sized]
+    [std::cell::UnsafeCell<T> where T: ?Sized]
+    [std::ptr::NonNull<T> where T: ?Sized]
+    [std::rc::Rc<T> where T: ?Sized]
+    [std::rc::Weak<T> where T: ?Sized]
+    [std::cell::OnceCell<T> where T]
+    [std::sync::mpsc::Receiver<T> where T]
+    [std::sync::mpsc::Sender<T> where T]
+);
+
+#[cfg(any(unix, target_os = "hermit", target_os = "wasi", target_os = "solid_asp3"))]
+// Consistent with `std`, `os_imp::Env` is `!Sync` in these platforms
+impl !DynSync for std::env::VarsOs {}
+
+macro_rules! already_sync {
+    ($([$ty: ty])*) => {
+        $(unsafe impl DynSync for $ty where $ty: Sync {})*
+    };
+}
 
-        impl_dyn_sync!(
-            [std::sync::atomic::AtomicPtr<T> where T]
-            [std::sync::OnceLock<T> where T: DynSend + DynSync]
-            [std::sync::Mutex<T> where T: ?Sized + DynSend]
-            [std::sync::Arc<T> where T: ?Sized + DynSync + DynSend]
-            [std::sync::LazyLock<T, F> where T: DynSend + DynSync, F: DynSend]
-            [std::collections::HashSet<K, S> where K: DynSync, S: DynSync]
-            [std::collections::HashMap<K, V, S> where K: DynSync, V: DynSync, S: DynSync]
-            [std::collections::BTreeMap<K, V, A> where K: DynSync, V: DynSync, A: std::alloc::Allocator + Clone + DynSync]
-            [Vec<T, A> where T: DynSync, A: std::alloc::Allocator + DynSync]
-            [Box<T, A> where T: ?Sized + DynSync, A: std::alloc::Allocator + DynSync]
-            [crate::sync::RwLock<T> where T: DynSend + DynSync]
-            [crate::sync::WorkerLocal<T> where T: DynSend]
-            [crate::intern::Interned<'a, T> where 'a, T: DynSync]
-            [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Sync + crate::tagged_ptr::Pointer, T: Sync + crate::tagged_ptr::Tag, const CP: bool]
-            [parking_lot::lock_api::Mutex<R, T> where R: DynSync, T: ?Sized + DynSend]
-            [parking_lot::lock_api::RwLock<R, T> where R: DynSync, T: ?Sized + DynSend + DynSync]
-            [indexmap::IndexSet<V, S> where V: DynSync, S: DynSync]
-            [indexmap::IndexMap<K, V, S> where K: DynSync, V: DynSync, S: DynSync]
-            [smallvec::SmallVec<A> where A: smallvec::Array + DynSync]
-            [thin_vec::ThinVec<T> where T: DynSync]
-        );
-    }
+// These structures are already `Sync`.
+already_sync!(
+    [std::sync::atomic::AtomicBool][std::sync::atomic::AtomicUsize][std::sync::atomic::AtomicU8]
+        [std::sync::atomic::AtomicU32][std::backtrace::Backtrace][std::io::Error][std::fs::File]
+        [jobserver_crate::Client][crate::memmap::Mmap][crate::profiling::SelfProfiler]
+        [crate::owned_slice::OwnedSlice]
+);
+
+// Use portable AtomicU64 for targets without native 64-bit atomics
+#[cfg(target_has_atomic = "64")]
+already_sync!([std::sync::atomic::AtomicU64]);
+
+#[cfg(not(target_has_atomic = "64"))]
+already_sync!([portable_atomic::AtomicU64]);
+
+macro_rules! impl_dyn_sync {
+    ($($($attr: meta)* [$ty: ty where $($generics2: tt)*])*) => {
+        $(unsafe impl<$($generics2)*> DynSync for $ty {})*
+    };
 }
 
+impl_dyn_sync!(
+    [std::sync::atomic::AtomicPtr<T> where T]
+    [std::sync::OnceLock<T> where T: DynSend + DynSync]
+    [std::sync::Mutex<T> where T: ?Sized + DynSend]
+    [std::sync::Arc<T> where T: ?Sized + DynSync + DynSend]
+    [std::sync::LazyLock<T, F> where T: DynSend + DynSync, F: DynSend]
+    [std::collections::HashSet<K, S> where K: DynSync, S: DynSync]
+    [std::collections::HashMap<K, V, S> where K: DynSync, V: DynSync, S: DynSync]
+    [std::collections::BTreeMap<K, V, A> where K: DynSync, V: DynSync, A: std::alloc::Allocator + Clone + DynSync]
+    [Vec<T, A> where T: DynSync, A: std::alloc::Allocator + DynSync]
+    [Box<T, A> where T: ?Sized + DynSync, A: std::alloc::Allocator + DynSync]
+    [crate::sync::RwLock<T> where T: DynSend + DynSync]
+    [crate::sync::WorkerLocal<T> where T: DynSend]
+    [crate::intern::Interned<'a, T> where 'a, T: DynSync]
+    [crate::tagged_ptr::CopyTaggedPtr<P, T, CP> where P: Sync + crate::tagged_ptr::Pointer, T: Sync + crate::tagged_ptr::Tag, const CP: bool]
+    [parking_lot::lock_api::Mutex<R, T> where R: DynSync, T: ?Sized + DynSend]
+    [parking_lot::lock_api::RwLock<R, T> where R: DynSync, T: ?Sized + DynSend + DynSync]
+    [indexmap::IndexSet<V, S> where V: DynSync, S: DynSync]
+    [indexmap::IndexMap<K, V, S> where K: DynSync, V: DynSync, S: DynSync]
+    [smallvec::SmallVec<A> where A: smallvec::Array + DynSync]
+    [thin_vec::ThinVec<T> where T: DynSync]
+);
+
 pub fn assert_dyn_sync<T: ?Sized + DynSync>() {}
 pub fn assert_dyn_send<T: ?Sized + DynSend>() {}
 pub fn assert_dyn_send_val<T: ?Sized + DynSend>(_t: &T) {}
@@ -203,7 +171,6 @@ impl<T> FromDyn<T> {
         // Check that `sync::is_dyn_thread_safe()` is true on creation so we can
         // implement `Send` and `Sync` for this structure when `T`
         // implements `DynSend` and `DynSync` respectively.
-        #[cfg(parallel_compiler)]
         assert!(crate::sync::is_dyn_thread_safe());
         FromDyn(val)
     }
@@ -215,11 +182,9 @@ impl<T> FromDyn<T> {
 }
 
 // `FromDyn` is `Send` if `T` is `DynSend`, since it ensures that sync::is_dyn_thread_safe() is true.
-#[cfg(parallel_compiler)]
 unsafe impl<T: DynSend> Send for FromDyn<T> {}
 
 // `FromDyn` is `Sync` if `T` is `DynSync`, since it ensures that sync::is_dyn_thread_safe() is true.
-#[cfg(parallel_compiler)]
 unsafe impl<T: DynSync> Sync for FromDyn<T> {}
 
 impl<T> std::ops::Deref for FromDyn<T> {
@@ -237,9 +202,7 @@ impl<T> std::ops::Deref for FromDyn<T> {
 #[derive(Copy, Clone)]
 pub struct IntoDynSyncSend<T: ?Sized>(pub T);
 
-#[cfg(parallel_compiler)]
 unsafe impl<T: ?Sized + Send> DynSend for IntoDynSyncSend<T> {}
-#[cfg(parallel_compiler)]
 unsafe impl<T: ?Sized + Sync> DynSync for IntoDynSyncSend<T> {}
 
 impl<T> std::ops::Deref for IntoDynSyncSend<T> {
diff --git a/compiler/rustc_data_structures/src/owned_slice.rs b/compiler/rustc_data_structures/src/owned_slice.rs
index bbe6691e548..c8be0ab52e9 100644
--- a/compiler/rustc_data_structures/src/owned_slice.rs
+++ b/compiler/rustc_data_structures/src/owned_slice.rs
@@ -139,11 +139,9 @@ impl Borrow<[u8]> for OwnedSlice {
 }
 
 // Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc<dyn Send + Sync>)`, which is `Send`
-#[cfg(parallel_compiler)]
 unsafe impl sync::Send for OwnedSlice {}
 
 // Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc<dyn Send + Sync>)`, which is `Sync`
-#[cfg(parallel_compiler)]
 unsafe impl sync::Sync for OwnedSlice {}
 
 #[cfg(test)]
diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs
index d0b6fe2bc6f..65488c73d3c 100644
--- a/compiler/rustc_data_structures/src/sharded.rs
+++ b/compiler/rustc_data_structures/src/sharded.rs
@@ -3,27 +3,22 @@ use std::collections::hash_map::RawEntryMut;
 use std::hash::{Hash, Hasher};
 use std::{iter, mem};
 
-#[cfg(parallel_compiler)]
 use either::Either;
 
 use crate::fx::{FxHashMap, FxHasher};
-#[cfg(parallel_compiler)]
-use crate::sync::{CacheAligned, is_dyn_thread_safe};
-use crate::sync::{Lock, LockGuard, Mode};
+use crate::sync::{CacheAligned, Lock, LockGuard, Mode, is_dyn_thread_safe};
 
 // 32 shards is sufficient to reduce contention on an 8-core Ryzen 7 1700,
 // but this should be tested on higher core count CPUs. How the `Sharded` type gets used
 // may also affect the ideal number of shards.
 const SHARD_BITS: usize = 5;
 
-#[cfg(parallel_compiler)]
 const SHARDS: usize = 1 << SHARD_BITS;
 
 /// An array of cache-line aligned inner locked structures with convenience methods.
 /// A single field is used when the compiler uses only one thread.
 pub enum Sharded<T> {
     Single(Lock<T>),
-    #[cfg(parallel_compiler)]
     Shards(Box<[CacheAligned<Lock<T>>; SHARDS]>),
 }
 
@@ -37,7 +32,6 @@ impl<T: Default> Default for Sharded<T> {
 impl<T> Sharded<T> {
     #[inline]
     pub fn new(mut value: impl FnMut() -> T) -> Self {
-        #[cfg(parallel_compiler)]
         if is_dyn_thread_safe() {
             return Sharded::Shards(Box::new(
                 [(); SHARDS].map(|()| CacheAligned(Lock::new(value()))),
@@ -52,7 +46,6 @@ impl<T> Sharded<T> {
     pub fn get_shard_by_value<K: Hash + ?Sized>(&self, _val: &K) -> &Lock<T> {
         match self {
             Self::Single(single) => single,
-            #[cfg(parallel_compiler)]
             Self::Shards(..) => self.get_shard_by_hash(make_hash(_val)),
         }
     }
@@ -66,7 +59,6 @@ impl<T> Sharded<T> {
     pub fn get_shard_by_index(&self, _i: usize) -> &Lock<T> {
         match self {
             Self::Single(single) => single,
-            #[cfg(parallel_compiler)]
             Self::Shards(shards) => {
                 // SAFETY: The index gets ANDed with the shard mask, ensuring it is always inbounds.
                 unsafe { &shards.get_unchecked(_i & (SHARDS - 1)).0 }
@@ -87,7 +79,6 @@ impl<T> Sharded<T> {
                 // `might_be_dyn_thread_safe` was also false.
                 unsafe { single.lock_assume(Mode::NoSync) }
             }
-            #[cfg(parallel_compiler)]
             Self::Shards(..) => self.lock_shard_by_hash(make_hash(_val)),
         }
     }
@@ -110,7 +101,6 @@ impl<T> Sharded<T> {
                 // `might_be_dyn_thread_safe` was also false.
                 unsafe { single.lock_assume(Mode::NoSync) }
             }
-            #[cfg(parallel_compiler)]
             Self::Shards(shards) => {
                 // Synchronization is enabled so use the `lock_assume_sync` method optimized
                 // for that case.
@@ -127,11 +117,7 @@ impl<T> Sharded<T> {
     #[inline]
     pub fn lock_shards(&self) -> impl Iterator<Item = LockGuard<'_, T>> {
         match self {
-            #[cfg(not(parallel_compiler))]
-            Self::Single(single) => iter::once(single.lock()),
-            #[cfg(parallel_compiler)]
             Self::Single(single) => Either::Left(iter::once(single.lock())),
-            #[cfg(parallel_compiler)]
             Self::Shards(shards) => Either::Right(shards.iter().map(|shard| shard.0.lock())),
         }
     }
@@ -139,11 +125,7 @@ impl<T> Sharded<T> {
     #[inline]
     pub fn try_lock_shards(&self) -> impl Iterator<Item = Option<LockGuard<'_, T>>> {
         match self {
-            #[cfg(not(parallel_compiler))]
-            Self::Single(single) => iter::once(single.try_lock()),
-            #[cfg(parallel_compiler)]
             Self::Single(single) => Either::Left(iter::once(single.try_lock())),
-            #[cfg(parallel_compiler)]
             Self::Shards(shards) => Either::Right(shards.iter().map(|shard| shard.0.try_lock())),
         }
     }
@@ -151,7 +133,6 @@ impl<T> Sharded<T> {
 
 #[inline]
 pub fn shards() -> usize {
-    #[cfg(parallel_compiler)]
     if is_dyn_thread_safe() {
         return SHARDS;
     }
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index a3491dbfec7..7a9533031f4 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -54,9 +54,7 @@ mod worker_local;
 pub use worker_local::{Registry, WorkerLocal};
 
 mod parallel;
-#[cfg(parallel_compiler)]
-pub use parallel::scope;
-pub use parallel::{join, par_for_each_in, par_map, parallel_guard, try_par_for_each_in};
+pub use parallel::{join, par_for_each_in, par_map, parallel_guard, scope, try_par_for_each_in};
 pub use vec::{AppendOnlyIndexVec, AppendOnlyVec};
 
 mod vec;
@@ -104,226 +102,66 @@ mod mode {
     }
 }
 
-pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
-
-cfg_match! {
-    cfg(not(parallel_compiler)) => {
-        use std::ops::Add;
-        use std::cell::Cell;
-        use std::sync::atomic::Ordering;
-
-        pub unsafe auto trait Send {}
-        pub unsafe auto trait Sync {}
-
-        unsafe impl<T> Send for T {}
-        unsafe impl<T> Sync for T {}
-
-        /// This is a single threaded variant of `AtomicU64`, `AtomicUsize`, etc.
-        /// It has explicit ordering arguments and is only intended for use with
-        /// the native atomic types.
-        /// You should use this type through the `AtomicU64`, `AtomicUsize`, etc, type aliases
-        /// as it's not intended to be used separately.
-        #[derive(Debug, Default)]
-        pub struct Atomic<T: Copy>(Cell<T>);
-
-        impl<T: Copy> Atomic<T> {
-            #[inline]
-            pub fn new(v: T) -> Self {
-                Atomic(Cell::new(v))
-            }
-
-            #[inline]
-            pub fn into_inner(self) -> T {
-                self.0.into_inner()
-            }
-
-            #[inline]
-            pub fn load(&self, _: Ordering) -> T {
-                self.0.get()
-            }
-
-            #[inline]
-            pub fn store(&self, val: T, _: Ordering) {
-                self.0.set(val)
-            }
-
-            #[inline]
-            pub fn swap(&self, val: T, _: Ordering) -> T {
-                self.0.replace(val)
-            }
-        }
+// FIXME(parallel_compiler): Get rid of these aliases across the compiler.
 
-        impl Atomic<bool> {
-            pub fn fetch_or(&self, val: bool, _: Ordering) -> bool {
-                let old = self.0.get();
-                self.0.set(val | old);
-                old
-            }
-            pub fn fetch_and(&self, val: bool, _: Ordering) -> bool {
-                let old = self.0.get();
-                self.0.set(val & old);
-                old
-            }
-        }
+pub use std::marker::{Send, Sync};
+// Use portable AtomicU64 for targets without native 64-bit atomics
+#[cfg(target_has_atomic = "64")]
+pub use std::sync::atomic::AtomicU64;
+pub use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize};
+pub use std::sync::{Arc as Lrc, OnceLock, Weak};
 
-        impl<T: Copy + PartialEq> Atomic<T> {
-            #[inline]
-            pub fn compare_exchange(&self,
-                                    current: T,
-                                    new: T,
-                                    _: Ordering,
-                                    _: Ordering)
-                                    -> Result<T, T> {
-                let read = self.0.get();
-                if read == current {
-                    self.0.set(new);
-                    Ok(read)
-                } else {
-                    Err(read)
-                }
-            }
-        }
+pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
+pub use parking_lot::{
+    MappedMutexGuard as MappedLockGuard, MappedRwLockReadGuard as MappedReadGuard,
+    MappedRwLockWriteGuard as MappedWriteGuard, RwLockReadGuard as ReadGuard,
+    RwLockWriteGuard as WriteGuard,
+};
+#[cfg(not(target_has_atomic = "64"))]
+pub use portable_atomic::AtomicU64;
 
-        impl<T: Add<Output=T> + Copy> Atomic<T> {
-            #[inline]
-            pub fn fetch_add(&self, val: T, _: Ordering) -> T {
-                let old = self.0.get();
-                self.0.set(old + val);
-                old
-            }
-        }
+pub type LRef<'a, T> = &'a T;
 
-        pub type AtomicUsize = Atomic<usize>;
-        pub type AtomicBool = Atomic<bool>;
-        pub type AtomicU32 = Atomic<u32>;
-        pub type AtomicU64 = Atomic<u64>;
-
-        pub use std::rc::Rc as Lrc;
-        pub use std::rc::Weak as Weak;
-        #[doc(no_inline)]
-        pub use std::cell::Ref as ReadGuard;
-        #[doc(no_inline)]
-        pub use std::cell::Ref as MappedReadGuard;
-        #[doc(no_inline)]
-        pub use std::cell::RefMut as WriteGuard;
-        #[doc(no_inline)]
-        pub use std::cell::RefMut as MappedWriteGuard;
-        #[doc(no_inline)]
-        pub use std::cell::RefMut as MappedLockGuard;
-
-        pub use std::cell::OnceCell as OnceLock;
-
-        use std::cell::RefCell as InnerRwLock;
-
-        pub type LRef<'a, T> = &'a mut T;
-
-        #[derive(Debug, Default)]
-        pub struct MTLock<T>(T);
-
-        impl<T> MTLock<T> {
-            #[inline(always)]
-            pub fn new(inner: T) -> Self {
-                MTLock(inner)
-            }
-
-            #[inline(always)]
-            pub fn into_inner(self) -> T {
-                self.0
-            }
-
-            #[inline(always)]
-            pub fn get_mut(&mut self) -> &mut T {
-                &mut self.0
-            }
-
-            #[inline(always)]
-            pub fn lock(&self) -> &T {
-                &self.0
-            }
-
-            #[inline(always)]
-            pub fn lock_mut(&mut self) -> &mut T {
-                &mut self.0
-            }
-        }
+#[derive(Debug, Default)]
+pub struct MTLock<T>(Lock<T>);
 
-        // FIXME: Probably a bad idea (in the threaded case)
-        impl<T: Clone> Clone for MTLock<T> {
-            #[inline]
-            fn clone(&self) -> Self {
-                MTLock(self.0.clone())
-            }
-        }
+impl<T> MTLock<T> {
+    #[inline(always)]
+    pub fn new(inner: T) -> Self {
+        MTLock(Lock::new(inner))
     }
-    _ => {
-        pub use std::marker::Send as Send;
-        pub use std::marker::Sync as Sync;
-
-        pub use parking_lot::RwLockReadGuard as ReadGuard;
-        pub use parking_lot::MappedRwLockReadGuard as MappedReadGuard;
-        pub use parking_lot::RwLockWriteGuard as WriteGuard;
-        pub use parking_lot::MappedRwLockWriteGuard as MappedWriteGuard;
-
-        pub use parking_lot::MappedMutexGuard as MappedLockGuard;
 
-        pub use std::sync::OnceLock;
-
-        pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32};
-
-        // Use portable AtomicU64 for targets without native 64-bit atomics
-        #[cfg(target_has_atomic = "64")]
-        pub use std::sync::atomic::AtomicU64;
-
-        #[cfg(not(target_has_atomic = "64"))]
-        pub use portable_atomic::AtomicU64;
-
-        pub use std::sync::Arc as Lrc;
-        pub use std::sync::Weak as Weak;
-
-        pub type LRef<'a, T> = &'a T;
-
-        #[derive(Debug, Default)]
-        pub struct MTLock<T>(Lock<T>);
-
-        impl<T> MTLock<T> {
-            #[inline(always)]
-            pub fn new(inner: T) -> Self {
-                MTLock(Lock::new(inner))
-            }
-
-            #[inline(always)]
-            pub fn into_inner(self) -> T {
-                self.0.into_inner()
-            }
-
-            #[inline(always)]
-            pub fn get_mut(&mut self) -> &mut T {
-                self.0.get_mut()
-            }
-
-            #[inline(always)]
-            pub fn lock(&self) -> LockGuard<'_, T> {
-                self.0.lock()
-            }
+    #[inline(always)]
+    pub fn into_inner(self) -> T {
+        self.0.into_inner()
+    }
 
-            #[inline(always)]
-            pub fn lock_mut(&self) -> LockGuard<'_, T> {
-                self.lock()
-            }
-        }
+    #[inline(always)]
+    pub fn get_mut(&mut self) -> &mut T {
+        self.0.get_mut()
+    }
 
-        use parking_lot::RwLock as InnerRwLock;
+    #[inline(always)]
+    pub fn lock(&self) -> LockGuard<'_, T> {
+        self.0.lock()
+    }
 
-        /// This makes locks panic if they are already held.
-        /// It is only useful when you are running in a single thread
-        const ERROR_CHECKING: bool = false;
+    #[inline(always)]
+    pub fn lock_mut(&self) -> LockGuard<'_, T> {
+        self.lock()
     }
 }
 
+use parking_lot::RwLock as InnerRwLock;
+
+/// This makes locks panic if they are already held.
+/// It is only useful when you are running in a single thread
+const ERROR_CHECKING: bool = false;
+
 pub type MTLockRef<'a, T> = LRef<'a, MTLock<T>>;
 
 #[derive(Default)]
-#[cfg_attr(parallel_compiler, repr(align(64)))]
+#[repr(align(64))]
 pub struct CacheAligned<T>(pub T);
 
 pub trait HashMapExt<K, V> {
@@ -357,14 +195,6 @@ impl<T> RwLock<T> {
         self.0.get_mut()
     }
 
-    #[cfg(not(parallel_compiler))]
-    #[inline(always)]
-    #[track_caller]
-    pub fn read(&self) -> ReadGuard<'_, T> {
-        self.0.borrow()
-    }
-
-    #[cfg(parallel_compiler)]
     #[inline(always)]
     pub fn read(&self) -> ReadGuard<'_, T> {
         if ERROR_CHECKING {
@@ -380,26 +210,11 @@ impl<T> RwLock<T> {
         f(&*self.read())
     }
 
-    #[cfg(not(parallel_compiler))]
-    #[inline(always)]
-    pub fn try_write(&self) -> Result<WriteGuard<'_, T>, ()> {
-        self.0.try_borrow_mut().map_err(|_| ())
-    }
-
-    #[cfg(parallel_compiler)]
     #[inline(always)]
     pub fn try_write(&self) -> Result<WriteGuard<'_, T>, ()> {
         self.0.try_write().ok_or(())
     }
 
-    #[cfg(not(parallel_compiler))]
-    #[inline(always)]
-    #[track_caller]
-    pub fn write(&self) -> WriteGuard<'_, T> {
-        self.0.borrow_mut()
-    }
-
-    #[cfg(parallel_compiler)]
     #[inline(always)]
     pub fn write(&self) -> WriteGuard<'_, T> {
         if ERROR_CHECKING {
@@ -427,13 +242,6 @@ impl<T> RwLock<T> {
         self.write()
     }
 
-    #[cfg(not(parallel_compiler))]
-    #[inline(always)]
-    pub fn leak(&self) -> &T {
-        ReadGuard::leak(self.read())
-    }
-
-    #[cfg(parallel_compiler)]
     #[inline(always)]
     pub fn leak(&self) -> &T {
         let guard = self.read();
diff --git a/compiler/rustc_data_structures/src/sync/freeze.rs b/compiler/rustc_data_structures/src/sync/freeze.rs
index fad5f583d1c..5236c9fe156 100644
--- a/compiler/rustc_data_structures/src/sync/freeze.rs
+++ b/compiler/rustc_data_structures/src/sync/freeze.rs
@@ -5,9 +5,7 @@ use std::ops::{Deref, DerefMut};
 use std::ptr::NonNull;
 use std::sync::atomic::Ordering;
 
-use crate::sync::{AtomicBool, ReadGuard, RwLock, WriteGuard};
-#[cfg(parallel_compiler)]
-use crate::sync::{DynSend, DynSync};
+use crate::sync::{AtomicBool, DynSend, DynSync, ReadGuard, RwLock, WriteGuard};
 
 /// A type which allows mutation using a lock until
 /// the value is frozen and can be accessed lock-free.
@@ -22,7 +20,6 @@ pub struct FreezeLock<T> {
     lock: RwLock<()>,
 }
 
-#[cfg(parallel_compiler)]
 unsafe impl<T: DynSync + DynSend> DynSync for FreezeLock<T> {}
 
 impl<T> FreezeLock<T> {
diff --git a/compiler/rustc_data_structures/src/sync/lock.rs b/compiler/rustc_data_structures/src/sync/lock.rs
index 012ee7f900e..2ccf06ccd4f 100644
--- a/compiler/rustc_data_structures/src/sync/lock.rs
+++ b/compiler/rustc_data_structures/src/sync/lock.rs
@@ -1,236 +1,177 @@
 //! This module implements a lock which only uses synchronization if `might_be_dyn_thread_safe` is true.
 //! It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync` traits.
-//!
-//! When `cfg(parallel_compiler)` is not set, the lock is instead a wrapper around `RefCell`.
 
 #![allow(dead_code)]
 
 use std::fmt;
 
-#[cfg(parallel_compiler)]
-pub use maybe_sync::*;
-#[cfg(not(parallel_compiler))]
-pub use no_sync::*;
-
 #[derive(Clone, Copy, PartialEq)]
 pub enum Mode {
     NoSync,
     Sync,
 }
 
-mod maybe_sync {
-    use std::cell::{Cell, UnsafeCell};
-    use std::intrinsics::unlikely;
-    use std::marker::PhantomData;
-    use std::mem::ManuallyDrop;
-    use std::ops::{Deref, DerefMut};
+use std::cell::{Cell, UnsafeCell};
+use std::intrinsics::unlikely;
+use std::marker::PhantomData;
+use std::mem::ManuallyDrop;
+use std::ops::{Deref, DerefMut};
 
-    use parking_lot::RawMutex;
-    use parking_lot::lock_api::RawMutex as _;
+use parking_lot::RawMutex;
+use parking_lot::lock_api::RawMutex as _;
 
-    use super::Mode;
-    use crate::sync::mode;
-    #[cfg(parallel_compiler)]
-    use crate::sync::{DynSend, DynSync};
+use crate::sync::{DynSend, DynSync, mode};
 
-    /// A guard holding mutable access to a `Lock` which is in a locked state.
-    #[must_use = "if unused the Lock will immediately unlock"]
-    pub struct LockGuard<'a, T> {
-        lock: &'a Lock<T>,
-        marker: PhantomData<&'a mut T>,
+/// A guard holding mutable access to a `Lock` which is in a locked state.
+#[must_use = "if unused the Lock will immediately unlock"]
+pub struct LockGuard<'a, T> {
+    lock: &'a Lock<T>,
+    marker: PhantomData<&'a mut T>,
 
-        /// The synchronization mode of the lock. This is explicitly passed to let LLVM relate it
-        /// to the original lock operation.
-        mode: Mode,
-    }
+    /// The synchronization mode of the lock. This is explicitly passed to let LLVM relate it
+    /// to the original lock operation.
+    mode: Mode,
+}
 
-    impl<'a, T: 'a> Deref for LockGuard<'a, T> {
-        type Target = T;
-        #[inline]
-        fn deref(&self) -> &T {
-            // SAFETY: We have shared access to the mutable access owned by this type,
-            // so we can give out a shared reference.
-            unsafe { &*self.lock.data.get() }
-        }
+impl<'a, T: 'a> Deref for LockGuard<'a, T> {
+    type Target = T;
+    #[inline]
+    fn deref(&self) -> &T {
+        // SAFETY: We have shared access to the mutable access owned by this type,
+        // so we can give out a shared reference.
+        unsafe { &*self.lock.data.get() }
     }
+}
 
-    impl<'a, T: 'a> DerefMut for LockGuard<'a, T> {
-        #[inline]
-        fn deref_mut(&mut self) -> &mut T {
-            // SAFETY: We have mutable access to the data so we can give out a mutable reference.
-            unsafe { &mut *self.lock.data.get() }
-        }
+impl<'a, T: 'a> DerefMut for LockGuard<'a, T> {
+    #[inline]
+    fn deref_mut(&mut self) -> &mut T {
+        // SAFETY: We have mutable access to the data so we can give out a mutable reference.
+        unsafe { &mut *self.lock.data.get() }
     }
+}
 
-    impl<'a, T: 'a> Drop for LockGuard<'a, T> {
-        #[inline]
-        fn drop(&mut self) {
-            // SAFETY (union access): We get `self.mode` from the lock operation so it is consistent
-            // with the `lock.mode` state. This means we access the right union fields.
-            match self.mode {
-                Mode::NoSync => {
-                    let cell = unsafe { &self.lock.mode_union.no_sync };
-                    debug_assert!(cell.get());
-                    cell.set(false);
-                }
-                // SAFETY (unlock): We know that the lock is locked as this type is a proof of that.
-                Mode::Sync => unsafe { self.lock.mode_union.sync.unlock() },
+impl<'a, T: 'a> Drop for LockGuard<'a, T> {
+    #[inline]
+    fn drop(&mut self) {
+        // SAFETY (union access): We get `self.mode` from the lock operation so it is consistent
+        // with the `lock.mode` state. This means we access the right union fields.
+        match self.mode {
+            Mode::NoSync => {
+                let cell = unsafe { &self.lock.mode_union.no_sync };
+                debug_assert!(cell.get());
+                cell.set(false);
             }
+            // SAFETY (unlock): We know that the lock is locked as this type is a proof of that.
+            Mode::Sync => unsafe { self.lock.mode_union.sync.unlock() },
         }
     }
+}
 
-    union ModeUnion {
-        /// Indicates if the cell is locked. Only used if `Lock.mode` is `NoSync`.
-        no_sync: ManuallyDrop<Cell<bool>>,
+union ModeUnion {
+    /// Indicates if the cell is locked. Only used if `Lock.mode` is `NoSync`.
+    no_sync: ManuallyDrop<Cell<bool>>,
 
-        /// A lock implementation that's only used if `Lock.mode` is `Sync`.
-        sync: ManuallyDrop<RawMutex>,
-    }
+    /// A lock implementation that's only used if `Lock.mode` is `Sync`.
+    sync: ManuallyDrop<RawMutex>,
+}
 
-    /// The value representing a locked state for the `Cell`.
-    const LOCKED: bool = true;
+/// The value representing a locked state for the `Cell`.
+const LOCKED: bool = true;
 
-    /// A lock which only uses synchronization if `might_be_dyn_thread_safe` is true.
-    /// It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync`.
-    pub struct Lock<T> {
-        /// Indicates if synchronization is used via `mode_union.sync` if it's `Sync`, or if a
-        /// not thread safe cell is used via `mode_union.no_sync` if it's `NoSync`.
-        /// This is set on initialization and never changed.
-        mode: Mode,
+/// A lock which only uses synchronization if `might_be_dyn_thread_safe` is true.
+/// It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync`.
+pub struct Lock<T> {
+    /// Indicates if synchronization is used via `mode_union.sync` if it's `Sync`, or if a
+    /// not thread safe cell is used via `mode_union.no_sync` if it's `NoSync`.
+    /// This is set on initialization and never changed.
+    mode: Mode,
 
-        mode_union: ModeUnion,
-        data: UnsafeCell<T>,
-    }
+    mode_union: ModeUnion,
+    data: UnsafeCell<T>,
+}
 
-    impl<T> Lock<T> {
-        #[inline(always)]
-        pub fn new(inner: T) -> Self {
-            let (mode, mode_union) = if unlikely(mode::might_be_dyn_thread_safe()) {
-                // Create the lock with synchronization enabled using the `RawMutex` type.
-                (Mode::Sync, ModeUnion { sync: ManuallyDrop::new(RawMutex::INIT) })
-            } else {
-                // Create the lock with synchronization disabled.
-                (Mode::NoSync, ModeUnion { no_sync: ManuallyDrop::new(Cell::new(!LOCKED)) })
-            };
-            Lock { mode, mode_union, data: UnsafeCell::new(inner) }
-        }
+impl<T> Lock<T> {
+    #[inline(always)]
+    pub fn new(inner: T) -> Self {
+        let (mode, mode_union) = if unlikely(mode::might_be_dyn_thread_safe()) {
+            // Create the lock with synchronization enabled using the `RawMutex` type.
+            (Mode::Sync, ModeUnion { sync: ManuallyDrop::new(RawMutex::INIT) })
+        } else {
+            // Create the lock with synchronization disabled.
+            (Mode::NoSync, ModeUnion { no_sync: ManuallyDrop::new(Cell::new(!LOCKED)) })
+        };
+        Lock { mode, mode_union, data: UnsafeCell::new(inner) }
+    }
 
-        #[inline(always)]
-        pub fn into_inner(self) -> T {
-            self.data.into_inner()
-        }
+    #[inline(always)]
+    pub fn into_inner(self) -> T {
+        self.data.into_inner()
+    }
 
-        #[inline(always)]
-        pub fn get_mut(&mut self) -> &mut T {
-            self.data.get_mut()
-        }
+    #[inline(always)]
+    pub fn get_mut(&mut self) -> &mut T {
+        self.data.get_mut()
+    }
 
-        #[inline(always)]
-        pub fn try_lock(&self) -> Option<LockGuard<'_, T>> {
-            let mode = self.mode;
-            // SAFETY: This is safe since the union fields are used in accordance with `self.mode`.
-            match mode {
-                Mode::NoSync => {
-                    let cell = unsafe { &self.mode_union.no_sync };
-                    let was_unlocked = cell.get() != LOCKED;
-                    if was_unlocked {
-                        cell.set(LOCKED);
-                    }
-                    was_unlocked
+    #[inline(always)]
+    pub fn try_lock(&self) -> Option<LockGuard<'_, T>> {
+        let mode = self.mode;
+        // SAFETY: This is safe since the union fields are used in accordance with `self.mode`.
+        match mode {
+            Mode::NoSync => {
+                let cell = unsafe { &self.mode_union.no_sync };
+                let was_unlocked = cell.get() != LOCKED;
+                if was_unlocked {
+                    cell.set(LOCKED);
                 }
-                Mode::Sync => unsafe { self.mode_union.sync.try_lock() },
+                was_unlocked
             }
-            .then(|| LockGuard { lock: self, marker: PhantomData, mode })
+            Mode::Sync => unsafe { self.mode_union.sync.try_lock() },
         }
+        .then(|| LockGuard { lock: self, marker: PhantomData, mode })
+    }
 
-        /// This acquires the lock assuming synchronization is in a specific mode.
-        ///
-        /// Safety
-        /// This method must only be called with `Mode::Sync` if `might_be_dyn_thread_safe` was
-        /// true on lock creation.
-        #[inline(always)]
+    /// This acquires the lock assuming synchronization is in a specific mode.
+    ///
+    /// Safety
+    /// This method must only be called with `Mode::Sync` if `might_be_dyn_thread_safe` was
+    /// true on lock creation.
+    #[inline(always)]
+    #[track_caller]
+    pub unsafe fn lock_assume(&self, mode: Mode) -> LockGuard<'_, T> {
+        #[inline(never)]
         #[track_caller]
-        pub unsafe fn lock_assume(&self, mode: Mode) -> LockGuard<'_, T> {
-            #[inline(never)]
-            #[track_caller]
-            #[cold]
-            fn lock_held() -> ! {
-                panic!("lock was already held")
-            }
+        #[cold]
+        fn lock_held() -> ! {
+            panic!("lock was already held")
+        }
 
-            // SAFETY: This is safe since the union fields are used in accordance with `mode`
-            // which also must match `self.mode` due to the safety precondition.
-            unsafe {
-                match mode {
-                    Mode::NoSync => {
-                        if unlikely(self.mode_union.no_sync.replace(LOCKED) == LOCKED) {
-                            lock_held()
-                        }
+        // SAFETY: This is safe since the union fields are used in accordance with `mode`
+        // which also must match `self.mode` due to the safety precondition.
+        unsafe {
+            match mode {
+                Mode::NoSync => {
+                    if unlikely(self.mode_union.no_sync.replace(LOCKED) == LOCKED) {
+                        lock_held()
                     }
-                    Mode::Sync => self.mode_union.sync.lock(),
                 }
+                Mode::Sync => self.mode_union.sync.lock(),
             }
-            LockGuard { lock: self, marker: PhantomData, mode }
-        }
-
-        #[inline(always)]
-        #[track_caller]
-        pub fn lock(&self) -> LockGuard<'_, T> {
-            unsafe { self.lock_assume(self.mode) }
         }
+        LockGuard { lock: self, marker: PhantomData, mode }
     }
 
-    #[cfg(parallel_compiler)]
-    unsafe impl<T: DynSend> DynSend for Lock<T> {}
-    #[cfg(parallel_compiler)]
-    unsafe impl<T: DynSend> DynSync for Lock<T> {}
-}
-
-mod no_sync {
-    use std::cell::RefCell;
-    #[doc(no_inline)]
-    pub use std::cell::RefMut as LockGuard;
-
-    use super::Mode;
-
-    pub struct Lock<T>(RefCell<T>);
-
-    impl<T> Lock<T> {
-        #[inline(always)]
-        pub fn new(inner: T) -> Self {
-            Lock(RefCell::new(inner))
-        }
-
-        #[inline(always)]
-        pub fn into_inner(self) -> T {
-            self.0.into_inner()
-        }
-
-        #[inline(always)]
-        pub fn get_mut(&mut self) -> &mut T {
-            self.0.get_mut()
-        }
-
-        #[inline(always)]
-        pub fn try_lock(&self) -> Option<LockGuard<'_, T>> {
-            self.0.try_borrow_mut().ok()
-        }
-
-        #[inline(always)]
-        #[track_caller]
-        // This is unsafe to match the API for the `parallel_compiler` case.
-        pub unsafe fn lock_assume(&self, _mode: Mode) -> LockGuard<'_, T> {
-            self.0.borrow_mut()
-        }
-
-        #[inline(always)]
-        #[track_caller]
-        pub fn lock(&self) -> LockGuard<'_, T> {
-            self.0.borrow_mut()
-        }
+    #[inline(always)]
+    #[track_caller]
+    pub fn lock(&self) -> LockGuard<'_, T> {
+        unsafe { self.lock_assume(self.mode) }
     }
 }
 
+unsafe impl<T: DynSend> DynSend for Lock<T> {}
+unsafe impl<T: DynSend> DynSync for Lock<T> {}
+
 impl<T> Lock<T> {
     #[inline(always)]
     #[track_caller]
diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs
index c7df19842d6..1ba631b8623 100644
--- a/compiler/rustc_data_structures/src/sync/parallel.rs
+++ b/compiler/rustc_data_structures/src/sync/parallel.rs
@@ -6,14 +6,11 @@
 use std::any::Any;
 use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
 
-#[cfg(not(parallel_compiler))]
-pub use disabled::*;
-#[cfg(parallel_compiler)]
-pub use enabled::*;
 use parking_lot::Mutex;
+use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};
 
 use crate::FatalErrorMarker;
-use crate::sync::IntoDynSyncSend;
+use crate::sync::{DynSend, DynSync, FromDyn, IntoDynSyncSend, mode};
 
 /// A guard used to hold panics that occur during a parallel section to later by unwound.
 /// This is used for the parallel compiler to prevent fatal errors from non-deterministically
@@ -49,65 +46,23 @@ pub fn parallel_guard<R>(f: impl FnOnce(&ParallelGuard) -> R) -> R {
     ret
 }
 
-mod disabled {
-    use crate::sync::parallel_guard;
-
-    #[macro_export]
-    #[cfg(not(parallel_compiler))]
-    macro_rules! parallel {
-        ($($blocks:block),*) => {{
-            $crate::sync::parallel_guard(|guard| {
-                $(guard.run(|| $blocks);)*
-            });
-        }}
-    }
-
-    pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
-    where
-        A: FnOnce() -> RA,
-        B: FnOnce() -> RB,
-    {
-        let (a, b) = parallel_guard(|guard| {
-            let a = guard.run(oper_a);
-            let b = guard.run(oper_b);
-            (a, b)
-        });
-        (a.unwrap(), b.unwrap())
-    }
-
-    pub fn par_for_each_in<T: IntoIterator>(t: T, mut for_each: impl FnMut(T::Item)) {
-        parallel_guard(|guard| {
-            t.into_iter().for_each(|i| {
-                guard.run(|| for_each(i));
-            });
-        })
-    }
-
-    pub fn try_par_for_each_in<T: IntoIterator, E>(
-        t: T,
-        mut for_each: impl FnMut(T::Item) -> Result<(), E>,
-    ) -> Result<(), E> {
-        parallel_guard(|guard| {
-            t.into_iter().filter_map(|i| guard.run(|| for_each(i))).fold(Ok(()), Result::and)
-        })
-    }
-
-    pub fn par_map<T: IntoIterator, R, C: FromIterator<R>>(
-        t: T,
-        mut map: impl FnMut(<<T as IntoIterator>::IntoIter as Iterator>::Item) -> R,
-    ) -> C {
-        parallel_guard(|guard| t.into_iter().filter_map(|i| guard.run(|| map(i))).collect())
-    }
+pub fn serial_join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
+where
+    A: FnOnce() -> RA,
+    B: FnOnce() -> RB,
+{
+    let (a, b) = parallel_guard(|guard| {
+        let a = guard.run(oper_a);
+        let b = guard.run(oper_b);
+        (a, b)
+    });
+    (a.unwrap(), b.unwrap())
 }
 
-#[cfg(parallel_compiler)]
-mod enabled {
-    use crate::sync::{DynSend, DynSync, FromDyn, mode, parallel_guard};
-
-    /// Runs a list of blocks in parallel. The first block is executed immediately on
-    /// the current thread. Use that for the longest running block.
-    #[macro_export]
-    macro_rules! parallel {
+/// Runs a list of blocks in parallel. The first block is executed immediately on
+/// the current thread. Use that for the longest running block.
+#[macro_export]
+macro_rules! parallel {
         (impl $fblock:block [$($c:expr,)*] [$block:expr $(, $rest:expr)*]) => {
             parallel!(impl $fblock [$block, $($c,)*] [$($rest),*])
         };
@@ -139,92 +94,89 @@ mod enabled {
         };
     }
 
-    // This function only works when `mode::is_dyn_thread_safe()`.
-    pub fn scope<'scope, OP, R>(op: OP) -> R
-    where
-        OP: FnOnce(&rayon::Scope<'scope>) -> R + DynSend,
-        R: DynSend,
-    {
-        let op = FromDyn::from(op);
-        rayon::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
+// This function only works when `mode::is_dyn_thread_safe()`.
+pub fn scope<'scope, OP, R>(op: OP) -> R
+where
+    OP: FnOnce(&rayon::Scope<'scope>) -> R + DynSend,
+    R: DynSend,
+{
+    let op = FromDyn::from(op);
+    rayon::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
+}
+
+#[inline]
+pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
+where
+    A: FnOnce() -> RA + DynSend,
+    B: FnOnce() -> RB + DynSend,
+{
+    if mode::is_dyn_thread_safe() {
+        let oper_a = FromDyn::from(oper_a);
+        let oper_b = FromDyn::from(oper_b);
+        let (a, b) = parallel_guard(|guard| {
+            rayon::join(
+                move || guard.run(move || FromDyn::from(oper_a.into_inner()())),
+                move || guard.run(move || FromDyn::from(oper_b.into_inner()())),
+            )
+        });
+        (a.unwrap().into_inner(), b.unwrap().into_inner())
+    } else {
+        serial_join(oper_a, oper_b)
     }
+}
 
-    #[inline]
-    pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
-    where
-        A: FnOnce() -> RA + DynSend,
-        B: FnOnce() -> RB + DynSend,
-    {
+pub fn par_for_each_in<I, T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>>(
+    t: T,
+    for_each: impl Fn(I) + DynSync + DynSend,
+) {
+    parallel_guard(|guard| {
         if mode::is_dyn_thread_safe() {
-            let oper_a = FromDyn::from(oper_a);
-            let oper_b = FromDyn::from(oper_b);
-            let (a, b) = parallel_guard(|guard| {
-                rayon::join(
-                    move || guard.run(move || FromDyn::from(oper_a.into_inner()())),
-                    move || guard.run(move || FromDyn::from(oper_b.into_inner()())),
-                )
+            let for_each = FromDyn::from(for_each);
+            t.into_par_iter().for_each(|i| {
+                guard.run(|| for_each(i));
             });
-            (a.unwrap().into_inner(), b.unwrap().into_inner())
         } else {
-            super::disabled::join(oper_a, oper_b)
+            t.into_iter().for_each(|i| {
+                guard.run(|| for_each(i));
+            });
         }
-    }
-
-    use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};
-
-    pub fn par_for_each_in<I, T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>>(
-        t: T,
-        for_each: impl Fn(I) + DynSync + DynSend,
-    ) {
-        parallel_guard(|guard| {
-            if mode::is_dyn_thread_safe() {
-                let for_each = FromDyn::from(for_each);
-                t.into_par_iter().for_each(|i| {
-                    guard.run(|| for_each(i));
-                });
-            } else {
-                t.into_iter().for_each(|i| {
-                    guard.run(|| for_each(i));
-                });
-            }
-        });
-    }
+    });
+}
 
-    pub fn try_par_for_each_in<
-        T: IntoIterator + IntoParallelIterator<Item = <T as IntoIterator>::Item>,
-        E: Send,
-    >(
-        t: T,
-        for_each: impl Fn(<T as IntoIterator>::Item) -> Result<(), E> + DynSync + DynSend,
-    ) -> Result<(), E> {
-        parallel_guard(|guard| {
-            if mode::is_dyn_thread_safe() {
-                let for_each = FromDyn::from(for_each);
-                t.into_par_iter()
-                    .filter_map(|i| guard.run(|| for_each(i)))
-                    .reduce(|| Ok(()), Result::and)
-            } else {
-                t.into_iter().filter_map(|i| guard.run(|| for_each(i))).fold(Ok(()), Result::and)
-            }
-        })
-    }
+pub fn try_par_for_each_in<
+    T: IntoIterator + IntoParallelIterator<Item = <T as IntoIterator>::Item>,
+    E: Send,
+>(
+    t: T,
+    for_each: impl Fn(<T as IntoIterator>::Item) -> Result<(), E> + DynSync + DynSend,
+) -> Result<(), E> {
+    parallel_guard(|guard| {
+        if mode::is_dyn_thread_safe() {
+            let for_each = FromDyn::from(for_each);
+            t.into_par_iter()
+                .filter_map(|i| guard.run(|| for_each(i)))
+                .reduce(|| Ok(()), Result::and)
+        } else {
+            t.into_iter().filter_map(|i| guard.run(|| for_each(i))).fold(Ok(()), Result::and)
+        }
+    })
+}
 
-    pub fn par_map<
-        I,
-        T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>,
-        R: std::marker::Send,
-        C: FromIterator<R> + FromParallelIterator<R>,
-    >(
-        t: T,
-        map: impl Fn(I) -> R + DynSync + DynSend,
-    ) -> C {
-        parallel_guard(|guard| {
-            if mode::is_dyn_thread_safe() {
-                let map = FromDyn::from(map);
-                t.into_par_iter().filter_map(|i| guard.run(|| map(i))).collect()
-            } else {
-                t.into_iter().filter_map(|i| guard.run(|| map(i))).collect()
-            }
-        })
-    }
+pub fn par_map<
+    I,
+    T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>,
+    R: std::marker::Send,
+    C: FromIterator<R> + FromParallelIterator<R>,
+>(
+    t: T,
+    map: impl Fn(I) -> R + DynSync + DynSend,
+) -> C {
+    parallel_guard(|guard| {
+        if mode::is_dyn_thread_safe() {
+            let map = FromDyn::from(map);
+            t.into_par_iter().filter_map(|i| guard.run(|| map(i))).collect()
+        } else {
+            t.into_iter().filter_map(|i| guard.run(|| map(i))).collect()
+        }
+    })
 }
diff --git a/compiler/rustc_data_structures/src/sync/vec.rs b/compiler/rustc_data_structures/src/sync/vec.rs
index 314496ce9f0..21ec5cf6c13 100644
--- a/compiler/rustc_data_structures/src/sync/vec.rs
+++ b/compiler/rustc_data_structures/src/sync/vec.rs
@@ -4,40 +4,23 @@ use rustc_index::Idx;
 
 #[derive(Default)]
 pub struct AppendOnlyIndexVec<I: Idx, T: Copy> {
-    #[cfg(not(parallel_compiler))]
-    vec: elsa::vec::FrozenVec<T>,
-    #[cfg(parallel_compiler)]
     vec: elsa::sync::LockFreeFrozenVec<T>,
     _marker: PhantomData<fn(&I)>,
 }
 
 impl<I: Idx, T: Copy> AppendOnlyIndexVec<I, T> {
     pub fn new() -> Self {
-        Self {
-            #[cfg(not(parallel_compiler))]
-            vec: elsa::vec::FrozenVec::new(),
-            #[cfg(parallel_compiler)]
-            vec: elsa::sync::LockFreeFrozenVec::new(),
-            _marker: PhantomData,
-        }
+        Self { vec: elsa::sync::LockFreeFrozenVec::new(), _marker: PhantomData }
     }
 
     pub fn push(&self, val: T) -> I {
-        #[cfg(not(parallel_compiler))]
-        let i = self.vec.len();
-        #[cfg(not(parallel_compiler))]
-        self.vec.push(val);
-        #[cfg(parallel_compiler)]
         let i = self.vec.push(val);
         I::new(i)
     }
 
     pub fn get(&self, i: I) -> Option<T> {
         let i = i.index();
-        #[cfg(not(parallel_compiler))]
-        return self.vec.get_copy(i);
-        #[cfg(parallel_compiler)]
-        return self.vec.get(i);
+        self.vec.get(i)
     }
 }
 
diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs
index b6efcada10b..d75af009850 100644
--- a/compiler/rustc_data_structures/src/sync/worker_local.rs
+++ b/compiler/rustc_data_structures/src/sync/worker_local.rs
@@ -5,8 +5,9 @@ use std::ptr;
 use std::sync::Arc;
 
 use parking_lot::Mutex;
-#[cfg(parallel_compiler)]
-use {crate::outline, crate::sync::CacheAligned};
+
+use crate::outline;
+use crate::sync::CacheAligned;
 
 /// A pointer to the `RegistryData` which uniquely identifies a registry.
 /// This identifier can be reused if the registry gets freed.
@@ -21,7 +22,6 @@ impl RegistryId {
     ///
     /// Note that there's a race possible where the identifier in `THREAD_DATA` could be reused
     /// so this can succeed from a different registry.
-    #[cfg(parallel_compiler)]
     fn verify(self) -> usize {
         let (id, index) = THREAD_DATA.with(|data| (data.registry_id.get(), data.index.get()));
 
@@ -102,11 +102,7 @@ impl Registry {
 /// worker local value through the `Deref` impl on the registry associated with the thread it was
 /// created on. It will panic otherwise.
 pub struct WorkerLocal<T> {
-    #[cfg(not(parallel_compiler))]
-    local: T,
-    #[cfg(parallel_compiler)]
     locals: Box<[CacheAligned<T>]>,
-    #[cfg(parallel_compiler)]
     registry: Registry,
 }
 
@@ -114,7 +110,6 @@ pub struct WorkerLocal<T> {
 // or it will panic for threads without an associated local. So there isn't a need for `T` to do
 // it's own synchronization. The `verify` method on `RegistryId` has an issue where the id
 // can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse.
-#[cfg(parallel_compiler)]
 unsafe impl<T: Send> Sync for WorkerLocal<T> {}
 
 impl<T> WorkerLocal<T> {
@@ -122,33 +117,17 @@ impl<T> WorkerLocal<T> {
     /// value this worker local should take for each thread in the registry.
     #[inline]
     pub fn new<F: FnMut(usize) -> T>(mut initial: F) -> WorkerLocal<T> {
-        #[cfg(parallel_compiler)]
-        {
-            let registry = Registry::current();
-            WorkerLocal {
-                locals: (0..registry.0.thread_limit.get())
-                    .map(|i| CacheAligned(initial(i)))
-                    .collect(),
-                registry,
-            }
-        }
-        #[cfg(not(parallel_compiler))]
-        {
-            WorkerLocal { local: initial(0) }
+        let registry = Registry::current();
+        WorkerLocal {
+            locals: (0..registry.0.thread_limit.get()).map(|i| CacheAligned(initial(i))).collect(),
+            registry,
         }
     }
 
     /// Returns the worker-local values for each thread
     #[inline]
     pub fn into_inner(self) -> impl Iterator<Item = T> {
-        #[cfg(parallel_compiler)]
-        {
-            self.locals.into_vec().into_iter().map(|local| local.0)
-        }
-        #[cfg(not(parallel_compiler))]
-        {
-            std::iter::once(self.local)
-        }
+        self.locals.into_vec().into_iter().map(|local| local.0)
     }
 }
 
@@ -156,13 +135,6 @@ impl<T> Deref for WorkerLocal<T> {
     type Target = T;
 
     #[inline(always)]
-    #[cfg(not(parallel_compiler))]
-    fn deref(&self) -> &T {
-        &self.local
-    }
-
-    #[inline(always)]
-    #[cfg(parallel_compiler)]
     fn deref(&self) -> &T {
         // This is safe because `verify` will only return values less than
         // `self.registry.thread_limit` which is the size of the `self.locals` array.
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index 74da0d11e4b..81f15ebcbf8 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -77,9 +77,4 @@ rustc_randomized_layouts = [
     'rustc_index/rustc_randomized_layouts',
     'rustc_middle/rustc_randomized_layouts'
 ]
-rustc_use_parallel_compiler = [
-    'rustc_data_structures/rustc_use_parallel_compiler',
-    'rustc_interface/rustc_use_parallel_compiler',
-    'rustc_middle/rustc_use_parallel_compiler'
-]
 # tidy-alphabetical-end
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 78ba841d89f..b6f7abed6f3 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -934,9 +934,12 @@ pub fn version_at_macro_invocation(
 }
 
 fn usage(verbose: bool, include_unstable_options: bool, nightly_build: bool) {
-    let groups = if verbose { config::rustc_optgroups() } else { config::rustc_short_optgroups() };
     let mut options = getopts::Options::new();
-    for option in groups.iter().filter(|x| include_unstable_options || x.is_stable()) {
+    for option in config::rustc_optgroups()
+        .iter()
+        .filter(|x| verbose || !x.is_verbose_help_only)
+        .filter(|x| include_unstable_options || x.is_stable())
+    {
         option.apply(&mut options);
     }
     let message = "Usage: rustc [OPTIONS] INPUT";
diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml
index 5b6b8b3f183..6974c12f994 100644
--- a/compiler/rustc_error_messages/Cargo.toml
+++ b/compiler/rustc_error_messages/Cargo.toml
@@ -19,8 +19,3 @@ rustc_span = { path = "../rustc_span" }
 tracing = "0.1"
 unic-langid = { version = "0.9.0", features = ["macros"] }
 # tidy-alphabetical-end
-
-[features]
-# tidy-alphabetical-start
-rustc_use_parallel_compiler = ['rustc_baked_icu_data/rustc_use_parallel_compiler']
-# tidy-alphabetical-end
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 2ede7d805fa..74b6d63365a 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -8,12 +8,9 @@
 // tidy-alphabetical-end
 
 use std::borrow::Cow;
-#[cfg(not(parallel_compiler))]
-use std::cell::LazyCell as Lazy;
 use std::error::Error;
 use std::path::{Path, PathBuf};
-#[cfg(parallel_compiler)]
-use std::sync::LazyLock as Lazy;
+use std::sync::LazyLock;
 use std::{fmt, fs, io};
 
 use fluent_bundle::FluentResource;
@@ -21,9 +18,6 @@ pub use fluent_bundle::types::FluentType;
 pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
 use fluent_syntax::parser::ParserError;
 use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker};
-#[cfg(not(parallel_compiler))]
-use intl_memoizer::IntlLangMemoizer;
-#[cfg(parallel_compiler)]
 use intl_memoizer::concurrent::IntlLangMemoizer;
 use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
 use rustc_macros::{Decodable, Encodable};
@@ -34,12 +28,6 @@ pub use unic_langid::{LanguageIdentifier, langid};
 pub type FluentBundle =
     IntoDynSyncSend<fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>>;
 
-#[cfg(not(parallel_compiler))]
-fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle {
-    IntoDynSyncSend(fluent_bundle::bundle::FluentBundle::new(locales))
-}
-
-#[cfg(parallel_compiler)]
 fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle {
     IntoDynSyncSend(fluent_bundle::bundle::FluentBundle::new_concurrent(locales))
 }
@@ -217,7 +205,7 @@ fn register_functions(bundle: &mut FluentBundle) {
 
 /// Type alias for the result of `fallback_fluent_bundle` - a reference-counted pointer to a lazily
 /// evaluated fluent bundle.
-pub type LazyFallbackBundle = Lrc<Lazy<FluentBundle, impl FnOnce() -> FluentBundle>>;
+pub type LazyFallbackBundle = Lrc<LazyLock<FluentBundle, impl FnOnce() -> FluentBundle>>;
 
 /// Return the default `FluentBundle` with standard "en-US" diagnostic messages.
 #[instrument(level = "trace", skip(resources))]
@@ -225,7 +213,7 @@ pub fn fallback_fluent_bundle(
     resources: Vec<&'static str>,
     with_directionality_markers: bool,
 ) -> LazyFallbackBundle {
-    Lrc::new(Lazy::new(move || {
+    Lrc::new(LazyLock::new(move || {
         let mut fallback_bundle = new_bundle(vec![langid!("en-US")]);
 
         register_functions(&mut fallback_bundle);
@@ -548,15 +536,6 @@ pub fn fluent_value_from_str_list_sep_by_and(l: Vec<Cow<'_, str>>) -> FluentValu
             Cow::Owned(result)
         }
 
-        #[cfg(not(parallel_compiler))]
-        fn as_string_threadsafe(
-            &self,
-            _intls: &intl_memoizer::concurrent::IntlLangMemoizer,
-        ) -> Cow<'static, str> {
-            unreachable!("`as_string_threadsafe` is not used in non-parallel rustc")
-        }
-
-        #[cfg(parallel_compiler)]
         fn as_string_threadsafe(
             &self,
             intls: &intl_memoizer::concurrent::IntlLangMemoizer,
diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index 41ebe4ae267..06bae57638f 100644
--- a/compiler/rustc_errors/Cargo.toml
+++ b/compiler/rustc_errors/Cargo.toml
@@ -36,8 +36,3 @@ features = [
     "Win32_Security",
     "Win32_System_Threading",
 ]
-
-[features]
-# tidy-alphabetical-start
-rustc_use_parallel_compiler = ['rustc_error_messages/rustc_use_parallel_compiler']
-# tidy-alphabetical-end
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 6552cf224ea..a386129e814 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -22,7 +22,7 @@ use rustc_error_messages::{FluentArgs, SpanLabel};
 use rustc_lint_defs::pluralize;
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::SourceMap;
-use rustc_span::{FileLines, FileName, SourceFile, Span, char_width};
+use rustc_span::{FileLines, FileName, SourceFile, Span, char_width, str_width};
 use termcolor::{Buffer, BufferWriter, Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
 use tracing::{debug, instrument, trace, warn};
 
@@ -44,6 +44,7 @@ const DEFAULT_COLUMN_WIDTH: usize = 140;
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum HumanReadableErrorType {
     Default,
+    Unicode,
     AnnotateSnippet,
     Short,
 }
@@ -112,8 +113,12 @@ impl Margin {
     fn was_cut_right(&self, line_len: usize) -> bool {
         let right =
             if self.computed_right == self.span_right || self.computed_right == self.label_right {
+                // FIXME: This comment refers to the only callsite of this method.
+                //        Rephrase it or refactor it, so it can stand on its own.
                 // Account for the "..." padding given above. Otherwise we end up with code lines
                 // that do fit but end in "..." as if they were trimmed.
+                // FIXME: Don't hard-code this offset. Is this meant to represent
+                //        `2 * str_width(self.margin())`?
                 self.computed_right - 6
             } else {
                 self.computed_right
@@ -595,6 +600,12 @@ impl ColorConfig {
     }
 }
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum OutputTheme {
+    Ascii,
+    Unicode,
+}
+
 /// Handles the writing of `HumanReadableErrorType::Default` and `HumanReadableErrorType::Short`
 #[derive(Setters)]
 pub struct HumanEmitter {
@@ -613,6 +624,7 @@ pub struct HumanEmitter {
     macro_backtrace: bool,
     track_diagnostics: bool,
     terminal_url: TerminalUrl,
+    theme: OutputTheme,
 }
 
 #[derive(Debug)]
@@ -637,6 +649,7 @@ impl HumanEmitter {
             macro_backtrace: false,
             track_diagnostics: false,
             terminal_url: TerminalUrl::No,
+            theme: OutputTheme::Ascii,
         }
     }
 
@@ -664,6 +677,7 @@ impl HumanEmitter {
         // Create the source line we will highlight.
         let left = margin.left(line_len);
         let right = margin.right(line_len);
+        // FIXME: The following code looks fishy. See #132860.
         // On long lines, we strip the source line, accounting for unicode.
         let mut taken = 0;
         let code: String = source_string
@@ -680,17 +694,19 @@ impl HumanEmitter {
             })
             .collect();
         buffer.puts(line_offset, code_offset, &code, Style::Quotation);
+        let placeholder = self.margin();
         if margin.was_cut_left() {
             // We have stripped some code/whitespace from the beginning, make it clear.
-            buffer.puts(line_offset, code_offset, "...", Style::LineNumber);
+            buffer.puts(line_offset, code_offset, placeholder, Style::LineNumber);
         }
         if margin.was_cut_right(line_len) {
+            let padding = str_width(placeholder);
             // We have stripped some code after the rightmost span end, make it clear we did so.
-            buffer.puts(line_offset, code_offset + taken - 3, "...", Style::LineNumber);
+            buffer.puts(line_offset, code_offset + taken - padding, placeholder, Style::LineNumber);
         }
         buffer.puts(line_offset, 0, &self.maybe_anonymized(line_index), Style::LineNumber);
 
-        draw_col_separator_no_space(buffer, line_offset, width_offset - 2);
+        self.draw_col_separator_no_space(buffer, line_offset, width_offset - 2);
     }
 
     #[instrument(level = "trace", skip(self), ret)]
@@ -702,6 +718,7 @@ impl HumanEmitter {
         width_offset: usize,
         code_offset: usize,
         margin: Margin,
+        close_window: bool,
     ) -> Vec<(usize, Style)> {
         // Draw:
         //
@@ -732,6 +749,7 @@ impl HumanEmitter {
         // Left trim
         let left = margin.left(source_string.len());
 
+        // FIXME: This looks fishy. See #132860.
         // Account for unicode characters of width !=0 that were removed.
         let left = source_string.chars().take(left).map(|ch| char_width(ch)).sum();
 
@@ -767,13 +785,10 @@ impl HumanEmitter {
         for ann in &line.annotations {
             if let AnnotationType::MultilineStart(depth) = ann.annotation_type {
                 if source_string.chars().take(ann.start_col.display).all(|c| c.is_whitespace()) {
-                    let style = if ann.is_primary {
-                        Style::UnderlinePrimary
-                    } else {
-                        Style::UnderlineSecondary
-                    };
-                    annotations.push((depth, style));
-                    buffer_ops.push((line_offset, width_offset + depth - 1, '/', style));
+                    let uline = self.underline(ann.is_primary);
+                    let chr = uline.multiline_whole_line;
+                    annotations.push((depth, uline.style));
+                    buffer_ops.push((line_offset, width_offset + depth - 1, chr, uline.style));
                 } else {
                     short_start = false;
                     break;
@@ -970,7 +985,7 @@ impl HumanEmitter {
             // 3 │       X0 Y0 Z0
             //   │ ┏━━━━━┛  │  │     < We are writing these lines
             //   │ ┃┌───────┘  │     < by reverting the "depth" of
-            //   │ ┃│┌─────────┘     < their multilne spans.
+            //   │ ┃│┌─────────┘     < their multiline spans.
             // 4 │ ┃││   X1 Y1 Z1
             // 5 │ ┃││   X2 Y2 Z2
             //   │ ┃│└────╿──│──┘ `Z` label
@@ -997,7 +1012,10 @@ impl HumanEmitter {
         // 4 |   }
         //   |
         for pos in 0..=line_len {
-            draw_col_separator_no_space(buffer, line_offset + pos + 1, width_offset - 2);
+            self.draw_col_separator_no_space(buffer, line_offset + pos + 1, width_offset - 2);
+        }
+        if close_window {
+            self.draw_col_separator_end(buffer, line_offset + line_len + 1, width_offset - 2);
         }
 
         // Write the horizontal lines for multiline annotations
@@ -1013,21 +1031,17 @@ impl HumanEmitter {
         // 4 |   }
         //   |  _
         for &(pos, annotation) in &annotations_position {
-            let style = if annotation.is_primary {
-                Style::UnderlinePrimary
-            } else {
-                Style::UnderlineSecondary
-            };
+            let underline = self.underline(annotation.is_primary);
             let pos = pos + 1;
             match annotation.annotation_type {
                 AnnotationType::MultilineStart(depth) | AnnotationType::MultilineEnd(depth) => {
-                    draw_range(
+                    self.draw_range(
                         buffer,
-                        '_',
+                        underline.multiline_horizontal,
                         line_offset + pos,
                         width_offset + depth,
                         (code_offset + annotation.start_col.display).saturating_sub(left),
-                        style,
+                        underline.style,
                     );
                 }
                 _ if self.teach => {
@@ -1035,7 +1049,7 @@ impl HumanEmitter {
                         line_offset,
                         (code_offset + annotation.start_col.display).saturating_sub(left),
                         (code_offset + annotation.end_col.display).saturating_sub(left),
-                        style,
+                        underline.style,
                         annotation.is_primary,
                     );
                 }
@@ -1055,11 +1069,7 @@ impl HumanEmitter {
         // 4 | | }
         //   | |_
         for &(pos, annotation) in &annotations_position {
-            let style = if annotation.is_primary {
-                Style::UnderlinePrimary
-            } else {
-                Style::UnderlineSecondary
-            };
+            let underline = self.underline(annotation.is_primary);
             let pos = pos + 1;
 
             if pos > 1 && (annotation.has_label() || annotation.takes_space()) {
@@ -1067,21 +1077,64 @@ impl HumanEmitter {
                     buffer.putc(
                         p,
                         (code_offset + annotation.start_col.display).saturating_sub(left),
-                        '|',
-                        style,
+                        match annotation.annotation_type {
+                            AnnotationType::MultilineLine(_) => underline.multiline_vertical,
+                            _ => underline.vertical_text_line,
+                        },
+                        underline.style,
+                    );
+                }
+                if let AnnotationType::MultilineStart(_) = annotation.annotation_type {
+                    buffer.putc(
+                        line_offset + pos,
+                        (code_offset + annotation.start_col.display).saturating_sub(left),
+                        underline.bottom_right,
+                        underline.style,
+                    );
+                }
+                if let AnnotationType::MultilineEnd(_) = annotation.annotation_type
+                    && annotation.has_label()
+                {
+                    buffer.putc(
+                        line_offset + pos,
+                        (code_offset + annotation.start_col.display).saturating_sub(left),
+                        underline.multiline_bottom_right_with_text,
+                        underline.style,
                     );
                 }
             }
             match annotation.annotation_type {
                 AnnotationType::MultilineStart(depth) => {
+                    buffer.putc(
+                        line_offset + pos,
+                        width_offset + depth - 1,
+                        underline.top_left,
+                        underline.style,
+                    );
                     for p in line_offset + pos + 1..line_offset + line_len + 2 {
-                        buffer.putc(p, width_offset + depth - 1, '|', style);
+                        buffer.putc(
+                            p,
+                            width_offset + depth - 1,
+                            underline.multiline_vertical,
+                            underline.style,
+                        );
                     }
                 }
                 AnnotationType::MultilineEnd(depth) => {
-                    for p in line_offset..=line_offset + pos {
-                        buffer.putc(p, width_offset + depth - 1, '|', style);
+                    for p in line_offset..line_offset + pos {
+                        buffer.putc(
+                            p,
+                            width_offset + depth - 1,
+                            underline.multiline_vertical,
+                            underline.style,
+                        );
                     }
+                    buffer.putc(
+                        line_offset + pos,
+                        width_offset + depth - 1,
+                        underline.bottom_left,
+                        underline.style,
+                    );
                 }
                 _ => (),
             }
@@ -1102,7 +1155,11 @@ impl HumanEmitter {
             let style =
                 if annotation.is_primary { Style::LabelPrimary } else { Style::LabelSecondary };
             let (pos, col) = if pos == 0 {
-                (pos + 1, (annotation.end_col.display + 1).saturating_sub(left))
+                if annotation.end_col.display == 0 {
+                    (pos + 1, (annotation.end_col.display + 2).saturating_sub(left))
+                } else {
+                    (pos + 1, (annotation.end_col.display + 1).saturating_sub(left))
+                }
             } else {
                 (pos + 2, annotation.start_col.display.saturating_sub(left))
             };
@@ -1135,18 +1192,60 @@ impl HumanEmitter {
         // 3 |
         // 4 |   }
         //   |  _^  test
-        for &(_, annotation) in &annotations_position {
-            let (underline, style) = if annotation.is_primary {
-                ('^', Style::UnderlinePrimary)
-            } else {
-                ('-', Style::UnderlineSecondary)
-            };
+        for &(pos, annotation) in &annotations_position {
+            let uline = self.underline(annotation.is_primary);
             for p in annotation.start_col.display..annotation.end_col.display {
+                // The default span label underline.
                 buffer.putc(
                     line_offset + 1,
                     (code_offset + p).saturating_sub(left),
-                    underline,
-                    style,
+                    uline.underline,
+                    uline.style,
+                );
+            }
+
+            if pos == 0
+                && matches!(
+                    annotation.annotation_type,
+                    AnnotationType::MultilineStart(_) | AnnotationType::MultilineEnd(_)
+                )
+            {
+                // The beginning of a multiline span with its leftward moving line on the same line.
+                buffer.putc(
+                    line_offset + 1,
+                    (code_offset + annotation.start_col.display).saturating_sub(left),
+                    match annotation.annotation_type {
+                        AnnotationType::MultilineStart(_) => uline.top_right_flat,
+                        AnnotationType::MultilineEnd(_) => uline.multiline_end_same_line,
+                        _ => panic!("unexpected annotation type: {annotation:?}"),
+                    },
+                    uline.style,
+                );
+            } else if pos != 0
+                && matches!(
+                    annotation.annotation_type,
+                    AnnotationType::MultilineStart(_) | AnnotationType::MultilineEnd(_)
+                )
+            {
+                // The beginning of a multiline span with its leftward moving line on another line,
+                // so we start going down first.
+                buffer.putc(
+                    line_offset + 1,
+                    (code_offset + annotation.start_col.display).saturating_sub(left),
+                    match annotation.annotation_type {
+                        AnnotationType::MultilineStart(_) => uline.multiline_start_down,
+                        AnnotationType::MultilineEnd(_) => uline.multiline_end_up,
+                        _ => panic!("unexpected annotation type: {annotation:?}"),
+                    },
+                    uline.style,
+                );
+            } else if pos != 0 && annotation.has_label() {
+                // The beginning of a span label with an actual label, we'll point down.
+                buffer.putc(
+                    line_offset + 1,
+                    (code_offset + annotation.start_col.display).saturating_sub(left),
+                    uline.label_start,
+                    uline.style,
                 );
             }
         }
@@ -1217,7 +1316,7 @@ impl HumanEmitter {
         padding: usize,
         label: &str,
         override_style: Option<Style>,
-    ) {
+    ) -> usize {
         // The extra 5 ` ` is padding that's always needed to align to the `note: `:
         //
         //   error: message
@@ -1281,6 +1380,7 @@ impl HumanEmitter {
                 buffer.append(line_number, text, style_or_override(*style, override_style));
             }
         }
+        line_number
     }
 
     #[instrument(level = "trace", skip(self, args), ret)]
@@ -1294,6 +1394,7 @@ impl HumanEmitter {
         max_line_num_len: usize,
         is_secondary: bool,
         emitted_at: Option<&DiagLocation>,
+        is_cont: bool,
     ) -> io::Result<()> {
         let mut buffer = StyledBuffer::new();
 
@@ -1303,12 +1404,29 @@ impl HumanEmitter {
             for _ in 0..max_line_num_len {
                 buffer.prepend(0, " ", Style::NoStyle);
             }
-            draw_note_separator(&mut buffer, 0, max_line_num_len + 1);
+            self.draw_note_separator(&mut buffer, 0, max_line_num_len + 1, is_cont);
             if *level != Level::FailureNote {
                 buffer.append(0, level.to_str(), Style::MainHeaderMsg);
                 buffer.append(0, ": ", Style::NoStyle);
             }
-            self.msgs_to_buffer(&mut buffer, msgs, args, max_line_num_len, "note", None);
+            let printed_lines =
+                self.msgs_to_buffer(&mut buffer, msgs, args, max_line_num_len, "note", None);
+            if is_cont && matches!(self.theme, OutputTheme::Unicode) {
+                // There's another note after this one, associated to the subwindow above.
+                // We write additional vertical lines to join them:
+                //   ╭▸ test.rs:3:3
+                //   │
+                // 3 │   code
+                //   │   ━━━━
+                //   │
+                //   ├ note: foo
+                //   │       bar
+                //   ╰ note: foo
+                //           bar
+                for i in 1..=printed_lines {
+                    self.draw_col_separator_no_space(&mut buffer, i, max_line_num_len + 1);
+                }
+            }
         } else {
             let mut label_width = 0;
             // The failure note level itself does not provide any useful diagnostic information
@@ -1439,9 +1557,13 @@ impl HumanEmitter {
                                 Style::LineAndColumn,
                             );
                             if annotation_id == 0 {
-                                buffer.prepend(line_idx, "--> ", Style::LineNumber);
+                                buffer.prepend(line_idx, self.file_start(), Style::LineNumber);
                             } else {
-                                buffer.prepend(line_idx, "::: ", Style::LineNumber);
+                                buffer.prepend(
+                                    line_idx,
+                                    self.secondary_file_start(),
+                                    Style::LineNumber,
+                                );
                             }
                             for _ in 0..max_line_num_len {
                                 buffer.prepend(line_idx, " ", Style::NoStyle);
@@ -1454,12 +1576,14 @@ impl HumanEmitter {
                             } else {
                                 Style::LabelSecondary
                             };
-                            buffer.prepend(line_idx, " |", Style::LineNumber);
+                            let pipe = self.col_separator();
+                            buffer.prepend(line_idx, &format!(" {pipe}"), Style::LineNumber);
                             for _ in 0..max_line_num_len {
                                 buffer.prepend(line_idx, " ", Style::NoStyle);
                             }
                             line_idx += 1;
-                            buffer.append(line_idx, " = note: ", style);
+                            let chr = self.note_separator();
+                            buffer.append(line_idx, &format!(" {chr} note: "), style);
                             for _ in 0..max_line_num_len {
                                 buffer.prepend(line_idx, " ", Style::NoStyle);
                             }
@@ -1480,7 +1604,7 @@ impl HumanEmitter {
                     // remember where we are in the output buffer for easy reference
                     let buffer_msg_line_offset = buffer.num_lines();
 
-                    buffer.prepend(buffer_msg_line_offset, "--> ", Style::LineNumber);
+                    buffer.prepend(buffer_msg_line_offset, self.file_start(), Style::LineNumber);
                     buffer.append(
                         buffer_msg_line_offset,
                         &format!(
@@ -1510,15 +1634,28 @@ impl HumanEmitter {
                 // remember where we are in the output buffer for easy reference
                 let buffer_msg_line_offset = buffer.num_lines();
 
-                // Add spacing line
-                draw_col_separator_no_space(
+                // Add spacing line, as shown:
+                //   --> $DIR/file:54:15
+                //    |
+                // LL |         code
+                //    |         ^^^^
+                //    | (<- It prints *this* line)
+                //   ::: $DIR/other_file.rs:15:5
+                //    |
+                // LL |     code
+                //    |     ----
+                self.draw_col_separator_no_space(
                     &mut buffer,
                     buffer_msg_line_offset,
                     max_line_num_len + 1,
                 );
 
                 // Then, the secondary file indicator
-                buffer.prepend(buffer_msg_line_offset + 1, "::: ", Style::LineNumber);
+                buffer.prepend(
+                    buffer_msg_line_offset + 1,
+                    self.secondary_file_start(),
+                    Style::LineNumber,
+                );
                 let loc = if let Some(first_line) = annotated_file.lines.first() {
                     let col = if let Some(first_annotation) = first_line.annotations.first() {
                         format!(":{}", first_annotation.start_col.file + 1)
@@ -1543,7 +1680,7 @@ impl HumanEmitter {
             if !self.short_message {
                 // Put in the spacer between the location and annotated source
                 let buffer_msg_line_offset = buffer.num_lines();
-                draw_col_separator_no_space(
+                self.draw_col_separator_no_space(
                     &mut buffer,
                     buffer_msg_line_offset,
                     max_line_num_len + 1,
@@ -1651,6 +1788,7 @@ impl HumanEmitter {
                         width_offset,
                         code_offset,
                         margin,
+                        !is_cont && line_idx + 1 == annotated_file.lines.len(),
                     );
 
                     let mut to_add = FxHashMap::default();
@@ -1666,7 +1804,13 @@ impl HumanEmitter {
                     // the code in this line.
                     for (depth, style) in &multilines {
                         for line in previous_buffer_line..buffer.num_lines() {
-                            draw_multiline_line(&mut buffer, line, width_offset, *depth, *style);
+                            self.draw_multiline_line(
+                                &mut buffer,
+                                line,
+                                width_offset,
+                                *depth,
+                                *style,
+                            );
                         }
                     }
                     // check to see if we need to print out or elide lines that come between
@@ -1676,11 +1820,15 @@ impl HumanEmitter {
                             - annotated_file.lines[line_idx].line_index;
                         if line_idx_delta > 2 {
                             let last_buffer_line_num = buffer.num_lines();
-                            buffer.puts(last_buffer_line_num, 0, "...", Style::LineNumber);
+                            self.draw_line_separator(
+                                &mut buffer,
+                                last_buffer_line_num,
+                                width_offset,
+                            );
 
                             // Set the multiline annotation vertical lines on `...` bridging line.
                             for (depth, style) in &multilines {
-                                draw_multiline_line(
+                                self.draw_multiline_line(
                                     &mut buffer,
                                     last_buffer_line_num,
                                     width_offset,
@@ -1695,7 +1843,7 @@ impl HumanEmitter {
                                         // In the case where we have elided the entire start of the
                                         // multispan because those lines were empty, we still need
                                         // to draw the `|`s across the `...`.
-                                        draw_multiline_line(
+                                        self.draw_multiline_line(
                                             &mut buffer,
                                             last_buffer_line_num,
                                             width_offset,
@@ -1728,7 +1876,7 @@ impl HumanEmitter {
                             );
 
                             for (depth, style) in &multilines {
-                                draw_multiline_line(
+                                self.draw_multiline_line(
                                     &mut buffer,
                                     last_buffer_line_num,
                                     width_offset,
@@ -1740,7 +1888,7 @@ impl HumanEmitter {
                                 for ann in &line.annotations {
                                     if let AnnotationType::MultilineStart(pos) = ann.annotation_type
                                     {
-                                        draw_multiline_line(
+                                        self.draw_multiline_line(
                                             &mut buffer,
                                             last_buffer_line_num,
                                             width_offset,
@@ -1824,13 +1972,24 @@ impl HumanEmitter {
         );
 
         let mut row_num = 2;
-        draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1);
-        for (complete, parts, highlights, _) in suggestions.iter().take(MAX_SUGGESTIONS) {
+        for (i, (complete, parts, highlights, _)) in
+            suggestions.iter().enumerate().take(MAX_SUGGESTIONS)
+        {
             debug!(?complete, ?parts, ?highlights);
 
             let has_deletion = parts.iter().any(|p| p.is_deletion(sm));
             let is_multiline = complete.lines().count() > 1;
 
+            if i == 0 {
+                self.draw_col_separator_start(&mut buffer, row_num - 1, max_line_num_len + 1);
+            } else {
+                buffer.puts(
+                    row_num - 1,
+                    max_line_num_len + 1,
+                    self.multi_suggestion_separator(),
+                    Style::LineNumber,
+                );
+            }
             if let Some(span) = span.primary_span() {
                 // Compare the primary span of the diagnostic with the span of the suggestion
                 // being emitted. If they belong to the same file, we don't *need* to show the
@@ -1838,7 +1997,9 @@ impl HumanEmitter {
                 // telling users to make a change but not clarifying *where*.
                 let loc = sm.lookup_char_pos(parts[0].span.lo());
                 if loc.file.name != sm.span_to_filename(span) && loc.file.name.is_real() {
-                    let arrow = "--> ";
+                    // --> file.rs:line:col
+                    //  |
+                    let arrow = self.file_start();
                     buffer.puts(row_num - 1, 0, arrow, Style::LineNumber);
                     let filename = sm.filename_for_diagnostics(&loc.file.name);
                     let offset = sm.doctest_offset_line(&loc.file.name, loc.line);
@@ -1852,6 +2013,7 @@ impl HumanEmitter {
                     for _ in 0..max_line_num_len {
                         buffer.prepend(row_num - 1, " ", Style::NoStyle);
                     }
+                    self.draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1);
                     row_num += 1;
                 }
             }
@@ -1882,7 +2044,6 @@ impl HumanEmitter {
             assert!(!file_lines.lines.is_empty() || parts[0].span.is_dummy());
 
             let line_start = sm.lookup_char_pos(parts[0].span.lo()).line;
-            draw_col_separator_no_space(&mut buffer, row_num - 1, max_line_num_len + 1);
             let mut lines = complete.lines();
             if lines.clone().next().is_none() {
                 // Account for a suggestion to completely remove a line(s) with whitespace (#94192).
@@ -1972,7 +2133,14 @@ impl HumanEmitter {
                             )
                         }
 
-                        buffer.puts(row_num, 0, "...", Style::LineNumber);
+                        let placeholder = self.margin();
+                        let padding = str_width(placeholder);
+                        buffer.puts(
+                            row_num,
+                            max_line_num_len.saturating_sub(padding),
+                            placeholder,
+                            Style::LineNumber,
+                        );
                         row_num += 1;
 
                         if let Some((p, l)) = last_line {
@@ -2040,7 +2208,6 @@ impl HumanEmitter {
             if let DisplaySuggestion::Diff | DisplaySuggestion::Underline | DisplaySuggestion::Add =
                 show_code_change
             {
-                draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1);
                 for part in parts {
                     let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display;
                     let span_end_pos = sm.lookup_char_pos(part.span.hi()).col_display;
@@ -2057,11 +2224,11 @@ impl HumanEmitter {
                     };
                     // ...or trailing spaces. Account for substitutions containing unicode
                     // characters.
-                    let sub_len: usize =
-                        if is_whitespace_addition { &part.snippet } else { part.snippet.trim() }
-                            .chars()
-                            .map(|ch| char_width(ch))
-                            .sum();
+                    let sub_len: usize = str_width(if is_whitespace_addition {
+                        &part.snippet
+                    } else {
+                        part.snippet.trim()
+                    });
 
                     let offset: isize = offsets
                         .iter()
@@ -2082,7 +2249,7 @@ impl HumanEmitter {
                             buffer.putc(
                                 row_num,
                                 (padding as isize + p) as usize,
-                                if part.is_addition(sm) { '+' } else { '~' },
+                                if part.is_addition(sm) { '+' } else { self.diff() },
                                 Style::Addition,
                             );
                         }
@@ -2099,8 +2266,7 @@ impl HumanEmitter {
                     }
 
                     // length of the code after substitution
-                    let full_sub_len =
-                        part.snippet.chars().map(|ch| char_width(ch)).sum::<usize>() as isize;
+                    let full_sub_len = str_width(&part.snippet) as isize;
 
                     // length of the code to be substituted
                     let snippet_len = span_end_pos as isize - span_start_pos as isize;
@@ -2114,10 +2280,23 @@ impl HumanEmitter {
 
             // if we elided some lines, add an ellipsis
             if lines.next().is_some() {
-                buffer.puts(row_num, max_line_num_len - 1, "...", Style::LineNumber);
-            } else if let DisplaySuggestion::None = show_code_change {
-                draw_col_separator_no_space(&mut buffer, row_num, max_line_num_len + 1);
-                row_num += 1;
+                let placeholder = self.margin();
+                let padding = str_width(placeholder);
+                buffer.puts(
+                    row_num,
+                    max_line_num_len.saturating_sub(padding),
+                    placeholder,
+                    Style::LineNumber,
+                );
+            } else {
+                let row = match show_code_change {
+                    DisplaySuggestion::Diff
+                    | DisplaySuggestion::Add
+                    | DisplaySuggestion::Underline => row_num - 1,
+                    DisplaySuggestion::None => row_num,
+                };
+                self.draw_col_separator_end(&mut buffer, row, max_line_num_len + 1);
+                row_num = row + 1;
             }
         }
         if suggestions.len() > MAX_SUGGESTIONS {
@@ -2125,6 +2304,7 @@ impl HumanEmitter {
             let msg = format!("and {} other candidate{}", others, pluralize!(others));
             buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
         }
+
         emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
         Ok(())
     }
@@ -2157,6 +2337,8 @@ impl HumanEmitter {
             max_line_num_len,
             false,
             emitted_at,
+            !children.is_empty()
+                || suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden),
         ) {
             Ok(()) => {
                 if !children.is_empty()
@@ -2164,7 +2346,15 @@ impl HumanEmitter {
                 {
                     let mut buffer = StyledBuffer::new();
                     if !self.short_message {
-                        draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1);
+                        if let Some(child) = children.iter().next()
+                            && child.span.primary_spans().is_empty()
+                        {
+                            // We'll continue the vertical bar to point into the next note.
+                            self.draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1);
+                        } else {
+                            // We'll close the vertical bar to visually end the code window.
+                            self.draw_col_separator_end(&mut buffer, 0, max_line_num_len + 1);
+                        }
                     }
                     if let Err(e) = emit_to_destination(
                         &buffer.render(),
@@ -2176,9 +2366,14 @@ impl HumanEmitter {
                     }
                 }
                 if !self.short_message {
-                    for child in children {
+                    for (i, child) in children.iter().enumerate() {
                         assert!(child.level.can_be_subdiag());
                         let span = &child.span;
+                        // FIXME: audit that this behaves correctly with suggestions.
+                        let should_close = match children.get(i + 1) {
+                            Some(c) => !c.span.primary_spans().is_empty(),
+                            None => i + 1 == children.len(),
+                        };
                         if let Err(err) = self.emit_messages_default_inner(
                             span,
                             &child.messages,
@@ -2188,11 +2383,12 @@ impl HumanEmitter {
                             max_line_num_len,
                             true,
                             None,
+                            !should_close,
                         ) {
                             panic!("failed to emit error: {err}");
                         }
                     }
-                    for sugg in suggestions {
+                    for (i, sugg) in suggestions.iter().enumerate() {
                         match sugg.style {
                             SuggestionStyle::CompletelyHidden => {
                                 // do not display this suggestion, it is meant only for tools
@@ -2207,6 +2403,9 @@ impl HumanEmitter {
                                     max_line_num_len,
                                     true,
                                     None,
+                                    // FIXME: this needs to account for the suggestion type,
+                                    //        some don't take any space.
+                                    i + 1 != suggestions.len(),
                                 ) {
                                     panic!("failed to emit error: {e}");
                                 }
@@ -2323,10 +2522,17 @@ impl HumanEmitter {
                     buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition);
                 }
                 [] => {
-                    draw_col_separator_no_space(buffer, *row_num, max_line_num_len + 1);
+                    // FIXME: needed? Doesn't get excercised in any test.
+                    self.draw_col_separator_no_space(buffer, *row_num, max_line_num_len + 1);
                 }
                 _ => {
-                    buffer.puts(*row_num, max_line_num_len + 1, "~ ", Style::Addition);
+                    let diff = self.diff();
+                    buffer.puts(
+                        *row_num,
+                        max_line_num_len + 1,
+                        &format!("{diff} "),
+                        Style::Addition,
+                    );
                 }
             }
             //   LL | line_to_add
@@ -2346,7 +2552,7 @@ impl HumanEmitter {
             buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle);
         } else {
             buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber);
-            draw_col_separator(buffer, *row_num, max_line_num_len + 1);
+            self.draw_col_separator(buffer, *row_num, max_line_num_len + 1);
             buffer.append(*row_num, &normalize_whitespace(line_to_add), Style::NoStyle);
         }
 
@@ -2374,6 +2580,306 @@ impl HumanEmitter {
         }
         *row_num += 1;
     }
+
+    fn underline(&self, is_primary: bool) -> UnderlineParts {
+        //               X0 Y0
+        // label_start > ┯━━━━ < underline
+        //               │ < vertical_text_line
+        //               text
+
+        //    multiline_start_down ⤷ X0 Y0
+        //            top_left > ┌───╿──┘ < top_right_flat
+        //           top_left > ┏│━━━┙ < top_right
+        // multiline_vertical > ┃│
+        //                      ┃│   X1 Y1
+        //                      ┃│   X2 Y2
+        //                      ┃└────╿──┘ < multiline_end_same_line
+        //        bottom_left > ┗━━━━━┥ < bottom_right_with_text
+        //   multiline_horizontal ^   `X` is a good letter
+
+        // multiline_whole_line > ┏ X0 Y0
+        //                        ┃   X1 Y1
+        //                        ┗━━━━┛ < multiline_end_same_line
+
+        // multiline_whole_line > ┏ X0 Y0
+        //                        ┃ X1 Y1
+        //                        ┃  ╿ < multiline_end_up
+        //                        ┗━━┛ < bottom_right
+
+        match (self.theme, is_primary) {
+            (OutputTheme::Ascii, true) => UnderlineParts {
+                style: Style::UnderlinePrimary,
+                underline: '^',
+                label_start: '^',
+                vertical_text_line: '|',
+                multiline_vertical: '|',
+                multiline_horizontal: '_',
+                multiline_whole_line: '/',
+                multiline_start_down: '^',
+                bottom_right: '|',
+                top_left: ' ',
+                top_right_flat: '^',
+                bottom_left: '|',
+                multiline_end_up: '^',
+                multiline_end_same_line: '^',
+                multiline_bottom_right_with_text: '|',
+            },
+            (OutputTheme::Ascii, false) => UnderlineParts {
+                style: Style::UnderlineSecondary,
+                underline: '-',
+                label_start: '-',
+                vertical_text_line: '|',
+                multiline_vertical: '|',
+                multiline_horizontal: '_',
+                multiline_whole_line: '/',
+                multiline_start_down: '-',
+                bottom_right: '|',
+                top_left: ' ',
+                top_right_flat: '-',
+                bottom_left: '|',
+                multiline_end_up: '-',
+                multiline_end_same_line: '-',
+                multiline_bottom_right_with_text: '|',
+            },
+            (OutputTheme::Unicode, true) => UnderlineParts {
+                style: Style::UnderlinePrimary,
+                underline: '━',
+                label_start: '┯',
+                vertical_text_line: '│',
+                multiline_vertical: '┃',
+                multiline_horizontal: '━',
+                multiline_whole_line: '┏',
+                multiline_start_down: '╿',
+                bottom_right: '┙',
+                top_left: '┏',
+                top_right_flat: '┛',
+                bottom_left: '┗',
+                multiline_end_up: '╿',
+                multiline_end_same_line: '┛',
+                multiline_bottom_right_with_text: '┥',
+            },
+            (OutputTheme::Unicode, false) => UnderlineParts {
+                style: Style::UnderlineSecondary,
+                underline: '─',
+                label_start: '┬',
+                vertical_text_line: '│',
+                multiline_vertical: '│',
+                multiline_horizontal: '─',
+                multiline_whole_line: '┌',
+                multiline_start_down: '│',
+                bottom_right: '┘',
+                top_left: '┌',
+                top_right_flat: '┘',
+                bottom_left: '└',
+                multiline_end_up: '│',
+                multiline_end_same_line: '┘',
+                multiline_bottom_right_with_text: '┤',
+            },
+        }
+    }
+
+    fn col_separator(&self) -> char {
+        match self.theme {
+            OutputTheme::Ascii => '|',
+            OutputTheme::Unicode => '│',
+        }
+    }
+
+    fn note_separator(&self) -> char {
+        match self.theme {
+            OutputTheme::Ascii => '=',
+            OutputTheme::Unicode => '╰',
+        }
+    }
+
+    fn multi_suggestion_separator(&self) -> &'static str {
+        match self.theme {
+            OutputTheme::Ascii => "|",
+            OutputTheme::Unicode => "├╴",
+        }
+    }
+
+    fn draw_col_separator(&self, buffer: &mut StyledBuffer, line: usize, col: usize) {
+        let chr = self.col_separator();
+        buffer.puts(line, col, &format!("{chr} "), Style::LineNumber);
+    }
+
+    fn draw_col_separator_no_space(&self, buffer: &mut StyledBuffer, line: usize, col: usize) {
+        let chr = self.col_separator();
+        self.draw_col_separator_no_space_with_style(buffer, chr, line, col, Style::LineNumber);
+    }
+
+    fn draw_col_separator_start(&self, buffer: &mut StyledBuffer, line: usize, col: usize) {
+        match self.theme {
+            OutputTheme::Ascii => {
+                self.draw_col_separator_no_space_with_style(
+                    buffer,
+                    '|',
+                    line,
+                    col,
+                    Style::LineNumber,
+                );
+            }
+            OutputTheme::Unicode => {
+                self.draw_col_separator_no_space_with_style(
+                    buffer,
+                    '╭',
+                    line,
+                    col,
+                    Style::LineNumber,
+                );
+                self.draw_col_separator_no_space_with_style(
+                    buffer,
+                    '╴',
+                    line,
+                    col + 1,
+                    Style::LineNumber,
+                );
+            }
+        }
+    }
+
+    fn draw_col_separator_end(&self, buffer: &mut StyledBuffer, line: usize, col: usize) {
+        match self.theme {
+            OutputTheme::Ascii => {
+                self.draw_col_separator_no_space_with_style(
+                    buffer,
+                    '|',
+                    line,
+                    col,
+                    Style::LineNumber,
+                );
+            }
+            OutputTheme::Unicode => {
+                self.draw_col_separator_no_space_with_style(
+                    buffer,
+                    '╰',
+                    line,
+                    col,
+                    Style::LineNumber,
+                );
+                self.draw_col_separator_no_space_with_style(
+                    buffer,
+                    '╴',
+                    line,
+                    col + 1,
+                    Style::LineNumber,
+                );
+            }
+        }
+    }
+
+    fn draw_col_separator_no_space_with_style(
+        &self,
+        buffer: &mut StyledBuffer,
+        chr: char,
+        line: usize,
+        col: usize,
+        style: Style,
+    ) {
+        buffer.putc(line, col, chr, style);
+    }
+
+    fn draw_range(
+        &self,
+        buffer: &mut StyledBuffer,
+        symbol: char,
+        line: usize,
+        col_from: usize,
+        col_to: usize,
+        style: Style,
+    ) {
+        for col in col_from..col_to {
+            buffer.putc(line, col, symbol, style);
+        }
+    }
+
+    fn draw_note_separator(
+        &self,
+        buffer: &mut StyledBuffer,
+        line: usize,
+        col: usize,
+        is_cont: bool,
+    ) {
+        let chr = match self.theme {
+            OutputTheme::Ascii => "= ",
+            OutputTheme::Unicode if is_cont => "├ ",
+            OutputTheme::Unicode => "╰ ",
+        };
+        buffer.puts(line, col, chr, Style::LineNumber);
+    }
+
+    fn draw_multiline_line(
+        &self,
+        buffer: &mut StyledBuffer,
+        line: usize,
+        offset: usize,
+        depth: usize,
+        style: Style,
+    ) {
+        let chr = match (style, self.theme) {
+            (Style::UnderlinePrimary | Style::LabelPrimary, OutputTheme::Ascii) => '|',
+            (_, OutputTheme::Ascii) => '|',
+            (Style::UnderlinePrimary | Style::LabelPrimary, OutputTheme::Unicode) => '┃',
+            (_, OutputTheme::Unicode) => '│',
+        };
+        buffer.putc(line, offset + depth - 1, chr, style);
+    }
+
+    fn file_start(&self) -> &'static str {
+        match self.theme {
+            OutputTheme::Ascii => "--> ",
+            OutputTheme::Unicode => " ╭▸ ",
+        }
+    }
+
+    fn secondary_file_start(&self) -> &'static str {
+        match self.theme {
+            OutputTheme::Ascii => "::: ",
+            OutputTheme::Unicode => " ⸬ ",
+        }
+    }
+
+    fn diff(&self) -> char {
+        match self.theme {
+            OutputTheme::Ascii => '~',
+            OutputTheme::Unicode => '±',
+        }
+    }
+
+    fn draw_line_separator(&self, buffer: &mut StyledBuffer, line: usize, col: usize) {
+        let (column, dots) = match self.theme {
+            OutputTheme::Ascii => (0, "..."),
+            OutputTheme::Unicode => (col - 2, "‡"),
+        };
+        buffer.puts(line, column, dots, Style::LineNumber);
+    }
+
+    fn margin(&self) -> &'static str {
+        match self.theme {
+            OutputTheme::Ascii => "...",
+            OutputTheme::Unicode => "…",
+        }
+    }
+}
+
+#[derive(Debug, Clone, Copy)]
+struct UnderlineParts {
+    style: Style,
+    underline: char,
+    label_start: char,
+    vertical_text_line: char,
+    multiline_vertical: char,
+    multiline_horizontal: char,
+    multiline_whole_line: char,
+    multiline_start_down: char,
+    bottom_right: char,
+    top_left: char,
+    top_right_flat: char,
+    bottom_left: char,
+    multiline_end_up: char,
+    multiline_end_same_line: char,
+    multiline_bottom_right_with_text: char,
 }
 
 #[derive(Clone, Copy, Debug)]
@@ -2666,50 +3172,6 @@ fn normalize_whitespace(s: &str) -> String {
     })
 }
 
-fn draw_col_separator(buffer: &mut StyledBuffer, line: usize, col: usize) {
-    buffer.puts(line, col, "| ", Style::LineNumber);
-}
-
-fn draw_col_separator_no_space(buffer: &mut StyledBuffer, line: usize, col: usize) {
-    draw_col_separator_no_space_with_style(buffer, line, col, Style::LineNumber);
-}
-
-fn draw_col_separator_no_space_with_style(
-    buffer: &mut StyledBuffer,
-    line: usize,
-    col: usize,
-    style: Style,
-) {
-    buffer.putc(line, col, '|', style);
-}
-
-fn draw_range(
-    buffer: &mut StyledBuffer,
-    symbol: char,
-    line: usize,
-    col_from: usize,
-    col_to: usize,
-    style: Style,
-) {
-    for col in col_from..col_to {
-        buffer.putc(line, col, symbol, style);
-    }
-}
-
-fn draw_note_separator(buffer: &mut StyledBuffer, line: usize, col: usize) {
-    buffer.puts(line, col, "= ", Style::LineNumber);
-}
-
-fn draw_multiline_line(
-    buffer: &mut StyledBuffer,
-    line: usize,
-    offset: usize,
-    depth: usize,
-    style: Style,
-) {
-    buffer.putc(line, offset + depth - 1, '|', style);
-}
-
 fn num_overlap(
     a_start: usize,
     a_end: usize,
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 91e2b9996cd..e3b6dcea892 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -27,7 +27,7 @@ use termcolor::{ColorSpec, WriteColor};
 
 use crate::diagnostic::IsLint;
 use crate::emitter::{
-    ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType,
+    ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType, OutputTheme,
     should_show_source_code,
 };
 use crate::registry::Registry;
@@ -377,6 +377,11 @@ impl Diagnostic {
             .terminal_url(je.terminal_url)
             .ui_testing(je.ui_testing)
             .ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone())
+            .theme(if let HumanReadableErrorType::Unicode = je.json_rendered {
+                OutputTheme::Unicode
+            } else {
+                OutputTheme::Ascii
+            })
             .emit_diagnostic(diag);
         let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap();
         let buf = String::from_utf8(buf).unwrap();
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 94365a89adc..98200c367f9 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -623,12 +623,25 @@ impl Drop for DiagCtxtInner {
             self.flush_delayed()
         }
 
+        // Sanity check: did we use some of the expensive `trimmed_def_paths` functions
+        // unexpectedly, that is, without producing diagnostics? If so, for debugging purposes, we
+        // suggest where this happened and how to avoid it.
         if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() {
             if let Some(backtrace) = &self.must_produce_diag {
+                let suggestion = match backtrace.status() {
+                    BacktraceStatus::Disabled => String::from(
+                        "Backtraces are currently disabled: set `RUST_BACKTRACE=1` and re-run \
+                        to see where it happened.",
+                    ),
+                    BacktraceStatus::Captured => format!(
+                        "This happened in the following `must_produce_diag` call's backtrace:\n\
+                        {backtrace}",
+                    ),
+                    _ => String::from("(impossible to capture backtrace where this happened)"),
+                };
                 panic!(
-                    "must_produce_diag: `trimmed_def_paths` called but no diagnostics emitted; \
-                     `with_no_trimmed_paths` for debugging. \
-                     called at: {backtrace}"
+                    "`trimmed_def_paths` called, diagnostics were expected but none were emitted. \
+                    Use `with_no_trimmed_paths` for debugging. {suggestion}"
                 );
             }
         }
diff --git a/compiler/rustc_errors/src/tests.rs b/compiler/rustc_errors/src/tests.rs
index 70179237e5d..376fd24d57b 100644
--- a/compiler/rustc_errors/src/tests.rs
+++ b/compiler/rustc_errors/src/tests.rs
@@ -26,16 +26,11 @@ fn make_dummy(ftl: &'static str) -> Dummy {
 
     let langid_en = langid!("en-US");
 
-    #[cfg(parallel_compiler)]
     let mut bundle: FluentBundle =
         IntoDynSyncSend(crate::fluent_bundle::bundle::FluentBundle::new_concurrent(vec![
             langid_en,
         ]));
 
-    #[cfg(not(parallel_compiler))]
-    let mut bundle: FluentBundle =
-        IntoDynSyncSend(crate::fluent_bundle::bundle::FluentBundle::new(vec![langid_en]));
-
     bundle.add_resource(resource).expect("Failed to add FTL resources to the bundle.");
 
     Dummy { bundle }
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 7e4bc508e5c..bed500c3032 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -866,9 +866,7 @@ impl SyntaxExtension {
             })
             .unwrap_or_else(|| (None, helper_attrs));
         let stability = attr::find_stability(sess, attrs, span);
-        // We set `is_const_fn` false to avoid getting any implicit const stability.
-        let const_stability =
-            attr::find_const_stability(sess, attrs, span, /* is_const_fn */ false);
+        let const_stability = attr::find_const_stability(sess, attrs, span);
         let body_stability = attr::find_body_stability(sess, attrs);
         if let Some((_, sp)) = const_stability {
             sess.dcx().emit_err(errors::MacroConstStability {
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index c952d5f6d77..15cb331d07a 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -241,6 +241,8 @@ language_item_table! {
     DerefMut,                sym::deref_mut,           deref_mut_trait,            Target::Trait,          GenericRequirement::Exact(0);
     DerefPure,               sym::deref_pure,          deref_pure_trait,           Target::Trait,          GenericRequirement::Exact(0);
     DerefTarget,             sym::deref_target,        deref_target,               Target::AssocTy,        GenericRequirement::None;
+    Receiver,                sym::receiver,            receiver_trait,             Target::Trait,          GenericRequirement::None;
+    ReceiverTarget,          sym::receiver_target,     receiver_target,            Target::AssocTy,        GenericRequirement::None;
     LegacyReceiver,          sym::legacy_receiver,     legacy_receiver_trait,      Target::Trait,          GenericRequirement::None;
 
     Fn,                      kw::Fn,                   fn_trait,                   Target::Trait,          GenericRequirement::Exact(1);
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 3a6ea545741..1802f00bc1f 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1427,16 +1427,6 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
     let predicates = tcx.predicates_of(def_id.to_def_id());
     let generics = tcx.generics_of(def_id);
 
-    let is_our_default = |def: &ty::GenericParamDef| match def.kind {
-        GenericParamDefKind::Type { has_default, .. }
-        | GenericParamDefKind::Const { has_default, .. } => {
-            has_default && def.index >= generics.parent_count as u32
-        }
-        GenericParamDefKind::Lifetime => {
-            span_bug!(tcx.def_span(def.def_id), "lifetime params can have no default")
-        }
-    };
-
     // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`.
     // For example, this forbids the declaration:
     //
@@ -1444,40 +1434,21 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
     //
     // Here, the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
     for param in &generics.own_params {
-        match param.kind {
-            GenericParamDefKind::Type { .. } => {
-                if is_our_default(param) {
-                    let ty = tcx.type_of(param.def_id).instantiate_identity();
-                    // Ignore dependent defaults -- that is, where the default of one type
-                    // parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
-                    // be sure if it will error or not as user might always specify the other.
-                    if !ty.has_param() {
-                        wfcx.register_wf_obligation(
-                            tcx.def_span(param.def_id),
-                            Some(WellFormedLoc::Ty(param.def_id.expect_local())),
-                            ty.into(),
-                        );
-                    }
-                }
-            }
-            GenericParamDefKind::Const { .. } => {
-                if is_our_default(param) {
-                    // FIXME(const_generics_defaults): This
-                    // is incorrect when dealing with unused args, for example
-                    // for `struct Foo<const N: usize, const M: usize = { 1 - 2 }>`
-                    // we should eagerly error.
-                    let default_ct = tcx.const_param_default(param.def_id).instantiate_identity();
-                    if !default_ct.has_param() {
-                        wfcx.register_wf_obligation(
-                            tcx.def_span(param.def_id),
-                            None,
-                            default_ct.into(),
-                        );
-                    }
-                }
+        if let Some(default) = param.default_value(tcx).map(ty::EarlyBinder::instantiate_identity) {
+            // Ignore dependent defaults -- that is, where the default of one type
+            // parameter includes another (e.g., `<T, U = T>`). In those cases, we can't
+            // be sure if it will error or not as user might always specify the other.
+            // FIXME(generic_const_exprs): This is incorrect when dealing with unused const params.
+            // E.g: `struct Foo<const N: usize, const M: usize = { 1 - 2 }>;`. Here, we should
+            // eagerly error but we don't as we have `ConstKind::Unevaluated(.., [N, M])`.
+            if !default.has_param() {
+                wfcx.register_wf_obligation(
+                    tcx.def_span(param.def_id),
+                    matches!(param.kind, GenericParamDefKind::Type { .. })
+                        .then(|| WellFormedLoc::Ty(param.def_id.expect_local())),
+                    default,
+                );
             }
-            // Doesn't have defaults.
-            GenericParamDefKind::Lifetime => {}
         }
     }
 
@@ -1490,39 +1461,16 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
     //
     // First we build the defaulted generic parameters.
     let args = GenericArgs::for_item(tcx, def_id.to_def_id(), |param, _| {
-        match param.kind {
-            GenericParamDefKind::Lifetime => {
-                // All regions are identity.
-                tcx.mk_param_from_def(param)
-            }
-
-            GenericParamDefKind::Type { .. } => {
-                // If the param has a default, ...
-                if is_our_default(param) {
-                    let default_ty = tcx.type_of(param.def_id).instantiate_identity();
-                    // ... and it's not a dependent default, ...
-                    if !default_ty.has_param() {
-                        // ... then instantiate it with the default.
-                        return default_ty.into();
-                    }
-                }
-
-                tcx.mk_param_from_def(param)
-            }
-            GenericParamDefKind::Const { .. } => {
-                // If the param has a default, ...
-                if is_our_default(param) {
-                    let default_ct = tcx.const_param_default(param.def_id).instantiate_identity();
-                    // ... and it's not a dependent default, ...
-                    if !default_ct.has_param() {
-                        // ... then instantiate it with the default.
-                        return default_ct.into();
-                    }
-                }
-
-                tcx.mk_param_from_def(param)
-            }
+        if param.index >= generics.parent_count as u32
+            // If the param has a default, ...
+            && let Some(default) = param.default_value(tcx).map(ty::EarlyBinder::instantiate_identity)
+            // ... and it's not a dependent default, ...
+            && !default.has_param()
+        {
+            // ... then instantiate it with the default.
+            return default;
         }
+        tcx.mk_param_from_def(param)
     });
 
     // Now we build the instantiated predicates.
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 1774772b50b..bfdf764d299 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -15,7 +15,7 @@ use crate::{Diverges, Expectation, FnCtxt, Needs};
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     #[instrument(skip(self), level = "debug", ret)]
-    pub(crate) fn check_match(
+    pub(crate) fn check_expr_match(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         scrut: &'tcx hir::Expr<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 20502de38a2..e6e0f62b54d 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -62,7 +62,7 @@ enum CallStep<'tcx> {
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub(crate) fn check_call(
+    pub(crate) fn check_expr_call(
         &self,
         call_expr: &'tcx hir::Expr<'tcx>,
         callee_expr: &'tcx hir::Expr<'tcx>,
@@ -74,8 +74,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .check_expr_with_expectation_and_args(
                     callee_expr,
                     Expectation::NoExpectation,
-                    arg_exprs,
-                    Some(call_expr),
+                    Some((call_expr, arg_exprs)),
                 ),
             _ => self.check_expr(callee_expr),
         };
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 2026fd9a614..51d78646373 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -137,7 +137,7 @@ pub(super) fn check_fn<'a, 'tcx>(
     }
 
     fcx.is_whole_body.set(true);
-    fcx.check_return_expr(body.value, false);
+    fcx.check_return_or_body_tail(body.value, false);
 
     // Finalize the return check by taking the LUB of the return types
     // we saw and assigning it to the expected return type. This isn't
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index b05731c6d52..354993513da 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -55,6 +55,9 @@ use crate::{
 };
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
+    /// Check an expr with an expectation type, and also demand that the expr's
+    /// evaluated type is a subtype of the expectation at the end. This is a
+    /// *hard* requirement.
     pub(crate) fn check_expr_has_type_or_error(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
@@ -97,6 +100,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ty
     }
 
+    /// Check an expr with an expectation type, and also demand that the expr's
+    /// evaluated type is a coercible to the expectation at the end. This is a
+    /// *hard* requirement.
     pub(super) fn check_expr_coercible_to_type(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
@@ -128,6 +134,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// Check an expr with an expectation type. Don't actually enforce that expectation
+    /// is related to the expr's evaluated type via subtyping or coercion. This is
+    /// usually called because we want to do that subtype/coerce call manually for better
+    /// diagnostics.
     pub(super) fn check_expr_with_hint(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
@@ -136,6 +146,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.check_expr_with_expectation(expr, ExpectHasType(expected))
     }
 
+    /// Check an expr with an expectation type, and also [`Needs`] which will
+    /// prompt typeck to convert any implicit immutable derefs to mutable derefs.
     fn check_expr_with_expectation_and_needs(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
@@ -153,10 +165,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         ty
     }
 
+    /// Check an expr with no expectations.
     pub(super) fn check_expr(&self, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> {
         self.check_expr_with_expectation(expr, NoExpectation)
     }
 
+    /// Check an expr with no expectations, but with [`Needs`] which will
+    /// prompt typeck to convert any implicit immutable derefs to mutable derefs.
     pub(super) fn check_expr_with_needs(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
@@ -165,33 +180,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
     }
 
-    /// Invariant:
-    /// If an expression has any sub-expressions that result in a type error,
-    /// inspecting that expression's type with `ty.references_error()` will return
-    /// true. Likewise, if an expression is known to diverge, inspecting its
-    /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
-    /// strict, _|_ can appear in the type of an expression that does not,
-    /// itself, diverge: for example, fn() -> _|_.)
-    /// Note that inspecting a type's structure *directly* may expose the fact
-    /// that there are actually multiple representations for `Error`, so avoid
-    /// that when err needs to be handled differently.
+    /// Check an expr with an expectation type which may be used to eagerly
+    /// guide inference when evaluating that expr.
     #[instrument(skip(self, expr), level = "debug")]
     pub(super) fn check_expr_with_expectation(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
-        self.check_expr_with_expectation_and_args(expr, expected, &[], None)
+        self.check_expr_with_expectation_and_args(expr, expected, None)
     }
 
-    /// Same as `check_expr_with_expectation`, but allows us to pass in the arguments of a
-    /// `ExprKind::Call` when evaluating its callee when it is an `ExprKind::Path`.
+    /// Same as [`Self::check_expr_with_expectation`], but allows us to pass in
+    /// the arguments of a [`ExprKind::Call`] when evaluating its callee that
+    /// is an [`ExprKind::Path`]. We use this to refine the spans for certain
+    /// well-formedness guarantees for the path expr.
     pub(super) fn check_expr_with_expectation_and_args(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
-        args: &'tcx [hir::Expr<'tcx>],
-        call: Option<&'tcx hir::Expr<'tcx>>,
+        call_expr_and_args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
     ) -> Ty<'tcx> {
         if self.tcx().sess.verbose_internals() {
             // make this code only run with -Zverbose-internals because it is probably slow
@@ -236,9 +244,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let ty = ensure_sufficient_stack(|| match &expr.kind {
+            // Intercept the callee path expr and give it better spans.
             hir::ExprKind::Path(
                 qpath @ (hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)),
-            ) => self.check_expr_path(qpath, expr, Some(args), call),
+            ) => self.check_expr_path(qpath, expr, call_expr_and_args),
             _ => self.check_expr_kind(expr, expected),
         });
         let ty = self.resolve_vars_if_possible(ty);
@@ -472,28 +481,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let tcx = self.tcx;
         match expr.kind {
-            ExprKind::Lit(ref lit) => self.check_lit(lit, expected),
-            ExprKind::Binary(op, lhs, rhs) => self.check_binop(expr, op, lhs, rhs, expected),
+            ExprKind::Lit(ref lit) => self.check_expr_lit(lit, expected),
+            ExprKind::Binary(op, lhs, rhs) => self.check_expr_binop(expr, op, lhs, rhs, expected),
             ExprKind::Assign(lhs, rhs, span) => {
                 self.check_expr_assign(expr, expected, lhs, rhs, span)
             }
             ExprKind::AssignOp(op, lhs, rhs) => {
-                self.check_binop_assign(expr, op, lhs, rhs, expected)
+                self.check_expr_binop_assign(expr, op, lhs, rhs, expected)
             }
-            ExprKind::Unary(unop, oprnd) => self.check_expr_unary(unop, oprnd, expected, expr),
+            ExprKind::Unary(unop, oprnd) => self.check_expr_unop(unop, oprnd, expected, expr),
             ExprKind::AddrOf(kind, mutbl, oprnd) => {
                 self.check_expr_addr_of(kind, mutbl, oprnd, expected, expr)
             }
             ExprKind::Path(QPath::LangItem(lang_item, _)) => {
                 self.check_lang_item_path(lang_item, expr)
             }
-            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, None, None),
+            ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, None),
             ExprKind::InlineAsm(asm) => {
                 // We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
                 self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id));
                 self.check_expr_asm(asm)
             }
-            ExprKind::OffsetOf(container, fields) => self.check_offset_of(container, fields, expr),
+            ExprKind::OffsetOf(container, fields) => {
+                self.check_expr_offset_of(container, fields, expr)
+            }
             ExprKind::Break(destination, ref expr_opt) => {
                 self.check_expr_break(destination, expr_opt.as_deref(), expr)
             }
@@ -512,13 +523,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_expr_loop(body, source, expected, expr)
             }
             ExprKind::Match(discrim, arms, match_src) => {
-                self.check_match(expr, discrim, arms, expected, match_src)
+                self.check_expr_match(expr, discrim, arms, expected, match_src)
             }
             ExprKind::Closure(closure) => self.check_expr_closure(closure, expr.span, expected),
-            ExprKind::Block(body, _) => self.check_block_with_expected(body, expected),
-            ExprKind::Call(callee, args) => self.check_call(expr, callee, args, expected),
+            ExprKind::Block(body, _) => self.check_expr_block(body, expected),
+            ExprKind::Call(callee, args) => self.check_expr_call(expr, callee, args, expected),
             ExprKind::MethodCall(segment, receiver, args, _) => {
-                self.check_method_call(expr, segment, receiver, args, expected)
+                self.check_expr_method_call(expr, segment, receiver, args, expected)
             }
             ExprKind::Cast(e, t) => self.check_expr_cast(e, t, expr),
             ExprKind::Type(e, t) => {
@@ -528,7 +539,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ascribed_ty
             }
             ExprKind::If(cond, then_expr, opt_else_expr) => {
-                self.check_then_else(cond, then_expr, opt_else_expr, expr.span, expected)
+                self.check_expr_if(cond, then_expr, opt_else_expr, expr.span, expected)
             }
             ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected),
             ExprKind::Array(args) => self.check_expr_array(args, expected, expr),
@@ -540,7 +551,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ExprKind::Struct(qpath, fields, ref base_expr) => {
                 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
             }
-            ExprKind::Field(base, field) => self.check_field(expr, base, field, expected),
+            ExprKind::Field(base, field) => self.check_expr_field(expr, base, field, expected),
             ExprKind::Index(base, idx, brackets_span) => {
                 self.check_expr_index(base, idx, expr, brackets_span)
             }
@@ -549,7 +560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn check_expr_unary(
+    fn check_expr_unop(
         &self,
         unop: hir::UnOp,
         oprnd: &'tcx hir::Expr<'tcx>,
@@ -699,8 +710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         qpath: &'tcx hir::QPath<'tcx>,
         expr: &'tcx hir::Expr<'tcx>,
-        args: Option<&'tcx [hir::Expr<'tcx>]>,
-        call: Option<&'tcx hir::Expr<'tcx>>,
+        call_expr_and_args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let (res, opt_ty, segs) =
@@ -730,7 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     segs,
                     opt_ty,
                     res,
-                    call.map_or(expr.span, |e| e.span),
+                    call_expr_and_args.map_or(expr.span, |(e, _)| e.span),
                     expr.span,
                     expr.hir_id,
                 )
@@ -769,7 +779,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // We just want to check sizedness, so instead of introducing
                     // placeholder lifetimes with probing, we just replace higher lifetimes
                     // with fresh vars.
-                    let span = args.and_then(|args| args.get(i)).map_or(expr.span, |arg| arg.span);
+                    let span = call_expr_and_args
+                        .and_then(|(_, args)| args.get(i))
+                        .map_or(expr.span, |arg| arg.span);
                     let input = self.instantiate_binder_with_fresh_vars(
                         span,
                         infer::BoundRegionConversionTime::FnCall,
@@ -795,7 +807,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
             self.require_type_is_sized_deferred(
                 output,
-                call.map_or(expr.span, |e| e.span),
+                call_expr_and_args.map_or(expr.span, |(e, _)| e.span),
                 ObligationCauseCode::SizedCallReturnType,
             );
         }
@@ -972,7 +984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if self.ret_coercion_span.get().is_none() {
                 self.ret_coercion_span.set(Some(e.span));
             }
-            self.check_return_expr(e, true);
+            self.check_return_or_body_tail(e, true);
         } else {
             let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
             if self.ret_coercion_span.get().is_none() {
@@ -1035,7 +1047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ///
     /// `explicit_return` is `true` if we're checking an explicit `return expr`,
     /// and `false` if we're checking a trailing expression.
-    pub(super) fn check_return_expr(
+    pub(super) fn check_return_or_body_tail(
         &self,
         return_expr: &'tcx hir::Expr<'tcx>,
         explicit_return: bool,
@@ -1259,7 +1271,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     // A generic function for checking the 'then' and 'else' clauses in an 'if'
     // or 'if-else' expression.
-    fn check_then_else(
+    fn check_expr_if(
         &self,
         cond_expr: &'tcx hir::Expr<'tcx>,
         then_expr: &'tcx hir::Expr<'tcx>,
@@ -1542,7 +1554,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Checks a method call.
-    fn check_method_call(
+    fn check_expr_method_call(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         segment: &'tcx hir::PathSegment<'tcx>,
@@ -2594,7 +2606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     // Check field access expressions
-    fn check_field(
+    fn check_expr_field(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         base: &'tcx hir::Expr<'tcx>,
@@ -3535,8 +3547,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let previous_diverges = self.diverges.get();
 
                     // The label blocks should have unit return value or diverge.
-                    let ty =
-                        self.check_block_with_expected(block, ExpectHasType(self.tcx.types.unit));
+                    let ty = self.check_expr_block(block, ExpectHasType(self.tcx.types.unit));
                     if !ty.is_never() {
                         self.demand_suptype(block.span, self.tcx.types.unit, ty);
                         diverge = false;
@@ -3551,7 +3562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if diverge { self.tcx.types.never } else { self.tcx.types.unit }
     }
 
-    fn check_offset_of(
+    fn check_expr_offset_of(
         &self,
         container: &'tcx hir::Ty<'tcx>,
         fields: &[Ident],
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index 97f3807c252..7719facccc7 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -621,7 +621,11 @@ impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
                 .iter()
                 .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
                 .count();
-            for (idx, arg) in args.iter().enumerate() {
+            for (idx, arg) in args
+                .iter()
+                .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
+                .enumerate()
+            {
                 if let Some(ty) = arg.as_type()
                     && let Some(vid) = self.fcx.root_vid(ty)
                     && self.reachable_vids.contains(&vid)
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index ce0ab8a913b..f0738491609 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1306,30 +1306,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             rustc_hir_analysis::hir_ty_lowering::RegionInferReason::Param(param),
                         )
                         .into(),
-                    GenericParamDefKind::Type { has_default, .. } => {
-                        if !infer_args && has_default {
-                            // If we have a default, then it doesn't matter that we're not
-                            // inferring the type arguments: we provide the default where any
-                            // is missing.
-                            tcx.type_of(param.def_id).instantiate(tcx, preceding_args).into()
-                        } else {
-                            // If no type arguments were provided, we have to infer them.
-                            // This case also occurs as a result of some malformed input, e.g.
-                            // a lifetime argument being given instead of a type parameter.
-                            // Using inference instead of `Error` gives better error messages.
-                            self.fcx.var_for_def(self.span, param)
+                    GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
+                        if !infer_args && let Some(default) = param.default_value(tcx) {
+                            // If we have a default, then it doesn't matter that we're not inferring
+                            // the type/const arguments: We provide the default where any is missing.
+                            return default.instantiate(tcx, preceding_args);
                         }
-                    }
-                    GenericParamDefKind::Const { has_default, .. } => {
-                        if has_default {
-                            if !infer_args {
-                                return tcx
-                                    .const_param_default(param.def_id)
-                                    .instantiate(tcx, preceding_args)
-                                    .into();
-                            }
-                        }
-
+                        // If no type/const arguments were provided, we have to infer them.
+                        // This case also occurs as a result of some malformed input, e.g.,
+                        // a lifetime argument being given instead of a type/const parameter.
+                        // Using inference instead of `Error` gives better error messages.
                         self.fcx.var_for_def(self.span, param)
                     }
                 }
@@ -1491,7 +1477,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
         } else if self.tcx.features().generic_const_exprs() {
-            ct.normalize_internal(self.tcx, self.param_env)
+            rustc_trait_selection::traits::evaluate_const(&self.infcx, ct, self.param_env)
         } else {
             ct
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index f93d0e93406..b09d78614c3 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -316,12 +316,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .tcx
             .generics_of(def_id)
             .own_args(ty::GenericArgs::identity_for_item(self.tcx, def_id));
-        let Some((index, _)) =
-            own_args.iter().enumerate().find(|(_, arg)| **arg == param_to_point_at)
-        else {
+        let Some(mut index) = own_args.iter().position(|arg| *arg == param_to_point_at) else {
             return false;
         };
-        let Some(arg) = segment.args().args.get(index) else {
+        // SUBTLE: We may or may not turbofish lifetime arguments, which will
+        // otherwise be elided. if our "own args" starts with a lifetime, but
+        // the args list does not, then we should chop off all of the lifetimes,
+        // since they're all elided.
+        let segment_args = segment.args().args;
+        if matches!(own_args[0].unpack(), ty::GenericArgKind::Lifetime(_))
+            && segment_args.first().is_some_and(|arg| arg.is_ty_or_const())
+            && let Some(offset) = own_args.iter().position(|arg| {
+                matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_))
+            })
+            && let Some(new_index) = index.checked_sub(offset)
+        {
+            index = new_index;
+        }
+        let Some(arg) = segment_args.get(index) else {
             return false;
         };
         error.obligation.cause.span = arg
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index a6c249da103..50d1322eba6 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1565,7 +1565,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     // AST fragment checking
-    pub(in super::super) fn check_lit(
+    pub(in super::super) fn check_expr_lit(
         &self,
         lit: &hir::Lit,
         expected: Expectation<'tcx>,
@@ -1747,7 +1747,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if let Some(blk) = decl.origin.try_get_else() {
             let previous_diverges = self.diverges.get();
-            let else_ty = self.check_block_with_expected(blk, NoExpectation);
+            let else_ty = self.check_expr_block(blk, NoExpectation);
             let cause = self.cause(blk.span, ObligationCauseCode::LetElse);
             if let Err(err) = self.demand_eqtype_with_origin(&cause, self.tcx.types.never, else_ty)
             {
@@ -1805,7 +1805,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub(crate) fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
         let unit = self.tcx.types.unit;
-        let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
+        let ty = self.check_expr_block(blk, ExpectHasType(unit));
 
         // if the block produces a `!` value, that can always be
         // (effectively) coerced to unit.
@@ -1814,7 +1814,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub(in super::super) fn check_block_with_expected(
+    pub(in super::super) fn check_expr_block(
         &self,
         blk: &'tcx hir::Block<'tcx>,
         expected: Expectation<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index f5987a11fa5..63dccf8b0ce 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -4,6 +4,7 @@
 #![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
+#![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(try_blocks)]
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index cb20a1d7c7b..8772599e316 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3874,22 +3874,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 param.name.ident(),
                             ));
                             let bounds_span = hir_generics.bounds_span_for_suggestions(def_id);
+                            let mut applicability = Applicability::MaybeIncorrect;
+                            // Format the path of each suggested candidate, providing placeholders
+                            // for any generic arguments without defaults.
+                            let candidate_strs: Vec<_> = candidates
+                                .iter()
+                                .map(|cand| {
+                                    let cand_path = self.tcx.def_path_str(cand.def_id);
+                                    let cand_params = &self.tcx.generics_of(cand.def_id).own_params;
+                                    let cand_args: String = cand_params
+                                        .iter()
+                                        .skip(1)
+                                        .filter_map(|param| match param.kind {
+                                            ty::GenericParamDefKind::Type {
+                                                has_default: true,
+                                                ..
+                                            }
+                                            | ty::GenericParamDefKind::Const {
+                                                has_default: true,
+                                                ..
+                                            } => None,
+                                            _ => Some(param.name.as_str()),
+                                        })
+                                        .intersperse(", ")
+                                        .collect();
+                                    if cand_args.is_empty() {
+                                        cand_path
+                                    } else {
+                                        applicability = Applicability::HasPlaceholders;
+                                        format!("{cand_path}</* {cand_args} */>")
+                                    }
+                                })
+                                .collect();
+
                             if rcvr_ty.is_ref()
                                 && param.is_impl_trait()
                                 && let Some((bounds_span, _)) = bounds_span
                             {
                                 err.multipart_suggestions(
                                     msg,
-                                    candidates.iter().map(|t| {
+                                    candidate_strs.iter().map(|cand| {
                                         vec![
                                             (param.span.shrink_to_lo(), "(".to_string()),
-                                            (
-                                                bounds_span,
-                                                format!(" + {})", self.tcx.def_path_str(t.def_id)),
-                                            ),
+                                            (bounds_span, format!(" + {cand})")),
                                         ]
                                     }),
-                                    Applicability::MaybeIncorrect,
+                                    applicability,
                                 );
                                 return;
                             }
@@ -3905,16 +3935,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     (param.span.shrink_to_hi(), Introducer::Colon, None)
                                 };
 
-                            let all_suggs = candidates.iter().map(|cand| {
-                                let suggestion = format!(
-                                    "{} {}",
-                                    match introducer {
-                                        Introducer::Plus => " +",
-                                        Introducer::Colon => ":",
-                                        Introducer::Nothing => "",
-                                    },
-                                    self.tcx.def_path_str(cand.def_id)
-                                );
+                            let all_suggs = candidate_strs.iter().map(|cand| {
+                                let suggestion = format!("{} {cand}", match introducer {
+                                    Introducer::Plus => " +",
+                                    Introducer::Colon => ":",
+                                    Introducer::Nothing => "",
+                                },);
 
                                 let mut suggs = vec![];
 
@@ -3928,11 +3954,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 suggs
                             });
 
-                            err.multipart_suggestions(
-                                msg,
-                                all_suggs,
-                                Applicability::MaybeIncorrect,
-                            );
+                            err.multipart_suggestions(msg, all_suggs, applicability);
 
                             return;
                         }
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index 9a3492abc9f..72b930ee84d 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -26,7 +26,7 @@ use crate::Expectation;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Checks a `a <op>= b`
-    pub(crate) fn check_binop_assign(
+    pub(crate) fn check_expr_binop_assign(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         op: hir::BinOp,
@@ -85,7 +85,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Checks a potentially overloaded binary operator.
-    pub(crate) fn check_binop(
+    pub(crate) fn check_expr_binop(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         op: hir::BinOp,
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index fc54d69449f..12df4a10e63 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -25,10 +25,10 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_macros::extension;
 pub use rustc_macros::{TypeFoldable, TypeVisitable};
+use rustc_middle::bug;
 use rustc_middle::infer::canonical::{CanonicalQueryInput, CanonicalVarValues};
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableValue, ConstVidKey};
 use rustc_middle::mir::ConstraintCategory;
-use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
 use rustc_middle::traits::select;
 pub use rustc_middle::ty::IntVarValue;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
@@ -40,7 +40,6 @@ use rustc_middle::ty::{
     self, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef,
     GenericParamDefKind, InferConst, IntVid, Ty, TyCtxt, TyVid, TypingMode,
 };
-use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
 use rustc_span::symbol::Symbol;
 use rustc_type_ir::solve::Reveal;
@@ -1279,84 +1278,6 @@ impl<'tcx> InferCtxt<'tcx> {
         u
     }
 
-    pub fn try_const_eval_resolve(
-        &self,
-        param_env: ty::ParamEnv<'tcx>,
-        unevaluated: ty::UnevaluatedConst<'tcx>,
-        span: Span,
-    ) -> Result<ty::Const<'tcx>, ErrorHandled> {
-        match self.const_eval_resolve(param_env, unevaluated, span) {
-            Ok(Ok(val)) => Ok(ty::Const::new_value(
-                self.tcx,
-                val,
-                self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args),
-            )),
-            Ok(Err(bad_ty)) => {
-                let tcx = self.tcx;
-                let def_id = unevaluated.def;
-                span_bug!(
-                    tcx.def_span(def_id),
-                    "unable to construct a valtree for the unevaluated constant {:?}: type {bad_ty} is not valtree-compatible",
-                    unevaluated
-                );
-            }
-            Err(err) => Err(err),
-        }
-    }
-
-    /// Resolves and evaluates a constant.
-    ///
-    /// The constant can be located on a trait like `<A as B>::C`, in which case the given
-    /// generic parameters and environment are used to resolve the constant. Alternatively if the
-    /// constant has generic parameters in scope the instantiations are used to evaluate the value
-    /// of the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
-    /// constant `bar::<T>()` requires a instantiation for `T`, if the instantiation for `T` is
-    /// still too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
-    /// returned.
-    ///
-    /// This handles inferences variables within both `param_env` and `args` by
-    /// performing the operation on their respective canonical forms.
-    #[instrument(skip(self), level = "debug")]
-    pub fn const_eval_resolve(
-        &self,
-        mut param_env: ty::ParamEnv<'tcx>,
-        unevaluated: ty::UnevaluatedConst<'tcx>,
-        span: Span,
-    ) -> EvalToValTreeResult<'tcx> {
-        let mut args = self.resolve_vars_if_possible(unevaluated.args);
-        debug!(?args);
-
-        // Postpone the evaluation of constants whose args depend on inference
-        // variables
-        let tcx = self.tcx;
-        if args.has_non_region_infer() {
-            if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? {
-                let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args));
-                if let Err(e) = ct.error_reported() {
-                    return Err(ErrorHandled::Reported(e.into(), span));
-                } else if ct.has_non_region_infer() || ct.has_non_region_param() {
-                    return Err(ErrorHandled::TooGeneric(span));
-                } else {
-                    args = replace_param_and_infer_args_with_placeholder(tcx, args);
-                }
-            } else {
-                args = GenericArgs::identity_for_item(tcx, unevaluated.def);
-                param_env = tcx.param_env(unevaluated.def);
-            }
-        }
-
-        let param_env_erased = tcx.erase_regions(param_env);
-        let args_erased = tcx.erase_regions(args);
-        debug!(?param_env_erased);
-        debug!(?args_erased);
-
-        let unevaluated = ty::UnevaluatedConst { def: unevaluated.def, args: args_erased };
-
-        // The return value is the evaluated value which doesn't contain any reference to inference
-        // variables, thus we don't need to instantiate back the original values.
-        tcx.const_eval_resolve_for_typeck(param_env_erased, unevaluated, span)
-    }
-
     /// The returned function is used in a fast path. If it returns `true` the variable is
     /// unchanged, `false` indicates that the status is unknown.
     #[inline]
@@ -1622,61 +1543,6 @@ impl RegionVariableOrigin {
     }
 }
 
-/// Replaces args that reference param or infer variables with suitable
-/// placeholders. This function is meant to remove these param and infer
-/// args when they're not actually needed to evaluate a constant.
-fn replace_param_and_infer_args_with_placeholder<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    args: GenericArgsRef<'tcx>,
-) -> GenericArgsRef<'tcx> {
-    struct ReplaceParamAndInferWithPlaceholder<'tcx> {
-        tcx: TyCtxt<'tcx>,
-        idx: u32,
-    }
-
-    impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceParamAndInferWithPlaceholder<'tcx> {
-        fn cx(&self) -> TyCtxt<'tcx> {
-            self.tcx
-        }
-
-        fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-            if let ty::Infer(_) = t.kind() {
-                let idx = {
-                    let idx = self.idx;
-                    self.idx += 1;
-                    idx
-                };
-                Ty::new_placeholder(self.tcx, ty::PlaceholderType {
-                    universe: ty::UniverseIndex::ROOT,
-                    bound: ty::BoundTy {
-                        var: ty::BoundVar::from_u32(idx),
-                        kind: ty::BoundTyKind::Anon,
-                    },
-                })
-            } else {
-                t.super_fold_with(self)
-            }
-        }
-
-        fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
-            if let ty::ConstKind::Infer(_) = c.kind() {
-                ty::Const::new_placeholder(self.tcx, ty::PlaceholderConst {
-                    universe: ty::UniverseIndex::ROOT,
-                    bound: ty::BoundVar::from_u32({
-                        let idx = self.idx;
-                        self.idx += 1;
-                        idx
-                    }),
-                })
-            } else {
-                c.super_fold_with(self)
-            }
-        }
-    }
-
-    args.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 })
-}
-
 impl<'tcx> InferCtxt<'tcx> {
     /// Given a [`hir::Block`], get the span of its last expression or
     /// statement, peeling off any inner blocks.
diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index b5abf145d6b..7a2ba07ce87 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -5,8 +5,8 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
-rustc-rayon = { version = "0.5.0", optional = true }
-rustc-rayon-core = { version = "0.5.0", optional = true }
+rustc-rayon = { version = "0.5.0" }
+rustc-rayon-core = { version = "0.5.0" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_lowering = { path = "../rustc_ast_lowering" }
 rustc_ast_passes = { path = "../rustc_ast_passes" }
@@ -54,10 +54,4 @@ tracing = "0.1"
 [features]
 # tidy-alphabetical-start
 llvm = ['dep:rustc_codegen_llvm']
-rustc_use_parallel_compiler = [
-    'dep:rustc-rayon',
-    'dep:rustc-rayon-core',
-    'rustc_query_impl/rustc_use_parallel_compiler',
-    'rustc_errors/rustc_use_parallel_compiler'
-]
 # tidy-alphabetical-end
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index fd850d2f39a..7e629c1d18f 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -175,7 +175,7 @@ fn configure_and_expand(
         if cfg!(windows) {
             old_path = env::var_os("PATH").unwrap_or(old_path);
             let mut new_path = Vec::from_iter(
-                sess.host_filesearch(PathKind::All).search_paths().map(|p| p.dir.clone()),
+                sess.host_filesearch().search_paths(PathKind::All).map(|p| p.dir.clone()),
             );
             for path in env::split_paths(&old_path) {
                 if !new_path.contains(&path) {
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index b5bddc4b21a..d3213b1263c 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -6,7 +6,6 @@ use std::{env, iter, thread};
 
 use rustc_ast as ast;
 use rustc_codegen_ssa::traits::CodegenBackend;
-#[cfg(parallel_compiler)]
 use rustc_data_structures::sync;
 use rustc_metadata::{DylibError, load_symbol_from_dylib};
 use rustc_middle::ty::CurrentGcx;
@@ -117,19 +116,6 @@ fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
     })
 }
 
-#[cfg(not(parallel_compiler))]
-pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
-    thread_builder_diag: &EarlyDiagCtxt,
-    edition: Edition,
-    _threads: usize,
-    sm_inputs: SourceMapInputs,
-    f: F,
-) -> R {
-    let thread_stack_size = init_stack_size(thread_builder_diag);
-    run_in_thread_with_globals(thread_stack_size, edition, sm_inputs, f)
-}
-
-#[cfg(parallel_compiler)]
 pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>(
     thread_builder_diag: &EarlyDiagCtxt,
     edition: Edition,
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 9187f6caad4..6e35d89b488 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -346,7 +346,6 @@ lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than pos
         *[other] these lifetimes are
      } in scope but not mentioned in the type's bounds
     .note2 = all lifetimes in scope will be captured by `impl Trait`s in edition 2024
-    .suggestion = use the precise capturing `use<...>` syntax to make the captures explicit
 
 lint_impl_trait_redundant_captures = all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
     .suggestion = remove the `use<...>` syntax
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 02d22ee49bd..130f3cb7c2a 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1298,12 +1298,30 @@ impl UnreachablePub {
         let mut applicability = Applicability::MachineApplicable;
         if cx.tcx.visibility(def_id).is_public() && !cx.effective_visibilities.is_reachable(def_id)
         {
+            // prefer suggesting `pub(super)` instead of `pub(crate)` when possible,
+            // except when `pub(super) == pub(crate)`
+            let new_vis = if let Some(ty::Visibility::Restricted(restricted_did)) =
+                cx.effective_visibilities.effective_vis(def_id).map(|effective_vis| {
+                    effective_vis.at_level(rustc_middle::middle::privacy::Level::Reachable)
+                })
+                && let parent_parent = cx.tcx.parent_module_from_def_id(
+                    cx.tcx.parent_module_from_def_id(def_id.into()).into(),
+                )
+                && *restricted_did == parent_parent.to_local_def_id()
+                && !restricted_did.to_def_id().is_crate_root()
+            {
+                "pub(super)"
+            } else {
+                "pub(crate)"
+            };
+
             if vis_span.from_expansion() {
                 applicability = Applicability::MaybeIncorrect;
             }
             let def_span = cx.tcx.def_span(def_id);
             cx.emit_span_lint(UNREACHABLE_PUB, def_span, BuiltinUnreachablePub {
                 what,
+                new_vis,
                 suggestion: (vis_span, applicability),
                 help: exportable,
             });
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index 002ab027982..beab4d4e6a9 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -3,7 +3,7 @@ use std::cell::LazyCell;
 
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
 use rustc_data_structures::unord::UnordSet;
-use rustc_errors::{Applicability, LintDiagnostic};
+use rustc_errors::{LintDiagnostic, Subdiagnostic};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -22,6 +22,9 @@ use rustc_session::lint::FutureIncompatibilityReason;
 use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::edition::Edition;
 use rustc_span::{Span, Symbol};
+use rustc_trait_selection::errors::{
+    AddPreciseCapturingForOvercapture, impl_trait_overcapture_suggestion,
+};
 use rustc_trait_selection::traits::ObligationCtxt;
 use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt;
 
@@ -259,7 +262,11 @@ where
             // If it's owned by this function
             && let opaque =
                 self.tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty()
-            && let hir::OpaqueTyOrigin::FnReturn { parent, .. } = opaque.origin
+            // We want to recurse into RPITs and async fns, even though the latter
+            // doesn't overcapture on its own, it may mention additional RPITs
+            // in its bounds.
+            && let hir::OpaqueTyOrigin::FnReturn { parent, .. }
+                | hir::OpaqueTyOrigin::AsyncFn { parent, .. } = opaque.origin
             && parent == self.parent_def_id
         {
             let opaque_span = self.tcx.def_span(opaque_def_id);
@@ -334,32 +341,12 @@ where
                 // If we have uncaptured args, and if the opaque doesn't already have
                 // `use<>` syntax on it, and we're < edition 2024, then warn the user.
                 if !uncaptured_args.is_empty() {
-                    let suggestion = if let Ok(snippet) =
-                        self.tcx.sess.source_map().span_to_snippet(opaque_span)
-                        && snippet.starts_with("impl ")
-                    {
-                        let (lifetimes, others): (Vec<_>, Vec<_>) =
-                            captured.into_iter().partition(|def_id| {
-                                self.tcx.def_kind(*def_id) == DefKind::LifetimeParam
-                            });
-                        // Take all lifetime params first, then all others (ty/ct).
-                        let generics: Vec<_> = lifetimes
-                            .into_iter()
-                            .chain(others)
-                            .map(|def_id| self.tcx.item_name(def_id).to_string())
-                            .collect();
-                        // Make sure that we're not trying to name any APITs
-                        if generics.iter().all(|name| !name.starts_with("impl ")) {
-                            Some((
-                                format!(" + use<{}>", generics.join(", ")),
-                                opaque_span.shrink_to_hi(),
-                            ))
-                        } else {
-                            None
-                        }
-                    } else {
-                        None
-                    };
+                    let suggestion = impl_trait_overcapture_suggestion(
+                        self.tcx,
+                        opaque_def_id,
+                        self.parent_def_id,
+                        captured,
+                    );
 
                     let uncaptured_spans: Vec<_> = uncaptured_args
                         .into_iter()
@@ -451,7 +438,7 @@ struct ImplTraitOvercapturesLint<'tcx> {
     uncaptured_spans: Vec<Span>,
     self_ty: Ty<'tcx>,
     num_captured: usize,
-    suggestion: Option<(String, Span)>,
+    suggestion: Option<AddPreciseCapturingForOvercapture>,
 }
 
 impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> {
@@ -461,13 +448,8 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> {
             .arg("num_captured", self.num_captured)
             .span_note(self.uncaptured_spans, fluent::lint_note)
             .note(fluent::lint_note2);
-        if let Some((suggestion, span)) = self.suggestion {
-            diag.span_suggestion(
-                span,
-                fluent::lint_suggestion,
-                suggestion,
-                Applicability::MachineApplicable,
-            );
+        if let Some(suggestion) = self.suggestion {
+            suggestion.add_to_diag(diag);
         }
     }
 }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 38e52570e53..352155729e5 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -254,7 +254,8 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
 #[diag(lint_builtin_unreachable_pub)]
 pub(crate) struct BuiltinUnreachablePub<'a> {
     pub what: &'a str,
-    #[suggestion(code = "pub(crate)")]
+    pub new_vis: &'a str,
+    #[suggestion(code = "{new_vis}")]
     pub suggestion: (Span, Applicability),
     #[help]
     pub help: bool,
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 1ed702ab4cb..489c911d7ee 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -882,10 +882,12 @@ extern "C" LLVMRustResult LLVMRustOptimize(
         SanitizerOptions->SanitizeKernelAddress) {
       OptimizerLastEPCallbacks.push_back(
 #if LLVM_VERSION_GE(20, 0)
-          [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level,
-                             ThinOrFullLTOPhase phase) {
+          [SanitizerOptions, TM](ModulePassManager &MPM,
+                                 OptimizationLevel Level,
+                                 ThinOrFullLTOPhase phase) {
 #else
-          [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
+          [SanitizerOptions, TM](ModulePassManager &MPM,
+                                 OptimizationLevel Level) {
 #endif
             auto CompileKernel = SanitizerOptions->SanitizeKernelAddress;
             AddressSanitizerOptions opts = AddressSanitizerOptions{
@@ -895,7 +897,12 @@ extern "C" LLVMRustResult LLVMRustOptimize(
                 /*UseAfterScope=*/true,
                 AsanDetectStackUseAfterReturnMode::Runtime,
             };
-            MPM.addPass(AddressSanitizerPass(opts));
+            MPM.addPass(AddressSanitizerPass(
+                opts,
+                /*UseGlobalGC*/ true,
+                // UseOdrIndicator should be false on windows machines
+                // https://reviews.llvm.org/D137227
+                !TM->getTargetTriple().isOSWindows()));
           });
     }
     if (SanitizerOptions->SanitizeHWAddress) {
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index e525d94a0c1..ca16a66763a 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -507,7 +507,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         locator.is_proc_macro = true;
         locator.target = &self.sess.host;
         locator.tuple = TargetTuple::from_tuple(config::host_tuple());
-        locator.filesearch = self.sess.host_filesearch(path_kind);
+        locator.filesearch = self.sess.host_filesearch();
+        locator.path_kind = path_kind;
 
         let Some(host_result) = self.load(locator)? else {
             return Ok(None);
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index ddd97fc66f6..0b53e5eeaa8 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -253,9 +253,10 @@ pub(crate) struct CrateLocator<'a> {
     extra_filename: Option<&'a str>,
     pub target: &'a Target,
     pub tuple: TargetTuple,
-    pub filesearch: FileSearch<'a>,
+    pub filesearch: &'a FileSearch,
     pub is_proc_macro: bool,
 
+    pub path_kind: PathKind,
     // Mutable in-progress state or output.
     crate_rejections: CrateRejections,
 }
@@ -339,7 +340,8 @@ impl<'a> CrateLocator<'a> {
             extra_filename,
             target: &sess.target,
             tuple: sess.opts.target_triple.clone(),
-            filesearch: sess.target_filesearch(path_kind),
+            filesearch: sess.target_filesearch(),
+            path_kind,
             is_proc_macro: false,
             crate_rejections: CrateRejections::default(),
         }
@@ -407,47 +409,49 @@ impl<'a> CrateLocator<'a> {
         // given that `extra_filename` comes from the `-C extra-filename`
         // option and thus can be anything, and the incorrect match will be
         // handled safely in `extract_one`.
-        for search_path in self.filesearch.search_paths() {
+        for search_path in self.filesearch.search_paths(self.path_kind) {
             debug!("searching {}", search_path.dir.display());
-            for spf in search_path.files.iter() {
-                debug!("testing {}", spf.path.display());
+            let spf = &search_path.files;
 
-                let f = &spf.file_name_str;
-                let (hash, kind) = if let Some(f) = f.strip_prefix(rlib_prefix)
-                    && let Some(f) = f.strip_suffix(rlib_suffix)
-                {
-                    (f, CrateFlavor::Rlib)
-                } else if let Some(f) = f.strip_prefix(rmeta_prefix)
-                    && let Some(f) = f.strip_suffix(rmeta_suffix)
-                {
-                    (f, CrateFlavor::Rmeta)
-                } else if let Some(f) = f.strip_prefix(dylib_prefix)
-                    && let Some(f) = f.strip_suffix(dylib_suffix.as_ref())
-                {
-                    (f, CrateFlavor::Dylib)
-                } else {
-                    if f.starts_with(staticlib_prefix) && f.ends_with(staticlib_suffix.as_ref()) {
-                        self.crate_rejections.via_kind.push(CrateMismatch {
-                            path: spf.path.clone(),
-                            got: "static".to_string(),
-                        });
-                    }
-                    continue;
-                };
-
-                info!("lib candidate: {}", spf.path.display());
+            let mut should_check_staticlibs = true;
+            for (prefix, suffix, kind) in [
+                (rlib_prefix.as_str(), rlib_suffix, CrateFlavor::Rlib),
+                (rmeta_prefix.as_str(), rmeta_suffix, CrateFlavor::Rmeta),
+                (dylib_prefix, dylib_suffix, CrateFlavor::Dylib),
+            ] {
+                if prefix == staticlib_prefix && suffix == staticlib_suffix {
+                    should_check_staticlibs = false;
+                }
+                if let Some(matches) = spf.query(prefix, suffix) {
+                    for (hash, spf) in matches {
+                        info!("lib candidate: {}", spf.path.display());
 
-                let (rlibs, rmetas, dylibs) = candidates.entry(hash.to_string()).or_default();
-                let path = try_canonicalize(&spf.path).unwrap_or_else(|_| spf.path.clone());
-                if seen_paths.contains(&path) {
-                    continue;
-                };
-                seen_paths.insert(path.clone());
-                match kind {
-                    CrateFlavor::Rlib => rlibs.insert(path, search_path.kind),
-                    CrateFlavor::Rmeta => rmetas.insert(path, search_path.kind),
-                    CrateFlavor::Dylib => dylibs.insert(path, search_path.kind),
-                };
+                        let (rlibs, rmetas, dylibs) =
+                            candidates.entry(hash.to_string()).or_default();
+                        let path =
+                            try_canonicalize(&spf.path).unwrap_or_else(|_| spf.path.to_path_buf());
+                        if seen_paths.contains(&path) {
+                            continue;
+                        };
+                        seen_paths.insert(path.clone());
+                        match kind {
+                            CrateFlavor::Rlib => rlibs.insert(path, search_path.kind),
+                            CrateFlavor::Rmeta => rmetas.insert(path, search_path.kind),
+                            CrateFlavor::Dylib => dylibs.insert(path, search_path.kind),
+                        };
+                    }
+                }
+            }
+            if let Some(static_matches) = should_check_staticlibs
+                .then(|| spf.query(staticlib_prefix, staticlib_suffix))
+                .flatten()
+            {
+                for (_, spf) in static_matches {
+                    self.crate_rejections.via_kind.push(CrateMismatch {
+                        path: spf.path.to_path_buf(),
+                        got: "static".to_string(),
+                    });
+                }
             }
         }
 
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index b7695216f3c..493db498b7c 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -28,10 +28,10 @@ pub fn walk_native_lib_search_dirs<R>(
     mut f: impl FnMut(&Path, bool /*is_framework*/) -> ControlFlow<R>,
 ) -> ControlFlow<R> {
     // Library search paths explicitly supplied by user (`-L` on the command line).
-    for search_path in sess.target_filesearch(PathKind::Native).cli_search_paths() {
+    for search_path in sess.target_filesearch().cli_search_paths(PathKind::Native) {
         f(&search_path.dir, false)?;
     }
-    for search_path in sess.target_filesearch(PathKind::Framework).cli_search_paths() {
+    for search_path in sess.target_filesearch().cli_search_paths(PathKind::Framework) {
         // Frameworks are looked up strictly in framework-specific paths.
         if search_path.kind != PathKind::All {
             f(&search_path.dir, true)?;
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index 485d1c14df3..3bda3a4aa63 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -11,7 +11,7 @@ either = "1.5.0"
 field-offset = "0.3.5"
 gsgdt = "0.1.2"
 polonius-engine = "0.13.0"
-rustc-rayon-core = { version = "0.5.0", optional = true }
+rustc-rayon-core = { version = "0.5.0" }
 rustc_abi = { path = "../rustc_abi" }
 rustc_apfloat = "0.2.0"
 rustc_arena = { path = "../rustc_arena" }
@@ -43,5 +43,4 @@ tracing = "0.1"
 [features]
 # tidy-alphabetical-start
 rustc_randomized_layouts = []
-rustc_use_parallel_compiler = ["dep:rustc-rayon-core"]
 # tidy-alphabetical-end
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 1ae0bd6740d..f95635370dc 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -1,17 +1,17 @@
 use std::fmt::{self, Debug, Display, Formatter};
 
-use either::Either;
 use rustc_abi::{HasDataLayout, Size};
 use rustc_hir::def_id::DefId;
 use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_session::RemapFileNameExt;
 use rustc_session::config::RemapPathScopeComponents;
 use rustc_span::{DUMMY_SP, Span};
+use rustc_type_ir::visit::TypeVisitableExt;
 
 use crate::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, Scalar, alloc_range};
 use crate::mir::{Promoted, pretty_print_const_value};
 use crate::ty::print::{pretty_print_const, with_no_trimmed_paths};
-use crate::ty::{self, GenericArgsRef, ScalarInt, Ty, TyCtxt};
+use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt};
 
 ///////////////////////////////////////////////////////////////////////////
 /// Evaluated Constants
@@ -319,15 +319,16 @@ impl<'tcx> Const<'tcx> {
     ) -> Result<ConstValue<'tcx>, ErrorHandled> {
         match self {
             Const::Ty(_, c) => {
-                // We want to consistently have a "clean" value for type system constants (i.e., no
-                // data hidden in the padding), so we always go through a valtree here.
-                match c.eval_valtree(tcx, param_env, span) {
-                    Ok((ty, val)) => Ok(tcx.valtree_to_const_val((ty, val))),
-                    Err(Either::Left(_bad_ty)) => Err(tcx
-                        .dcx()
-                        .delayed_bug("`mir::Const::eval` called on a non-valtree-compatible type")
-                        .into()),
-                    Err(Either::Right(e)) => Err(e),
+                if c.has_non_region_param() {
+                    return Err(ErrorHandled::TooGeneric(span));
+                }
+
+                match c.kind() {
+                    ConstKind::Value(ty, val) => Ok(tcx.valtree_to_const_val((ty, val))),
+                    ConstKind::Expr(_) => {
+                        bug!("Normalization of `ty::ConstKind::Expr` is unimplemented")
+                    }
+                    _ => Err(tcx.dcx().delayed_bug("Unevaluated `ty::Const` in MIR body").into()),
                 }
             }
             Const::Unevaluated(uneval, _) => {
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 4a876dc1228..11a4e7f89a7 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Formatter};
 
 use rustc_index::IndexVec;
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
-use rustc_span::{Span, Symbol};
+use rustc_span::Span;
 
 rustc_index::newtype_index! {
     /// Used by [`CoverageKind::BlockMarker`] to mark blocks during THIR-to-MIR
@@ -158,7 +158,6 @@ impl Debug for CoverageKind {
 #[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq, Eq, PartialOrd, Ord)]
 #[derive(TypeFoldable, TypeVisitable)]
 pub struct SourceRegion {
-    pub file_name: Symbol,
     pub start_line: u32,
     pub start_col: u32,
     pub end_line: u32,
@@ -167,11 +166,8 @@ pub struct SourceRegion {
 
 impl Debug for SourceRegion {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        write!(
-            fmt,
-            "{}:{}:{} - {}:{}",
-            self.file_name, self.start_line, self.start_col, self.end_line, self.end_col
-        )
+        let &Self { start_line, start_col, end_line, end_col } = self;
+        write!(fmt, "{start_line}:{start_col} - {end_line}:{end_col}")
     }
 }
 
@@ -246,6 +242,7 @@ pub struct Mapping {
 #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
 pub struct FunctionCoverageInfo {
     pub function_source_hash: u64,
+    pub body_span: Span,
     pub num_counters: usize,
     pub mcdc_bitmap_bits: usize,
     pub expressions: IndexVec<ExpressionId, Expression>,
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index d0f93c19e44..f0e2b7a376c 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -596,8 +596,10 @@ fn write_function_coverage_info(
     function_coverage_info: &coverage::FunctionCoverageInfo,
     w: &mut dyn io::Write,
 ) -> io::Result<()> {
-    let coverage::FunctionCoverageInfo { expressions, mappings, .. } = function_coverage_info;
+    let coverage::FunctionCoverageInfo { body_span, expressions, mappings, .. } =
+        function_coverage_info;
 
+    writeln!(w, "{INDENT}coverage body span: {body_span:?}")?;
     for (id, expression) in expressions.iter_enumerated() {
         writeln!(w, "{INDENT}coverage {id:?} => {expression:?};")?;
     }
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 54ead9a7a75..4e3668822ec 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -463,7 +463,7 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    /// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`.
+    /// Fetch the THIR for a given body.
     query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> {
         // Perf tests revealed that hashing THIR is inefficient (see #85729).
         no_hash
@@ -2326,13 +2326,19 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    /// Check the signature of this function as well as all the call expressions inside of it
-    /// to ensure that any target features required by the ABI are enabled.
-    /// Should be called on a fully monomorphized instance.
-    query check_feature_dependent_abi(key: ty::Instance<'tcx>) {
-        desc { "check for feature-dependent ABI" }
+    /// Perform monomorphization-time checking on this item.
+    /// This is used for lints/errors that can only be checked once the instance is fully
+    /// monomorphized.
+    query check_mono_item(key: ty::Instance<'tcx>) {
+        desc { "monomorphization-time checking" }
         cache_on_disk_if { true }
     }
+
+    /// Builds the set of functions that should be skipped for the move-size check.
+    query skip_move_check_fns(_: ()) -> &'tcx FxIndexSet<DefId> {
+        arena_cache
+        desc { "functions to skip for move-size check" }
+    }
 }
 
 rustc_query_append! { define_callbacks! }
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index 57da5b39ba7..20ba1b27c0e 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -319,7 +319,7 @@ macro_rules! define_callbacks {
 
                 pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erase<$V>>;
 
-                // Ensure that keys grow no larger than 72 bytes by accident.
+                // Ensure that keys grow no larger than 80 bytes by accident.
                 // Increase this limit if necessary, but do try to keep the size low if possible
                 #[cfg(target_pointer_width = "64")]
                 const _: () = {
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 45ceb0a555d..70df2379016 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -645,7 +645,7 @@ impl<'tcx> Pat<'tcx> {
             | Binding { subpattern: Some(subpattern), .. }
             | Deref { subpattern }
             | DerefPattern { subpattern, .. }
-            | InlineConstant { subpattern, .. } => subpattern.walk_(it),
+            | ExpandedConstant { subpattern, .. } => subpattern.walk_(it),
             Leaf { subpatterns } | Variant { subpatterns, .. } => {
                 subpatterns.iter().for_each(|field| field.pattern.walk_(it))
             }
@@ -788,12 +788,17 @@ pub enum PatKind<'tcx> {
         value: mir::Const<'tcx>,
     },
 
-    /// Inline constant found while lowering a pattern.
-    InlineConstant {
-        /// [LocalDefId] of the constant, we need this so that we have a
+    /// Pattern obtained by converting a constant (inline or named) to its pattern
+    /// representation using `const_to_pat`.
+    ExpandedConstant {
+        /// [DefId] of the constant, we need this so that we have a
         /// reference that can be used by unsafety checking to visit nested
-        /// unevaluated constants.
-        def: LocalDefId,
+        /// unevaluated constants and for diagnostics. If the `DefId` doesn't
+        /// correspond to a local crate, it points at the `const` item.
+        def_id: DefId,
+        /// If `false`, then `def_id` points at a `const` item, otherwise it
+        /// corresponds to a local inline const.
+        is_inline: bool,
         /// If the inline constant is used in a range pattern, this subpattern
         /// represents the range (if both ends are inline constants, there will
         /// be multiple InlineConstant wrappers).
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 36f0e3d890c..81202a6eaad 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -247,7 +247,7 @@ pub fn walk_pat<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
             }
         }
         Constant { value: _ } => {}
-        InlineConstant { def: _, subpattern } => visitor.visit_pat(subpattern),
+        ExpandedConstant { def_id: _, is_inline: _, subpattern } => visitor.visit_pat(subpattern),
         Range(_) => {}
         Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
             for subpattern in prefix.iter() {
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 5ab85a69ce6..5689f3d4265 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -1,4 +1,3 @@
-use either::Either;
 use rustc_data_structures::intern::Interned;
 use rustc_error_messages::MultiSpan;
 use rustc_hir::def::{DefKind, Res};
@@ -9,7 +8,7 @@ use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
 use tracing::{debug, instrument};
 
 use crate::middle::resolve_bound_vars as rbv;
-use crate::mir::interpret::{ErrorHandled, LitToConstInput, Scalar};
+use crate::mir::interpret::{LitToConstInput, Scalar};
 use crate::ty::{self, GenericArgs, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
 
 mod int;
@@ -18,7 +17,7 @@ mod valtree;
 
 pub use int::*;
 pub use kind::*;
-use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
+use rustc_span::{DUMMY_SP, ErrorGuaranteed};
 pub use valtree::*;
 
 pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
@@ -363,60 +362,6 @@ impl<'tcx> Const<'tcx> {
         Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
     }
 
-    /// Returns the evaluated constant as a valtree;
-    /// if that fails due to a valtree-incompatible type, indicate which type that is
-    /// by returning `Err(Left(bad_type))`.
-    #[inline]
-    pub fn eval_valtree(
-        self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ParamEnv<'tcx>,
-        span: Span,
-    ) -> Result<(Ty<'tcx>, ValTree<'tcx>), Either<Ty<'tcx>, ErrorHandled>> {
-        assert!(!self.has_escaping_bound_vars(), "escaping vars in {self:?}");
-        match self.kind() {
-            ConstKind::Unevaluated(unevaluated) => {
-                // FIXME(eddyb) maybe the `const_eval_*` methods should take
-                // `ty::ParamEnvAnd` instead of having them separate.
-                let (param_env, unevaluated) = unevaluated.prepare_for_eval(tcx, param_env);
-                // try to resolve e.g. associated constants to their definition on an impl, and then
-                // evaluate the const.
-                match tcx.const_eval_resolve_for_typeck(param_env, unevaluated, span) {
-                    Ok(Ok(c)) => {
-                        Ok((tcx.type_of(unevaluated.def).instantiate(tcx, unevaluated.args), c))
-                    }
-                    Ok(Err(bad_ty)) => Err(Either::Left(bad_ty)),
-                    Err(err) => Err(Either::Right(err)),
-                }
-            }
-            ConstKind::Value(ty, val) => Ok((ty, val)),
-            ConstKind::Error(g) => Err(Either::Right(g.into())),
-            ConstKind::Param(_)
-            | ConstKind::Infer(_)
-            | ConstKind::Bound(_, _)
-            | ConstKind::Placeholder(_)
-            | ConstKind::Expr(_) => Err(Either::Right(ErrorHandled::TooGeneric(span))),
-        }
-    }
-
-    /// Normalizes the constant to a value or an error if possible.
-    #[inline]
-    pub fn normalize_internal(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
-        match self.eval_valtree(tcx, param_env, DUMMY_SP) {
-            Ok((ty, val)) => Self::new_value(tcx, val, ty),
-            Err(Either::Left(_bad_ty)) => {
-                // This can happen when we run on ill-typed code.
-                Self::new_error(
-                    tcx,
-                    tcx.dcx()
-                        .delayed_bug("`ty::Const::eval` called on a non-valtree-compatible type"),
-                )
-            }
-            Err(Either::Right(ErrorHandled::Reported(r, _span))) => Self::new_error(tcx, r.into()),
-            Err(Either::Right(ErrorHandled::TooGeneric(_span))) => self,
-        }
-    }
-
     /// Panics if self.kind != ty::ConstKind::Value
     pub fn to_valtree(self) -> (ty::ValTree<'tcx>, Ty<'tcx>) {
         match self.kind() {
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index 91b764ae1d4..b3436550e8e 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -1,46 +1,12 @@
 use std::assert_matches::assert_matches;
 
-use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, extension};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 
 use super::Const;
 use crate::mir;
 use crate::ty::abstract_const::CastKind;
-use crate::ty::visit::TypeVisitableExt as _;
 use crate::ty::{self, Ty, TyCtxt};
 
-#[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)]
-impl<'tcx> ty::UnevaluatedConst<'tcx> {
-    /// FIXME(RalfJung): I cannot explain what this does or why it makes sense, but not doing this
-    /// hurts performance.
-    #[inline]
-    fn prepare_for_eval(
-        self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> (ty::ParamEnv<'tcx>, Self) {
-        // HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
-        // also does later, but we want to do it before checking for
-        // inference variables.
-        // Note that we erase regions *before* calling `with_reveal_all_normalized`,
-        // so that we don't try to invoke this query with
-        // any region variables.
-
-        // HACK(eddyb) when the query key would contain inference variables,
-        // attempt using identity args and `ParamEnv` instead, that will succeed
-        // when the expression doesn't depend on any parameters.
-        // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that
-        // we can call `infcx.const_eval_resolve` which handles inference variables.
-        if (param_env, self).has_non_region_infer() {
-            (tcx.param_env(self.def), ty::UnevaluatedConst {
-                def: self.def,
-                args: ty::GenericArgs::identity_for_item(tcx, self.def),
-            })
-        } else {
-            (tcx.erase_regions(param_env).with_reveal_all_normalized(tcx), tcx.erase_regions(self))
-        }
-    }
-}
-
 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
 #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
 pub enum ExprKind {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index c55733da7b3..84ac281c258 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -22,9 +22,9 @@ use rustc_data_structures::profiling::SelfProfilerRef;
 use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
-use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, RwLock, WorkerLocal};
-#[cfg(parallel_compiler)]
-use rustc_data_structures::sync::{DynSend, DynSync};
+use rustc_data_structures::sync::{
+    self, DynSend, DynSync, FreezeReadGuard, Lock, Lrc, RwLock, WorkerLocal,
+};
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, LintDiagnostic, MultiSpan,
@@ -1259,9 +1259,7 @@ pub struct TyCtxt<'tcx> {
 }
 
 // Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution.
-#[cfg(parallel_compiler)]
 unsafe impl DynSend for TyCtxt<'_> {}
-#[cfg(parallel_compiler)]
 unsafe impl DynSync for TyCtxt<'_> {}
 fn _assert_tcx_fields() {
     sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
@@ -1383,9 +1381,7 @@ pub struct CurrentGcx {
     value: Lrc<RwLock<Option<*const ()>>>,
 }
 
-#[cfg(parallel_compiler)]
 unsafe impl DynSend for CurrentGcx {}
-#[cfg(parallel_compiler)]
 unsafe impl DynSync for CurrentGcx {}
 
 impl CurrentGcx {
diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs
index 6a5d3030646..eaab8474dd2 100644
--- a/compiler/rustc_middle/src/ty/context/tls.rs
+++ b/compiler/rustc_middle/src/ty/context/tls.rs
@@ -1,5 +1,3 @@
-#[cfg(not(parallel_compiler))]
-use std::cell::Cell;
 use std::{mem, ptr};
 
 use rustc_data_structures::sync::{self, Lock};
@@ -50,16 +48,8 @@ impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
 }
 
 // Import the thread-local variable from Rayon, which is preserved for Rayon jobs.
-#[cfg(parallel_compiler)]
 use rayon_core::tlv::TLV;
 
-// Otherwise define our own
-#[cfg(not(parallel_compiler))]
-thread_local! {
-    /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
-    static TLV: Cell<*const ()> = const { Cell::new(ptr::null()) };
-}
-
 #[inline]
 fn erase(context: &ImplicitCtxt<'_, '_>) -> *const () {
     context as *const _ as *const ()
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 737f1362b34..fd84d75b53f 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -143,12 +143,10 @@ impl<'tcx> rustc_type_ir::inherent::IntoKind for GenericArg<'tcx> {
     }
 }
 
-#[cfg(parallel_compiler)]
 unsafe impl<'tcx> rustc_data_structures::sync::DynSend for GenericArg<'tcx> where
     &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSend
 {
 }
-#[cfg(parallel_compiler)]
 unsafe impl<'tcx> rustc_data_structures::sync::DynSync for GenericArg<'tcx> where
     &'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSync
 {
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 19779740227..ce40ab18261 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -86,10 +86,10 @@ impl GenericParamDef {
         tcx: TyCtxt<'tcx>,
     ) -> Option<EarlyBinder<'tcx, ty::GenericArg<'tcx>>> {
         match self.kind {
-            GenericParamDefKind::Type { has_default, .. } if has_default => {
+            GenericParamDefKind::Type { has_default: true, .. } => {
                 Some(tcx.type_of(self.def_id).map_bound(|t| t.into()))
             }
-            GenericParamDefKind::Const { has_default, .. } if has_default => {
+            GenericParamDefKind::Const { has_default: true, .. } => {
                 Some(tcx.const_param_default(self.def_id).map_bound(|c| c.into()))
             }
             _ => None,
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index ea07cd3a1b9..30a5586f59c 100644
--- a/compiler/rustc_middle/src/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
@@ -5,7 +5,6 @@ use std::ops::Deref;
 use std::{fmt, iter, mem, ptr, slice};
 
 use rustc_data_structures::aligned::{Aligned, align_of};
-#[cfg(parallel_compiler)]
 use rustc_data_structures::sync::DynSync;
 use rustc_serialize::{Encodable, Encoder};
 
@@ -259,7 +258,6 @@ impl<'a, H, T: Copy> IntoIterator for &'a RawList<H, T> {
 unsafe impl<H: Sync, T: Sync> Sync for RawList<H, T> {}
 
 // We need this since `List` uses extern type `OpaqueListContents`.
-#[cfg(parallel_compiler)]
 unsafe impl<H: DynSync, T: DynSync> DynSync for RawList<H, T> {}
 
 // Safety:
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 1a3128ed936..7fda0662a34 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -487,12 +487,10 @@ impl<'tcx> rustc_type_ir::inherent::IntoKind for Term<'tcx> {
     }
 }
 
-#[cfg(parallel_compiler)]
 unsafe impl<'tcx> rustc_data_structures::sync::DynSend for Term<'tcx> where
     &'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSend
 {
 }
-#[cfg(parallel_compiler)]
 unsafe impl<'tcx> rustc_data_structures::sync::DynSync for Term<'tcx> where
     &'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSync
 {
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index 07964e304b9..62d173987fc 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -144,12 +144,20 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
         let mut targets = Vec::new();
         for arm in rest {
             let arm = &self.thir[*arm];
-            let PatKind::Constant { value } = arm.pattern.kind else {
-                return Err(ParseError {
-                    span: arm.pattern.span,
-                    item_description: format!("{:?}", arm.pattern.kind),
-                    expected: "constant pattern".to_string(),
-                });
+            let value = match arm.pattern.kind {
+                PatKind::Constant { value } => value,
+                PatKind::ExpandedConstant { ref subpattern, def_id: _, is_inline: false }
+                    if let PatKind::Constant { value } = subpattern.kind =>
+                {
+                    value
+                }
+                _ => {
+                    return Err(ParseError {
+                        span: arm.pattern.span,
+                        item_description: format!("{:?}", arm.pattern.kind),
+                        expected: "constant pattern".to_string(),
+                    });
+                }
             };
             values.push(value.eval_bits(self.tcx, self.param_env));
             targets.push(self.parse_block(arm.body)?);
diff --git a/compiler/rustc_mir_build/src/build/matches/match_pair.rs b/compiler/rustc_mir_build/src/build/matches/match_pair.rs
index 6df50057ee8..6beabb5ccdb 100644
--- a/compiler/rustc_mir_build/src/build/matches/match_pair.rs
+++ b/compiler/rustc_mir_build/src/build/matches/match_pair.rs
@@ -162,7 +162,11 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
                 TestCase::Irrefutable { ascription: None, binding }
             }
 
-            PatKind::InlineConstant { subpattern: ref pattern, def, .. } => {
+            PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => {
+                subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx));
+                default_irrefutable()
+            }
+            PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
                 // Apply a type ascription for the inline constant to the value at `match_pair.place`
                 let ascription = place.map(|source| {
                     let span = pattern.span;
@@ -173,7 +177,7 @@ impl<'pat, 'tcx> MatchPairTree<'pat, 'tcx> {
                     })
                     .args;
                     let user_ty = cx.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
-                        def.to_def_id(),
+                        def_id,
                         ty::UserArgs { args, user_self_ty: None },
                     ));
                     let annotation = ty::CanonicalUserTypeAnnotation {
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index a62d4e9d873..9f81e1052d6 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -917,7 +917,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 self.visit_primary_bindings(subpattern, subpattern_user_ty, f)
             }
 
-            PatKind::InlineConstant { ref subpattern, .. } => {
+            PatKind::ExpandedConstant { ref subpattern, .. } => {
                 self.visit_primary_bindings(subpattern, pattern_user_ty, f)
             }
 
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index f3e6301d9d1..52e5f2950a5 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -332,7 +332,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 PatKind::Wild |
                 // these just wrap other patterns, which we recurse on below.
                 PatKind::Or { .. } |
-                PatKind::InlineConstant { .. } |
+                PatKind::ExpandedConstant { .. } |
                 PatKind::AscribeUserType { .. } |
                 PatKind::Error(_) => {}
             }
@@ -386,8 +386,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 visit::walk_pat(self, pat);
                 self.inside_adt = old_inside_adt;
             }
-            PatKind::InlineConstant { def, .. } => {
-                self.visit_inner_body(*def);
+            PatKind::ExpandedConstant { def_id, is_inline, .. } => {
+                if let Some(def) = def_id.as_local()
+                    && *is_inline
+                {
+                    self.visit_inner_body(def);
+                }
                 visit::walk_pat(self, pat);
             }
             _ => {
@@ -1005,10 +1009,6 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
     // Runs all other queries that depend on THIR.
     tcx.ensure_with_value().mir_built(def);
     let thir = &thir.steal();
-    // If `thir` is empty, a type error occurred, skip this body.
-    if thir.exprs.is_empty() {
-        return;
-    }
 
     let hir_id = tcx.local_def_id_to_hir_id(def);
     let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 00f65e0c7d0..4443d9aebc6 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -860,8 +860,10 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
     pub(crate) uncovered: Uncovered,
     #[subdiagnostic]
     pub(crate) inform: Option<Inform>,
+    #[label(mir_build_confused)]
+    pub(crate) interpreted_as_const: Option<Span>,
     #[subdiagnostic]
-    pub(crate) interpreted_as_const: Option<InterpretedAsConst>,
+    pub(crate) interpreted_as_const_sugg: Option<InterpretedAsConst>,
     #[subdiagnostic]
     pub(crate) adt_defined_here: Option<AdtDefinedHere<'tcx>>,
     #[note(mir_build_privately_uninhabited)]
@@ -911,9 +913,9 @@ impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> {
 #[suggestion(
     mir_build_interpreted_as_const,
     code = "{variable}_var",
-    applicability = "maybe-incorrect"
+    applicability = "maybe-incorrect",
+    style = "verbose"
 )]
-#[label(mir_build_confused)]
 pub(crate) struct InterpretedAsConst {
     #[primary_span]
     pub(crate) span: Span,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index f222a869c03..4b872d9b7f7 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -668,8 +668,25 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
         let mut let_suggestion = None;
         let mut misc_suggestion = None;
         let mut interpreted_as_const = None;
+        let mut interpreted_as_const_sugg = None;
 
-        if let PatKind::Constant { .. }
+        if let PatKind::ExpandedConstant { def_id, is_inline: false, .. }
+        | PatKind::AscribeUserType {
+            subpattern:
+                box Pat { kind: PatKind::ExpandedConstant { def_id, is_inline: false, .. }, .. },
+            ..
+        } = pat.kind
+            && let DefKind::Const = self.tcx.def_kind(def_id)
+            && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
+            // We filter out paths with multiple path::segments.
+            && snippet.chars().all(|c| c.is_alphanumeric() || c == '_')
+        {
+            let span = self.tcx.def_span(def_id);
+            let variable = self.tcx.item_name(def_id).to_string();
+            // When we encounter a constant as the binding name, point at the `const` definition.
+            interpreted_as_const = Some(span);
+            interpreted_as_const_sugg = Some(InterpretedAsConst { span: pat.span, variable });
+        } else if let PatKind::Constant { .. }
         | PatKind::AscribeUserType {
             subpattern: box Pat { kind: PatKind::Constant { .. }, .. },
             ..
@@ -682,9 +699,6 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
                 misc_suggestion = Some(MiscPatternSuggestion::AttemptedIntegerLiteral {
                     start_span: pat.span.shrink_to_lo(),
                 });
-            } else if snippet.chars().all(|c| c.is_alphanumeric() || c == '_') {
-                interpreted_as_const =
-                    Some(InterpretedAsConst { span: pat.span, variable: snippet });
             }
         }
 
@@ -733,6 +747,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
             uncovered: Uncovered::new(pat.span, &cx, witnesses),
             inform,
             interpreted_as_const,
+            interpreted_as_const_sugg,
             witness_1_is_privately_uninhabited,
             _p: (),
             pattern_ty,
@@ -1102,13 +1117,13 @@ fn report_non_exhaustive_match<'p, 'tcx>(
             if ty.is_ptr_sized_integral() {
                 if ty.inner() == cx.tcx.types.usize {
                     err.note(format!(
-                        "`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \
-                             exhaustively",
+                        "`{ty}` does not have a fixed maximum value, so half-open ranges are \
+                         necessary to match exhaustively",
                     ));
                 } else if ty.inner() == cx.tcx.types.isize {
                     err.note(format!(
-                        "`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \
-                             exhaustively",
+                        "`{ty}` does not have fixed minimum and maximum values, so half-open \
+                         ranges are necessary to match exhaustively",
                     ));
                 }
             } else if ty.inner() == cx.tcx.types.str_ {
@@ -1129,6 +1144,31 @@ fn report_non_exhaustive_match<'p, 'tcx>(
         }
     }
 
+    for &arm in arms {
+        let arm = &thir.arms[arm];
+        if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } = arm.pattern.kind
+            && let Ok(snippet) = cx.tcx.sess.source_map().span_to_snippet(arm.pattern.span)
+            // We filter out paths with multiple path::segments.
+            && snippet.chars().all(|c| c.is_alphanumeric() || c == '_')
+        {
+            let const_name = cx.tcx.item_name(def_id);
+            err.span_label(
+                arm.pattern.span,
+                format!(
+                    "this pattern doesn't introduce a new catch-all binding, but rather pattern \
+                     matches against the value of constant `{const_name}`",
+                ),
+            );
+            err.span_note(cx.tcx.def_span(def_id), format!("constant `{const_name}` defined here"));
+            err.span_suggestion_verbose(
+                arm.pattern.span.shrink_to_hi(),
+                "if you meant to introduce a binding, use a different name",
+                "_var".to_string(),
+                Applicability::MaybeIncorrect,
+            );
+        }
+    }
+
     // Whether we suggest the actual missing patterns or `_`.
     let suggest_the_witnesses = witnesses.len() < 4;
     let suggested_arm = if suggest_the_witnesses {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 983853d2de1..82632350af5 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -1,14 +1,13 @@
-use either::Either;
 use rustc_abi::{FieldIdx, VariantIdx};
 use rustc_apfloat::Float;
 use rustc_hir as hir;
 use rustc_index::Idx;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::Obligation;
-use rustc_middle::mir;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::thir::{FieldPat, Pat, PatKind};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, ValTree};
+use rustc_middle::{mir, span_bug};
 use rustc_span::Span;
 use rustc_trait_selection::traits::ObligationCause;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -40,7 +39,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         // of opaques defined in this function here.
         let infcx = self.tcx.infer_ctxt().build(TypingMode::non_body_analysis());
         let mut convert = ConstToPat::new(self, id, span, infcx);
-        convert.to_pat(c, ty)
+
+        match c.kind() {
+            ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
+            ty::ConstKind::Value(_, val) => convert.valtree_to_pat(val, ty),
+            _ => span_bug!(span, "Invalid `ConstKind` for `const_to_pat`: {:?}", c),
+        }
     }
 }
 
@@ -81,27 +85,42 @@ impl<'tcx> ConstToPat<'tcx> {
         ty.is_structural_eq_shallow(self.infcx.tcx)
     }
 
-    fn to_pat(&mut self, c: ty::Const<'tcx>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
+    fn unevaluated_to_pat(
+        &mut self,
+        uv: ty::UnevaluatedConst<'tcx>,
+        ty: Ty<'tcx>,
+    ) -> Box<Pat<'tcx>> {
         trace!(self.treat_byte_string_as_slice);
         let pat_from_kind = |kind| Box::new(Pat { span: self.span, ty, kind });
 
-        // Get a valtree. If that fails, this const is definitely not valid for use as a pattern.
-        let valtree = match c.eval_valtree(self.tcx(), self.param_env, self.span) {
-            Ok((_, valtree)) => valtree,
-            Err(Either::Right(e)) => {
-                let err = match e {
-                    ErrorHandled::Reported(..) => {
-                        // Let's tell the use where this failing const occurs.
-                        self.tcx().dcx().emit_err(CouldNotEvalConstPattern { span: self.span })
-                    }
-                    ErrorHandled::TooGeneric(_) => self
-                        .tcx()
-                        .dcx()
-                        .emit_err(ConstPatternDependsOnGenericParameter { span: self.span }),
-                };
-                return pat_from_kind(PatKind::Error(err));
+        // It's not *technically* correct to be revealing opaque types here as borrowcheck has
+        // not run yet. However, CTFE itself uses `Reveal::All` unconditionally even during
+        // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821). As a
+        // result we always use a revealed env when resolving the instance to evaluate.
+        //
+        // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
+        // instead of having this logic here
+        let param_env =
+            self.tcx().erase_regions(self.param_env).with_reveal_all_normalized(self.tcx());
+        let uv = self.tcx().erase_regions(uv);
+
+        // try to resolve e.g. associated constants to their definition on an impl, and then
+        // evaluate the const.
+        let valtree = match self.infcx.tcx.const_eval_resolve_for_typeck(param_env, uv, self.span) {
+            Ok(Ok(c)) => c,
+            Err(ErrorHandled::Reported(_, _)) => {
+                // Let's tell the use where this failing const occurs.
+                let e = self.tcx().dcx().emit_err(CouldNotEvalConstPattern { span: self.span });
+                return pat_from_kind(PatKind::Error(e));
             }
-            Err(Either::Left(bad_ty)) => {
+            Err(ErrorHandled::TooGeneric(_)) => {
+                let e = self
+                    .tcx()
+                    .dcx()
+                    .emit_err(ConstPatternDependsOnGenericParameter { span: self.span });
+                return pat_from_kind(PatKind::Error(e));
+            }
+            Ok(Err(bad_ty)) => {
                 // The pattern cannot be turned into a valtree.
                 let e = match bad_ty.kind() {
                     ty::Adt(def, ..) => {
@@ -128,8 +147,7 @@ impl<'tcx> ConstToPat<'tcx> {
             if !self.type_has_partial_eq_impl(ty) {
                 let err = TypeNotPartialEq { span: self.span, non_peq_ty: ty };
                 let e = self.tcx().dcx().emit_err(err);
-                let kind = PatKind::Error(e);
-                return Box::new(Pat { span: self.span, ty, kind });
+                return pat_from_kind(PatKind::Error(e));
             }
         }
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index ec852add94d..9b63d788194 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -149,21 +149,30 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             None => Ok((None, None, None)),
             Some(expr) => {
                 let (kind, ascr, inline_const) = match self.lower_lit(expr) {
-                    PatKind::InlineConstant { subpattern, def } => {
-                        (subpattern.kind, None, Some(def))
+                    PatKind::ExpandedConstant { subpattern, def_id, is_inline: true } => {
+                        (subpattern.kind, None, def_id.as_local())
+                    }
+                    PatKind::ExpandedConstant { subpattern, is_inline: false, .. } => {
+                        (subpattern.kind, None, None)
                     }
                     PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
                         (kind, Some(ascription), None)
                     }
                     kind => (kind, None, None),
                 };
-                let value = if let PatKind::Constant { value } = kind {
-                    value
-                } else {
-                    let msg = format!(
-                        "found bad range pattern endpoint `{expr:?}` outside of error recovery"
-                    );
-                    return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
+                let value = match kind {
+                    PatKind::Constant { value } => value,
+                    PatKind::ExpandedConstant { subpattern, .. }
+                        if let PatKind::Constant { value } = subpattern.kind =>
+                    {
+                        value
+                    }
+                    _ => {
+                        let msg = format!(
+                            "found bad range pattern endpoint `{expr:?}` outside of error recovery"
+                        );
+                        return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
+                    }
                 };
                 Ok((Some(PatRangeBoundary::Finite(value)), ascr, inline_const))
             }
@@ -288,7 +297,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             };
         }
         for def in [lo_inline, hi_inline].into_iter().flatten() {
-            kind = PatKind::InlineConstant { def, subpattern: Box::new(Pat { span, ty, kind }) };
+            kind = PatKind::ExpandedConstant {
+                def_id: def.to_def_id(),
+                is_inline: true,
+                subpattern: Box::new(Pat { span, ty, kind }),
+            };
         }
         Ok(kind)
     }
@@ -562,7 +575,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
         let args = self.typeck_results.node_args(id);
         let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args });
-        let pattern = self.const_to_pat(c, ty, id, span);
+        let subpattern = self.const_to_pat(c, ty, id, span);
+        let pattern = Box::new(Pat {
+            span,
+            ty,
+            kind: PatKind::ExpandedConstant { subpattern, def_id, is_inline: false },
+        });
 
         if !is_associated_const {
             return pattern;
@@ -637,7 +655,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
         let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args };
         let subpattern = self.const_to_pat(ty::Const::new_unevaluated(self.tcx, ct), ty, id, span);
-        PatKind::InlineConstant { subpattern, def: def_id }
+        PatKind::ExpandedConstant { subpattern, def_id: def_id.to_def_id(), is_inline: true }
     }
 
     /// Converts literals, paths and negation of literals to patterns.
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index dae13df4054..6be0ed5fb31 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -707,9 +707,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
                 print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
                 print_indented!(self, "}", depth_lvl + 1);
             }
-            PatKind::InlineConstant { def, subpattern } => {
-                print_indented!(self, "InlineConstant {", depth_lvl + 1);
-                print_indented!(self, format!("def: {:?}", def), depth_lvl + 2);
+            PatKind::ExpandedConstant { def_id, is_inline, subpattern } => {
+                print_indented!(self, "ExpandedConstant {", depth_lvl + 1);
+                print_indented!(self, format!("def_id: {def_id:?}"), depth_lvl + 2);
+                print_indented!(self, format!("is_inline: {is_inline:?}"), depth_lvl + 2);
                 print_indented!(self, "subpattern:", depth_lvl + 2);
                 self.print_pat(subpattern, depth_lvl + 2);
                 print_indented!(self, "}", depth_lvl + 1);
diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl
index c8992b8b834..9bbfae17fd9 100644
--- a/compiler/rustc_mir_transform/messages.ftl
+++ b/compiler/rustc_mir_transform/messages.ftl
@@ -34,3 +34,5 @@ mir_transform_undefined_transmute = pointers cannot be transmuted to integers du
     .note = at compile-time, pointers do not have an integer value
     .note2 = avoiding this restriction via `union` or raw pointers leads to compile-time undefined behavior
     .help = for more information, see https://doc.rust-lang.org/std/mem/fn.transmute.html
+
+mir_transform_unknown_pass_name = MIR pass `{$name}` is unknown and will be ignored
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 2e4c503f3ce..e8b3d80be02 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -22,8 +22,8 @@ use rustc_middle::mir::{
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::source_map::SourceMap;
-use rustc_span::{BytePos, Pos, RelativeBytePos, Span, Symbol};
-use tracing::{debug, debug_span, instrument, trace};
+use rustc_span::{BytePos, Pos, SourceFile, Span};
+use tracing::{debug, debug_span, trace};
 
 use crate::coverage::counters::{CounterIncrementSite, CoverageCounters};
 use crate::coverage::graph::CoverageGraph;
@@ -122,6 +122,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
 
     mir_body.function_coverage_info = Some(Box::new(FunctionCoverageInfo {
         function_source_hash: hir_info.function_source_hash,
+        body_span: hir_info.body_span,
         num_counters: coverage_counters.num_counters(),
         mcdc_bitmap_bits: extracted_mappings.mcdc_bitmap_bits,
         expressions: coverage_counters.into_expressions(),
@@ -142,19 +143,11 @@ fn create_mappings<'tcx>(
     coverage_counters: &CoverageCounters,
 ) -> Vec<Mapping> {
     let source_map = tcx.sess.source_map();
-    let body_span = hir_info.body_span;
-
-    let source_file = source_map.lookup_source_file(body_span.lo());
-
-    use rustc_session::RemapFileNameExt;
-    use rustc_session::config::RemapPathScopeComponents;
-    let file_name = Symbol::intern(
-        &source_file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(),
-    );
+    let file = source_map.lookup_source_file(hir_info.body_span.lo());
 
     let term_for_bcb =
         |bcb| coverage_counters.term_for_bcb(bcb).expect("all BCBs with spans were given counters");
-    let region_for_span = |span: Span| make_source_region(source_map, file_name, span, body_span);
+    let region_for_span = |span: Span| make_source_region(source_map, hir_info, &file, span);
 
     // Fully destructure the mappings struct to make sure we don't miss any kinds.
     let ExtractedMappings {
@@ -398,7 +391,42 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb
     data.statements.insert(0, statement);
 }
 
-/// Convert the Span into its file name, start line and column, and end line and column.
+fn ensure_non_empty_span(
+    source_map: &SourceMap,
+    hir_info: &ExtractedHirInfo,
+    span: Span,
+) -> Option<Span> {
+    if !span.is_empty() {
+        return Some(span);
+    }
+
+    let lo = span.lo();
+    let hi = span.hi();
+
+    // The span is empty, so try to expand it to cover an adjacent '{' or '}',
+    // but only within the bounds of the body span.
+    let try_next = hi < hir_info.body_span.hi();
+    let try_prev = hir_info.body_span.lo() < lo;
+    if !(try_next || try_prev) {
+        return None;
+    }
+
+    source_map
+        .span_to_source(span, |src, start, end| try {
+            // We're only checking for specific ASCII characters, so we don't
+            // have to worry about multi-byte code points.
+            if try_next && src.as_bytes()[end] == b'{' {
+                Some(span.with_hi(hi + BytePos(1)))
+            } else if try_prev && src.as_bytes()[start - 1] == b'}' {
+                Some(span.with_lo(lo - BytePos(1)))
+            } else {
+                None
+            }
+        })
+        .ok()?
+}
+
+/// Converts the span into its start line and column, and end line and column.
 ///
 /// Line numbers and column numbers are 1-based. Unlike most column numbers emitted by
 /// the compiler, these column numbers are denoted in **bytes**, because that's what
@@ -408,56 +436,29 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb
 /// but it's hard to rule out entirely (especially in the presence of complex macros
 /// or other expansions), and if it does happen then skipping a span or function is
 /// better than an ICE or `llvm-cov` failure that the user might have no way to avoid.
-#[instrument(level = "debug", skip(source_map))]
 fn make_source_region(
     source_map: &SourceMap,
-    file_name: Symbol,
+    hir_info: &ExtractedHirInfo,
+    file: &SourceFile,
     span: Span,
-    body_span: Span,
 ) -> Option<SourceRegion> {
+    let span = ensure_non_empty_span(source_map, hir_info, span)?;
+
     let lo = span.lo();
     let hi = span.hi();
 
-    let file = source_map.lookup_source_file(lo);
-    if !file.contains(hi) {
-        debug!(?span, ?file, ?lo, ?hi, "span crosses multiple files; skipping");
-        return None;
-    }
-
     // Column numbers need to be in bytes, so we can't use the more convenient
     // `SourceMap` methods for looking up file coordinates.
-    let rpos_and_line_and_byte_column = |pos: BytePos| -> Option<(RelativeBytePos, usize, usize)> {
+    let line_and_byte_column = |pos: BytePos| -> Option<(usize, usize)> {
         let rpos = file.relative_position(pos);
         let line_index = file.lookup_line(rpos)?;
         let line_start = file.lines()[line_index];
         // Line numbers and column numbers are 1-based, so add 1 to each.
-        Some((rpos, line_index + 1, (rpos - line_start).to_usize() + 1))
+        Some((line_index + 1, (rpos - line_start).to_usize() + 1))
     };
 
-    let (lo_rpos, mut start_line, mut start_col) = rpos_and_line_and_byte_column(lo)?;
-    let (hi_rpos, mut end_line, mut end_col) = rpos_and_line_and_byte_column(hi)?;
-
-    // If the span is empty, try to expand it horizontally by one character's
-    // worth of bytes, so that it is more visible in `llvm-cov` reports.
-    // We do this after resolving line/column numbers, so that empty spans at the
-    // end of a line get an extra column instead of wrapping to the next line.
-    if span.is_empty()
-        && body_span.contains(span)
-        && let Some(src) = &file.src
-    {
-        // Prefer to expand the end position, if it won't go outside the body span.
-        if hi < body_span.hi() {
-            let hi_rpos = hi_rpos.to_usize();
-            let nudge_bytes = src.ceil_char_boundary(hi_rpos + 1) - hi_rpos;
-            end_col += nudge_bytes;
-        } else if lo > body_span.lo() {
-            let lo_rpos = lo_rpos.to_usize();
-            let nudge_bytes = lo_rpos - src.floor_char_boundary(lo_rpos - 1);
-            // Subtract the nudge, but don't go below column 1.
-            start_col = start_col.saturating_sub(nudge_bytes).max(1);
-        }
-        // If neither nudge could be applied, stick with the empty span coordinates.
-    }
+    let (mut start_line, start_col) = line_and_byte_column(lo)?;
+    let (mut end_line, end_col) = line_and_byte_column(hi)?;
 
     // Apply an offset so that code in doctests has correct line numbers.
     // FIXME(#79417): Currently we have no way to offset doctest _columns_.
@@ -465,7 +466,6 @@ fn make_source_region(
     end_line = source_map.doctest_offset_line(&file.name, end_line);
 
     check_source_region(SourceRegion {
-        file_name,
         start_line: start_line as u32,
         start_col: start_col as u32,
         end_line: end_line as u32,
@@ -478,7 +478,7 @@ fn make_source_region(
 /// discard regions that are improperly ordered, or might be interpreted in a
 /// way that makes them improperly ordered.
 fn check_source_region(source_region: SourceRegion) -> Option<SourceRegion> {
-    let SourceRegion { file_name: _, start_line, start_col, end_line, end_col } = source_region;
+    let SourceRegion { start_line, start_col, end_line, end_col } = source_region;
 
     // Line/column coordinates are supposed to be 1-based. If we ever emit
     // coordinates of 0, `llvm-cov` might misinterpret them.
diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
index 42cbece32d8..589be81558c 100644
--- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs
+++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
@@ -50,6 +50,16 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
         _ => {}
     }
 
+    let sig = tcx.fn_sig(def_id).instantiate_identity();
+    for ty in sig.inputs().skip_binder().iter().chain(std::iter::once(&sig.output().skip_binder()))
+    {
+        // FIXME(f16_f128): in order to avoid crashes building `core`, always inline to skip
+        // codegen if the function is not used.
+        if ty == &tcx.types.f16 || ty == &tcx.types.f128 {
+            return true;
+        }
+    }
+
     // Don't do any inference when incremental compilation is enabled; the additional inlining that
     // inference permits also creates more work for small edits.
     if tcx.sess.opts.incremental.is_some() {
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index 8b309147c64..2d9eeddea2e 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -38,6 +38,12 @@ pub(crate) struct UnalignedPackedRef {
     pub span: Span,
 }
 
+#[derive(Diagnostic)]
+#[diag(mir_transform_unknown_pass_name)]
+pub(crate) struct UnknownPassName<'a> {
+    pub(crate) name: &'a str,
+}
+
 pub(crate) struct AssertLint<P> {
     pub span: Span,
     pub assert_kind: AssertKind<P>,
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index d184328748f..d2d5facbbdc 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -9,7 +9,6 @@
 #![feature(let_chains)]
 #![feature(map_try_insert)]
 #![feature(never_type)]
-#![feature(round_char_boundary)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
 #![warn(unreachable_pub)]
@@ -41,77 +40,158 @@ use tracing::{debug, trace};
 #[macro_use]
 mod pass_manager;
 
+use std::sync::LazyLock;
+
 use pass_manager::{self as pm, Lint, MirLint, MirPass, WithMinOptLevel};
 
-mod abort_unwinding_calls;
-mod add_call_guards;
-mod add_moves_for_packed_drops;
-mod add_retag;
-mod add_subtyping_projections;
-mod check_alignment;
-mod check_const_item_mutation;
-mod check_packed_ref;
-mod check_undefined_transmutes;
-// This pass is public to allow external drivers to perform MIR cleanup
-pub mod cleanup_post_borrowck;
-mod copy_prop;
-mod coroutine;
 mod cost_checker;
-mod coverage;
 mod cross_crate_inline;
-mod ctfe_limit;
-mod dataflow_const_prop;
-mod dead_store_elimination;
 mod deduce_param_attrs;
-mod deduplicate_blocks;
-mod deref_separator;
-mod dest_prop;
-pub mod dump_mir;
-mod early_otherwise_branch;
-mod elaborate_box_derefs;
-mod elaborate_drops;
 mod errors;
 mod ffi_unwind_calls;
-mod function_item_references;
-mod gvn;
-// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
-// by custom rustc drivers, running all the steps by themselves. See #114628.
-pub mod inline;
-mod instsimplify;
-mod jump_threading;
-mod known_panics_lint;
-mod large_enums;
 mod lint;
-mod lower_intrinsics;
-mod lower_slice_len;
-mod match_branches;
-mod mentioned_items;
-mod multiple_return_terminators;
-mod nrvo;
-mod post_drop_elaboration;
-mod prettify;
-mod promote_consts;
-mod ref_prop;
-mod remove_noop_landing_pads;
-mod remove_place_mention;
-mod remove_storage_markers;
-mod remove_uninit_drops;
-mod remove_unneeded_drops;
-mod remove_zsts;
-mod required_consts;
-mod reveal_all;
-mod sanity_check;
 mod shim;
 mod ssa;
-// This pass is public to allow external drivers to perform MIR cleanup
-pub mod simplify;
-mod simplify_branches;
-mod simplify_comparison_integral;
-mod single_use_consts;
-mod sroa;
-mod unreachable_enum_branching;
-mod unreachable_prop;
-mod validate;
+
+/// We import passes via this macro so that we can have a static list of pass names
+/// (used to verify CLI arguments). It takes a list of modules, followed by the passes
+/// declared within them.
+/// ```ignore,macro-test
+/// declare_passes! {
+///     // Declare a single pass from the module `abort_unwinding_calls`
+///     mod abort_unwinding_calls : AbortUnwindingCalls;
+///     // When passes are grouped together as an enum, declare the two constituent passes
+///     mod add_call_guards : AddCallGuards {
+///         AllCallEdges,
+///         CriticalCallEdges
+///     };
+///     // Declares multiple pass groups, each containing their own constituent passes
+///     mod simplify : SimplifyCfg {
+///         Initial,
+///         /* omitted */
+///     }, SimplifyLocals {
+///         BeforeConstProp,
+///         /* omitted */
+///     };
+/// }
+/// ```
+macro_rules! declare_passes {
+    (
+        $(
+            $vis:vis mod $mod_name:ident : $($pass_name:ident $( { $($ident:ident),* } )?),+ $(,)?;
+        )*
+    ) => {
+        $(
+            $vis mod $mod_name;
+            $(
+                // Make sure the type name is correct
+                #[allow(unused_imports)]
+                use $mod_name::$pass_name as _;
+            )+
+        )*
+
+        static PASS_NAMES: LazyLock<FxIndexSet<&str>> = LazyLock::new(|| [
+            // Fake marker pass
+            "PreCodegen",
+            $(
+                $(
+                    stringify!($pass_name),
+                    $(
+                        $(
+                            $mod_name::$pass_name::$ident.name(),
+                        )*
+                    )?
+                )+
+            )*
+        ].into_iter().collect());
+    };
+}
+
+declare_passes! {
+    mod abort_unwinding_calls : AbortUnwindingCalls;
+    mod add_call_guards : AddCallGuards { AllCallEdges, CriticalCallEdges };
+    mod add_moves_for_packed_drops : AddMovesForPackedDrops;
+    mod add_retag : AddRetag;
+    mod add_subtyping_projections : Subtyper;
+    mod check_alignment : CheckAlignment;
+    mod check_const_item_mutation : CheckConstItemMutation;
+    mod check_packed_ref : CheckPackedRef;
+    mod check_undefined_transmutes : CheckUndefinedTransmutes;
+    // This pass is public to allow external drivers to perform MIR cleanup
+    pub mod cleanup_post_borrowck : CleanupPostBorrowck;
+
+    mod copy_prop : CopyProp;
+    mod coroutine : StateTransform;
+    mod coverage : InstrumentCoverage;
+    mod ctfe_limit : CtfeLimit;
+    mod dataflow_const_prop : DataflowConstProp;
+    mod dead_store_elimination : DeadStoreElimination {
+        Initial,
+        Final
+    };
+    mod deduplicate_blocks : DeduplicateBlocks;
+    mod deref_separator : Derefer;
+    mod dest_prop : DestinationPropagation;
+    pub mod dump_mir : Marker;
+    mod early_otherwise_branch : EarlyOtherwiseBranch;
+    mod elaborate_box_derefs : ElaborateBoxDerefs;
+    mod elaborate_drops : ElaborateDrops;
+    mod function_item_references : FunctionItemReferences;
+    mod gvn : GVN;
+    // Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
+    // by custom rustc drivers, running all the steps by themselves. See #114628.
+    pub mod inline : Inline;
+    mod instsimplify : InstSimplify { BeforeInline, AfterSimplifyCfg };
+    mod jump_threading : JumpThreading;
+    mod known_panics_lint : KnownPanicsLint;
+    mod large_enums : EnumSizeOpt;
+    mod lower_intrinsics : LowerIntrinsics;
+    mod lower_slice_len : LowerSliceLenCalls;
+    mod match_branches : MatchBranchSimplification;
+    mod mentioned_items : MentionedItems;
+    mod multiple_return_terminators : MultipleReturnTerminators;
+    mod nrvo : RenameReturnPlace;
+    mod post_drop_elaboration : CheckLiveDrops;
+    mod prettify : ReorderBasicBlocks, ReorderLocals;
+    mod promote_consts : PromoteTemps;
+    mod ref_prop : ReferencePropagation;
+    mod remove_noop_landing_pads : RemoveNoopLandingPads;
+    mod remove_place_mention : RemovePlaceMention;
+    mod remove_storage_markers : RemoveStorageMarkers;
+    mod remove_uninit_drops : RemoveUninitDrops;
+    mod remove_unneeded_drops : RemoveUnneededDrops;
+    mod remove_zsts : RemoveZsts;
+    mod required_consts : RequiredConstsVisitor;
+    mod reveal_all : RevealAll;
+    mod sanity_check : SanityCheck;
+    // This pass is public to allow external drivers to perform MIR cleanup
+    pub mod simplify :
+        SimplifyCfg {
+            Initial,
+            PromoteConsts,
+            RemoveFalseEdges,
+            PostAnalysis,
+            PreOptimizations,
+            Final,
+            MakeShim,
+            AfterUnreachableEnumBranching
+        },
+        SimplifyLocals {
+            BeforeConstProp,
+            AfterGVN,
+            Final
+        };
+    mod simplify_branches : SimplifyConstCondition {
+        AfterConstProp,
+        Final
+    };
+    mod simplify_comparison_integral : SimplifyComparisonIntegral;
+    mod single_use_consts : SingleUseConsts;
+    mod sroa : ScalarReplacementOfAggregates;
+    mod unreachable_enum_branching : UnreachableEnumBranching;
+    mod unreachable_prop : UnreachablePropagation;
+    mod validate : Validator;
+}
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs
index 29f8b4f6e4d..779e7f22101 100644
--- a/compiler/rustc_mir_transform/src/pass_manager.rs
+++ b/compiler/rustc_mir_transform/src/pass_manager.rs
@@ -1,24 +1,25 @@
 use std::cell::RefCell;
 use std::collections::hash_map::Entry;
 
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_middle::mir::{self, Body, MirPhase, RuntimePhase};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use tracing::trace;
 
 use crate::lint::lint_body;
-use crate::validate;
+use crate::{errors, validate};
 
 thread_local! {
-    static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
+    /// Maps MIR pass names to a snake case form to match profiling naming style
+    static PASS_TO_PROFILER_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
         RefCell::new(FxHashMap::default())
     };
 }
 
 /// Converts a MIR pass name into a snake case form to match the profiling naming style.
 fn to_profiler_name(type_name: &'static str) -> &'static str {
-    PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
+    PASS_TO_PROFILER_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
         Entry::Occupied(e) => *e.get(),
         Entry::Vacant(e) => {
             let snake_case: String = type_name
@@ -198,6 +199,31 @@ fn run_passes_inner<'tcx>(
     let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes;
     trace!(?overridden_passes);
 
+    let named_passes: FxIndexSet<_> =
+        overridden_passes.iter().map(|(name, _)| name.as_str()).collect();
+
+    for &name in named_passes.difference(&*crate::PASS_NAMES) {
+        tcx.dcx().emit_warn(errors::UnknownPassName { name });
+    }
+
+    // Verify that no passes are missing from the `declare_passes` invocation
+    #[cfg(debug_assertions)]
+    #[allow(rustc::diagnostic_outside_of_impl)]
+    #[allow(rustc::untranslatable_diagnostic)]
+    {
+        let used_passes: FxIndexSet<_> = passes.iter().map(|p| p.name()).collect();
+
+        let undeclared = used_passes.difference(&*crate::PASS_NAMES).collect::<Vec<_>>();
+        if let Some((name, rest)) = undeclared.split_first() {
+            let mut err =
+                tcx.dcx().struct_bug(format!("pass `{name}` is not declared in `PASS_NAMES`"));
+            for name in rest {
+                err.note(format!("pass `{name}` is also not declared in `PASS_NAMES`"));
+            }
+            err.emit();
+        }
+    }
+
     let prof_arg = tcx.sess.prof.enabled().then(|| format!("{:?}", body.source.def_id()));
 
     if !body.should_skip() {
diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl
index 6da387bbebc..8528a2e68c0 100644
--- a/compiler/rustc_monomorphize/messages.ftl
+++ b/compiler/rustc_monomorphize/messages.ftl
@@ -1,12 +1,19 @@
 monomorphize_abi_error_disabled_vector_type_call =
-  ABI error: this function call uses a vector type that requires the `{$required_feature}` target feature, which is not enabled in the caller
+  this function call uses a SIMD vector type that (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled in the caller
   .label = function called here
   .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`)
 monomorphize_abi_error_disabled_vector_type_def =
-  ABI error: this function definition uses a vector type that requires the `{$required_feature}` target feature, which is not enabled
+  this function definition uses a SIMD vector type that (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled
   .label = function defined here
   .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`)
 
+monomorphize_abi_error_unsupported_vector_type_call =
+  this function call uses a SIMD vector type that is not currently supported with the chosen ABI
+  .label = function called here
+monomorphize_abi_error_unsupported_vector_type_def =
+  this function definition uses a SIMD vector type that is not currently supported with the chosen ABI
+  .label = function defined here
+
 monomorphize_couldnt_dump_mono_stats =
     unexpected error occurred while dumping monomorphization stats: {$error}
 
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 85151e5f093..429e31b2c88 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -205,13 +205,8 @@
 //! this is not implemented however: a mono item will be produced
 //! regardless of whether it is actually needed or not.
 
-mod abi_check;
-mod move_check;
-
 use std::path::PathBuf;
 
-use move_check::MoveCheckState;
-use rustc_abi::Size;
 use rustc_data_structures::sync::{LRef, MTLock, par_for_each_in};
 use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_hir as hir;
@@ -228,15 +223,15 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::print::{shrunk_instance_name, with_no_trimmed_paths};
 use rustc_middle::ty::{
-    self, AssocKind, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt,
-    TypeFoldable, TypeVisitableExt, VtblEntry,
+    self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable,
+    TypeVisitableExt, VtblEntry,
 };
 use rustc_middle::util::Providers;
 use rustc_middle::{bug, span_bug};
 use rustc_session::Limit;
 use rustc_session::config::EntryFnType;
 use rustc_span::source_map::{Spanned, dummy_spanned, respan};
-use rustc_span::symbol::{Ident, sym};
+use rustc_span::symbol::sym;
 use rustc_span::{DUMMY_SP, Span};
 use tracing::{debug, instrument, trace};
 
@@ -612,8 +607,6 @@ struct MirUsedCollector<'a, 'tcx> {
     /// Note that this contains *not-monomorphized* items!
     used_mentioned_items: &'a mut UnordSet<MentionedItem<'tcx>>,
     instance: Instance<'tcx>,
-    visiting_call_terminator: bool,
-    move_check: move_check::MoveCheckState,
 }
 
 impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
@@ -760,13 +753,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
         };
 
         match terminator.kind {
-            mir::TerminatorKind::Call { ref func, ref args, ref fn_span, .. }
-            | mir::TerminatorKind::TailCall { ref func, ref args, ref fn_span } => {
+            mir::TerminatorKind::Call { ref func, .. }
+            | mir::TerminatorKind::TailCall { ref func, .. } => {
                 let callee_ty = func.ty(self.body, tcx);
                 // *Before* monomorphizing, record that we already handled this mention.
                 self.used_mentioned_items.insert(MentionedItem::Fn(callee_ty));
                 let callee_ty = self.monomorphize(callee_ty);
-                self.check_fn_args_move_size(callee_ty, args, *fn_span, location);
                 visit_fn_use(self.tcx, callee_ty, true, source, &mut self.used_items)
             }
             mir::TerminatorKind::Drop { ref place, .. } => {
@@ -826,14 +818,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
             push_mono_lang_item(self, reason.lang_item());
         }
 
-        self.visiting_call_terminator = matches!(terminator.kind, mir::TerminatorKind::Call { .. });
         self.super_terminator(terminator, location);
-        self.visiting_call_terminator = false;
-    }
-
-    fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
-        self.super_operand(operand, location);
-        self.check_operand_move_size(operand, location);
     }
 }
 
@@ -1183,20 +1168,6 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
     }
 }
 
-fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> Option<DefId> {
-    for impl_def_id in tcx.inherent_impls(def_id) {
-        if let Some(new) = tcx.associated_items(impl_def_id).find_by_name_and_kind(
-            tcx,
-            fn_ident,
-            AssocKind::Fn,
-            def_id,
-        ) {
-            return Some(new.def_id);
-        }
-    }
-    None
-}
-
 /// Scans the MIR in order to find function calls, closures, and drop-glue.
 ///
 /// Anything that's found is added to `output`. Furthermore the "mentioned items" of the MIR are returned.
@@ -1208,7 +1179,8 @@ fn collect_items_of_instance<'tcx>(
     mentioned_items: &mut MonoItems<'tcx>,
     mode: CollectionMode,
 ) {
-    tcx.ensure().check_feature_dependent_abi(instance);
+    // This item is getting monomorphized, do mono-time checks.
+    tcx.ensure().check_mono_item(instance);
 
     let body = tcx.instance_mir(instance.def);
     // Naively, in "used" collection mode, all functions get added to *both* `used_items` and
@@ -1228,8 +1200,6 @@ fn collect_items_of_instance<'tcx>(
         used_items,
         used_mentioned_items: &mut used_mentioned_items,
         instance,
-        visiting_call_terminator: false,
-        move_check: MoveCheckState::new(),
     };
 
     if mode == CollectionMode::UsedItems {
@@ -1626,5 +1596,4 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
 
 pub(crate) fn provide(providers: &mut Providers) {
     providers.hooks.should_codegen_locally = should_codegen_locally;
-    abi_check::provide(providers);
 }
diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs
index 5048a8d5d99..02865cad302 100644
--- a/compiler/rustc_monomorphize/src/errors.rs
+++ b/compiler/rustc_monomorphize/src/errors.rs
@@ -110,3 +110,17 @@ pub(crate) struct AbiErrorDisabledVectorTypeCall<'a> {
     pub span: Span,
     pub required_feature: &'a str,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(monomorphize_abi_error_unsupported_vector_type_def)]
+pub(crate) struct AbiErrorUnsupportedVectorTypeDef {
+    #[label]
+    pub span: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(monomorphize_abi_error_unsupported_vector_type_call)]
+pub(crate) struct AbiErrorUnsupportedVectorTypeCall {
+    #[label]
+    pub span: Span,
+}
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index e92e6978d0f..0cfc4371db5 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -16,6 +16,7 @@ use rustc_span::ErrorGuaranteed;
 
 mod collector;
 mod errors;
+mod mono_checks;
 mod partitioning;
 mod polymorphize;
 mod util;
@@ -47,4 +48,5 @@ fn custom_coerce_unsize_info<'tcx>(
 pub fn provide(providers: &mut Providers) {
     partitioning::provide(providers);
     polymorphize::provide(providers);
+    mono_checks::provide(providers);
 }
diff --git a/compiler/rustc_monomorphize/src/collector/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
index f1c57f1e997..d53595929e7 100644
--- a/compiler/rustc_monomorphize/src/collector/abi_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
@@ -1,9 +1,7 @@
 //! This module ensures that if a function's ABI requires a particular target feature,
 //! that target feature is enabled both on the callee and all callers.
 use rustc_hir::CRATE_HIR_ID;
-use rustc_middle::mir::visit::Visitor as MirVisitor;
-use rustc_middle::mir::{self, Location, traversal};
-use rustc_middle::query::Providers;
+use rustc_middle::mir::{self, traversal};
 use rustc_middle::ty::inherent::*;
 use rustc_middle::ty::{self, Instance, InstanceKind, ParamEnv, Ty, TyCtxt};
 use rustc_session::lint::builtin::ABI_UNSUPPORTED_VECTOR_TYPES;
@@ -12,7 +10,10 @@ use rustc_span::{DUMMY_SP, Span, Symbol};
 use rustc_target::abi::call::{FnAbi, PassMode};
 use rustc_target::abi::{BackendRepr, RegKind};
 
-use crate::errors::{AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef};
+use crate::errors::{
+    AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef,
+    AbiErrorUnsupportedVectorTypeCall, AbiErrorUnsupportedVectorTypeDef,
+};
 
 fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool {
     match mode {
@@ -25,11 +26,15 @@ fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool {
     }
 }
 
+/// Checks whether a certain function ABI is compatible with the target features currently enabled
+/// for a certain function.
+/// If not, `emit_err` is called, with `Some(feature)` if a certain feature should be enabled and
+/// with `None` if no feature is known that would make the ABI compatible.
 fn do_check_abi<'tcx>(
     tcx: TyCtxt<'tcx>,
     abi: &FnAbi<'tcx, Ty<'tcx>>,
     target_feature_def: DefId,
-    mut emit_err: impl FnMut(&'static str),
+    mut emit_err: impl FnMut(Option<&'static str>),
 ) {
     let Some(feature_def) = tcx.sess.target.features_for_correct_vector_abi() else {
         return;
@@ -42,7 +47,7 @@ fn do_check_abi<'tcx>(
             let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) {
                 Some((_, feature)) => feature,
                 None => {
-                    emit_err("<no available feature for this size>");
+                    emit_err(None);
                     continue;
                 }
             };
@@ -50,7 +55,7 @@ fn do_check_abi<'tcx>(
             if !tcx.sess.unstable_target_features.contains(&feature_sym)
                 && !codegen_attrs.target_features.iter().any(|x| x.name == feature_sym)
             {
-                emit_err(feature);
+                emit_err(Some(&feature));
             }
         }
     }
@@ -67,12 +72,21 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
     };
     do_check_abi(tcx, abi, instance.def_id(), |required_feature| {
         let span = tcx.def_span(instance.def_id());
-        tcx.emit_node_span_lint(
-            ABI_UNSUPPORTED_VECTOR_TYPES,
-            CRATE_HIR_ID,
-            span,
-            AbiErrorDisabledVectorTypeDef { span, required_feature },
-        );
+        if let Some(required_feature) = required_feature {
+            tcx.emit_node_span_lint(
+                ABI_UNSUPPORTED_VECTOR_TYPES,
+                CRATE_HIR_ID,
+                span,
+                AbiErrorDisabledVectorTypeDef { span, required_feature },
+            );
+        } else {
+            tcx.emit_node_span_lint(
+                ABI_UNSUPPORTED_VECTOR_TYPES,
+                CRATE_HIR_ID,
+                span,
+                AbiErrorUnsupportedVectorTypeDef { span },
+            );
+        }
     })
 }
 
@@ -111,52 +125,49 @@ fn check_call_site_abi<'tcx>(
         return;
     };
     do_check_abi(tcx, callee_abi, caller.def_id(), |required_feature| {
-        tcx.emit_node_span_lint(
-            ABI_UNSUPPORTED_VECTOR_TYPES,
-            CRATE_HIR_ID,
-            span,
-            AbiErrorDisabledVectorTypeCall { span, required_feature },
-        );
+        if let Some(required_feature) = required_feature {
+            tcx.emit_node_span_lint(
+                ABI_UNSUPPORTED_VECTOR_TYPES,
+                CRATE_HIR_ID,
+                span,
+                AbiErrorDisabledVectorTypeCall { span, required_feature },
+            );
+        } else {
+            tcx.emit_node_span_lint(
+                ABI_UNSUPPORTED_VECTOR_TYPES,
+                CRATE_HIR_ID,
+                span,
+                AbiErrorUnsupportedVectorTypeCall { span },
+            );
+        }
     });
 }
 
-struct MirCallesAbiCheck<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    body: &'a mir::Body<'tcx>,
-    instance: Instance<'tcx>,
-}
-
-impl<'a, 'tcx> MirVisitor<'tcx> for MirCallesAbiCheck<'a, 'tcx> {
-    fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, _: Location) {
+fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &mir::Body<'tcx>) {
+    // Check all function call terminators.
+    for (bb, _data) in traversal::mono_reachable(body, tcx, instance) {
+        let terminator = body.basic_blocks[bb].terminator();
         match terminator.kind {
             mir::TerminatorKind::Call { ref func, ref fn_span, .. }
             | mir::TerminatorKind::TailCall { ref func, ref fn_span, .. } => {
-                let callee_ty = func.ty(self.body, self.tcx);
-                let callee_ty = self.instance.instantiate_mir_and_normalize_erasing_regions(
-                    self.tcx,
+                let callee_ty = func.ty(body, tcx);
+                let callee_ty = instance.instantiate_mir_and_normalize_erasing_regions(
+                    tcx,
                     ty::ParamEnv::reveal_all(),
                     ty::EarlyBinder::bind(callee_ty),
                 );
-                check_call_site_abi(self.tcx, callee_ty, *fn_span, self.body.source.instance);
+                check_call_site_abi(tcx, callee_ty, *fn_span, body.source.instance);
             }
             _ => {}
         }
     }
 }
 
-fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
-    let body = tcx.instance_mir(instance.def);
-    let mut visitor = MirCallesAbiCheck { tcx, body, instance };
-    for (bb, data) in traversal::mono_reachable(body, tcx, instance) {
-        visitor.visit_basic_block_data(bb, data)
-    }
-}
-
-fn check_feature_dependent_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
+pub(crate) fn check_feature_dependent_abi<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    instance: Instance<'tcx>,
+    body: &'tcx mir::Body<'tcx>,
+) {
     check_instance_abi(tcx, instance);
-    check_callees_abi(tcx, instance);
-}
-
-pub(super) fn provide(providers: &mut Providers) {
-    *providers = Providers { check_feature_dependent_abi, ..*providers }
+    check_callees_abi(tcx, instance, body);
 }
diff --git a/compiler/rustc_monomorphize/src/mono_checks/mod.rs b/compiler/rustc_monomorphize/src/mono_checks/mod.rs
new file mode 100644
index 00000000000..1ecda824fb8
--- /dev/null
+++ b/compiler/rustc_monomorphize/src/mono_checks/mod.rs
@@ -0,0 +1,23 @@
+//! This implements a single query, `check_mono_fn`, that gets fired for each
+//! monomorphization of all functions. This lets us implement monomorphization-time
+//! checks in a way that is friendly to incremental compilation.
+
+use rustc_middle::query::Providers;
+use rustc_middle::ty::{Instance, TyCtxt};
+
+mod abi_check;
+mod move_check;
+
+fn check_mono_item<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
+    let body = tcx.instance_mir(instance.def);
+    abi_check::check_feature_dependent_abi(tcx, instance, body);
+    move_check::check_moves(tcx, instance, body);
+}
+
+pub(super) fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        check_mono_item,
+        skip_move_check_fns: move_check::skip_move_check_fns,
+        ..*providers
+    }
+}
diff --git a/compiler/rustc_monomorphize/src/collector/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
index b86ef1e7373..7f04bdf46f1 100644
--- a/compiler/rustc_monomorphize/src/collector/move_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs
@@ -1,38 +1,74 @@
+use rustc_abi::Size;
+use rustc_data_structures::fx::FxIndexSet;
+use rustc_hir::def_id::DefId;
+use rustc_middle::mir::visit::Visitor as MirVisitor;
+use rustc_middle::mir::{self, Location, traversal};
+use rustc_middle::ty::{self, AssocKind, Instance, Ty, TyCtxt, TypeFoldable};
+use rustc_session::Limit;
 use rustc_session::lint::builtin::LARGE_ASSIGNMENTS;
-use tracing::debug;
+use rustc_span::Span;
+use rustc_span::source_map::Spanned;
+use rustc_span::symbol::{Ident, sym};
+use tracing::{debug, trace};
 
-use super::*;
 use crate::errors::LargeAssignmentsLint;
 
-pub(super) struct MoveCheckState {
+struct MoveCheckVisitor<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    instance: Instance<'tcx>,
+    body: &'tcx mir::Body<'tcx>,
     /// Spans for move size lints already emitted. Helps avoid duplicate lints.
     move_size_spans: Vec<Span>,
-    /// Set of functions for which it is OK to move large data into.
-    skip_move_check_fns: Option<Vec<DefId>>,
 }
 
-impl MoveCheckState {
-    pub(super) fn new() -> Self {
-        MoveCheckState { move_size_spans: vec![], skip_move_check_fns: None }
+pub(crate) fn check_moves<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    instance: Instance<'tcx>,
+    body: &'tcx mir::Body<'tcx>,
+) {
+    let mut visitor = MoveCheckVisitor { tcx, instance, body, move_size_spans: vec![] };
+    for (bb, data) in traversal::mono_reachable(body, tcx, instance) {
+        visitor.visit_basic_block_data(bb, data)
     }
 }
 
-impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
-    pub(super) fn check_operand_move_size(
-        &mut self,
-        operand: &mir::Operand<'tcx>,
-        location: Location,
-    ) {
-        let limit = self.tcx.move_size_limit();
-        if limit.0 == 0 {
-            return;
+impl<'tcx> MirVisitor<'tcx> for MoveCheckVisitor<'tcx> {
+    fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
+        match terminator.kind {
+            mir::TerminatorKind::Call { ref func, ref args, ref fn_span, .. }
+            | mir::TerminatorKind::TailCall { ref func, ref args, ref fn_span } => {
+                let callee_ty = func.ty(self.body, self.tcx);
+                let callee_ty = self.monomorphize(callee_ty);
+                self.check_fn_args_move_size(callee_ty, args, *fn_span, location);
+            }
+            _ => {}
         }
 
-        // This function is called by visit_operand() which visits _all_
-        // operands, including TerminatorKind::Call operands. But if
-        // check_fn_args_move_size() has been called, the operands have already
-        // been visited. Do not visit them again.
-        if self.visiting_call_terminator {
+        // We deliberately do *not* visit the nested operands here, to avoid
+        // hitting `visit_operand` for function arguments.
+    }
+
+    fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
+        self.check_operand_move_size(operand, location);
+    }
+}
+
+impl<'tcx> MoveCheckVisitor<'tcx> {
+    fn monomorphize<T>(&self, value: T) -> T
+    where
+        T: TypeFoldable<TyCtxt<'tcx>>,
+    {
+        trace!("monomorphize: self.instance={:?}", self.instance);
+        self.instance.instantiate_mir_and_normalize_erasing_regions(
+            self.tcx,
+            ty::ParamEnv::reveal_all(),
+            ty::EarlyBinder::bind(value),
+        )
+    }
+
+    fn check_operand_move_size(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
+        let limit = self.tcx.move_size_limit();
+        if limit.0 == 0 {
             return;
         }
 
@@ -64,12 +100,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
         let ty::FnDef(def_id, _) = *callee_ty.kind() else {
             return;
         };
-        if self
-            .move_check
-            .skip_move_check_fns
-            .get_or_insert_with(|| build_skip_move_check_fns(self.tcx))
-            .contains(&def_id)
-        {
+        if self.tcx.skip_move_check_fns(()).contains(&def_id) {
             return;
         }
 
@@ -116,14 +147,12 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
         span: Span,
     ) {
         let source_info = self.body.source_info(location);
-        debug!(?source_info);
-        for reported_span in &self.move_check.move_size_spans {
+        for reported_span in &self.move_size_spans {
             if reported_span.overlaps(span) {
                 return;
             }
         }
         let lint_root = source_info.scope.lint_root(&self.body.source_scopes);
-        debug!(?lint_root);
         let Some(lint_root) = lint_root else {
             // This happens when the issue is in a function from a foreign crate that
             // we monomorphized in the current crate. We can't get a `HirId` for things
@@ -137,11 +166,25 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
             size: too_large_size.bytes(),
             limit: limit as u64,
         });
-        self.move_check.move_size_spans.push(span);
+        self.move_size_spans.push(span);
+    }
+}
+
+fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) -> Option<DefId> {
+    for impl_def_id in tcx.inherent_impls(def_id) {
+        if let Some(new) = tcx.associated_items(impl_def_id).find_by_name_and_kind(
+            tcx,
+            fn_ident,
+            AssocKind::Fn,
+            def_id,
+        ) {
+            return Some(new.def_id);
+        }
     }
+    None
 }
 
-fn build_skip_move_check_fns(tcx: TyCtxt<'_>) -> Vec<DefId> {
+pub(crate) fn skip_move_check_fns(tcx: TyCtxt<'_>, _: ()) -> FxIndexSet<DefId> {
     let fns = [
         (tcx.lang_items().owned_box(), "new"),
         (tcx.get_diagnostic_item(sym::Rc), "new"),
@@ -151,5 +194,5 @@ fn build_skip_move_check_fns(tcx: TyCtxt<'_>) -> Vec<DefId> {
         .filter_map(|(def_id, fn_name)| {
             def_id.and_then(|def_id| assoc_fn_of_type(tcx, def_id, Ident::from_str(fn_name)))
         })
-        .collect::<Vec<_>>()
+        .collect()
 }
diff --git a/compiler/rustc_next_trait_solver/src/delegate.rs b/compiler/rustc_next_trait_solver/src/delegate.rs
index f7fbfed5b8e..4ba54a2e0bf 100644
--- a/compiler/rustc_next_trait_solver/src/delegate.rs
+++ b/compiler/rustc_next_trait_solver/src/delegate.rs
@@ -29,10 +29,10 @@ pub trait SolverDelegate: Deref<Target = <Self as SolverDelegate>::Infcx> + Size
     // FIXME: Uplift the leak check into this crate.
     fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution>;
 
-    fn try_const_eval_resolve(
+    fn evaluate_const(
         &self,
         param_env: <Self::Interner as Interner>::ParamEnv,
-        unevaluated: ty::UnevaluatedConst<Self::Interner>,
+        uv: ty::UnevaluatedConst<Self::Interner>,
     ) -> Option<<Self::Interner as Interner>::Const>;
 
     // FIXME: This only is here because `wf::obligations` is in `rustc_trait_selection`!
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 8685896715e..979a3794748 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
@@ -1001,12 +1001,12 @@ where
     // Try to evaluate a const, or return `None` if the const is too generic.
     // This doesn't mean the const isn't evaluatable, though, and should be treated
     // as an ambiguity rather than no-solution.
-    pub(super) fn try_const_eval_resolve(
+    pub(super) fn evaluate_const(
         &self,
         param_env: I::ParamEnv,
-        unevaluated: ty::UnevaluatedConst<I>,
+        uv: ty::UnevaluatedConst<I>,
     ) -> Option<I::Const> {
-        self.delegate.try_const_eval_resolve(param_env, unevaluated)
+        self.delegate.evaluate_const(param_env, uv)
     }
 
     pub(super) fn is_transmutable(
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index 6793779b205..5c54656cc59 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -143,7 +143,7 @@ where
     ) -> QueryResult<I> {
         match ct.kind() {
             ty::ConstKind::Unevaluated(uv) => {
-                // We never return `NoSolution` here as `try_const_eval_resolve` emits an
+                // We never return `NoSolution` here as `evaluate_const` emits an
                 // error itself when failing to evaluate, so emitting an additional fulfillment
                 // error in that case is unnecessary noise. This may change in the future once
                 // evaluation failures are allowed to impact selection, e.g. generic const
@@ -151,7 +151,7 @@ where
 
                 // FIXME(generic_const_exprs): Implement handling for generic
                 // const expressions here.
-                if let Some(_normalized) = self.try_const_eval_resolve(param_env, uv) {
+                if let Some(_normalized) = self.evaluate_const(param_env, uv) {
                     self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
                 } else {
                     self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs
index 5d5597429da..8ad0bf5cdf9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/anon_const.rs
@@ -14,7 +14,7 @@ where
         &mut self,
         goal: Goal<I, ty::NormalizesTo<I>>,
     ) -> QueryResult<I> {
-        if let Some(normalized_const) = self.try_const_eval_resolve(
+        if let Some(normalized_const) = self.evaluate_const(
             goal.param_env,
             ty::UnevaluatedConst::new(goal.predicate.alias.def_id, goal.predicate.alias.args),
         ) {
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 7f114013320..3546e5b0f04 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -683,7 +683,9 @@ impl<'a> Parser<'a> {
             })
         {
             self.bump();
-            self.dcx().emit_err(RemoveLet { span: lo });
+            // Trim extra space after the `let`
+            let span = lo.with_hi(self.token.span.lo());
+            self.dcx().emit_err(RemoveLet { span });
             lo = self.token.span;
         }
 
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index 92684505ab0..decaecd2682 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -12,7 +12,7 @@ use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, Toke
 use rustc_ast::{self as ast, PatKind, visit};
 use rustc_ast_pretty::pprust::item_to_string;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::emitter::HumanEmitter;
+use rustc_errors::emitter::{HumanEmitter, OutputTheme};
 use rustc_errors::{DiagCtxt, MultiSpan, PResult};
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::{FilePathMapping, SourceMap};
@@ -36,16 +36,17 @@ fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> {
     ))
 }
 
-fn create_test_handler() -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
+fn create_test_handler(theme: OutputTheme) -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
     let output = Arc::new(Mutex::new(Vec::new()));
     let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
     let fallback_bundle = rustc_errors::fallback_fluent_bundle(
         vec![crate::DEFAULT_LOCALE_RESOURCE, crate::DEFAULT_LOCALE_RESOURCE],
         false,
     );
-    let emitter = HumanEmitter::new(Box::new(Shared { data: output.clone() }), fallback_bundle)
+    let mut emitter = HumanEmitter::new(Box::new(Shared { data: output.clone() }), fallback_bundle)
         .sm(Some(source_map.clone()))
         .diagnostic_width(Some(140));
+    emitter = emitter.theme(theme);
     let dcx = DiagCtxt::new(Box::new(emitter));
     (dcx, source_map, output)
 }
@@ -69,7 +70,7 @@ fn with_expected_parse_error<T, F>(source_str: &str, expected_output: &str, f: F
 where
     F: for<'a> FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
 {
-    let (handler, source_map, output) = create_test_handler();
+    let (handler, source_map, output) = create_test_handler(OutputTheme::Ascii);
     let psess = ParseSess::with_dcx(handler, source_map);
     let mut p = string_to_parser(&psess, source_str.to_string());
     let result = f(&mut p);
@@ -189,34 +190,55 @@ impl<T: Write> Write for Shared<T> {
 }
 
 #[allow(rustc::untranslatable_diagnostic)] // no translation needed for tests
-fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) {
+fn test_harness(
+    file_text: &str,
+    span_labels: Vec<SpanLabel>,
+    notes: Vec<(Option<(Position, Position)>, &'static str)>,
+    expected_output_ascii: &str,
+    expected_output_unicode: &str,
+) {
     create_default_session_globals_then(|| {
-        let (dcx, source_map, output) = create_test_handler();
-        source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned());
-
-        let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end);
-        let mut msp = MultiSpan::from_span(primary_span);
-        for span_label in span_labels {
-            let span = make_span(&file_text, &span_label.start, &span_label.end);
-            msp.push_span_label(span, span_label.label);
-            println!("span: {:?} label: {:?}", span, span_label.label);
-            println!("text: {:?}", source_map.span_to_snippet(span));
-        }
+        for (theme, expected_output) in [
+            (OutputTheme::Ascii, expected_output_ascii),
+            (OutputTheme::Unicode, expected_output_unicode),
+        ] {
+            let (dcx, source_map, output) = create_test_handler(theme);
+            source_map
+                .new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned());
+
+            let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end);
+            let mut msp = MultiSpan::from_span(primary_span);
+            for span_label in &span_labels {
+                let span = make_span(&file_text, &span_label.start, &span_label.end);
+                msp.push_span_label(span, span_label.label);
+                println!("span: {:?} label: {:?}", span, span_label.label);
+                println!("text: {:?}", source_map.span_to_snippet(span));
+            }
 
-        dcx.handle().span_err(msp, "foo");
+            let mut err = dcx.handle().struct_span_err(msp, "foo");
+            for (position, note) in &notes {
+                if let Some((start, end)) = position {
+                    let span = make_span(&file_text, &start, &end);
+                    err.span_note(span, *note);
+                } else {
+                    err.note(*note);
+                }
+            }
+            err.emit();
 
-        assert!(
-            expected_output.chars().next() == Some('\n'),
-            "expected output should begin with newline"
-        );
-        let expected_output = &expected_output[1..];
+            assert!(
+                expected_output.chars().next() == Some('\n'),
+                "expected output should begin with newline"
+            );
+            let expected_output = &expected_output[1..];
 
-        let bytes = output.lock().unwrap();
-        let actual_output = str::from_utf8(&bytes).unwrap();
-        println!("expected output:\n------\n{}------", expected_output);
-        println!("actual output:\n------\n{}------", actual_output);
+            let bytes = output.lock().unwrap();
+            let actual_output = str::from_utf8(&bytes).unwrap();
+            println!("expected output:\n------\n{}------", expected_output);
+            println!("actual output:\n------\n{}------", actual_output);
 
-        assert!(expected_output == actual_output)
+            assert!(expected_output == actual_output)
+        }
     })
 }
 
@@ -253,6 +275,7 @@ fn foo() {
             end: Position { string: "}", count: 1 },
             label: "test",
         }],
+        vec![],
         r#"
 error: foo
  --> test.rs:2:10
@@ -263,6 +286,16 @@ error: foo
   | |_^ test
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:2:10
+  │
+2 │   fn foo() {
+  │ ┏━━━━━━━━━━┛
+3 │ ┃ }
+  ╰╴┗━┛ test
+
+"#,
     );
 }
 
@@ -280,6 +313,7 @@ fn foo() {
             end: Position { string: "}", count: 1 },
             label: "test",
         }],
+        vec![],
         r#"
 error: foo
  --> test.rs:2:10
@@ -291,6 +325,17 @@ error: foo
   | |___^ test
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:2:10
+  │
+2 │   fn foo() {
+  │ ┏━━━━━━━━━━┛
+  ‡ ┃
+5 │ ┃   }
+  ╰╴┗━━━┛ test
+
+"#,
     );
 }
 #[test]
@@ -315,6 +360,7 @@ fn foo() {
                 label: "`Y` is a good letter too",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -329,6 +375,20 @@ error: foo
   |       `X` is a good letter
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │      X0 Y0
+  │ ┏━━━━┛  │
+  │ ┃┌──────┘
+4 │ ┃│   X1 Y1
+5 │ ┃│   X2 Y2
+  │ ┃└────╿──┘ `Y` is a good letter too
+  │ ┗━━━━━┥
+  ╰╴      `X` is a good letter
+
+"#,
     );
 }
 
@@ -353,6 +413,7 @@ fn foo() {
                 label: "`Y` is a good letter too",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -366,6 +427,72 @@ error: foo
   |       `Y` is a good letter too
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │      X0 Y0
+  │ ┏━━━━┛  │
+  │ ┃┌──────┘
+4 │ ┃│   Y1 X1
+  │ ┗│━━━━│━━┛ `X` is a good letter
+  │  └────┤
+  ╰╴      `Y` is a good letter too
+
+"#,
+    );
+}
+
+#[test]
+fn multiline_and_normal_overlap() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![
+            SpanLabel {
+                start: Position { string: "Y0", count: 1 },
+                end: Position { string: "X2", count: 1 },
+                label: "`X` is a good letter",
+            },
+            SpanLabel {
+                start: Position { string: "X0", count: 1 },
+                end: Position { string: "Y0", count: 1 },
+                label: "`Y` is a good letter too",
+            },
+        ],
+        vec![],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |     X0 Y0 Z0
+  |  ___---^-
+  | |   |
+  | |   `Y` is a good letter too
+4 | |   X1 Y1 Z1
+5 | |   X2 Y2 Z2
+  | |____^ `X` is a good letter
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │     X0 Y0 Z0
+  │ ┏━━━┬──┛─
+  │ ┃   │
+  │ ┃   `Y` is a good letter too
+4 │ ┃   X1 Y1 Z1
+5 │ ┃   X2 Y2 Z2
+  ╰╴┗━━━━┛ `X` is a good letter
+
+"#,
     );
 }
 
@@ -392,6 +519,7 @@ fn foo() {
                 label: "`Y` is a good letter too",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:6
@@ -406,6 +534,789 @@ error: foo
   |  |____- `Y` is a good letter too
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │      X0 Y0 Z0
+  │ ┏━━━━━━━┛
+4 │ ┃    X1 Y1 Z1
+  │ ┃┌─────────┘
+5 │ ┃│   X2 Y2 Z2
+  │ ┗│━━━━┛ `X` is a good letter
+6 │  │   X3 Y3 Z3
+  ╰╴ └────┘ `Y` is a good letter too
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_1() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![(None, "bar")],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+  = note: bar
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  │
+  ╰ note: bar
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_2() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![(None, "bar"), (None, "qux")],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+  = note: bar
+  = note: qux
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  │
+  ├ note: bar
+  ╰ note: qux
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_3() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![(None, "bar"), (None, "baz"), (None, "qux")],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+  = note: bar
+  = note: baz
+  = note: qux
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  │
+  ├ note: bar
+  ├ note: baz
+  ╰ note: qux
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_1() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![(
+            Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+            "bar",
+        )],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+note: bar
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  ╰╴
+note: bar
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_2() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "bar",
+            ),
+            (
+                Some((Position { string: "X2", count: 1 }, Position { string: "Y2", count: 1 })),
+                "qux",
+            ),
+        ],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+note: bar
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+note: qux
+ --> test.rs:5:3
+  |
+5 |   X2 Y2 Z2
+  |   ^^^^^
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  ╰╴
+note: bar
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+note: qux
+  ╭▸ test.rs:5:3
+  │
+5 │   X2 Y2 Z2
+  ╰╴  ━━━━━
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_3() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "bar",
+            ),
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "baz",
+            ),
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "qux",
+            ),
+        ],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+note: bar
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+note: baz
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+note: qux
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  ╰╴
+note: bar
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+note: baz
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+note: qux
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_4() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "bar",
+            ),
+            (None, "qux"),
+        ],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+note: bar
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+  = note: qux
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  ╰╴
+note: bar
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  │   ━━━━━━━━
+  ╰ note: qux
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_5() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![
+            (None, "bar"),
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "qux",
+            ),
+        ],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+  = note: bar
+note: qux
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  │
+  ╰ note: bar
+note: qux
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_6() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![
+            (None, "bar"),
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "baz",
+            ),
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "qux",
+            ),
+        ],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+  = note: bar
+note: baz
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+note: qux
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  │
+  ╰ note: bar
+note: baz
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+note: qux
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_7() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z3", count: 1 })),
+                "bar",
+            ),
+            (None, "baz"),
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "qux",
+            ),
+        ],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+note: bar
+ --> test.rs:4:3
+  |
+4 | /   X1 Y1 Z1
+5 | |   X2 Y2 Z2
+6 | |   X3 Y3 Z3
+  | |__________^
+  = note: baz
+note: qux
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  ╰╴
+note: bar
+  ╭▸ test.rs:4:3
+  │
+4 │ ┏   X1 Y1 Z1
+5 │ ┃   X2 Y2 Z2
+6 │ ┃   X3 Y3 Z3
+  │ ┗━━━━━━━━━━┛
+  ╰ note: baz
+note: qux
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_8() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "bar",
+            ),
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "baz",
+            ),
+            (None, "qux"),
+        ],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+note: bar
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+note: baz
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+  = note: qux
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  ╰╴
+note: bar
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+note: baz
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  │   ━━━━━━━━
+  ╰ note: qux
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_9() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![
+            (None, "bar"),
+            (None, "baz"),
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "qux",
+            ),
+        ],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+  = note: bar
+  = note: baz
+note: qux
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  │
+  ├ note: bar
+  ╰ note: baz
+note: qux
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  ╰╴  ━━━━━━━━
+
+"#,
+    );
+}
+
+#[test]
+fn different_note_spanned_10() {
+    test_harness(
+        r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "Y0", count: 1 },
+            end: Position { string: "Z0", count: 1 },
+            label: "`X` is a good letter",
+        }],
+        vec![
+            (
+                Some((Position { string: "X1", count: 1 }, Position { string: "Z1", count: 1 })),
+                "bar",
+            ),
+            (None, "baz"),
+            (None, "qux"),
+        ],
+        r#"
+error: foo
+ --> test.rs:3:6
+  |
+3 |   X0 Y0 Z0
+  |      ^^^^^ `X` is a good letter
+  |
+note: bar
+ --> test.rs:4:3
+  |
+4 |   X1 Y1 Z1
+  |   ^^^^^^^^
+  = note: baz
+  = note: qux
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │   X0 Y0 Z0
+  │      ━━━━━ `X` is a good letter
+  ╰╴
+note: bar
+  ╭▸ test.rs:4:3
+  │
+4 │   X1 Y1 Z1
+  │   ━━━━━━━━
+  ├ note: baz
+  ╰ note: qux
+
+"#,
     );
 }
 
@@ -436,6 +1347,7 @@ fn foo() {
                 label: "`Z` label",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -452,6 +1364,22 @@ error: foo
   |        `X` is a good letter
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │       X0 Y0 Z0
+  │ ┏━━━━━┛  │  │
+  │ ┃┌───────┘  │
+  │ ┃│┌─────────┘
+4 │ ┃││   X1 Y1 Z1
+5 │ ┃││   X2 Y2 Z2
+  │ ┃│└────╿──│──┘ `Z` label
+  │ ┃└─────│──┤
+  │ ┗━━━━━━┥  `Y` is a good letter too
+  ╰╴       `X` is a good letter
+
+"#,
     );
 }
 
@@ -482,6 +1410,7 @@ fn foo() {
                 label: "`Z` label",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -496,6 +1425,20 @@ error: foo
   |      `Z` label
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │ ┏   X0 Y0 Z0
+4 │ ┃   X1 Y1 Z1
+5 │ ┃   X2 Y2 Z2
+  │ ┃    ╿
+  │ ┃    │
+  │ ┃    `X` is a good letter
+  │ ┗━━━━`Y` is a good letter too
+  ╰╴     `Z` label
+
+"#,
     );
 }
 
@@ -527,6 +1470,7 @@ fn foo() {
                 label: "`Z`",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:6
@@ -545,6 +1489,24 @@ error: foo
   |  |_______- `Z`
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │      X0 Y0 Z0
+  │ ┏━━━━━━━┛
+4 │ ┃    X1 Y1 Z1
+  │ ┃┌────╿─┘
+  │ ┗│━━━━┥
+  │  │    `X` is a good letter
+5 │  │   X2 Y2 Z2
+  │  └───│──────┘ `Y` is a good letter too
+  │  ┌───┘
+  │  │
+6 │  │   X3 Y3 Z3
+  ╰╴ └───────┘ `Z`
+
+"#,
     );
 }
 
@@ -571,6 +1533,7 @@ fn foo() {
                 label: "`Y` is a good letter too",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -584,6 +1547,19 @@ error: foo
   | |__________- `Y` is a good letter too
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │ ┏   X0 Y0 Z0
+4 │ ┃   X1 Y1 Z1
+  │ ┗━━━━┛ `X` is a good letter
+5 │     X2 Y2 Z2
+  │ ┌──────┘
+6 │ │   X3 Y3 Z3
+  ╰╴└──────────┘ `Y` is a good letter too
+
+"#,
     );
 }
 
@@ -610,6 +1586,7 @@ fn foo() {
                 label: "`Y` is a good letter too",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:6
@@ -625,6 +1602,21 @@ error: foo
   |  |__________- `Y` is a good letter too
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:6
+  │
+3 │      X0 Y0 Z0
+  │ ┏━━━━━━━┛
+4 │ ┃    X1 Y1 Z1
+  │ ┃┌────╿────┘
+  │ ┗│━━━━┥
+  │  │    `X` is a good letter
+5 │  │   X2 Y2 Z2
+6 │  │   X3 Y3 Z3
+  ╰╴ └──────────┘ `Y` is a good letter too
+
+"#,
     );
 }
 
@@ -653,6 +1645,7 @@ fn foo() {
                 label: "",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:7
@@ -661,6 +1654,57 @@ error: foo
   |   ----^^^^-^^-- `a` is a good letter
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:7
+  │
+3 │   a { b { c } d }
+  ╰╴  ────━━━━─━━── `a` is a good letter
+
+"#,
+    );
+}
+
+#[test]
+fn multiline_notes() {
+    test_harness(
+        r#"
+fn foo() {
+  a { b { c } d }
+}
+"#,
+        vec![SpanLabel {
+            start: Position { string: "a", count: 1 },
+            end: Position { string: "d", count: 1 },
+            label: "`a` is a good letter",
+        }],
+        vec![(None, "foo\nbar"), (None, "foo\nbar")],
+        r#"
+error: foo
+ --> test.rs:3:3
+  |
+3 |   a { b { c } d }
+  |   ^^^^^^^^^^^^^ `a` is a good letter
+  |
+  = note: foo
+          bar
+  = note: foo
+          bar
+
+"#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │   a { b { c } d }
+  │   ━━━━━━━━━━━━━ `a` is a good letter
+  │
+  ├ note: foo
+  │       bar
+  ╰ note: foo
+          bar
+
+"#,
     );
 }
 
@@ -684,6 +1728,7 @@ fn foo() {
                 label: "",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -692,6 +1737,14 @@ error: foo
   |   ^^^^-------^^ `a` is a good letter
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │   a { b { c } d }
+  ╰╴  ━━━━───────━━ `a` is a good letter
+
+"#,
     );
 }
 
@@ -720,6 +1773,7 @@ fn foo() {
                 label: "",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:7
@@ -730,6 +1784,16 @@ error: foo
   |       `b` is a good letter
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:7
+  │
+3 │   a { b { c } d }
+  │   ────┯━━━─━━──
+  │       │
+  ╰╴      `b` is a good letter
+
+"#,
     );
 }
 
@@ -753,6 +1817,7 @@ fn foo() {
                 label: "`b` is a good letter",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -763,6 +1828,16 @@ error: foo
   |       `b` is a good letter
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │   a { b { c } d }
+  │   ━━━━┬──────━━
+  │       │
+  ╰╴      `b` is a good letter
+
+"#,
     );
 }
 
@@ -786,6 +1861,7 @@ fn foo() {
                 label: "",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -796,6 +1872,16 @@ error: foo
   |   `a` is a good letter
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │   a  bc  d
+  │   ┯━━━────
+  │   │
+  ╰╴  `a` is a good letter
+
+"#,
     );
 }
 
@@ -819,6 +1905,7 @@ fn foo() {
                 label: "",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -827,6 +1914,14 @@ error: foo
   |   ^^^^-------^^
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │   a { b { c } d }
+  ╰╴  ━━━━───────━━
+
+"#,
     );
 }
 
@@ -855,6 +1950,7 @@ fn foo() {
                 label: "",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:7
@@ -863,6 +1959,14 @@ error: foo
   |   ----^^^^-^^--
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:7
+  │
+3 │   a { b { c } d }
+  ╰╴  ────━━━━─━━──
+
+"#,
     );
 }
 
@@ -886,6 +1990,7 @@ fn foo() {
                 label: "`b` is a good letter",
             },
         ],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -897,6 +2002,17 @@ error: foo
   |   `a` is a good letter
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │   a { b { c } d }
+  │   ┯━━━┬──────━━
+  │   │   │
+  │   │   `b` is a good letter
+  ╰╴  `a` is a good letter
+
+"#,
     );
 }
 
@@ -913,6 +2029,7 @@ fn foo() {
             end: Position { string: "d", count: 1 },
             label: "`a` is a good letter",
         }],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -921,6 +2038,14 @@ error: foo
   |   ^^^^^^^^^^^^^ `a` is a good letter
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │   a { b { c } d }
+  ╰╴  ━━━━━━━━━━━━━ `a` is a good letter
+
+"#,
     );
 }
 
@@ -937,6 +2062,7 @@ fn foo() {
             end: Position { string: "d", count: 1 },
             label: "",
         }],
+        vec![],
         r#"
 error: foo
  --> test.rs:3:3
@@ -945,6 +2071,14 @@ error: foo
   |   ^^^^^^^^^^^^^
 
 "#,
+        r#"
+error: foo
+  ╭▸ test.rs:3:3
+  │
+3 │   a { b { c } d }
+  ╰╴  ━━━━━━━━━━━━━
+
+"#,
     );
 }
 
@@ -981,6 +2115,7 @@ fn foo() {
                 label: "`Y` is a good letter too",
             },
         ],
+        vec![],
         r#"
 error: foo
   --> test.rs:3:6
@@ -1000,6 +2135,25 @@ error: foo
    |  |__________- `Y` is a good letter too
 
 "#,
+        r#"
+error: foo
+   ╭▸ test.rs:3:6
+   │
+3  │      X0 Y0 Z0
+   │ ┏━━━━━━━┛
+4  │ ┃    X1 Y1 Z1
+   │ ┃┌────╿────┘
+   │ ┗│━━━━┥
+   │  │    `X` is a good letter
+5  │  │ 1
+6  │  │ 2
+7  │  │ 3
+   ‡  │
+15 │  │   X2 Y2 Z2
+16 │  │   X3 Y3 Z3
+   ╰╴ └──────────┘ `Y` is a good letter too
+
+"#,
     );
 }
 
@@ -1036,6 +2190,7 @@ fn foo() {
                 label: "`Z` is a good letter too",
             },
         ],
+        vec![],
         r#"
 error: foo
   --> test.rs:3:6
@@ -1058,6 +2213,28 @@ error: foo
    | |________^ `Y` is a good letter
 
 "#,
+        r#"
+error: foo
+   ╭▸ test.rs:3:6
+   │
+3  │      X0 Y0 Z0
+   │ ┏━━━━━━━┛
+4  │ ┃  1
+5  │ ┃  2
+6  │ ┃  3
+7  │ ┃    X1 Y1 Z1
+   │ ┃┌─────────┘
+8  │ ┃│ 4
+9  │ ┃│ 5
+10 │ ┃│ 6
+11 │ ┃│   X2 Y2 Z2
+   │ ┃└──────────┘ `Z` is a good letter too
+   ‡ ┃
+15 │ ┃  10
+16 │ ┃    X3 Y3 Z3
+   ╰╴┗━━━━━━━━┛ `Y` is a good letter
+
+"#,
     );
 }
 
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 6f0bcf5c3f0..08098ae7f6c 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -234,6 +234,9 @@ passes_doc_masked_only_extern_crate =
 passes_doc_rust_logo =
     the `#[doc(rust_logo)]` attribute is used for Rust branding
 
+passes_doc_search_unbox_invalid =
+    `#[doc(search_unbox)]` should be used on generic structs and enums
+
 passes_doc_test_literal = `#![doc(test(...)]` does not take a literal
 
 passes_doc_test_takes_list =
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 64a527ef106..836511325f4 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -16,8 +16,8 @@ use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, B
 use rustc_hir::def_id::LocalModDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{
-    self as hir, self, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId, Item, ItemKind,
-    MethodKind, Safety, Target, TraitItem,
+    self as hir, self, AssocItemKind, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId,
+    Item, ItemKind, MethodKind, Safety, Target, TraitItem,
 };
 use rustc_macros::LintDiagnostic;
 use rustc_middle::hir::nested_filter;
@@ -937,6 +937,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
+    fn check_doc_search_unbox(&self, meta: &MetaItemInner, hir_id: HirId) {
+        let hir::Node::Item(item) = self.tcx.hir_node(hir_id) else {
+            self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });
+            return;
+        };
+        match item.kind {
+            ItemKind::Enum(_, generics) | ItemKind::Struct(_, generics)
+                if generics.params.len() != 0 => {}
+            ItemKind::Trait(_, _, generics, _, items)
+                if generics.params.len() != 0
+                    || items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {}
+            _ => {
+                self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });
+            }
+        }
+    }
+
     /// Checks `#[doc(inline)]`/`#[doc(no_inline)]` attributes.
     ///
     /// A doc inlining attribute is invalid if it is applied to a non-`use` item, or
@@ -1149,6 +1166,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             }
                         }
 
+                        sym::search_unbox => {
+                            if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
+                                self.check_doc_search_unbox(meta, hir_id);
+                            }
+                        }
+
                         sym::test => {
                             if self.check_attr_crate_level(attr, meta, hir_id) {
                                 self.check_test_attr(meta, hir_id);
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 70c92f0144c..2d1734c0314 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -245,6 +245,13 @@ pub(crate) struct DocKeywordOnlyImpl {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_doc_search_unbox_invalid)]
+pub(crate) struct DocSearchUnboxInvalid {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_doc_inline_conflict)]
 #[help]
 pub(crate) struct DocKeywordConflict {
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index cd47c8ece60..4a793f1875e 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -16,7 +16,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalModDefId};
 use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{Constness, FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
+use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::lib_features::{FeatureStability, LibFeatures};
 use rustc_middle::middle::privacy::EffectiveVisibilities;
@@ -149,6 +149,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             if let Some(stab) = self.parent_stab {
                 if inherit_deprecation.yes() && stab.is_unstable() {
                     self.index.stab_map.insert(def_id, stab);
+                    if fn_sig.is_some_and(|s| s.header.is_const()) {
+                        let const_stab =
+                            attr::unmarked_crate_const_stab(self.tcx.sess, attrs, stab);
+                        self.index.const_stab_map.insert(def_id, const_stab);
+                    }
                 }
             }
 
@@ -161,68 +166,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             return;
         }
 
+        // # Regular and body stability
+
         let stab = attr::find_stability(self.tcx.sess, attrs, item_sp);
-        let const_stab = attr::find_const_stability(
-            self.tcx.sess,
-            attrs,
-            item_sp,
-            fn_sig.is_some_and(|s| s.header.is_const()),
-        );
         let body_stab = attr::find_body_stability(self.tcx.sess, attrs);
 
-        // If the current node is a function with const stability attributes (directly given or
-        // implied), check if the function/method is const or the parent impl block is const.
-        if let Some(fn_sig) = fn_sig
-            && !fn_sig.header.is_const()
-            && const_stab.is_some()
-        {
-            self.tcx.dcx().emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span });
-        }
-
-        // If this is marked const *stable*, it must also be regular-stable.
-        if let Some((const_stab, const_span)) = const_stab
-            && let Some(fn_sig) = fn_sig
-            && const_stab.is_const_stable()
-            && !stab.is_some_and(|(s, _)| s.is_stable())
-        {
-            self.tcx
-                .dcx()
-                .emit_err(errors::ConstStableNotStable { fn_sig_span: fn_sig.span, const_span });
-        }
-
-        // Stable *language* features shouldn't be used as unstable library features.
-        // (Not doing this for stable library features is checked by tidy.)
-        if let Some((
-            ConstStability { level: Unstable { .. }, feature: Some(feature), .. },
-            const_span,
-        )) = const_stab
-        {
-            if ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some() {
-                self.tcx.dcx().emit_err(errors::UnstableAttrForAlreadyStableFeature {
-                    span: const_span,
-                    item_sp,
-                });
-            }
-        }
-
-        let const_stab = const_stab.map(|(const_stab, _span)| {
-            self.index.const_stab_map.insert(def_id, const_stab);
-            const_stab
-        });
-
-        // `impl const Trait for Type` items forward their const stability to their
-        // immediate children.
-        // FIXME(const_trait_impl): how is this supposed to interact with `#[rustc_const_stable_indirect]`?
-        // Currently, once that is set, we do not inherit anything from the parent any more.
-        if const_stab.is_none() {
-            debug!("annotate: const_stab not found, parent = {:?}", self.parent_const_stab);
-            if let Some(parent) = self.parent_const_stab {
-                if parent.is_const_unstable() {
-                    self.index.const_stab_map.insert(def_id, parent);
-                }
-            }
-        }
-
         if let Some((depr, span)) = &depr
             && depr.is_since_rustc_version()
             && stab.is_none()
@@ -289,15 +237,6 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
                 self.index.implications.insert(implied_by, feature);
             }
 
-            if let Some(ConstStability {
-                level: Unstable { implied_by: Some(implied_by), .. },
-                feature,
-                ..
-            }) = const_stab
-            {
-                self.index.implications.insert(implied_by, feature.unwrap());
-            }
-
             self.index.stab_map.insert(def_id, stab);
             stab
         });
@@ -311,6 +250,91 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             }
         }
 
+        let final_stab = self.index.stab_map.get(&def_id);
+
+        // # Const stability
+
+        let const_stab = attr::find_const_stability(self.tcx.sess, attrs, item_sp);
+
+        // If the current node is a function with const stability attributes (directly given or
+        // implied), check if the function/method is const.
+        if let Some(fn_sig) = fn_sig
+            && !fn_sig.header.is_const()
+            && const_stab.is_some()
+        {
+            self.tcx.dcx().emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span });
+        }
+
+        // If this is marked const *stable*, it must also be regular-stable.
+        if let Some((const_stab, const_span)) = const_stab
+            && let Some(fn_sig) = fn_sig
+            && const_stab.is_const_stable()
+            && !stab.is_some_and(|s| s.is_stable())
+        {
+            self.tcx
+                .dcx()
+                .emit_err(errors::ConstStableNotStable { fn_sig_span: fn_sig.span, const_span });
+        }
+
+        // Stable *language* features shouldn't be used as unstable library features.
+        // (Not doing this for stable library features is checked by tidy.)
+        if let Some((ConstStability { level: Unstable { .. }, feature, .. }, const_span)) =
+            const_stab
+        {
+            if ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some() {
+                self.tcx.dcx().emit_err(errors::UnstableAttrForAlreadyStableFeature {
+                    span: const_span,
+                    item_sp,
+                });
+            }
+        }
+
+        // After checking the immediate attributes, get rid of the span and compute implied
+        // const stability: inherit feature gate from regular stability.
+        let mut const_stab = const_stab.map(|(stab, _span)| stab);
+
+        // If this is a const fn but not annotated with stability markers, see if we can inherit regular stability.
+        if fn_sig.is_some_and(|s| s.header.is_const())  && const_stab.is_none() &&
+            // We only ever inherit unstable features.
+            let Some(inherit_regular_stab) =
+                final_stab.filter(|s| s.is_unstable())
+        {
+            const_stab = Some(ConstStability {
+                // We subject these implicitly-const functions to recursive const stability.
+                const_stable_indirect: true,
+                promotable: false,
+                level: inherit_regular_stab.level,
+                feature: inherit_regular_stab.feature,
+            });
+        }
+
+        // Now that everything is computed, insert it into the table.
+        const_stab.inspect(|const_stab| {
+            self.index.const_stab_map.insert(def_id, *const_stab);
+        });
+
+        if let Some(ConstStability {
+            level: Unstable { implied_by: Some(implied_by), .. },
+            feature,
+            ..
+        }) = const_stab
+        {
+            self.index.implications.insert(implied_by, feature);
+        }
+
+        // `impl const Trait for Type` items forward their const stability to their
+        // immediate children.
+        // FIXME(const_trait_impl): how is this supposed to interact with `#[rustc_const_stable_indirect]`?
+        // Currently, once that is set, we do not inherit anything from the parent any more.
+        if const_stab.is_none() {
+            debug!("annotate: const_stab not found, parent = {:?}", self.parent_const_stab);
+            if let Some(parent) = self.parent_const_stab {
+                if parent.is_const_unstable() {
+                    self.index.const_stab_map.insert(def_id, parent);
+                }
+            }
+        }
+
         self.recurse_with_stability_attrs(
             depr.map(|(d, _)| DeprecationEntry::local(d, def_id)),
             stab,
@@ -565,13 +589,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
         }
     }
 
-    fn check_missing_or_wrong_const_stability(&self, def_id: LocalDefId, span: Span) {
-        // The visitor runs for "unstable-if-unmarked" crates, but we don't yet support
-        // that on the const side.
-        if !self.tcx.features().staged_api() {
-            return;
-        }
-
+    fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) {
         // if the const impl is derived using the `derive_const` attribute,
         // then it would be "stable" at least for the impl.
         // We gate usages of it using `feature(const_trait_impl)` anyways
@@ -582,12 +600,12 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
 
         let is_const = self.tcx.is_const_fn(def_id.to_def_id())
             || self.tcx.is_const_trait_impl(def_id.to_def_id());
-        let is_stable =
-            self.tcx.lookup_stability(def_id).is_some_and(|stability| stability.level.is_stable());
-        let missing_const_stability_attribute =
-            self.tcx.lookup_const_stability(def_id).is_none_or(|s| s.feature.is_none());
 
-        if is_const && is_stable && missing_const_stability_attribute {
+        // Reachable const fn must have a stability attribute.
+        if is_const
+            && self.effective_visibilities.is_reachable(def_id)
+            && self.tcx.lookup_const_stability(def_id).is_none()
+        {
             let descr = self.tcx.def_descr(def_id.to_def_id());
             self.tcx.dcx().emit_err(errors::MissingConstStabAttr { span, descr });
         }
@@ -615,7 +633,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
         }
 
         // Ensure stable `const fn` have a const stability attribute.
-        self.check_missing_or_wrong_const_stability(i.owner_id.def_id, i.span);
+        self.check_missing_const_stability(i.owner_id.def_id, i.span);
 
         intravisit::walk_item(self, i)
     }
@@ -629,7 +647,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
         let impl_def_id = self.tcx.hir().get_parent_item(ii.hir_id());
         if self.tcx.impl_trait_ref(impl_def_id).is_none() {
             self.check_missing_stability(ii.owner_id.def_id, ii.span);
-            self.check_missing_or_wrong_const_stability(ii.owner_id.def_id, ii.span);
+            self.check_missing_const_stability(ii.owner_id.def_id, ii.span);
         }
         intravisit::walk_impl_item(self, ii);
     }
@@ -760,23 +778,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
             // For implementations of traits, check the stability of each item
             // individually as it's possible to have a stable trait with unstable
             // items.
-            hir::ItemKind::Impl(hir::Impl {
-                constness,
-                of_trait: Some(ref t),
-                self_ty,
-                items,
-                ..
-            }) => {
+            hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => {
                 let features = self.tcx.features();
                 if features.staged_api() {
                     let attrs = self.tcx.hir().attrs(item.hir_id());
                     let stab = attr::find_stability(self.tcx.sess, attrs, item.span);
-                    let const_stab = attr::find_const_stability(
-                        self.tcx.sess,
-                        attrs,
-                        item.span,
-                        matches!(constness, Constness::Const),
-                    );
+                    let const_stab = attr::find_const_stability(self.tcx.sess, attrs, item.span);
 
                     // If this impl block has an #[unstable] attribute, give an
                     // error if all involved types and traits are stable, because
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index 9ea5023064c..7cc6ba24450 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -453,7 +453,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
         let fields: Vec<_>;
         match &pat.kind {
             PatKind::AscribeUserType { subpattern, .. }
-            | PatKind::InlineConstant { subpattern, .. } => return self.lower_pat(subpattern),
+            | PatKind::ExpandedConstant { subpattern, .. } => return self.lower_pat(subpattern),
             PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
             PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
                 ctor = Wildcard;
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 1a5c29afdc9..c845d60ac07 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -782,21 +782,11 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
 impl ReachEverythingInTheInterfaceVisitor<'_, '_> {
     fn generics(&mut self) -> &mut Self {
         for param in &self.ev.tcx.generics_of(self.item_def_id).own_params {
-            match param.kind {
-                GenericParamDefKind::Lifetime => {}
-                GenericParamDefKind::Type { has_default, .. } => {
-                    if has_default {
-                        self.visit(self.ev.tcx.type_of(param.def_id).instantiate_identity());
-                    }
-                }
-                GenericParamDefKind::Const { has_default, .. } => {
-                    self.visit(self.ev.tcx.type_of(param.def_id).instantiate_identity());
-                    if has_default {
-                        self.visit(
-                            self.ev.tcx.const_param_default(param.def_id).instantiate_identity(),
-                        );
-                    }
-                }
+            if let GenericParamDefKind::Const { .. } = param.kind {
+                self.visit(self.ev.tcx.type_of(param.def_id).instantiate_identity());
+            }
+            if let Some(default) = param.default_value(self.ev.tcx) {
+                self.visit(default.instantiate_identity());
             }
         }
         self
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index 2bb1be22b98..6e8fd32610b 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -19,8 +19,3 @@ rustc_span = { path = "../rustc_span" }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
-
-[features]
-# tidy-alphabetical-start
-rustc_use_parallel_compiler = ["rustc_query_system/rustc_use_parallel_compiler"]
-# tidy-alphabetical-end
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index 2f42fa47728..96b210accdb 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2021"
 [dependencies]
 # tidy-alphabetical-start
 parking_lot = "0.12"
-rustc-rayon-core = { version = "0.5.0", optional = true }
+rustc-rayon-core = { version = "0.5.0" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
@@ -23,8 +23,3 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
 thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
-
-[features]
-# tidy-alphabetical-start
-rustc_use_parallel_compiler = ["dep:rustc-rayon-core"]
-# tidy-alphabetical-end
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index e7ed8288499..9b26a5bbcc6 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -837,12 +837,6 @@ impl<D: Deps> DepGraphData<D> {
     ) -> Option<DepNodeIndex> {
         let frame = MarkFrame { index: prev_dep_node_index, parent: frame };
 
-        #[cfg(not(parallel_compiler))]
-        {
-            debug_assert!(!self.dep_node_exists(dep_node));
-            debug_assert!(self.colors.get(prev_dep_node_index).is_none());
-        }
-
         // We never try to mark eval_always nodes as green
         debug_assert!(!qcx.dep_context().is_eval_always(dep_node.kind));
 
@@ -871,13 +865,6 @@ impl<D: Deps> DepGraphData<D> {
         // Maybe store a list on disk and encode this fact in the DepNodeState
         let side_effects = qcx.load_side_effects(prev_dep_node_index);
 
-        #[cfg(not(parallel_compiler))]
-        debug_assert!(
-            self.colors.get(prev_dep_node_index).is_none(),
-            "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \
-                      insertion for {dep_node:?}"
-        );
-
         if side_effects.maybe_any() {
             qcx.dep_context().dep_graph().with_query_deserialization(|| {
                 self.emit_side_effects(qcx, dep_node_index, side_effects)
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index 5af41b9e687..2a7d759ab35 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -1,21 +1,16 @@
 use std::hash::Hash;
 use std::io::Write;
+use std::iter;
 use std::num::NonZero;
+use std::sync::Arc;
 
-use rustc_data_structures::fx::FxHashMap;
+use parking_lot::{Condvar, Mutex};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::jobserver;
 use rustc_errors::{Diag, DiagCtxtHandle};
 use rustc_hir::def::DefKind;
 use rustc_session::Session;
-use rustc_span::Span;
-#[cfg(parallel_compiler)]
-use {
-    parking_lot::{Condvar, Mutex},
-    rustc_data_structures::fx::FxHashSet,
-    rustc_data_structures::jobserver,
-    rustc_span::DUMMY_SP,
-    std::iter,
-    std::sync::Arc,
-};
+use rustc_span::{DUMMY_SP, Span};
 
 use crate::dep_graph::DepContext;
 use crate::error::CycleStack;
@@ -41,17 +36,14 @@ impl QueryJobId {
         map.get(&self).unwrap().query.clone()
     }
 
-    #[cfg(parallel_compiler)]
     fn span(self, map: &QueryMap) -> Span {
         map.get(&self).unwrap().job.span
     }
 
-    #[cfg(parallel_compiler)]
     fn parent(self, map: &QueryMap) -> Option<QueryJobId> {
         map.get(&self).unwrap().job.parent
     }
 
-    #[cfg(parallel_compiler)]
     fn latch(self, map: &QueryMap) -> Option<&QueryLatch> {
         map.get(&self).unwrap().job.latch.as_ref()
     }
@@ -75,7 +67,6 @@ pub struct QueryJob {
     pub parent: Option<QueryJobId>,
 
     /// The latch that is used to wait on this job.
-    #[cfg(parallel_compiler)]
     latch: Option<QueryLatch>,
 }
 
@@ -83,16 +74,9 @@ impl QueryJob {
     /// Creates a new query job.
     #[inline]
     pub fn new(id: QueryJobId, span: Span, parent: Option<QueryJobId>) -> Self {
-        QueryJob {
-            id,
-            span,
-            parent,
-            #[cfg(parallel_compiler)]
-            latch: None,
-        }
+        QueryJob { id, span, parent, latch: None }
     }
 
-    #[cfg(parallel_compiler)]
     pub(super) fn latch(&mut self) -> QueryLatch {
         if self.latch.is_none() {
             self.latch = Some(QueryLatch::new());
@@ -106,11 +90,8 @@ impl QueryJob {
     /// as there are no concurrent jobs which could be waiting on us
     #[inline]
     pub fn signal_complete(self) {
-        #[cfg(parallel_compiler)]
-        {
-            if let Some(latch) = self.latch {
-                latch.set();
-            }
+        if let Some(latch) = self.latch {
+            latch.set();
         }
     }
 }
@@ -176,7 +157,6 @@ impl QueryJobId {
     }
 }
 
-#[cfg(parallel_compiler)]
 #[derive(Debug)]
 struct QueryWaiter {
     query: Option<QueryJobId>,
@@ -185,7 +165,6 @@ struct QueryWaiter {
     cycle: Mutex<Option<CycleError>>,
 }
 
-#[cfg(parallel_compiler)]
 impl QueryWaiter {
     fn notify(&self, registry: &rayon_core::Registry) {
         rayon_core::mark_unblocked(registry);
@@ -193,20 +172,17 @@ impl QueryWaiter {
     }
 }
 
-#[cfg(parallel_compiler)]
 #[derive(Debug)]
 struct QueryLatchInfo {
     complete: bool,
     waiters: Vec<Arc<QueryWaiter>>,
 }
 
-#[cfg(parallel_compiler)]
 #[derive(Clone, Debug)]
 pub(super) struct QueryLatch {
     info: Arc<Mutex<QueryLatchInfo>>,
 }
 
-#[cfg(parallel_compiler)]
 impl QueryLatch {
     fn new() -> Self {
         QueryLatch {
@@ -273,7 +249,6 @@ impl QueryLatch {
 }
 
 /// A resumable waiter of a query. The usize is the index into waiters in the query's latch
-#[cfg(parallel_compiler)]
 type Waiter = (QueryJobId, usize);
 
 /// Visits all the non-resumable and resumable waiters of a query.
@@ -285,7 +260,6 @@ type Waiter = (QueryJobId, usize);
 /// For visits of resumable waiters it returns Some(Some(Waiter)) which has the
 /// required information to resume the waiter.
 /// If all `visit` calls returns None, this function also returns None.
-#[cfg(parallel_compiler)]
 fn visit_waiters<F>(query_map: &QueryMap, query: QueryJobId, mut visit: F) -> Option<Option<Waiter>>
 where
     F: FnMut(Span, QueryJobId) -> Option<Option<Waiter>>,
@@ -316,7 +290,6 @@ where
 /// `span` is the reason for the `query` to execute. This is initially DUMMY_SP.
 /// If a cycle is detected, this initial value is replaced with the span causing
 /// the cycle.
-#[cfg(parallel_compiler)]
 fn cycle_check(
     query_map: &QueryMap,
     query: QueryJobId,
@@ -357,7 +330,6 @@ fn cycle_check(
 /// Finds out if there's a path to the compiler root (aka. code which isn't in a query)
 /// from `query` without going through any of the queries in `visited`.
 /// This is achieved with a depth first search.
-#[cfg(parallel_compiler)]
 fn connected_to_root(
     query_map: &QueryMap,
     query: QueryJobId,
@@ -380,7 +352,6 @@ fn connected_to_root(
 }
 
 // Deterministically pick an query from a list
-#[cfg(parallel_compiler)]
 fn pick_query<'a, T, F>(query_map: &QueryMap, queries: &'a [T], f: F) -> &'a T
 where
     F: Fn(&T) -> (Span, QueryJobId),
@@ -406,7 +377,6 @@ where
 /// the function return true.
 /// If a cycle was not found, the starting query is removed from `jobs` and
 /// the function returns false.
-#[cfg(parallel_compiler)]
 fn remove_cycle(
     query_map: &QueryMap,
     jobs: &mut Vec<QueryJobId>,
@@ -511,7 +481,6 @@ fn remove_cycle(
 /// uses a query latch and then resuming that waiter.
 /// There may be multiple cycles involved in a deadlock, so this searches
 /// all active queries for cycles before finally resuming all the waiters at once.
-#[cfg(parallel_compiler)]
 pub fn break_query_cycles(query_map: QueryMap, registry: &rayon_core::Registry) {
     let mut wakelist = Vec::new();
     let mut jobs: Vec<QueryJobId> = query_map.keys().cloned().collect();
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index 3e35fdb77b3..b81386f06ec 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -2,10 +2,9 @@ mod plumbing;
 pub use self::plumbing::*;
 
 mod job;
-#[cfg(parallel_compiler)]
-pub use self::job::break_query_cycles;
 pub use self::job::{
-    QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap, print_query_stack, report_cycle,
+    QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryMap, break_query_cycles, print_query_stack,
+    report_cycle,
 };
 
 mod caches;
@@ -38,7 +37,6 @@ pub struct QueryStackFrame {
     pub dep_kind: DepKind,
     /// This hash is used to deterministically pick
     /// a query to remove cycles in the parallel compiler.
-    #[cfg(parallel_compiler)]
     hash: Hash64,
 }
 
@@ -51,18 +49,9 @@ impl QueryStackFrame {
         def_kind: Option<DefKind>,
         dep_kind: DepKind,
         ty_def_id: Option<DefId>,
-        _hash: impl FnOnce() -> Hash64,
+        hash: impl FnOnce() -> Hash64,
     ) -> Self {
-        Self {
-            description,
-            span,
-            def_id,
-            def_kind,
-            ty_def_id,
-            dep_kind,
-            #[cfg(parallel_compiler)]
-            hash: _hash(),
-        }
+        Self { description, span, def_id, def_kind, ty_def_id, dep_kind, hash: hash() }
     }
 
     // FIXME(eddyb) Get more valid `Span`s on queries.
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 17486be04dc..aac8ab87c64 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -13,7 +13,6 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sharded::Sharded;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::sync::Lock;
-#[cfg(parallel_compiler)]
 use rustc_data_structures::{outline, sync};
 use rustc_errors::{Diag, FatalError, StashKey};
 use rustc_span::{DUMMY_SP, Span};
@@ -25,9 +24,7 @@ use crate::HandleCycleError;
 use crate::dep_graph::{DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeParams};
 use crate::ich::StableHashingContext;
 use crate::query::caches::QueryCache;
-#[cfg(parallel_compiler)]
-use crate::query::job::QueryLatch;
-use crate::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, report_cycle};
+use crate::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, report_cycle};
 use crate::query::{
     QueryContext, QueryMap, QuerySideEffects, QueryStackFrame, SerializedDepNodeIndex,
 };
@@ -263,7 +260,6 @@ where
 }
 
 #[inline(always)]
-#[cfg(parallel_compiler)]
 fn wait_for_query<Q, Qcx>(
     query: Q,
     qcx: Qcx,
@@ -334,7 +330,7 @@ where
     // re-executing the query since `try_start` only checks that the query is not currently
     // executing, but another thread may have already completed the query and stores it result
     // in the query cache.
-    if cfg!(parallel_compiler) && qcx.dep_context().sess().threads() > 1 {
+    if qcx.dep_context().sess().threads() > 1 {
         if let Some((value, index)) = query.query_cache(qcx).lookup(&key) {
             qcx.dep_context().profiler().query_cache_hit(index.into());
             return (value, Some(index));
@@ -359,7 +355,6 @@ where
         Entry::Occupied(mut entry) => {
             match entry.get_mut() {
                 QueryResult::Started(job) => {
-                    #[cfg(parallel_compiler)]
                     if sync::is_dyn_thread_safe() {
                         // Get the latch out
                         let latch = job.latch();
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index a825458dc89..bf27b767a49 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -130,18 +130,16 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
         &self,
         anon_const: &'a AnonConst,
     ) -> Option<(PendingAnonConstInfo, NodeId)> {
-        let (block_was_stripped, expr) = anon_const.value.maybe_unwrap_block();
-        match expr {
-            Expr { kind: ExprKind::MacCall(..), id, .. } => Some((
+        anon_const.value.optionally_braced_mac_call(false).map(|(block_was_stripped, id)| {
+            (
                 PendingAnonConstInfo {
                     id: anon_const.id,
                     span: anon_const.value.span,
                     block_was_stripped,
                 },
-                *id,
-            )),
-            _ => None,
-        }
+                id,
+            )
+        })
     }
 
     /// Determines whether the expression `const_arg_sub_expr` is a simple macro call, sometimes
@@ -161,18 +159,11 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
             panic!("Checking expr is trivial macro call without having entered anon const: `{const_arg_sub_expr:?}`"),
         );
 
-        let (block_was_stripped, expr) = if pending_anon.block_was_stripped {
-            (true, const_arg_sub_expr)
-        } else {
-            const_arg_sub_expr.maybe_unwrap_block()
-        };
-
-        match expr {
-            Expr { kind: ExprKind::MacCall(..), id, .. } => {
-                Some((PendingAnonConstInfo { block_was_stripped, ..pending_anon }, *id))
-            }
-            _ => None,
-        }
+        const_arg_sub_expr.optionally_braced_mac_call(pending_anon.block_was_stripped).map(
+            |(block_was_stripped, id)| {
+                (PendingAnonConstInfo { block_was_stripped, ..pending_anon }, id)
+            },
+        )
     }
 }
 
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index fa2403db925..44721bd889a 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1398,9 +1398,25 @@ pub enum OptionKind {
 }
 
 pub struct RustcOptGroup {
-    apply: Box<dyn Fn(&mut getopts::Options) -> &mut getopts::Options>,
+    /// The "primary" name for this option. Normally equal to `long_name`,
+    /// except for options that don't have a long name, in which case
+    /// `short_name` is used.
+    ///
+    /// This is needed when interacting with `getopts` in some situations,
+    /// because if an option has both forms, that library treats the long name
+    /// as primary and the short name as an alias.
     pub name: &'static str,
     stability: OptionStability,
+    kind: OptionKind,
+
+    short_name: &'static str,
+    long_name: &'static str,
+    desc: &'static str,
+    value_hint: &'static str,
+
+    /// If true, this option should not be printed by `rustc --help`, but
+    /// should still be printed by `rustc --help -v`.
+    pub is_verbose_help_only: bool,
 }
 
 impl RustcOptGroup {
@@ -1409,7 +1425,13 @@ impl RustcOptGroup {
     }
 
     pub fn apply(&self, options: &mut getopts::Options) {
-        (self.apply)(options);
+        let &Self { short_name, long_name, desc, value_hint, .. } = self;
+        match self.kind {
+            OptionKind::Opt => options.optopt(short_name, long_name, desc, value_hint),
+            OptionKind::Multi => options.optmulti(short_name, long_name, desc, value_hint),
+            OptionKind::Flag => options.optflag(short_name, long_name, desc),
+            OptionKind::FlagMulti => options.optflagmulti(short_name, long_name, desc),
+        };
     }
 }
 
@@ -1419,31 +1441,22 @@ pub fn make_opt(
     short_name: &'static str,
     long_name: &'static str,
     desc: &'static str,
-    hint: &'static str,
+    value_hint: &'static str,
 ) -> RustcOptGroup {
+    // "Flag" options don't have a value, and therefore don't have a value hint.
+    match kind {
+        OptionKind::Opt | OptionKind::Multi => {}
+        OptionKind::Flag | OptionKind::FlagMulti => assert_eq!(value_hint, ""),
+    }
     RustcOptGroup {
         name: cmp::max_by_key(short_name, long_name, |s| s.len()),
         stability,
-        apply: match kind {
-            OptionKind::Opt => Box::new(move |opts: &mut getopts::Options| {
-                opts.optopt(short_name, long_name, desc, hint)
-            }),
-            OptionKind::Multi => Box::new(move |opts: &mut getopts::Options| {
-                opts.optmulti(short_name, long_name, desc, hint)
-            }),
-            OptionKind::Flag => {
-                assert_eq!(hint, "");
-                Box::new(move |opts: &mut getopts::Options| {
-                    opts.optflag(short_name, long_name, desc)
-                })
-            }
-            OptionKind::FlagMulti => {
-                assert_eq!(hint, "");
-                Box::new(move |opts: &mut getopts::Options| {
-                    opts.optflagmulti(short_name, long_name, desc)
-                })
-            }
-        },
+        kind,
+        short_name,
+        long_name,
+        desc,
+        value_hint,
+        is_verbose_help_only: false,
     }
 }
 
@@ -1454,16 +1467,15 @@ The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE
     )
 });
 
-/// Returns the "short" subset of the rustc command line options,
-/// including metadata for each option, such as whether the option is
-/// part of the stable long-term interface for rustc.
-pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
+/// Returns all rustc command line options, including metadata for
+/// each option, such as whether the option is stable.
+pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
     use OptionKind::{Flag, FlagMulti, Multi, Opt};
-    use OptionStability::Stable;
+    use OptionStability::{Stable, Unstable};
 
     use self::make_opt as opt;
 
-    vec![
+    let mut options = vec![
         opt(Stable, Flag, "h", "help", "Display this message", ""),
         opt(
             Stable,
@@ -1550,21 +1562,11 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
         opt(Stable, Multi, "C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
         opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
         opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
-    ]
-}
-
-/// Returns all rustc command line options, including metadata for
-/// each option, such as whether the option is part of the stable
-/// long-term interface for rustc.
-pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
-    use OptionKind::{Multi, Opt};
-    use OptionStability::{Stable, Unstable};
-
-    use self::make_opt as opt;
+    ];
 
-    let mut opts = rustc_short_optgroups();
-    // FIXME: none of these descriptions are actually used
-    opts.extend(vec![
+    // Options in this list are hidden from `rustc --help` by default, but are
+    // shown by `rustc --help -v`.
+    let verbose_only = [
         opt(
             Stable,
             Multi,
@@ -1590,9 +1592,9 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             "",
             "color",
             "Configure coloring of output:
-                                 auto   = colorize, if output goes to a tty (default);
-                                 always = always colorize output;
-                                 never  = never colorize output",
+                auto   = colorize, if output goes to a tty (default);
+                always = always colorize output;
+                never  = never colorize output",
             "auto|always|never",
         ),
         opt(
@@ -1612,8 +1614,13 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             "FROM=TO",
         ),
         opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "VAR=VALUE"),
-    ]);
-    opts
+    ];
+    options.extend(verbose_only.into_iter().map(|mut opt| {
+        opt.is_verbose_help_only = true;
+        opt
+    }));
+
+    options
 }
 
 pub fn get_cmd_lint_options(
@@ -1721,6 +1728,9 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json
         for sub_option in option.split(',') {
             match sub_option {
                 "diagnostic-short" => json_rendered = HumanReadableErrorType::Short,
+                "diagnostic-unicode" => {
+                    json_rendered = HumanReadableErrorType::Unicode;
+                }
                 "diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
                 "artifacts" => json_artifact_notifications = true,
                 "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
@@ -1767,14 +1777,17 @@ pub fn parse_error_format(
                 ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color }
             }
             Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short, color),
+            Some("human-unicode") => {
+                ErrorOutputType::HumanReadable(HumanReadableErrorType::Unicode, color)
+            }
             Some(arg) => {
                 early_dcx.abort_if_error_and_set_error_format(ErrorOutputType::HumanReadable(
                     HumanReadableErrorType::Default,
                     color,
                 ));
                 early_dcx.early_fatal(format!(
-                    "argument for `--error-format` must be `human`, `json` or \
-                     `short` (instead was `{arg}`)"
+                    "argument for `--error-format` must be `human`, `human-annotate-rs`, \
+                    `human-unicode`, `json`, `pretty-json` or `short` (instead was `{arg}`)"
                 ))
             }
         }
@@ -1827,18 +1840,21 @@ pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches
 fn check_error_format_stability(
     early_dcx: &EarlyDiagCtxt,
     unstable_opts: &UnstableOptions,
-    error_format: ErrorOutputType,
+    format: ErrorOutputType,
 ) {
-    if !unstable_opts.unstable_options {
-        if let ErrorOutputType::Json { pretty: true, .. } = error_format {
-            early_dcx.early_fatal("`--error-format=pretty-json` is unstable");
-        }
-        if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet, _) =
-            error_format
-        {
-            early_dcx.early_fatal("`--error-format=human-annotate-rs` is unstable");
-        }
-    }
+    if unstable_opts.unstable_options {
+        return;
+    }
+    let format = match format {
+        ErrorOutputType::Json { pretty: true, .. } => "pretty-json",
+        ErrorOutputType::HumanReadable(format, _) => match format {
+            HumanReadableErrorType::AnnotateSnippet => "human-annotate-rs",
+            HumanReadableErrorType::Unicode => "human-unicode",
+            _ => return,
+        },
+        _ => return,
+    };
+    early_dcx.early_fatal(format!("`--error-format={format}` is unstable"))
 }
 
 fn parse_output_types(
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index 213a94ab880..4be013fd6fd 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -4,37 +4,44 @@ use std::path::{Path, PathBuf};
 use std::{env, fs};
 
 use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
+use rustc_target::spec::Target;
 use smallvec::{SmallVec, smallvec};
 
 use crate::search_paths::{PathKind, SearchPath};
 
 #[derive(Clone)]
-pub struct FileSearch<'a> {
-    cli_search_paths: &'a [SearchPath],
-    tlib_path: &'a SearchPath,
-    kind: PathKind,
+pub struct FileSearch {
+    cli_search_paths: Vec<SearchPath>,
+    tlib_path: SearchPath,
 }
 
-impl<'a> FileSearch<'a> {
-    pub fn cli_search_paths(&self) -> impl Iterator<Item = &'a SearchPath> {
-        let kind = self.kind;
+impl FileSearch {
+    pub fn cli_search_paths<'b>(&'b self, kind: PathKind) -> impl Iterator<Item = &'b SearchPath> {
         self.cli_search_paths.iter().filter(move |sp| sp.kind.matches(kind))
     }
 
-    pub fn search_paths(&self) -> impl Iterator<Item = &'a SearchPath> {
-        let kind = self.kind;
+    pub fn search_paths<'b>(&'b self, kind: PathKind) -> impl Iterator<Item = &'b SearchPath> {
         self.cli_search_paths
             .iter()
             .filter(move |sp| sp.kind.matches(kind))
-            .chain(std::iter::once(self.tlib_path))
+            .chain(std::iter::once(&self.tlib_path))
     }
 
-    pub fn new(
-        cli_search_paths: &'a [SearchPath],
-        tlib_path: &'a SearchPath,
-        kind: PathKind,
-    ) -> FileSearch<'a> {
-        FileSearch { cli_search_paths, tlib_path, kind }
+    pub fn new(cli_search_paths: &[SearchPath], tlib_path: &SearchPath, target: &Target) -> Self {
+        let this = FileSearch {
+            cli_search_paths: cli_search_paths.to_owned(),
+            tlib_path: tlib_path.clone(),
+        };
+        this.refine(&["lib", &target.staticlib_prefix, &target.dll_prefix])
+    }
+    // Produce a new file search from this search that has a smaller set of candidates.
+    fn refine(mut self, allowed_prefixes: &[&str]) -> FileSearch {
+        self.cli_search_paths
+            .iter_mut()
+            .for_each(|search_paths| search_paths.files.retain(allowed_prefixes));
+        self.tlib_path.files.retain(allowed_prefixes);
+
+        self
     }
 }
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 087ba0522eb..f485e8cace5 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -130,7 +130,7 @@ top_level_options!(
     pub struct Options {
         /// The crate config requested for the session, which may be combined
         /// with additional crate configurations during the compile process.
-        #[rustc_lint_opt_deny_field_access("use `Session::crate_types` instead of this field")]
+        #[rustc_lint_opt_deny_field_access("use `TyCtxt::crate_types` instead of this field")]
         crate_types: Vec<CrateType> [TRACKED],
         optimize: OptLevel [TRACKED],
         /// Include the `debug_assertions` flag in dependency tracking, since it
diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs
index c148b09c718..78473fccd2d 100644
--- a/compiler/rustc_session/src/search_paths.rs
+++ b/compiler/rustc_session/src/search_paths.rs
@@ -1,4 +1,5 @@
 use std::path::{Path, PathBuf};
+use std::sync::Arc;
 
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_target::spec::TargetTuple;
@@ -10,9 +11,44 @@ use crate::filesearch::make_target_lib_path;
 pub struct SearchPath {
     pub kind: PathKind,
     pub dir: PathBuf,
-    pub files: Vec<SearchPathFile>,
+    pub files: FilesIndex,
 }
 
+/// [FilesIndex] contains paths that can be efficiently looked up with (prefix, suffix) pairs.
+#[derive(Clone, Debug)]
+pub struct FilesIndex(Vec<(Arc<str>, SearchPathFile)>);
+
+impl FilesIndex {
+    /// Look up [SearchPathFile] by (prefix, suffix) pair.
+    pub fn query<'this, 'prefix, 'suffix>(
+        &'this self,
+        prefix: &'prefix str,
+        suffix: &'suffix str,
+    ) -> Option<impl Iterator<Item = (String, &'this SearchPathFile)> + use<'this, 'prefix, 'suffix>>
+    {
+        let start = self.0.partition_point(|(k, _)| **k < *prefix);
+        if start == self.0.len() {
+            return None;
+        }
+        let end = self.0[start..].partition_point(|(k, _)| k.starts_with(prefix));
+        let prefixed_items = &self.0[start..][..end];
+
+        let ret = prefixed_items.into_iter().filter_map(move |(k, v)| {
+            k.ends_with(suffix).then(|| {
+                (
+                    String::from(
+                        &v.file_name_str[prefix.len()..v.file_name_str.len() - suffix.len()],
+                    ),
+                    v,
+                )
+            })
+        });
+        Some(ret)
+    }
+    pub fn retain(&mut self, prefixes: &[&str]) {
+        self.0.retain(|(k, _)| prefixes.iter().any(|prefix| k.starts_with(prefix)));
+    }
+}
 /// The obvious implementation of `SearchPath::files` is a `Vec<PathBuf>`. But
 /// it is searched repeatedly by `find_library_crate`, and the searches involve
 /// checking the prefix and suffix of the filename of each `PathBuf`. This is
@@ -26,8 +62,8 @@ pub struct SearchPath {
 /// UTF-8, and so a non-UTF-8 filename couldn't be one we're looking for.)
 #[derive(Clone, Debug)]
 pub struct SearchPathFile {
-    pub path: PathBuf,
-    pub file_name_str: String,
+    pub path: Arc<Path>,
+    pub file_name_str: Arc<str>,
 }
 
 #[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, Encodable, Decodable, HashStable_Generic)]
@@ -98,20 +134,25 @@ impl SearchPath {
 
     pub fn new(kind: PathKind, dir: PathBuf) -> Self {
         // Get the files within the directory.
-        let files = match std::fs::read_dir(&dir) {
+        let mut files = match std::fs::read_dir(&dir) {
             Ok(files) => files
                 .filter_map(|e| {
                     e.ok().and_then(|e| {
-                        e.file_name().to_str().map(|s| SearchPathFile {
-                            path: e.path(),
-                            file_name_str: s.to_string(),
+                        e.file_name().to_str().map(|s| {
+                            let file_name_str: Arc<str> = s.into();
+                            (Arc::clone(&file_name_str), SearchPathFile {
+                                path: e.path().into(),
+                                file_name_str,
+                            })
                         })
                     })
                 })
                 .collect::<Vec<_>>(),
-            Err(..) => vec![],
-        };
 
+            Err(..) => Default::default(),
+        };
+        files.sort_by(|(lhs, _), (rhs, _)| lhs.cmp(rhs));
+        let files = FilesIndex(files);
         SearchPath { kind, dir, files }
     }
 }
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 9d9434a7776..29fabdd1deb 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -16,7 +16,9 @@ use rustc_data_structures::sync::{
 };
 use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
 use rustc_errors::codes::*;
-use rustc_errors::emitter::{DynEmitter, HumanEmitter, HumanReadableErrorType, stderr_destination};
+use rustc_errors::emitter::{
+    DynEmitter, HumanEmitter, HumanReadableErrorType, OutputTheme, stderr_destination,
+};
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::registry::Registry;
 use rustc_errors::{
@@ -42,8 +44,9 @@ use crate::config::{
     InstrumentCoverage, OptLevel, OutFileName, OutputType, RemapPathScopeComponents,
     SwitchWithOptPath,
 };
+use crate::filesearch::FileSearch;
 use crate::parse::{ParseSess, add_feature_diagnostics};
-use crate::search_paths::{PathKind, SearchPath};
+use crate::search_paths::SearchPath;
 use crate::{errors, filesearch, lint};
 
 struct OptimizationFuel {
@@ -216,6 +219,9 @@ pub struct Session {
     /// This is mainly useful for other tools that reads that debuginfo to figure out
     /// how to call the compiler with the same arguments.
     pub expanded_args: Vec<String>,
+
+    target_filesearch: FileSearch,
+    host_filesearch: FileSearch,
 }
 
 #[derive(PartialEq, Eq, PartialOrd, Ord)]
@@ -441,11 +447,11 @@ impl Session {
         format!("__rustc_proc_macro_decls_{:08x}__", stable_crate_id.as_u64())
     }
 
-    pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
-        filesearch::FileSearch::new(&self.opts.search_paths, &self.target_tlib_path, kind)
+    pub fn target_filesearch(&self) -> &filesearch::FileSearch {
+        &self.target_filesearch
     }
-    pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
-        filesearch::FileSearch::new(&self.opts.search_paths, &self.host_tlib_path, kind)
+    pub fn host_filesearch(&self) -> &filesearch::FileSearch {
+        &self.host_filesearch
     }
 
     /// Returns a list of directories where target-specific tool binaries are located. Some fallback
@@ -966,6 +972,11 @@ fn default_emitter(
                     .macro_backtrace(macro_backtrace)
                     .track_diagnostics(track_diagnostics)
                     .terminal_url(terminal_url)
+                    .theme(if let HumanReadableErrorType::Unicode = kind {
+                        OutputTheme::Unicode
+                    } else {
+                        OutputTheme::Ascii
+                    })
                     .ignored_directories_in_source_blocks(
                         sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(),
                     );
@@ -1104,7 +1115,9 @@ pub fn build_session(
     });
 
     let asm_arch = if target.allow_asm { InlineAsmArch::from_str(&target.arch).ok() } else { None };
-
+    let target_filesearch =
+        filesearch::FileSearch::new(&sopts.search_paths, &target_tlib_path, &target);
+    let host_filesearch = filesearch::FileSearch::new(&sopts.search_paths, &host_tlib_path, &host);
     let sess = Session {
         target,
         host,
@@ -1131,6 +1144,8 @@ pub fn build_session(
         cfg_version,
         using_internal_features,
         expanded_args,
+        target_filesearch,
+        host_filesearch,
     };
 
     validate_commandline_args_with_session_available(&sess);
@@ -1470,6 +1485,11 @@ fn mk_emitter(output: ErrorOutputType) -> Box<DynEmitter> {
             let short = kind.short();
             Box::new(
                 HumanEmitter::new(stderr_destination(color_config), fallback_bundle)
+                    .theme(if let HumanReadableErrorType::Unicode = kind {
+                        OutputTheme::Unicode
+                    } else {
+                        OutputTheme::Ascii
+                    })
                     .short_message(short),
             )
         }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index c57d516fcae..a9ca5dbe509 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1300,7 +1300,6 @@ pub fn register_expn_id(
     let expn_id = ExpnId { krate, local_id };
     HygieneData::with(|hygiene_data| {
         let _old_data = hygiene_data.foreign_expn_data.insert(expn_id, data);
-        debug_assert!(_old_data.is_none() || cfg!(parallel_compiler));
         let _old_hash = hygiene_data.foreign_expn_hashes.insert(expn_id, hash);
         debug_assert!(_old_hash.is_none() || _old_hash == Some(hash));
         let _old_id = hygiene_data.expn_hash_to_expn_id.insert(hash, expn_id);
@@ -1423,18 +1422,7 @@ pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContext
             ctxt_data = old.clone();
         }
 
-        let dummy = std::mem::replace(
-            &mut hygiene_data.syntax_context_data[ctxt.as_u32() as usize],
-            ctxt_data,
-        );
-        if cfg!(not(parallel_compiler)) {
-            // Make sure nothing weird happened while `decode_data` was running.
-            // We used `kw::Empty` for the dummy value and we expect nothing to be
-            // modifying the dummy entry.
-            // This does not hold for the parallel compiler as another thread may
-            // have inserted the fully decoded data.
-            assert_eq!(dummy.dollar_crate_name, kw::Empty);
-        }
+        hygiene_data.syntax_context_data[ctxt.as_u32() as usize] = ctxt_data;
     });
 
     // Mark the context as completed
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 5b1be5bca05..8966cfc9171 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -521,14 +521,6 @@ impl SpanData {
     }
 }
 
-// The interner is pointed to by a thread local value which is only set on the main thread
-// with parallelization is disabled. So we don't allow `Span` to transfer between threads
-// to avoid panics and other errors, even though it would be memory safe to do so.
-#[cfg(not(parallel_compiler))]
-impl !Send for Span {}
-#[cfg(not(parallel_compiler))]
-impl !Sync for Span {}
-
 impl PartialOrd for Span {
     fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
         PartialOrd::partial_cmp(&self.data(), &rhs.data())
@@ -567,12 +559,6 @@ impl Span {
         !self.is_dummy() && sm.is_span_accessible(self)
     }
 
-    /// Returns `true` if this span comes from any kind of macro, desugaring or inlining.
-    #[inline]
-    pub fn from_expansion(self) -> bool {
-        !self.ctxt().is_root()
-    }
-
     /// Returns `true` if `span` originates in a derive-macro's expansion.
     pub fn in_derive_expansion(self) -> bool {
         matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _))
@@ -2223,6 +2209,10 @@ pub fn char_width(ch: char) -> usize {
     }
 }
 
+pub fn str_width(s: &str) -> usize {
+    s.chars().map(char_width).sum()
+}
+
 /// Normalizes the source code and records the normalizations.
 fn normalize_src(src: &mut String) -> Vec<NormalizedPos> {
     let mut normalized_pos = vec![];
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index f36bb38623e..e74a5c2d8fe 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -534,7 +534,7 @@ impl SourceMap {
     /// Extracts the source surrounding the given `Span` using the `extract_source` function. The
     /// extract function takes three arguments: a string slice containing the source, an index in
     /// the slice for the beginning of the span and an index in the slice for the end of the span.
-    fn span_to_source<F, T>(&self, sp: Span, extract_source: F) -> Result<T, SpanSnippetError>
+    pub fn span_to_source<F, T>(&self, sp: Span, extract_source: F) -> Result<T, SpanSnippetError>
     where
         F: Fn(&str, usize, usize) -> Result<T, SpanSnippetError>,
     {
diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs
index db8170fa6ae..9d6c7d2a42a 100644
--- a/compiler/rustc_span/src/span_encoding.rs
+++ b/compiler/rustc_span/src/span_encoding.rs
@@ -303,6 +303,13 @@ impl Span {
         }
     }
 
+    /// Returns `true` if this span comes from any kind of macro, desugaring or inlining.
+    #[inline]
+    pub fn from_expansion(self) -> bool {
+        // If the span is fully inferred then ctxt > MAX_CTXT
+        self.inline_ctxt().map_or(true, |ctxt| !ctxt.is_root())
+    }
+
     /// Returns `true` if this is a dummy span with any hygienic context.
     #[inline]
     pub fn is_dummy(self) -> bool {
@@ -370,9 +377,10 @@ impl Span {
     pub fn eq_ctxt(self, other: Span) -> bool {
         match (self.inline_ctxt(), other.inline_ctxt()) {
             (Ok(ctxt1), Ok(ctxt2)) => ctxt1 == ctxt2,
-            (Ok(ctxt), Err(index)) | (Err(index), Ok(ctxt)) => {
-                with_span_interner(|interner| ctxt == interner.spans[index].ctxt)
-            }
+            // If `inline_ctxt` returns `Ok` the context is <= MAX_CTXT.
+            // If it returns `Err` the span is fully interned and the context is > MAX_CTXT.
+            // As these do not overlap an `Ok` and `Err` result cannot have an equal context.
+            (Ok(_), Err(_)) | (Err(_), Ok(_)) => false,
             (Err(index1), Err(index2)) => with_span_interner(|interner| {
                 interner.spans[index1].ctxt == interner.spans[index2].ctxt
             }),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index c04c793ba46..42c6221dc57 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1568,6 +1568,8 @@ symbols! {
         readonly,
         realloc,
         reason,
+        receiver,
+        receiver_target,
         recursion_limit,
         reexport_test_harness_main,
         ref_pat_eat_one_layer_2024,
@@ -1761,6 +1763,7 @@ symbols! {
         saturating_add,
         saturating_div,
         saturating_sub,
+        search_unbox,
         select_unpredictable,
         self_in_typedefs,
         self_struct_ctor,
diff --git a/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs
index c0bcc79b5b9..1515d8fe00a 100644
--- a/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/m68k_unknown_linux_gnu.rs
@@ -1,5 +1,5 @@
 use crate::abi::Endian;
-use crate::spec::{Target, TargetOptions, base};
+use crate::spec::{LinkSelfContainedDefault, Target, TargetOptions, base};
 
 pub(crate) fn target() -> Target {
     let mut base = base::linux_gnu::opts();
@@ -17,6 +17,13 @@ pub(crate) fn target() -> Target {
         pointer_width: 32,
         data_layout: "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16".into(),
         arch: "m68k".into(),
-        options: TargetOptions { endian: Endian::Big, mcount: "_mcount".into(), ..base },
+        options: TargetOptions {
+            endian: Endian::Big,
+            mcount: "_mcount".into(),
+
+            // LLD currently does not have support for M68k
+            link_self_contained: LinkSelfContainedDefault::False,
+            ..base
+        },
     }
 }
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index c4f9c742650..88536926b11 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -92,6 +92,11 @@ impl Stability {
 //
 // Stabilizing a target feature requires t-lang approval.
 
+// If feature A "implies" feature B, then:
+// - when A gets enabled (via `-Ctarget-feature` or `#[target_feature]`), we also enable B
+// - when B gets disabled (via `-Ctarget-feature`), we also disable A
+//
+// Both of these are also applied transitively.
 type ImpliedFeatures = &'static [&'static str];
 
 const ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
@@ -463,13 +468,14 @@ const WASM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("bulk-memory", Stable, &[]),
     ("exception-handling", Unstable(sym::wasm_target_feature), &[]),
     ("extended-const", Stable, &[]),
-    ("multivalue", Unstable(sym::wasm_target_feature), &[]),
+    ("multivalue", Stable, &[]),
     ("mutable-globals", Stable, &[]),
     ("nontrapping-fptoint", Stable, &[]),
-    ("reference-types", Unstable(sym::wasm_target_feature), &[]),
+    ("reference-types", Stable, &[]),
     ("relaxed-simd", Stable, &["simd128"]),
     ("sign-ext", Stable, &[]),
     ("simd128", Stable, &[]),
+    ("tail-call", Stable, &[]),
     ("wide-arithmetic", Unstable(sym::wasm_target_feature), &[]),
     // tidy-alphabetical-end
 ];
@@ -580,9 +586,20 @@ pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
 // certain size to have their "proper" ABI on each architecture.
 // Note that they must be kept sorted by vector size.
 const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
-    &[(128, "sse"), (256, "avx"), (512, "avx512f")];
+    &[(128, "sse"), (256, "avx"), (512, "avx512f")]; // FIXME: might need changes for AVX10.
 const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
 
+// We might want to add "helium" too.
+const ARM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
+
+const POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "altivec")];
+const WASM_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "simd128")];
+const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
+const RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
+    &[/*(64, "zvl64b"), */ (128, "v")];
+// Always warn on SPARC, as the necessary target features cannot be enabled in Rust at the moment.
+const SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[/*(128, "vis")*/];
+
 impl super::spec::Target {
     pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
         match &*self.arch {
@@ -607,8 +624,15 @@ impl super::spec::Target {
     pub fn features_for_correct_vector_abi(&self) -> Option<&'static [(u64, &'static str)]> {
         match &*self.arch {
             "x86" | "x86_64" => Some(X86_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            "aarch64" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
-            // FIXME: add support for non-tier1 architectures
+            "aarch64" | "arm64ec" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
+            "arm" => Some(ARM_FEATURES_FOR_CORRECT_VECTOR_ABI),
+            "powerpc" | "powerpc64" => Some(POWERPC_FEATURES_FOR_CORRECT_VECTOR_ABI),
+            "loongarch64" => Some(&[]), // on-stack ABI, so we complain about all by-val vectors
+            "riscv32" | "riscv64" => Some(RISCV_FEATURES_FOR_CORRECT_VECTOR_ABI),
+            "wasm32" | "wasm64" => Some(WASM_FEATURES_FOR_CORRECT_VECTOR_ABI),
+            "s390x" => Some(S390X_FEATURES_FOR_CORRECT_VECTOR_ABI),
+            "sparc" | "sparc64" => Some(SPARC_FEATURES_FOR_CORRECT_VECTOR_ABI),
+            // FIXME: add support for non-tier2 architectures
             _ => None,
         }
     }
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index 3ddd23924b5..1ab89ecde7a 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -282,6 +282,8 @@ trait_selection_precise_capturing_new = add a `use<...>` bound to explicitly cap
 
 trait_selection_precise_capturing_new_but_apit = add a `use<...>` bound to explicitly capture `{$new_lifetime}` after turning all argument-position `impl Trait` into type parameters, noting that this possibly affects the API of this crate
 
+trait_selection_precise_capturing_overcaptures = use the precise capturing `use<...>` syntax to make the captures explicit
+
 trait_selection_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here...
 trait_selection_prlf_defined_without_sub = the lifetime defined here...
 trait_selection_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
@@ -455,7 +457,9 @@ trait_selection_unable_to_construct_constant_value = unable to construct a const
 trait_selection_unknown_format_parameter_for_on_unimplemented_attr = there is no parameter `{$argument_name}` on trait `{$trait_name}`
     .help = expect either a generic argument name or {"`{Self}`"} as format argument
 
-trait_selection_warn_removing_apit_params = you could use a `use<...>` bound to explicitly capture `{$new_lifetime}`, but argument-position `impl Trait`s are not nameable
+trait_selection_warn_removing_apit_params_for_overcapture = you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable
+
+trait_selection_warn_removing_apit_params_for_undercapture = you could use a `use<...>` bound to explicitly capture `{$new_lifetime}`, but argument-position `impl Trait`s are not nameable
 
 trait_selection_where_copy_predicates = copy the `where` clause predicates from the trait
 
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 455e3ec751e..afac6fc6004 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -1,13 +1,14 @@
 use std::path::PathBuf;
 
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_errors::codes::*;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, DiagMessage, DiagStyledString, Diagnostic,
     EmissionGuarantee, IntoDiagArg, Level, MultiSpan, SubdiagMessageOp, Subdiagnostic,
 };
 use rustc_hir as hir;
-use rustc_hir::def_id::LocalDefId;
+use rustc_hir::def::DefKind;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{Visitor, walk_ty};
 use rustc_hir::{FnRetTy, GenericParamKind};
 use rustc_macros::{Diagnostic, Subdiagnostic};
@@ -1792,6 +1793,138 @@ impl Subdiagnostic for AddPreciseCapturingAndParams {
             self.suggs,
             Applicability::MaybeIncorrect,
         );
-        diag.span_note(self.apit_spans, fluent::trait_selection_warn_removing_apit_params);
+        diag.span_note(
+            self.apit_spans,
+            fluent::trait_selection_warn_removing_apit_params_for_undercapture,
+        );
+    }
+}
+
+/// Given a set of captured `DefId` for an RPIT (opaque_def_id) and a given
+/// function (fn_def_id), try to suggest adding `+ use<...>` to capture just
+/// the specified parameters. If one of those parameters is an APIT, then try
+/// to suggest turning it into a regular type parameter.
+pub fn impl_trait_overcapture_suggestion<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    opaque_def_id: LocalDefId,
+    fn_def_id: LocalDefId,
+    captured_args: FxIndexSet<DefId>,
+) -> Option<AddPreciseCapturingForOvercapture> {
+    let generics = tcx.generics_of(fn_def_id);
+
+    let mut captured_lifetimes = FxIndexSet::default();
+    let mut captured_non_lifetimes = FxIndexSet::default();
+    let mut synthetics = vec![];
+
+    for arg in captured_args {
+        if tcx.def_kind(arg) == DefKind::LifetimeParam {
+            captured_lifetimes.insert(tcx.item_name(arg));
+        } else {
+            let idx = generics.param_def_id_to_index(tcx, arg).expect("expected arg in scope");
+            let param = generics.param_at(idx as usize, tcx);
+            if param.kind.is_synthetic() {
+                synthetics.push((tcx.def_span(arg), param.name));
+            } else {
+                captured_non_lifetimes.insert(tcx.item_name(arg));
+            }
+        }
+    }
+
+    let mut next_fresh_param = || {
+        ["T", "U", "V", "W", "X", "Y", "A", "B", "C"]
+            .into_iter()
+            .map(Symbol::intern)
+            .chain((0..).map(|i| Symbol::intern(&format!("T{i}"))))
+            .find(|s| captured_non_lifetimes.insert(*s))
+            .unwrap()
+    };
+
+    let mut suggs = vec![];
+    let mut apit_spans = vec![];
+
+    if !synthetics.is_empty() {
+        let mut new_params = String::new();
+        for (i, (span, name)) in synthetics.into_iter().enumerate() {
+            apit_spans.push(span);
+
+            let fresh_param = next_fresh_param();
+
+            // Suggest renaming.
+            suggs.push((span, fresh_param.to_string()));
+
+            // Super jank. Turn `impl Trait` into `T: Trait`.
+            //
+            // This currently involves stripping the `impl` from the name of
+            // the parameter, since APITs are always named after how they are
+            // rendered in the AST. This sucks! But to recreate the bound list
+            // from the APIT itself would be miserable, so we're stuck with
+            // this for now!
+            if i > 0 {
+                new_params += ", ";
+            }
+            let name_as_bounds = name.as_str().trim_start_matches("impl").trim_start();
+            new_params += fresh_param.as_str();
+            new_params += ": ";
+            new_params += name_as_bounds;
+        }
+
+        let Some(generics) = tcx.hir().get_generics(fn_def_id) else {
+            // This shouldn't happen, but don't ICE.
+            return None;
+        };
+
+        // Add generics or concatenate to the end of the list.
+        suggs.push(if let Some(params_span) = generics.span_for_param_suggestion() {
+            (params_span, format!(", {new_params}"))
+        } else {
+            (generics.span, format!("<{new_params}>"))
+        });
+    }
+
+    let concatenated_bounds = captured_lifetimes
+        .into_iter()
+        .chain(captured_non_lifetimes)
+        .map(|sym| sym.to_string())
+        .collect::<Vec<_>>()
+        .join(", ");
+
+    suggs.push((
+        tcx.def_span(opaque_def_id).shrink_to_hi(),
+        format!(" + use<{concatenated_bounds}>"),
+    ));
+
+    Some(AddPreciseCapturingForOvercapture { suggs, apit_spans })
+}
+
+pub struct AddPreciseCapturingForOvercapture {
+    pub suggs: Vec<(Span, String)>,
+    pub apit_spans: Vec<Span>,
+}
+
+impl Subdiagnostic for AddPreciseCapturingForOvercapture {
+    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
+        self,
+        diag: &mut Diag<'_, G>,
+        _f: &F,
+    ) {
+        let applicability = if self.apit_spans.is_empty() {
+            Applicability::MachineApplicable
+        } else {
+            // If there are APIT that are converted to regular parameters,
+            // then this may make the API turbofishable in ways that were
+            // not intended.
+            Applicability::MaybeIncorrect
+        };
+        diag.multipart_suggestion_verbose(
+            fluent::trait_selection_precise_capturing_overcaptures,
+            self.suggs,
+            applicability,
+        );
+        if !self.apit_spans.is_empty() {
+            diag.span_note(
+                self.apit_spans,
+                fluent::trait_selection_warn_removing_apit_params_for_overcapture,
+            );
+        }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index c53689b211d..2cc787c8bc5 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -15,7 +15,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
 use rustc_type_ir::TypingMode;
 use rustc_type_ir::solve::{Certainty, NoSolution};
 
-use crate::traits::specialization_graph;
+use crate::traits::{EvaluateConstErr, specialization_graph};
 
 #[repr(transparent)]
 pub struct SolverDelegate<'tcx>(InferCtxt<'tcx>);
@@ -77,20 +77,19 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
         self.0.leak_check(max_input_universe, None).map_err(|_| NoSolution)
     }
 
-    fn try_const_eval_resolve(
+    fn evaluate_const(
         &self,
         param_env: ty::ParamEnv<'tcx>,
-        unevaluated: ty::UnevaluatedConst<'tcx>,
+        uv: ty::UnevaluatedConst<'tcx>,
     ) -> Option<ty::Const<'tcx>> {
-        use rustc_middle::mir::interpret::ErrorHandled;
-        match self.const_eval_resolve(param_env, unevaluated, DUMMY_SP) {
-            Ok(Ok(val)) => Some(ty::Const::new_value(
-                self.tcx,
-                val,
-                self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args),
-            )),
-            Ok(Err(_)) | Err(ErrorHandled::TooGeneric(_)) => None,
-            Err(ErrorHandled::Reported(e, _)) => Some(ty::Const::new_error(self.tcx, e.into())),
+        let ct = ty::Const::new_unevaluated(self.tcx, uv);
+
+        match crate::traits::try_evaluate_const(&self.0, ct, param_env) {
+            Ok(ct) => Some(ct),
+            Err(EvaluateConstErr::EvaluationFailure(e)) => Some(ty::Const::new_error(self.tcx, e)),
+            Err(
+                EvaluateConstErr::InvalidConstParamTy(_) | EvaluateConstErr::HasGenericsOrInfers,
+            ) => None,
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 52ba5621d31..103f7c76a86 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -7,7 +7,6 @@ use std::iter;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet, IndexEntry};
 use rustc_data_structures::unord::UnordSet;
 use rustc_infer::infer::DefineOpaqueTypes;
-use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::{Region, RegionVid};
 use tracing::debug;
 use ty::TypingMode;
@@ -761,23 +760,20 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                 ty::PredicateKind::ConstEquate(c1, c2) => {
                     let evaluate = |c: ty::Const<'tcx>| {
                         if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
-                            match selcx.infcx.const_eval_resolve(
+                            let ct = super::try_evaluate_const(
+                                selcx.infcx,
+                                c,
                                 obligation.param_env,
-                                unevaluated,
-                                obligation.cause.span,
-                            ) {
-                                Ok(Ok(valtree)) => Ok(ty::Const::new_value(selcx.tcx(),valtree, self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args))),
-                                Ok(Err(_)) => {
-                                    let tcx = self.tcx;
-                                    let reported =
-                                        tcx.dcx().emit_err(UnableToConstructConstantValue {
-                                            span: tcx.def_span(unevaluated.def),
-                                            unevaluated,
-                                        });
-                                    Err(ErrorHandled::Reported(reported.into(), tcx.def_span(unevaluated.def)))
-                                }
-                                Err(err) => Err(err),
+                            );
+
+                            if let Err(EvaluateConstErr::InvalidConstParamTy(_)) = ct {
+                                self.tcx.dcx().emit_err(UnableToConstructConstantValue {
+                                    span: self.tcx.def_span(unevaluated.def),
+                                    unevaluated,
+                                });
                             }
+
+                            ct
                         } else {
                             Ok(c)
                         }
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 1be3c964454..15eb5d74cbf 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -12,13 +12,13 @@
 use rustc_hir::def::DefKind;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::bug;
-use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor};
 use rustc_span::{DUMMY_SP, Span};
 use tracing::{debug, instrument};
 
+use super::EvaluateConstErr;
 use crate::traits::ObligationCtxt;
 
 /// Check if a given constant can be evaluated.
@@ -68,16 +68,18 @@ pub fn is_const_evaluatable<'tcx>(
                 // here.
                 tcx.dcx().span_bug(span, "evaluating `ConstKind::Expr` is not currently supported");
             }
-            ty::ConstKind::Unevaluated(uv) => {
-                let concrete = infcx.const_eval_resolve(param_env, uv, span);
-                match concrete {
-                    Err(ErrorHandled::TooGeneric(_)) => {
+            ty::ConstKind::Unevaluated(_) => {
+                match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env) {
+                    Err(EvaluateConstErr::HasGenericsOrInfers) => {
                         Err(NotConstEvaluatable::Error(infcx.dcx().span_delayed_bug(
                             span,
                             "Missing value for constant, but no error reported?",
                         )))
                     }
-                    Err(ErrorHandled::Reported(e, _)) => Err(NotConstEvaluatable::Error(e.into())),
+                    Err(
+                        EvaluateConstErr::EvaluationFailure(e)
+                        | EvaluateConstErr::InvalidConstParamTy(e),
+                    ) => Err(NotConstEvaluatable::Error(e.into())),
                     Ok(_) => Ok(()),
                 }
             }
@@ -92,16 +94,7 @@ pub fn is_const_evaluatable<'tcx>(
             _ => bug!("unexpected constkind in `is_const_evalautable: {unexpanded_ct:?}`"),
         };
 
-        // FIXME: We should only try to evaluate a given constant here if it is fully concrete
-        // as we don't want to allow things like `[u8; std::mem::size_of::<*mut T>()]`.
-        //
-        // We previously did not check this, so we only emit a future compat warning if
-        // const evaluation succeeds and the given constant is still polymorphic for now
-        // and hopefully soon change this to an error.
-        //
-        // See #74595 for more details about this.
-        let concrete = infcx.const_eval_resolve(param_env, uv, span);
-        match concrete {
+        match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env) {
             // If we're evaluating a generic foreign constant, under a nightly compiler while
             // the current crate does not enable `feature(generic_const_exprs)`, abort
             // compilation with a useful error.
@@ -130,7 +123,7 @@ pub fn is_const_evaluatable<'tcx>(
                     .emit()
             }
 
-            Err(ErrorHandled::TooGeneric(_)) => {
+            Err(EvaluateConstErr::HasGenericsOrInfers) => {
                 let err = if uv.has_non_region_infer() {
                     NotConstEvaluatable::MentionsInfer
                 } else if uv.has_non_region_param() {
@@ -145,7 +138,9 @@ pub fn is_const_evaluatable<'tcx>(
 
                 Err(err)
             }
-            Err(ErrorHandled::Reported(e, _)) => Err(NotConstEvaluatable::Error(e.into())),
+            Err(
+                EvaluateConstErr::EvaluationFailure(e) | EvaluateConstErr::InvalidConstParamTy(e),
+            ) => Err(NotConstEvaluatable::Error(e.into())),
             Ok(_) => Ok(()),
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 21141f6e18f..2ec5f0d2249 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -10,7 +10,6 @@ use rustc_infer::traits::{
     TraitEngine,
 };
 use rustc_middle::bug;
-use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::{self, Binder, Const, GenericArgsRef, TypeVisitableExt, TypingMode};
@@ -26,6 +25,7 @@ use super::{
 };
 use crate::error_reporting::InferCtxtErrorExt;
 use crate::infer::{InferCtxt, TyOrConstInferVar};
+use crate::traits::EvaluateConstErr;
 use crate::traits::normalize::normalize_with_depth_to;
 use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _};
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
@@ -664,23 +664,25 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
 
                     let mut evaluate = |c: Const<'tcx>| {
                         if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
-                            match self.selcx.infcx.try_const_eval_resolve(
+                            match super::try_evaluate_const(
+                                self.selcx.infcx,
+                                c,
                                 obligation.param_env,
-                                unevaluated,
-                                obligation.cause.span,
                             ) {
                                 Ok(val) => Ok(val),
-                                Err(e) => {
-                                    match e {
-                                        ErrorHandled::TooGeneric(..) => {
-                                            stalled_on.extend(unevaluated.args.iter().filter_map(
-                                                TyOrConstInferVar::maybe_from_generic_arg,
-                                            ));
-                                        }
-                                        _ => {}
-                                    }
-                                    Err(e)
+                                e @ Err(EvaluateConstErr::HasGenericsOrInfers) => {
+                                    stalled_on.extend(
+                                        unevaluated
+                                            .args
+                                            .iter()
+                                            .filter_map(TyOrConstInferVar::maybe_from_generic_arg),
+                                    );
+                                    e
                                 }
+                                e @ Err(
+                                    EvaluateConstErr::EvaluationFailure(_)
+                                    | EvaluateConstErr::InvalidConstParamTy(_),
+                                ) => e,
                             }
                         } else {
                             Ok(c)
@@ -707,14 +709,20 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 }
                             }
                         }
-                        (Err(ErrorHandled::Reported(reported, _)), _)
-                        | (_, Err(ErrorHandled::Reported(reported, _))) => ProcessResult::Error(
-                            FulfillmentErrorCode::Select(SelectionError::NotConstEvaluatable(
-                                NotConstEvaluatable::Error(reported.into()),
-                            )),
-                        ),
-                        (Err(ErrorHandled::TooGeneric(_)), _)
-                        | (_, Err(ErrorHandled::TooGeneric(_))) => {
+                        (Err(EvaluateConstErr::InvalidConstParamTy(e)), _)
+                        | (_, Err(EvaluateConstErr::InvalidConstParamTy(e))) => {
+                            ProcessResult::Error(FulfillmentErrorCode::Select(
+                                SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e)),
+                            ))
+                        }
+                        (Err(EvaluateConstErr::EvaluationFailure(e)), _)
+                        | (_, Err(EvaluateConstErr::EvaluationFailure(e))) => {
+                            ProcessResult::Error(FulfillmentErrorCode::Select(
+                                SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e)),
+                            ))
+                        }
+                        (Err(EvaluateConstErr::HasGenericsOrInfers), _)
+                        | (_, Err(EvaluateConstErr::HasGenericsOrInfers)) => {
                             if c1.has_non_region_infer() || c2.has_non_region_infer() {
                                 ProcessResult::Unchanged
                             } else {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 436c0fabd29..fe90066b4e7 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -27,6 +27,7 @@ use std::fmt::Debug;
 use std::ops::ControlFlow;
 
 use rustc_errors::ErrorGuaranteed;
+use rustc_hir::def::DefKind;
 pub use rustc_infer::traits::*;
 use rustc_middle::query::Providers;
 use rustc_middle::span_bug;
@@ -34,11 +35,11 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{
-    self, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFolder, TypeSuperVisitable, TypingMode,
-    Upcast,
+    self, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFolder, TypeSuperFoldable,
+    TypeSuperVisitable, TypingMode, Upcast,
 };
-use rustc_span::Span;
 use rustc_span::def_id::DefId;
+use rustc_span::{DUMMY_SP, Span};
 use tracing::{debug, instrument};
 
 pub use self::coherence::{
@@ -366,11 +367,23 @@ pub fn normalize_param_env_or_error<'tcx>(
                     if c.has_escaping_bound_vars() {
                         return ty::Const::new_misc_error(self.0);
                     }
+
                     // While it is pretty sus to be evaluating things with an empty param env, it
                     // should actually be okay since without `feature(generic_const_exprs)` the only
                     // const arguments that have a non-empty param env are array repeat counts. These
                     // do not appear in the type system though.
-                    c.normalize_internal(self.0, ty::ParamEnv::empty())
+                    if let ty::ConstKind::Unevaluated(uv) = c.kind()
+                        && self.0.def_kind(uv.def) == DefKind::AnonConst
+                    {
+                        let infcx = self.0.infer_ctxt().build(TypingMode::non_body_analysis());
+                        let c = evaluate_const(&infcx, c, ty::ParamEnv::empty());
+                        // We should never wind up with any `infcx` local state when normalizing anon consts
+                        // under min const generics.
+                        assert!(!c.has_infer() && !c.has_placeholders());
+                        return c;
+                    }
+
+                    c
                 }
             }
 
@@ -474,6 +487,210 @@ pub fn normalize_param_env_or_error<'tcx>(
     ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal())
 }
 
+#[derive(Debug)]
+pub enum EvaluateConstErr {
+    /// The constant being evaluated was either a generic parameter or inference variable, *or*,
+    /// some unevaluated constant with either generic parameters or inference variables in its
+    /// generic arguments.
+    HasGenericsOrInfers,
+    /// The type this constant evalauted to is not valid for use in const generics. This should
+    /// always result in an error when checking the constant is correctly typed for the parameter
+    /// it is an argument to, so a bug is delayed when encountering this.
+    InvalidConstParamTy(ErrorGuaranteed),
+    /// CTFE failed to evaluate the constant in some unrecoverable way (e.g. encountered a `panic!`).
+    /// This is also used when the constant was already tainted by error.
+    EvaluationFailure(ErrorGuaranteed),
+}
+
+// FIXME(BoxyUwU): Private this once we `generic_const_exprs` isn't doing its own normalization routine
+// FIXME(generic_const_exprs): Consider accepting a `ty::UnevaluatedConst` when we are not rolling our own
+// normalization scheme
+/// Evaluates a type system constant returning a `ConstKind::Error` in cases where CTFE failed and
+/// returning the passed in constant if it was not fully concrete (i.e. depended on generic parameters
+/// or inference variables)
+///
+/// You should not call this function unless you are implementing normalization itself. Prefer to use
+/// `normalize_erasing_regions` or the `normalize` functions on `ObligationCtxt`/`FnCtxt`/`InferCtxt`.
+pub fn evaluate_const<'tcx>(
+    infcx: &InferCtxt<'tcx>,
+    ct: ty::Const<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+) -> ty::Const<'tcx> {
+    match try_evaluate_const(infcx, ct, param_env) {
+        Ok(ct) => ct,
+        Err(EvaluateConstErr::EvaluationFailure(e) | EvaluateConstErr::InvalidConstParamTy(e)) => {
+            ty::Const::new_error(infcx.tcx, e)
+        }
+        Err(EvaluateConstErr::HasGenericsOrInfers) => ct,
+    }
+}
+
+// FIXME(BoxyUwU): Private this once we `generic_const_exprs` isn't doing its own normalization routine
+// FIXME(generic_const_exprs): Consider accepting a `ty::UnevaluatedConst` when we are not rolling our own
+// normalization scheme
+/// Evaluates a type system constant making sure to not allow constants that depend on generic parameters
+/// or inference variables to succeed in evaluating.
+///
+/// You should not call this function unless you are implementing normalization itself. Prefer to use
+/// `normalize_erasing_regions` or the `normalize` functions on `ObligationCtxt`/`FnCtxt`/`InferCtxt`.
+#[instrument(level = "debug", skip(infcx), ret)]
+pub fn try_evaluate_const<'tcx>(
+    infcx: &InferCtxt<'tcx>,
+    ct: ty::Const<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+) -> Result<ty::Const<'tcx>, EvaluateConstErr> {
+    let tcx = infcx.tcx;
+    let ct = infcx.resolve_vars_if_possible(ct);
+    debug!(?ct);
+
+    match ct.kind() {
+        ty::ConstKind::Value(..) => Ok(ct),
+        ty::ConstKind::Error(e) => Err(EvaluateConstErr::EvaluationFailure(e)),
+        ty::ConstKind::Param(_)
+        | ty::ConstKind::Infer(_)
+        | ty::ConstKind::Bound(_, _)
+        | ty::ConstKind::Placeholder(_)
+        | ty::ConstKind::Expr(_) => Err(EvaluateConstErr::HasGenericsOrInfers),
+        ty::ConstKind::Unevaluated(uv) => {
+            // Postpone evaluation of constants that depend on generic parameters or inference variables.
+            let (args, param_env) = if tcx.features().generic_const_exprs()
+                && uv.has_non_region_infer()
+            {
+                // `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
+                // inference variables and generic parameters to show up in `ty::Const` even though the anon const
+                // does not actually make use of them. We handle this case specially and attempt to evaluate anyway.
+                match tcx.thir_abstract_const(uv.def) {
+                    Ok(Some(ct)) => {
+                        let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, uv.args));
+                        if let Err(e) = ct.error_reported() {
+                            return Err(EvaluateConstErr::EvaluationFailure(e));
+                        } else if ct.has_non_region_infer() || ct.has_non_region_param() {
+                            // If the anon const *does* actually use generic parameters or inference variables from
+                            // the generic arguments provided for it, then we should *not* attempt to evaluate it.
+                            return Err(EvaluateConstErr::HasGenericsOrInfers);
+                        } else {
+                            (replace_param_and_infer_args_with_placeholder(tcx, uv.args), param_env)
+                        }
+                    }
+                    Err(_) | Ok(None) => {
+                        let args = GenericArgs::identity_for_item(tcx, uv.def);
+                        let param_env = tcx.param_env(uv.def);
+                        (args, param_env)
+                    }
+                }
+            } else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() {
+                // FIXME: remove this when `const_evaluatable_unchecked` is a hard error.
+                //
+                // Diagnostics will sometimes replace the identity args of anon consts in
+                // array repeat expr counts with inference variables so we have to handle this
+                // even though it is not something we should ever actually encounter.
+                //
+                // Array repeat expr counts are allowed to syntactically use generic parameters
+                // but must not actually depend on them in order to evalaute succesfully. This means
+                // that it is actually fine to evalaute them in their own environment rather than with
+                // the actually provided generic arguments.
+                tcx.dcx().delayed_bug(
+                    "Encountered anon const with inference variable args but no error reported",
+                );
+
+                let args = GenericArgs::identity_for_item(tcx, uv.def);
+                let param_env = tcx.param_env(uv.def);
+                (args, param_env)
+            } else {
+                // FIXME: This codepath is reachable under `associated_const_equality` and in the
+                // future will be reachable by `min_generic_const_args`. We should handle inference
+                // variables and generic parameters properly instead of doing nothing.
+                (uv.args, param_env)
+            };
+            let uv = ty::UnevaluatedConst::new(uv.def, args);
+
+            // It's not *technically* correct to be revealing opaque types here as we could still be
+            // before borrowchecking. However, CTFE itself uses `Reveal::All` unconditionally even during
+            // typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821). As a result we
+            // always use a revealed env when resolving the instance to evaluate.
+            //
+            // FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
+            // instead of having this logic here
+            let env = tcx.erase_regions(param_env).with_reveal_all_normalized(tcx);
+            let erased_uv = tcx.erase_regions(uv);
+
+            use rustc_middle::mir::interpret::ErrorHandled;
+            match tcx.const_eval_resolve_for_typeck(env, erased_uv, DUMMY_SP) {
+                Ok(Ok(val)) => Ok(ty::Const::new_value(
+                    tcx,
+                    val,
+                    tcx.type_of(uv.def).instantiate(tcx, uv.args),
+                )),
+                Ok(Err(_)) => {
+                    let e = tcx.dcx().delayed_bug(
+                        "Type system constant with non valtree'able type evaluated but no error emitted",
+                    );
+                    Err(EvaluateConstErr::InvalidConstParamTy(e))
+                }
+                Err(ErrorHandled::Reported(info, _)) => {
+                    Err(EvaluateConstErr::EvaluationFailure(info.into()))
+                }
+                Err(ErrorHandled::TooGeneric(_)) => Err(EvaluateConstErr::HasGenericsOrInfers),
+            }
+        }
+    }
+}
+
+/// Replaces args that reference param or infer variables with suitable
+/// placeholders. This function is meant to remove these param and infer
+/// args when they're not actually needed to evaluate a constant.
+fn replace_param_and_infer_args_with_placeholder<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    args: GenericArgsRef<'tcx>,
+) -> GenericArgsRef<'tcx> {
+    struct ReplaceParamAndInferWithPlaceholder<'tcx> {
+        tcx: TyCtxt<'tcx>,
+        idx: u32,
+    }
+
+    impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceParamAndInferWithPlaceholder<'tcx> {
+        fn cx(&self) -> TyCtxt<'tcx> {
+            self.tcx
+        }
+
+        fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+            if let ty::Infer(_) = t.kind() {
+                let idx = {
+                    let idx = self.idx;
+                    self.idx += 1;
+                    idx
+                };
+                Ty::new_placeholder(self.tcx, ty::PlaceholderType {
+                    universe: ty::UniverseIndex::ROOT,
+                    bound: ty::BoundTy {
+                        var: ty::BoundVar::from_u32(idx),
+                        kind: ty::BoundTyKind::Anon,
+                    },
+                })
+            } else {
+                t.super_fold_with(self)
+            }
+        }
+
+        fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
+            if let ty::ConstKind::Infer(_) = c.kind() {
+                ty::Const::new_placeholder(self.tcx, ty::PlaceholderConst {
+                    universe: ty::UniverseIndex::ROOT,
+                    bound: ty::BoundVar::from_u32({
+                        let idx = self.idx;
+                        self.idx += 1;
+                        idx
+                    }),
+                })
+            } else {
+                c.super_fold_with(self)
+            }
+        }
+    }
+
+    args.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 })
+}
+
 /// Normalizes the predicates and checks whether they hold in an empty environment. If this
 /// returns true, then either normalize encountered an error or one of the predicates did not
 /// hold. Used when creating vtables to check for unsatisfiable methods. This should not be
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index 954dfe93387..5c38d162712 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -418,8 +418,9 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
                 self.selcx.infcx,
                 &mut self.universes,
                 constant,
-                |constant| constant.normalize_internal(tcx, self.param_env),
+                |constant| super::evaluate_const(self.selcx.infcx, constant, self.param_env),
             )
+            .super_fold_with(self)
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index a8d701a750d..5f89894fb82 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -342,7 +342,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
             self.infcx,
             &mut self.universes,
             constant,
-            |constant| constant.normalize_internal(self.infcx.tcx, self.param_env),
+            |constant| crate::traits::evaluate_const(&self.infcx, constant, self.param_env),
         );
         debug!(?constant, ?self.param_env);
         constant.try_super_fold_with(self)
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 041cfc21267..712856e6a8f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -403,7 +403,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let mut assume = predicate.trait_ref.args.const_at(2);
         // FIXME(min_generic_const_exprs): We should shallowly normalize this.
         if self.tcx().features().generic_const_exprs() {
-            assume = assume.normalize_internal(self.tcx(), obligation.param_env);
+            assume = crate::traits::evaluate_const(self.infcx, assume, obligation.param_env)
         }
         let Some(assume) =
             rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, assume)
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index cffb62ab559..5b4e895189b 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -22,7 +22,6 @@ use rustc_infer::infer::relate::TypeRelation;
 use rustc_infer::traits::{PredicateObligations, TraitObligation};
 use rustc_middle::bug;
 use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds};
-use rustc_middle::mir::interpret::ErrorHandled;
 pub use rustc_middle::traits::select::*;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::error::TypeErrorToStringExt;
@@ -50,7 +49,7 @@ use crate::infer::{InferCtxt, InferOk, TypeFreshener};
 use crate::solve::InferCtxtSelectExt as _;
 use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
 use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt};
-use crate::traits::{ProjectionCacheKey, Unimplemented, effects};
+use crate::traits::{EvaluateConstErr, ProjectionCacheKey, Unimplemented, effects};
 
 mod _match;
 mod candidate_assembly;
@@ -931,11 +930,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     }
 
                     let evaluate = |c: ty::Const<'tcx>| {
-                        if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
-                            match self.infcx.try_const_eval_resolve(
+                        if let ty::ConstKind::Unevaluated(_) = c.kind() {
+                            match crate::traits::try_evaluate_const(
+                                self.infcx,
+                                c,
                                 obligation.param_env,
-                                unevaluated,
-                                obligation.cause.span,
                             ) {
                                 Ok(val) => Ok(val),
                                 Err(e) => Err(e),
@@ -961,10 +960,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 Err(_) => Ok(EvaluatedToErr),
                             }
                         }
-                        (Err(ErrorHandled::Reported(..)), _)
-                        | (_, Err(ErrorHandled::Reported(..))) => Ok(EvaluatedToErr),
-                        (Err(ErrorHandled::TooGeneric(..)), _)
-                        | (_, Err(ErrorHandled::TooGeneric(..))) => {
+                        (Err(EvaluateConstErr::InvalidConstParamTy(..)), _)
+                        | (_, Err(EvaluateConstErr::InvalidConstParamTy(..))) => Ok(EvaluatedToErr),
+                        (Err(EvaluateConstErr::EvaluationFailure(..)), _)
+                        | (_, Err(EvaluateConstErr::EvaluationFailure(..))) => Ok(EvaluatedToErr),
+                        (Err(EvaluateConstErr::HasGenericsOrInfers), _)
+                        | (_, Err(EvaluateConstErr::HasGenericsOrInfers)) => {
                             if c1.has_non_region_infer() || c2.has_non_region_infer() {
                                 Ok(EvaluatedToAmbig)
                             } else {
diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
index 23b5f62b5ca..f8e8f2176c1 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs
@@ -83,7 +83,7 @@ impl<'tcx> At<'_, 'tcx> {
 
             Ok(self.infcx.resolve_vars_if_possible(new_infer_ct))
         } else if self.infcx.tcx.features().generic_const_exprs() {
-            Ok(ct.normalize_internal(self.infcx.tcx, self.param_env))
+            Ok(super::evaluate_const(&self.infcx, ct, self.param_env))
         } else {
             Ok(self.normalize(ct).into_value_registering_obligations(self.infcx, fulfill_cx))
         }
diff --git a/config.example.toml b/config.example.toml
index cd7ec6a05bc..9dc71b10f70 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -500,10 +500,11 @@
 # This is useful if you are working on tools, doc-comments, or library (you will be able to build
 # the standard library without needing to build the compiler).
 #
-# Set this to "if-unchanged" to only download if the compiler (and library if running on CI) have
-# not been modified.
-# Set this to `true` to download unconditionally.
-#download-rustc = false
+# Set this to "if-unchanged" if you are working on `src/tools`, `tests` or `library` (on CI, `library`
+# changes triggers in-tree compiler build) to speed up the build process.
+#
+# Set this to `true` to always download or `false` to always use the in-tree compiler.
+#download-rustc = "if-unchanged"
 
 # Number of codegen units to use for each compiler invocation. A value of 0
 # means "the number of cores on this machine", and 1+ is passed through to the
@@ -594,8 +595,7 @@
 
 # Build a multi-threaded rustc. This allows users to use parallel rustc
 # via the unstable option `-Z threads=n`.
-# Since stable/beta channels only allow using stable features,
-# `parallel-compiler = false` should be set for these channels.
+# This option is deprecated and always true.
 #parallel-compiler = true
 
 # The default linker that will be hard-coded into the generated
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 772f9b19695..70ecac4e17c 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -79,9 +79,9 @@ dependencies = [
 
 [[package]]
 name = "dlmalloc"
-version = "0.2.6"
+version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3264b043b8e977326c1ee9e723da2c1f8d09a99df52cacf00b4dbce5ac54414d"
+checksum = "d9b5e0d321d61de16390ed273b647ce51605b575916d3c25e6ddf27a1e140035"
 dependencies = [
  "cfg-if",
  "compiler_builtins",
@@ -189,9 +189,9 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.36.4"
+version = "0.36.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
+checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
 dependencies = [
  "compiler_builtins",
  "memchr",
@@ -427,9 +427,9 @@ dependencies = [
 
 [[package]]
 name = "windows-sys"
-version = "0.52.0"
+version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
 dependencies = [
  "windows-targets 0.52.6",
 ]
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index a91659b6de5..98402a46201 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -155,11 +155,14 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8
 /// # Examples
 ///
 /// ```
-/// use std::alloc::{alloc_zeroed, dealloc, Layout};
+/// use std::alloc::{alloc_zeroed, dealloc, handle_alloc_error, Layout};
 ///
 /// unsafe {
 ///     let layout = Layout::new::<u16>();
 ///     let ptr = alloc_zeroed(layout);
+///     if ptr.is_null() {
+///         handle_alloc_error(layout);
+///     }
 ///
 ///     assert_eq!(*(ptr as *mut u16), 0);
 ///
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index e4956c7c53c..bb6dd1d2d30 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -225,6 +225,7 @@ pub use thin::ThinBox;
 #[fundamental]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_insignificant_dtor]
+#[cfg_attr(not(bootstrap), doc(search_unbox))]
 // The declaration of the `Box` struct must be kept in sync with the
 // compiler or ICEs will happen.
 pub struct Box<
@@ -1734,7 +1735,7 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
         // Pre-allocate memory to allow writing the cloned value directly.
         let mut boxed = Self::new_uninit_in(self.1.clone());
         unsafe {
-            (**self).clone_to_uninit(boxed.as_mut_ptr());
+            (**self).clone_to_uninit(boxed.as_mut_ptr().cast());
             boxed.assume_init()
         }
     }
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 55649d865fc..66353ccfa47 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -289,40 +289,12 @@ impl<K: Clone, V: Clone, A: Allocator + Clone> Clone for BTreeMap<K, V, A> {
     }
 }
 
-impl<K, Q: ?Sized, A: Allocator + Clone> super::Recover<Q> for BTreeMap<K, SetValZST, A>
-where
-    K: Borrow<Q> + Ord,
-    Q: Ord,
-{
-    type Key = K;
-
-    fn get(&self, key: &Q) -> Option<&K> {
-        let root_node = self.root.as_ref()?.reborrow();
-        match root_node.search_tree(key) {
-            Found(handle) => Some(handle.into_kv().0),
-            GoDown(_) => None,
-        }
-    }
-
-    fn take(&mut self, key: &Q) -> Option<K> {
-        let (map, dormant_map) = DormantMutRef::new(self);
-        let root_node = map.root.as_mut()?.borrow_mut();
-        match root_node.search_tree(key) {
-            Found(handle) => Some(
-                OccupiedEntry {
-                    handle,
-                    dormant_map,
-                    alloc: (*map.alloc).clone(),
-                    _marker: PhantomData,
-                }
-                .remove_kv()
-                .0,
-            ),
-            GoDown(_) => None,
-        }
-    }
-
-    fn replace(&mut self, key: K) -> Option<K> {
+/// Internal functionality for `BTreeSet`.
+impl<K, A: Allocator + Clone> BTreeMap<K, SetValZST, A> {
+    pub(super) fn replace(&mut self, key: K) -> Option<K>
+    where
+        K: Ord,
+    {
         let (map, dormant_map) = DormantMutRef::new(self);
         let root_node =
             map.root.get_or_insert_with(|| Root::new((*map.alloc).clone())).borrow_mut();
diff --git a/library/alloc/src/collections/btree/mod.rs b/library/alloc/src/collections/btree/mod.rs
index c7d0144de30..b8667d09c33 100644
--- a/library/alloc/src/collections/btree/mod.rs
+++ b/library/alloc/src/collections/btree/mod.rs
@@ -12,11 +12,3 @@ mod search;
 pub mod set;
 mod set_val;
 mod split;
-
-trait Recover<Q: ?Sized> {
-    type Key;
-
-    fn get(&self, key: &Q) -> Option<&Self::Key>;
-    fn take(&mut self, key: &Q) -> Option<Self::Key>;
-    fn replace(&mut self, key: Self::Key) -> Option<Self::Key>;
-}
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index a40209fa2e3..8daee6030c2 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -7,7 +7,6 @@ use core::iter::{FusedIterator, Peekable};
 use core::mem::ManuallyDrop;
 use core::ops::{BitAnd, BitOr, BitXor, Bound, RangeBounds, Sub};
 
-use super::Recover;
 use super::map::{BTreeMap, Keys};
 use super::merge_iter::MergeIterInner;
 use super::set_val::SetValZST;
@@ -635,7 +634,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
         T: Borrow<Q> + Ord,
         Q: Ord,
     {
-        Recover::get(&self.map, value)
+        self.map.get_key_value(value).map(|(k, _)| k)
     }
 
     /// Returns `true` if `self` has no elements in common with `other`.
@@ -926,7 +925,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
     where
         T: Ord,
     {
-        Recover::replace(&mut self.map, value)
+        self.map.replace(value)
     }
 
     /// If the set contains an element equal to the value, removes it from the
@@ -978,7 +977,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
         T: Borrow<Q> + Ord,
         Q: Ord,
     {
-        Recover::take(&mut self.map, value)
+        self.map.remove_entry(value).map(|(k, _)| k)
     }
 
     /// Retains only the elements specified by the predicate.
diff --git a/library/alloc/src/collections/btree/set_val.rs b/library/alloc/src/collections/btree/set_val.rs
index 80c459bcf81..cf30160bfbb 100644
--- a/library/alloc/src/collections/btree/set_val.rs
+++ b/library/alloc/src/collections/btree/set_val.rs
@@ -3,14 +3,14 @@
 /// * `BTreeMap<T, ()>` (possible user-defined map)
 /// * `BTreeMap<T, SetValZST>` (internal set representation)
 #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Default)]
-pub struct SetValZST;
+pub(super) struct SetValZST;
 
 /// A trait to differentiate between `BTreeMap` and `BTreeSet` values.
 /// Returns `true` only for type `SetValZST`, `false` for all other types (blanket implementation).
 /// `TypeId` requires a `'static` lifetime, use of this trait avoids that restriction.
 ///
 /// [`TypeId`]: std::any::TypeId
-pub trait IsSetVal {
+pub(super) trait IsSetVal {
     fn is_set_val() -> bool;
 }
 
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 64b0520e983..3a9bd1b5bf1 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -307,6 +307,7 @@ fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout {
 /// `value.get_mut()`. This avoids conflicts with methods of the inner type `T`.
 ///
 /// [get_mut]: Rc::get_mut
+#[cfg_attr(not(bootstrap), doc(search_unbox))]
 #[cfg_attr(not(test), rustc_diagnostic_item = "Rc")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_insignificant_dtor]
@@ -1875,7 +1876,7 @@ impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Rc<T, A> {
             // Initialize with clone of this.
             let initialized_clone = unsafe {
                 // Clone. If the clone panics, `in_progress` will be dropped and clean up.
-                this_data_ref.clone_to_uninit(in_progress.data_ptr());
+                this_data_ref.clone_to_uninit(in_progress.data_ptr().cast());
                 // Cast type of pointer, now that it is initialized.
                 in_progress.into_rc()
             };
@@ -2931,7 +2932,9 @@ impl<T, I: iter::TrustedLen<Item = T>> ToRcSlice<T> for I {
 }
 
 /// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
-/// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
+/// managed allocation.
+///
+/// The allocation is accessed by calling [`upgrade`] on the `Weak`
 /// pointer, which returns an <code>[Option]<[Rc]\<T>></code>.
 ///
 /// Since a `Weak` reference does not count towards ownership, it will not
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index f348fba6220..da2d6bb3bce 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -235,6 +235,7 @@ macro_rules! acquire {
 /// counting in general.
 ///
 /// [rc_examples]: crate::rc#examples
+#[cfg_attr(not(bootstrap), doc(search_unbox))]
 #[cfg_attr(not(test), rustc_diagnostic_item = "Arc")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_insignificant_dtor]
@@ -290,7 +291,9 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
 }
 
 /// `Weak` is a version of [`Arc`] that holds a non-owning reference to the
-/// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
+/// managed allocation.
+///
+/// The allocation is accessed by calling [`upgrade`] on the `Weak`
 /// pointer, which returns an <code>[Option]<[Arc]\<T>></code>.
 ///
 /// Since a `Weak` reference does not count towards ownership, it will not
@@ -2269,7 +2272,7 @@ impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Arc<T, A> {
 
             let initialized_clone = unsafe {
                 // Clone. If the clone panics, `in_progress` will be dropped and clean up.
-                this_data_ref.clone_to_uninit(in_progress.data_ptr());
+                this_data_ref.clone_to_uninit(in_progress.data_ptr().cast());
                 // Cast type of pointer, now that it is initialized.
                 in_progress.into_arc()
             };
diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs
index 27589aed2f9..0f8e74300a4 100644
--- a/library/alloc/src/task.rs
+++ b/library/alloc/src/task.rs
@@ -176,9 +176,11 @@ fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
     )
 }
 
-/// An analogous trait to `Wake` but used to construct a `LocalWaker`. This API
-/// works in exactly the same way as `Wake`, except that it uses an `Rc` instead
-/// of an `Arc`, and the result is a `LocalWaker` instead of a `Waker`.
+/// An analogous trait to `Wake` but used to construct a `LocalWaker`.
+///
+/// This API works in exactly the same way as `Wake`,
+/// except that it uses an `Rc` instead of an `Arc`,
+/// and the result is a `LocalWaker` instead of a `Waker`.
 ///
 /// The benefits of using `LocalWaker` over `Waker` are that it allows the local waker
 /// to hold data that does not implement `Send` and `Sync`. Additionally, it saves calls
diff --git a/library/core/benches/fmt.rs b/library/core/benches/fmt.rs
index 4baefd55788..ed478b0f1e0 100644
--- a/library/core/benches/fmt.rs
+++ b/library/core/benches/fmt.rs
@@ -149,3 +149,17 @@ fn write_u64_min(bh: &mut Bencher) {
         test::black_box(format!("{}", 0u64));
     });
 }
+
+#[bench]
+fn write_u8_max(bh: &mut Bencher) {
+    bh.iter(|| {
+        test::black_box(format!("{}", u8::MAX));
+    });
+}
+
+#[bench]
+fn write_u8_min(bh: &mut Bencher) {
+    bh.iter(|| {
+        test::black_box(format!("{}", 0u8));
+    });
+}
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index ab76cd7a6be..1a461987c76 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -3,8 +3,8 @@
 //! Rust memory safety is based on this rule: Given an object `T`, it is only possible to
 //! have one of the following:
 //!
-//! - Having several immutable references (`&T`) to the object (also known as **aliasing**).
-//! - Having one mutable reference (`&mut T`) to the object (also known as **mutability**).
+//! - Several immutable references (`&T`) to the object (also known as **aliasing**).
+//! - One mutable reference (`&mut T`) to the object (also known as **mutability**).
 //!
 //! This is enforced by the Rust compiler. However, there are situations where this rule is not
 //! flexible enough. Sometimes it is required to have multiple references to an object and yet
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index 02cc0f9d770..974e7baccf7 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -301,7 +301,7 @@ impl char {
     ///
     /// # Panics
     ///
-    /// Panics if given a radix larger than 36.
+    /// Panics if given a radix smaller than 2 or larger than 36.
     ///
     /// # Examples
     ///
@@ -319,6 +319,13 @@ impl char {
     /// // this panics
     /// '1'.is_digit(37);
     /// ```
+    ///
+    /// Passing a small radix, causing a panic:
+    ///
+    /// ```should_panic
+    /// // this panics
+    /// '1'.is_digit(1);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_char_classify", issue = "132241")]
     #[inline]
@@ -345,7 +352,7 @@ impl char {
     ///
     /// # Panics
     ///
-    /// Panics if given a radix larger than 36.
+    /// Panics if given a radix smaller than 2 or larger than 36.
     ///
     /// # Examples
     ///
@@ -369,24 +376,35 @@ impl char {
     /// // this panics
     /// let _ = '1'.to_digit(37);
     /// ```
+    /// Passing a small radix, causing a panic:
+    ///
+    /// ```should_panic
+    /// // this panics
+    /// let _ = '1'.to_digit(1);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_char_convert", since = "1.67.0")]
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[inline]
     pub const fn to_digit(self, radix: u32) -> Option<u32> {
-        // If not a digit, a number greater than radix will be created.
-        let mut digit = (self as u32).wrapping_sub('0' as u32);
-        if radix > 10 {
-            assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
-            if digit < 10 {
-                return Some(digit);
-            }
-            // Force the 6th bit to be set to ensure ascii is lower case.
-            digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
-        }
+        assert!(
+            radix >= 2 && radix <= 36,
+            "to_digit: invalid radix -- radix must be in the range 2 to 36 inclusive"
+        );
+        // check radix to remove letter handling code when radix is a known constant
+        let value = if self > '9' && radix > 10 {
+            // convert ASCII letters to lowercase
+            let lower = self as u32 | 0x20;
+            // convert an ASCII letter to the corresponding value,
+            // non-letters convert to values > 36
+            lower.wrapping_sub('a' as u32) as u64 + 10
+        } else {
+            // convert digit to value, non-digits wrap to values > 36
+            (self as u32).wrapping_sub('0' as u32) as u64
+        };
         // FIXME(const-hack): once then_some is const fn, use it here
-        if digit < radix { Some(digit) } else { None }
+        if value < radix as u64 { Some(value as u32) } else { None }
     }
 
     /// Returns an iterator that yields the hexadecimal Unicode escape of a
@@ -775,13 +793,12 @@ impl char {
     /// In a const context:
     ///
     /// ```
-    /// #![feature(const_unicode_case_lookup)]
     /// const CAPITAL_DELTA_IS_LOWERCASE: bool = 'Δ'.is_lowercase();
     /// assert!(!CAPITAL_DELTA_IS_LOWERCASE);
     /// ```
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_unicode_case_lookup", issue = "101400")]
+    #[rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0")]
     #[inline]
     pub const fn is_lowercase(self) -> bool {
         match self {
@@ -817,13 +834,12 @@ impl char {
     /// In a const context:
     ///
     /// ```
-    /// #![feature(const_unicode_case_lookup)]
     /// const CAPITAL_DELTA_IS_UPPERCASE: bool = 'Δ'.is_uppercase();
     /// assert!(CAPITAL_DELTA_IS_UPPERCASE);
     /// ```
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_unicode_case_lookup", issue = "101400")]
+    #[rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0")]
     #[inline]
     pub const fn is_uppercase(self) -> bool {
         match self {
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index c5f8bd7401e..ec1aed53eaf 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -232,20 +232,20 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> {
 pub unsafe trait CloneToUninit {
     /// Performs copy-assignment from `self` to `dst`.
     ///
-    /// This is analogous to `std::ptr::write(dst, self.clone())`,
+    /// This is analogous to `std::ptr::write(dst.cast(), self.clone())`,
     /// except that `self` may be a dynamically-sized type ([`!Sized`](Sized)).
     ///
     /// Before this function is called, `dst` may point to uninitialized memory.
     /// After this function is called, `dst` will point to initialized memory; it will be
-    /// sound to create a `&Self` reference from the pointer.
+    /// sound to create a `&Self` reference from the pointer with the [pointer metadata]
+    /// from `self`.
     ///
     /// # Safety
     ///
     /// Behavior is undefined if any of the following conditions are violated:
     ///
-    /// * `dst` must be [valid] for writes.
-    /// * `dst` must be properly aligned.
-    /// * `dst` must have the same [pointer metadata] (slice length or `dyn` vtable) as `self`.
+    /// * `dst` must be [valid] for writes for `std::mem::size_of_val(self)` bytes.
+    /// * `dst` must be properly aligned to `std::mem::align_of_val(self)`.
     ///
     /// [valid]: crate::ptr#safety
     /// [pointer metadata]: crate::ptr::metadata()
@@ -266,15 +266,15 @@ pub unsafe trait CloneToUninit {
     /// that might have already been created. (For example, if a `[Foo]` of length 3 is being
     /// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo`
     /// cloned should be dropped.)
-    unsafe fn clone_to_uninit(&self, dst: *mut Self);
+    unsafe fn clone_to_uninit(&self, dst: *mut u8);
 }
 
 #[unstable(feature = "clone_to_uninit", issue = "126799")]
 unsafe impl<T: Clone> CloneToUninit for T {
     #[inline]
-    unsafe fn clone_to_uninit(&self, dst: *mut Self) {
+    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
         // SAFETY: we're calling a specialization with the same contract
-        unsafe { <T as self::uninit::CopySpec>::clone_one(self, dst) }
+        unsafe { <T as self::uninit::CopySpec>::clone_one(self, dst.cast::<T>()) }
     }
 }
 
@@ -282,7 +282,8 @@ unsafe impl<T: Clone> CloneToUninit for T {
 unsafe impl<T: Clone> CloneToUninit for [T] {
     #[inline]
     #[cfg_attr(debug_assertions, track_caller)]
-    unsafe fn clone_to_uninit(&self, dst: *mut Self) {
+    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
+        let dst: *mut [T] = dst.with_metadata_of(self);
         // SAFETY: we're calling a specialization with the same contract
         unsafe { <T as self::uninit::CopySpec>::clone_slice(self, dst) }
     }
@@ -292,21 +293,21 @@ unsafe impl<T: Clone> CloneToUninit for [T] {
 unsafe impl CloneToUninit for str {
     #[inline]
     #[cfg_attr(debug_assertions, track_caller)]
-    unsafe fn clone_to_uninit(&self, dst: *mut Self) {
+    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
         // SAFETY: str is just a [u8] with UTF-8 invariant
-        unsafe { self.as_bytes().clone_to_uninit(dst as *mut [u8]) }
+        unsafe { self.as_bytes().clone_to_uninit(dst) }
     }
 }
 
 #[unstable(feature = "clone_to_uninit", issue = "126799")]
 unsafe impl CloneToUninit for crate::ffi::CStr {
     #[cfg_attr(debug_assertions, track_caller)]
-    unsafe fn clone_to_uninit(&self, dst: *mut Self) {
+    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
         // SAFETY: For now, CStr is just a #[repr(trasnsparent)] [c_char] with some invariants.
         // And we can cast [c_char] to [u8] on all supported platforms (see: to_bytes_with_nul).
-        // The pointer metadata properly preserves the length (NUL included).
+        // The pointer metadata properly preserves the length (so NUL is also copied).
         // See: `cstr_metadata_is_length_with_nul` in tests.
-        unsafe { self.to_bytes_with_nul().clone_to_uninit(dst as *mut [u8]) }
+        unsafe { self.to_bytes_with_nul().clone_to_uninit(dst) }
     }
 }
 
diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs
index c70dbf54304..04230b1610a 100644
--- a/library/core/src/fmt/float.rs
+++ b/library/core/src/fmt/float.rs
@@ -13,7 +13,7 @@ macro_rules! impl_general_format {
     ($($t:ident)*) => {
         $(impl GeneralFormat for $t {
             fn already_rounded_value_should_use_exponential(&self) -> bool {
-                let abs = $t::abs_private(*self);
+                let abs = $t::abs(*self);
                 (abs != 0.0 && abs < 1e-4) || abs >= 1e+16
             }
         })*
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index d43f25d9fd1..f2d7e0f481e 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -65,11 +65,11 @@ unsafe trait GenericRadix: Sized {
         if is_nonnegative {
             // Accumulate each digit of the number from the least significant
             // to the most significant figure.
-            for byte in buf.iter_mut().rev() {
+            loop {
                 let n = x % base; // Get the current place value.
                 x = x / base; // Deaccumulate the number.
-                byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer.
                 curr -= 1;
+                buf[curr].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
                 if x == zero {
                     // No more digits left to accumulate.
                     break;
@@ -77,11 +77,11 @@ unsafe trait GenericRadix: Sized {
             }
         } else {
             // Do the same as above, but accounting for two's complement.
-            for byte in buf.iter_mut().rev() {
+            loop {
                 let n = zero - (x % base); // Get the current place value.
                 x = x / base; // Deaccumulate the number.
-                byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer.
                 curr -= 1;
+                buf[curr].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
                 if x == zero {
                     // No more digits left to accumulate.
                     break;
diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs
index ca1c2d1ca1f..234914c20fc 100644
--- a/library/core/src/future/future.rs
+++ b/library/core/src/future/future.rs
@@ -25,6 +25,7 @@ use crate::task::{Context, Poll};
 /// [`async`]: ../../std/keyword.async.html
 /// [`Waker`]: crate::task::Waker
 #[doc(notable_trait)]
+#[cfg_attr(not(bootstrap), doc(search_unbox))]
 #[must_use = "futures do nothing unless you `.await` or poll them"]
 #[stable(feature = "futures_api", since = "1.36.0")]
 #[lang = "future_trait"]
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index b6e22c42eee..72e34e5faf5 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -85,830 +85,1304 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     unsafe { crate::ptr::drop_in_place(to_drop) }
 }
 
-extern "rust-intrinsic" {
-    // N.B., these intrinsics take raw pointers because they mutate aliased
-    // memory, which is not valid for either `&` or `&mut`.
+// N.B., these intrinsics take raw pointers because they mutate aliased
+// memory, which is not valid for either `&` or `&mut`.
 
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Relaxed`] as both the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Acquire`] as both the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange` method by passing
-    /// [`Ordering::SeqCst`] as both the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchg_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::Relaxed`] as both the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_relaxed_relaxed<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_relaxed_acquire<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_relaxed_seqcst<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_acquire_relaxed<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::Acquire`] as both the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_acquire_acquire<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_acquire_seqcst<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_release_relaxed<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_release_acquire<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_release_seqcst<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_acqrel_relaxed<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_acqrel_acquire<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_acqrel_seqcst<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_seqcst_relaxed<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_seqcst_acquire<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange` method by passing
+/// [`Ordering::SeqCst`] as both the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchg_seqcst_seqcst<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
 
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Relaxed`] as both the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Acquire`] as both the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
-    /// Stores a value if the current value is the same as the `old` value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `compare_exchange_weak` method by passing
-    /// [`Ordering::SeqCst`] as both the success and failure parameters.
-    /// For example, [`AtomicBool::compare_exchange_weak`].
-    #[rustc_nounwind]
-    pub fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::Relaxed`] as both the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_relaxed_relaxed<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_relaxed_acquire<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_relaxed_seqcst<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_acquire_relaxed<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::Acquire`] as both the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_acquire_acquire<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_acquire_seqcst<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_release_relaxed<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_release_acquire<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_release_seqcst<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_acqrel_relaxed<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_acqrel_acquire<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_acqrel_seqcst<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_seqcst_relaxed<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_seqcst_acquire<T: Copy>(
+    _dst: *mut T,
+    _old: T,
+    _src: T,
+) -> (T, bool) {
+    unreachable!()
+}
+/// Stores a value if the current value is the same as the `old` value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `compare_exchange_weak` method by passing
+/// [`Ordering::SeqCst`] as both the success and failure parameters.
+/// For example, [`AtomicBool::compare_exchange_weak`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(_dst: *mut T, _old: T, _src: T) -> (T, bool) {
+    unreachable!()
+}
 
-    /// Loads the current value of the pointer.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `load` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`].
-    #[rustc_nounwind]
-    pub fn atomic_load_seqcst<T: Copy>(src: *const T) -> T;
-    /// Loads the current value of the pointer.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `load` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`].
-    #[rustc_nounwind]
-    pub fn atomic_load_acquire<T: Copy>(src: *const T) -> T;
-    /// Loads the current value of the pointer.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `load` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::load`].
-    #[rustc_nounwind]
-    pub fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
-    /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model!
-    /// In terms of the Rust Abstract Machine, this operation is equivalent to `src.read()`,
-    /// i.e., it performs a non-atomic read.
-    #[rustc_nounwind]
-    pub fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
+/// Loads the current value of the pointer.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `load` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_load_seqcst<T: Copy>(_src: *const T) -> T {
+    unreachable!()
+}
+/// Loads the current value of the pointer.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `load` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_load_acquire<T: Copy>(_src: *const T) -> T {
+    unreachable!()
+}
+/// Loads the current value of the pointer.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `load` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::load`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_load_relaxed<T: Copy>(_src: *const T) -> T {
+    unreachable!()
+}
+/// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model!
+/// In terms of the Rust Abstract Machine, this operation is equivalent to `src.read()`,
+/// i.e., it performs a non-atomic read.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_load_unordered<T: Copy>(_src: *const T) -> T {
+    unreachable!()
+}
 
-    /// Stores the value at the specified memory location.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `store` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`].
-    #[rustc_nounwind]
-    pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
-    /// Stores the value at the specified memory location.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `store` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`].
-    #[rustc_nounwind]
-    pub fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
-    /// Stores the value at the specified memory location.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `store` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::store`].
-    #[rustc_nounwind]
-    pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
-    /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model!
-    /// In terms of the Rust Abstract Machine, this operation is equivalent to `dst.write(val)`,
-    /// i.e., it performs a non-atomic write.
-    #[rustc_nounwind]
-    pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
+/// Stores the value at the specified memory location.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `store` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_store_seqcst<T: Copy>(_dst: *mut T, _val: T) {
+    unreachable!()
+}
+/// Stores the value at the specified memory location.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `store` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_store_release<T: Copy>(_dst: *mut T, _val: T) {
+    unreachable!()
+}
+/// Stores the value at the specified memory location.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `store` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::store`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_store_relaxed<T: Copy>(_dst: *mut T, _val: T) {
+    unreachable!()
+}
+/// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model!
+/// In terms of the Rust Abstract Machine, this operation is equivalent to `dst.write(val)`,
+/// i.e., it performs a non-atomic write.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_store_unordered<T: Copy>(_dst: *mut T, _val: T) {
+    unreachable!()
+}
 
-    /// Stores the value at the specified memory location, returning the old value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `swap` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`].
-    #[rustc_nounwind]
-    pub fn atomic_xchg_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Stores the value at the specified memory location, returning the old value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `swap` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`].
-    #[rustc_nounwind]
-    pub fn atomic_xchg_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Stores the value at the specified memory location, returning the old value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `swap` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`].
-    #[rustc_nounwind]
-    pub fn atomic_xchg_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Stores the value at the specified memory location, returning the old value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `swap` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::swap`].
-    #[rustc_nounwind]
-    pub fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Stores the value at the specified memory location, returning the old value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `swap` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::swap`].
-    #[rustc_nounwind]
-    pub fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Stores the value at the specified memory location, returning the old value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `swap` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xchg_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Stores the value at the specified memory location, returning the old value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `swap` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xchg_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Stores the value at the specified memory location, returning the old value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `swap` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xchg_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Stores the value at the specified memory location, returning the old value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `swap` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::swap`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xchg_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Stores the value at the specified memory location, returning the old value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `swap` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::swap`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xchg_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Adds to the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_add` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-    #[rustc_nounwind]
-    pub fn atomic_xadd_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Adds to the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_add` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-    #[rustc_nounwind]
-    pub fn atomic_xadd_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Adds to the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_add` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-    #[rustc_nounwind]
-    pub fn atomic_xadd_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Adds to the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_add` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-    #[rustc_nounwind]
-    pub fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Adds to the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_add` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_add`].
-    #[rustc_nounwind]
-    pub fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Adds to the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_add` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xadd_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Adds to the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_add` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xadd_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Adds to the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_add` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xadd_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Adds to the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_add` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_add`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xadd_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Adds to the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_add` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_add`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xadd_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Subtract from the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_sub` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-    #[rustc_nounwind]
-    pub fn atomic_xsub_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Subtract from the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_sub` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-    #[rustc_nounwind]
-    pub fn atomic_xsub_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Subtract from the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_sub` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-    #[rustc_nounwind]
-    pub fn atomic_xsub_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Subtract from the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_sub` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-    #[rustc_nounwind]
-    pub fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Subtract from the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_sub` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
-    #[rustc_nounwind]
-    pub fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Subtract from the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_sub` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xsub_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Subtract from the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_sub` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xsub_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Subtract from the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_sub` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xsub_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Subtract from the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_sub` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xsub_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Subtract from the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_sub` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xsub_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Bitwise and with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_and` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`].
-    #[rustc_nounwind]
-    pub fn atomic_and_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise and with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_and` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`].
-    #[rustc_nounwind]
-    pub fn atomic_and_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise and with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_and` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`].
-    #[rustc_nounwind]
-    pub fn atomic_and_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise and with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_and` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_and`].
-    #[rustc_nounwind]
-    pub fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise and with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_and` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_and`].
-    #[rustc_nounwind]
-    pub fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Bitwise and with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_and` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_and_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise and with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_and` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_and_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise and with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_and` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_and_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise and with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_and` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_and`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_and_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise and with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_and` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_and`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_and_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Bitwise nand with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`AtomicBool`] type via the `fetch_nand` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-    #[rustc_nounwind]
-    pub fn atomic_nand_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise nand with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`AtomicBool`] type via the `fetch_nand` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-    #[rustc_nounwind]
-    pub fn atomic_nand_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise nand with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`AtomicBool`] type via the `fetch_nand` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-    #[rustc_nounwind]
-    pub fn atomic_nand_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise nand with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`AtomicBool`] type via the `fetch_nand` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-    #[rustc_nounwind]
-    pub fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise nand with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`AtomicBool`] type via the `fetch_nand` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_nand`].
-    #[rustc_nounwind]
-    pub fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Bitwise nand with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`AtomicBool`] type via the `fetch_nand` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_nand_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise nand with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`AtomicBool`] type via the `fetch_nand` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_nand_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise nand with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`AtomicBool`] type via the `fetch_nand` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_nand_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise nand with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`AtomicBool`] type via the `fetch_nand` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_nand`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_nand_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise nand with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`AtomicBool`] type via the `fetch_nand` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_nand`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_nand_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Bitwise or with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_or` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`].
-    #[rustc_nounwind]
-    pub fn atomic_or_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise or with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_or` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`].
-    #[rustc_nounwind]
-    pub fn atomic_or_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise or with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_or` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`].
-    #[rustc_nounwind]
-    pub fn atomic_or_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise or with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_or` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_or`].
-    #[rustc_nounwind]
-    pub fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise or with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_or` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_or`].
-    #[rustc_nounwind]
-    pub fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Bitwise or with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_or` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_or_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise or with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_or` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_or_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise or with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_or` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_or_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise or with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_or` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_or`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_or_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise or with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_or` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_or`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_or_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Bitwise xor with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_xor` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-    #[rustc_nounwind]
-    pub fn atomic_xor_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise xor with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_xor` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-    #[rustc_nounwind]
-    pub fn atomic_xor_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise xor with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_xor` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-    #[rustc_nounwind]
-    pub fn atomic_xor_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise xor with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_xor` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-    #[rustc_nounwind]
-    pub fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Bitwise xor with the current value, returning the previous value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] types via the `fetch_xor` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_xor`].
-    #[rustc_nounwind]
-    pub fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Bitwise xor with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_xor` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xor_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise xor with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_xor` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xor_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise xor with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_xor` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xor_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise xor with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_xor` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_xor`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xor_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Bitwise xor with the current value, returning the previous value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] types via the `fetch_xor` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_xor`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_xor_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Maximum with the current value using a signed comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_max` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_max_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Maximum with the current value using a signed comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_max` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_max_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Maximum with the current value using a signed comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_max` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_max_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Maximum with the current value using a signed comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_max` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Maximum with the current value.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_max` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Maximum with the current value using a signed comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_max` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_max_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Maximum with the current value using a signed comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_max` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_max_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Maximum with the current value using a signed comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_max` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_max_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Maximum with the current value using a signed comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_max` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_max_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Maximum with the current value.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_max` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_max_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Minimum with the current value using a signed comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_min` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_min_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Minimum with the current value using a signed comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_min` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_min_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Minimum with the current value using a signed comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_min` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_min_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Minimum with the current value using a signed comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_min` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Minimum with the current value using a signed comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] signed integer types via the `fetch_min` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Minimum with the current value using a signed comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_min` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_min_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Minimum with the current value using a signed comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_min` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_min_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Minimum with the current value using a signed comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_min` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_min_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Minimum with the current value using a signed comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_min` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_min_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Minimum with the current value using a signed comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] signed integer types via the `fetch_min` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_min_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Minimum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_umin_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Minimum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_umin_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Minimum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_umin_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Minimum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Minimum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_min`].
-    #[rustc_nounwind]
-    pub fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Minimum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umin_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Minimum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umin_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Minimum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umin_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Minimum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umin_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Minimum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_min` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_min`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umin_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// Maximum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-    /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_umax_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Maximum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-    /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_umax_acquire<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Maximum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-    /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_umax_release<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Maximum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-    /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
-    /// Maximum with the current value using an unsigned comparison.
-    ///
-    /// The stabilized version of this intrinsic is available on the
-    /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
-    /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`].
-    #[rustc_nounwind]
-    pub fn atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
+/// Maximum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
+/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umax_seqcst<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Maximum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
+/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umax_acquire<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Maximum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
+/// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umax_release<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Maximum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
+/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umax_acqrel<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
+/// Maximum with the current value using an unsigned comparison.
+///
+/// The stabilized version of this intrinsic is available on the
+/// [`atomic`] unsigned integer types via the `fetch_max` method by passing
+/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`].
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_umax_relaxed<T: Copy>(_dst: *mut T, _src: T) -> T {
+    unreachable!()
+}
 
-    /// An atomic fence.
-    ///
-    /// The stabilized version of this intrinsic is available in
-    /// [`atomic::fence`] by passing [`Ordering::SeqCst`]
-    /// as the `order`.
-    #[rustc_nounwind]
-    pub fn atomic_fence_seqcst();
-    /// An atomic fence.
-    ///
-    /// The stabilized version of this intrinsic is available in
-    /// [`atomic::fence`] by passing [`Ordering::Acquire`]
-    /// as the `order`.
-    #[rustc_nounwind]
-    pub fn atomic_fence_acquire();
-    /// An atomic fence.
-    ///
-    /// The stabilized version of this intrinsic is available in
-    /// [`atomic::fence`] by passing [`Ordering::Release`]
-    /// as the `order`.
-    #[rustc_nounwind]
-    pub fn atomic_fence_release();
-    /// An atomic fence.
-    ///
-    /// The stabilized version of this intrinsic is available in
-    /// [`atomic::fence`] by passing [`Ordering::AcqRel`]
-    /// as the `order`.
-    #[rustc_nounwind]
-    pub fn atomic_fence_acqrel();
+/// An atomic fence.
+///
+/// The stabilized version of this intrinsic is available in
+/// [`atomic::fence`] by passing [`Ordering::SeqCst`]
+/// as the `order`.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_fence_seqcst() {
+    unreachable!()
+}
+/// An atomic fence.
+///
+/// The stabilized version of this intrinsic is available in
+/// [`atomic::fence`] by passing [`Ordering::Acquire`]
+/// as the `order`.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_fence_acquire() {
+    unreachable!()
+}
+/// An atomic fence.
+///
+/// The stabilized version of this intrinsic is available in
+/// [`atomic::fence`] by passing [`Ordering::Release`]
+/// as the `order`.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_fence_release() {
+    unreachable!()
+}
+/// An atomic fence.
+///
+/// The stabilized version of this intrinsic is available in
+/// [`atomic::fence`] by passing [`Ordering::AcqRel`]
+/// as the `order`.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_fence_acqrel() {
+    unreachable!()
+}
 
-    /// A compiler-only memory barrier.
-    ///
-    /// Memory accesses will never be reordered across this barrier by the
-    /// compiler, but no instructions will be emitted for it. This is
-    /// appropriate for operations on the same thread that may be preempted,
-    /// such as when interacting with signal handlers.
-    ///
-    /// The stabilized version of this intrinsic is available in
-    /// [`atomic::compiler_fence`] by passing [`Ordering::SeqCst`]
-    /// as the `order`.
-    #[rustc_nounwind]
-    pub fn atomic_singlethreadfence_seqcst();
-    /// A compiler-only memory barrier.
-    ///
-    /// Memory accesses will never be reordered across this barrier by the
-    /// compiler, but no instructions will be emitted for it. This is
-    /// appropriate for operations on the same thread that may be preempted,
-    /// such as when interacting with signal handlers.
-    ///
-    /// The stabilized version of this intrinsic is available in
-    /// [`atomic::compiler_fence`] by passing [`Ordering::Acquire`]
-    /// as the `order`.
-    #[rustc_nounwind]
-    pub fn atomic_singlethreadfence_acquire();
-    /// A compiler-only memory barrier.
-    ///
-    /// Memory accesses will never be reordered across this barrier by the
-    /// compiler, but no instructions will be emitted for it. This is
-    /// appropriate for operations on the same thread that may be preempted,
-    /// such as when interacting with signal handlers.
-    ///
-    /// The stabilized version of this intrinsic is available in
-    /// [`atomic::compiler_fence`] by passing [`Ordering::Release`]
-    /// as the `order`.
-    #[rustc_nounwind]
-    pub fn atomic_singlethreadfence_release();
-    /// A compiler-only memory barrier.
-    ///
-    /// Memory accesses will never be reordered across this barrier by the
-    /// compiler, but no instructions will be emitted for it. This is
-    /// appropriate for operations on the same thread that may be preempted,
-    /// such as when interacting with signal handlers.
-    ///
-    /// The stabilized version of this intrinsic is available in
-    /// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`]
-    /// as the `order`.
-    #[rustc_nounwind]
-    pub fn atomic_singlethreadfence_acqrel();
+/// A compiler-only memory barrier.
+///
+/// Memory accesses will never be reordered across this barrier by the
+/// compiler, but no instructions will be emitted for it. This is
+/// appropriate for operations on the same thread that may be preempted,
+/// such as when interacting with signal handlers.
+///
+/// The stabilized version of this intrinsic is available in
+/// [`atomic::compiler_fence`] by passing [`Ordering::SeqCst`]
+/// as the `order`.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_singlethreadfence_seqcst() {
+    unreachable!()
+}
+/// A compiler-only memory barrier.
+///
+/// Memory accesses will never be reordered across this barrier by the
+/// compiler, but no instructions will be emitted for it. This is
+/// appropriate for operations on the same thread that may be preempted,
+/// such as when interacting with signal handlers.
+///
+/// The stabilized version of this intrinsic is available in
+/// [`atomic::compiler_fence`] by passing [`Ordering::Acquire`]
+/// as the `order`.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_singlethreadfence_acquire() {
+    unreachable!()
+}
+/// A compiler-only memory barrier.
+///
+/// Memory accesses will never be reordered across this barrier by the
+/// compiler, but no instructions will be emitted for it. This is
+/// appropriate for operations on the same thread that may be preempted,
+/// such as when interacting with signal handlers.
+///
+/// The stabilized version of this intrinsic is available in
+/// [`atomic::compiler_fence`] by passing [`Ordering::Release`]
+/// as the `order`.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_singlethreadfence_release() {
+    unreachable!()
+}
+/// A compiler-only memory barrier.
+///
+/// Memory accesses will never be reordered across this barrier by the
+/// compiler, but no instructions will be emitted for it. This is
+/// appropriate for operations on the same thread that may be preempted,
+/// such as when interacting with signal handlers.
+///
+/// The stabilized version of this intrinsic is available in
+/// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`]
+/// as the `order`.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn atomic_singlethreadfence_acqrel() {
+    unreachable!()
+}
 
-    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-    /// if supported; otherwise, it is a no-op.
-    /// Prefetches have no effect on the behavior of the program but can change its performance
-    /// characteristics.
-    ///
-    /// The `locality` argument must be a constant integer and is a temporal locality specifier
-    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    pub fn prefetch_read_data<T>(data: *const T, locality: i32);
-    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-    /// if supported; otherwise, it is a no-op.
-    /// Prefetches have no effect on the behavior of the program but can change its performance
-    /// characteristics.
-    ///
-    /// The `locality` argument must be a constant integer and is a temporal locality specifier
-    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    pub fn prefetch_write_data<T>(data: *const T, locality: i32);
-    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-    /// if supported; otherwise, it is a no-op.
-    /// Prefetches have no effect on the behavior of the program but can change its performance
-    /// characteristics.
-    ///
-    /// The `locality` argument must be a constant integer and is a temporal locality specifier
-    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    pub fn prefetch_read_instruction<T>(data: *const T, locality: i32);
-    /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
-    /// if supported; otherwise, it is a no-op.
-    /// Prefetches have no effect on the behavior of the program but can change its performance
-    /// characteristics.
-    ///
-    /// The `locality` argument must be a constant integer and is a temporal locality specifier
-    /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    pub fn prefetch_write_instruction<T>(data: *const T, locality: i32);
+/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
+/// if supported; otherwise, it is a no-op.
+/// Prefetches have no effect on the behavior of the program but can change its performance
+/// characteristics.
+///
+/// The `locality` argument must be a constant integer and is a temporal locality specifier
+/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn prefetch_read_data<T>(_data: *const T, _locality: i32) {
+    unreachable!()
+}
+/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
+/// if supported; otherwise, it is a no-op.
+/// Prefetches have no effect on the behavior of the program but can change its performance
+/// characteristics.
+///
+/// The `locality` argument must be a constant integer and is a temporal locality specifier
+/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn prefetch_write_data<T>(_data: *const T, _locality: i32) {
+    unreachable!()
+}
+/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
+/// if supported; otherwise, it is a no-op.
+/// Prefetches have no effect on the behavior of the program but can change its performance
+/// characteristics.
+///
+/// The `locality` argument must be a constant integer and is a temporal locality specifier
+/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn prefetch_read_instruction<T>(_data: *const T, _locality: i32) {
+    unreachable!()
+}
+/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
+/// if supported; otherwise, it is a no-op.
+/// Prefetches have no effect on the behavior of the program but can change its performance
+/// characteristics.
+///
+/// The `locality` argument must be a constant integer and is a temporal locality specifier
+/// ranging from (0) - no locality, to (3) - extremely local keep in cache.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn prefetch_write_instruction<T>(_data: *const T, _locality: i32) {
+    unreachable!()
+}
 
-    /// Executes a breakpoint trap, for inspection by a debugger.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    pub fn breakpoint();
+/// Executes a breakpoint trap, for inspection by a debugger.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[rustc_nounwind]
+pub unsafe fn breakpoint() {
+    unreachable!()
 }
 
 /// Magic intrinsic that derives its meaning from attributes
@@ -2989,14 +3463,35 @@ pub(crate) macro const_eval_select {
             $(#[$compiletime_attr:meta])* $compiletime:block
         else
             $(#[$runtime_attr:meta])* $runtime:block
+    ) => {
+        // Use the `noinline` arm, after adding explicit `inline` attributes
+        $crate::intrinsics::const_eval_select!(
+            @capture { $($arg : $ty = $val),* } $(-> $ret)? :
+            #[noinline]
+            if const
+                #[inline] // prevent codegen on this function
+                $(#[$compiletime_attr])*
+                $compiletime
+            else
+                #[inline] // avoid the overhead of an extra fn call
+                $(#[$runtime_attr])*
+                $runtime
+        )
+    },
+    // With a leading #[noinline], we don't add inline attributes
+    (
+        @capture { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? :
+        #[noinline]
+        if const
+            $(#[$compiletime_attr:meta])* $compiletime:block
+        else
+            $(#[$runtime_attr:meta])* $runtime:block
     ) => {{
-        #[inline] // avoid the overhead of an extra fn call
         $(#[$runtime_attr])*
         fn runtime($($arg: $ty),*) $( -> $ret )? {
             $runtime
         }
 
-        #[inline] // prevent codegen on this function
         $(#[$compiletime_attr])*
         const fn compiletime($($arg: $ty),*) $( -> $ret )? {
             // Don't warn if one of the arguments is unused.
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 2f4f33dcc85..6f7ea769420 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -120,7 +120,6 @@
 #![feature(const_float_methods)]
 #![feature(const_heap)]
 #![feature(const_nonnull_new)]
-#![feature(const_option_ext)]
 #![feature(const_pin_2)]
 #![feature(const_ptr_is_null)]
 #![feature(const_ptr_sub_ptr)]
@@ -134,7 +133,6 @@
 #![feature(const_type_name)]
 #![feature(const_typed_swap)]
 #![feature(const_ub_checks)]
-#![feature(const_unicode_case_lookup)]
 #![feature(core_intrinsics)]
 #![feature(coverage_attribute)]
 #![feature(do_not_recommend)]
diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs
index 87bfd0d2566..6dca7406845 100644
--- a/library/core/src/num/dec2flt/mod.rs
+++ b/library/core/src/num/dec2flt/mod.rs
@@ -58,7 +58,7 @@
 //!
 //! There are unit tests but they are woefully inadequate at ensuring correctness, they only cover
 //! a small percentage of possible errors. Far more extensive tests are located in the directory
-//! `src/etc/test-float-parse` as a Python script.
+//! `src/etc/test-float-parse` as a Rust program.
 //!
 //! A note on integer overflow: Many parts of this file perform arithmetic with the decimal
 //! exponent `e`. Primarily, we shift the decimal point around: Before the first decimal digit,
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 0484611958d..3fac1ef099f 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -285,17 +285,6 @@ impl f128 {
         self != self
     }
 
-    // FIXME(#50145): `abs` is publicly unavailable in core due to
-    // concerns about portability, so this implementation is for
-    // private use internally.
-    #[inline]
-    pub(crate) const fn abs_private(self) -> f128 {
-        // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
-        unsafe {
-            mem::transmute::<u128, f128>(mem::transmute::<f128, u128>(self) & !Self::SIGN_MASK)
-        }
-    }
-
     /// Returns `true` if this value is positive infinity or negative infinity, and
     /// `false` otherwise.
     ///
@@ -345,10 +334,11 @@ impl f128 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
     pub const fn is_finite(self) -> bool {
         // There's no need to handle NaN separately: if self is NaN,
         // the comparison is not true, exactly as desired.
-        self.abs_private() < Self::INFINITY
+        self.abs() < Self::INFINITY
     }
 
     /// Returns `true` if the number is [subnormal].
@@ -836,8 +826,8 @@ impl f128 {
         const HI: f128 = f128::MAX / 2.;
 
         let (a, b) = (self, other);
-        let abs_a = a.abs_private();
-        let abs_b = b.abs_private();
+        let abs_a = a.abs();
+        let abs_b = b.abs();
 
         if abs_a <= HI && abs_b <= HI {
             // Overflow is impossible
@@ -1280,4 +1270,100 @@ impl f128 {
         }
         self
     }
+
+    /// Computes the absolute value of `self`.
+    ///
+    /// This function always returns the precise result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(f128)]
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
+    ///
+    /// let x = 3.5_f128;
+    /// let y = -3.5_f128;
+    ///
+    /// assert_eq!(x.abs(), x);
+    /// assert_eq!(y.abs(), -y);
+    ///
+    /// assert!(f128::NAN.abs().is_nan());
+    /// # }
+    /// ```
+    #[inline]
+    #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    pub const fn abs(self) -> Self {
+        // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available
+        // We don't do this now because LLVM has lowering bugs for f128 math.
+        Self::from_bits(self.to_bits() & !(1 << 127))
+    }
+
+    /// Returns a number that represents the sign of `self`.
+    ///
+    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
+    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+    /// - NaN if the number is NaN
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(f128)]
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
+    ///
+    /// let f = 3.5_f128;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f128::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f128::NAN.signum().is_nan());
+    /// # }
+    /// ```
+    #[inline]
+    #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    pub const fn signum(self) -> f128 {
+        if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) }
+    }
+
+    /// Returns a number composed of the magnitude of `self` and the sign of
+    /// `sign`.
+    ///
+    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
+    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(f128)]
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
+    ///
+    /// let f = 3.5_f128;
+    ///
+    /// assert_eq!(f.copysign(0.42), 3.5_f128);
+    /// assert_eq!(f.copysign(-0.42), -3.5_f128);
+    /// assert_eq!((-f).copysign(0.42), 3.5_f128);
+    /// assert_eq!((-f).copysign(-0.42), -3.5_f128);
+    ///
+    /// assert!(f128::NAN.copysign(1.0).is_nan());
+    /// # }
+    /// ```
+    #[inline]
+    #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    pub const fn copysign(self, sign: f128) -> f128 {
+        // SAFETY: this is actually a safe intrinsic
+        unsafe { intrinsics::copysignf128(self, sign) }
+    }
 }
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index 898caf835bf..eaac19f22f7 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -279,15 +279,6 @@ impl f16 {
         self != self
     }
 
-    // FIXMxE(#50145): `abs` is publicly unavailable in core due to
-    // concerns about portability, so this implementation is for
-    // private use internally.
-    #[inline]
-    pub(crate) const fn abs_private(self) -> f16 {
-        // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
-        unsafe { mem::transmute::<u16, f16>(mem::transmute::<f16, u16>(self) & !Self::SIGN_MASK) }
-    }
-
     /// Returns `true` if this value is positive infinity or negative infinity, and
     /// `false` otherwise.
     ///
@@ -335,10 +326,11 @@ impl f16 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
     pub const fn is_finite(self) -> bool {
         // There's no need to handle NaN separately: if self is NaN,
         // the comparison is not true, exactly as desired.
-        self.abs_private() < Self::INFINITY
+        self.abs() < Self::INFINITY
     }
 
     /// Returns `true` if the number is [subnormal].
@@ -821,8 +813,8 @@ impl f16 {
         const HI: f16 = f16::MAX / 2.;
 
         let (a, b) = (self, other);
-        let abs_a = a.abs_private();
-        let abs_b = b.abs_private();
+        let abs_a = a.abs();
+        let abs_b = b.abs();
 
         if abs_a <= HI && abs_b <= HI {
             // Overflow is impossible
@@ -1255,4 +1247,99 @@ impl f16 {
         }
         self
     }
+
+    /// Computes the absolute value of `self`.
+    ///
+    /// This function always returns the precise result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(f16)]
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
+    ///
+    /// let x = 3.5_f16;
+    /// let y = -3.5_f16;
+    ///
+    /// assert_eq!(x.abs(), x);
+    /// assert_eq!(y.abs(), -y);
+    ///
+    /// assert!(f16::NAN.abs().is_nan());
+    /// # }
+    /// ```
+    #[inline]
+    #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    pub const fn abs(self) -> Self {
+        // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available
+        Self::from_bits(self.to_bits() & !(1 << 15))
+    }
+
+    /// Returns a number that represents the sign of `self`.
+    ///
+    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
+    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+    /// - NaN if the number is NaN
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(f16)]
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
+    ///
+    /// let f = 3.5_f16;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f16::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f16::NAN.signum().is_nan());
+    /// # }
+    /// ```
+    #[inline]
+    #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    pub const fn signum(self) -> f16 {
+        if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) }
+    }
+
+    /// Returns a number composed of the magnitude of `self` and the sign of
+    /// `sign`.
+    ///
+    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
+    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(f16)]
+    /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] {
+    ///
+    /// let f = 3.5_f16;
+    ///
+    /// assert_eq!(f.copysign(0.42), 3.5_f16);
+    /// assert_eq!(f.copysign(-0.42), -3.5_f16);
+    /// assert_eq!((-f).copysign(0.42), 3.5_f16);
+    /// assert_eq!((-f).copysign(-0.42), -3.5_f16);
+    ///
+    /// assert!(f16::NAN.copysign(1.0).is_nan());
+    /// # }
+    /// ```
+    #[inline]
+    #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    pub const fn copysign(self, sign: f16) -> f16 {
+        // SAFETY: this is actually a safe intrinsic
+        unsafe { intrinsics::copysignf16(self, sign) }
+    }
 }
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 20ece883da6..ae9e69f56fb 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -525,15 +525,6 @@ impl f32 {
         self != self
     }
 
-    // FIXME(#50145): `abs` is publicly unavailable in core due to
-    // concerns about portability, so this implementation is for
-    // private use internally.
-    #[inline]
-    pub(crate) const fn abs_private(self) -> f32 {
-        // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
-        unsafe { mem::transmute::<u32, f32>(mem::transmute::<f32, u32>(self) & !Self::SIGN_MASK) }
-    }
-
     /// Returns `true` if this value is positive infinity or negative infinity, and
     /// `false` otherwise.
     ///
@@ -578,10 +569,11 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")]
     #[inline]
+    #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
     pub const fn is_finite(self) -> bool {
         // There's no need to handle NaN separately: if self is NaN,
         // the comparison is not true, exactly as desired.
-        self.abs_private() < Self::INFINITY
+        self.abs() < Self::INFINITY
     }
 
     /// Returns `true` if the number is [subnormal].
@@ -1019,8 +1011,8 @@ impl f32 {
                 const HI: f32 = f32::MAX / 2.;
 
                 let (a, b) = (self, other);
-                let abs_a = a.abs_private();
-                let abs_b = b.abs_private();
+                let abs_a = a.abs();
+                let abs_b = b.abs();
 
                 if abs_a <= HI && abs_b <= HI {
                     // Overflow is impossible
@@ -1424,4 +1416,87 @@ impl f32 {
         }
         self
     }
+
+    /// Computes the absolute value of `self`.
+    ///
+    /// This function always returns the precise result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x = 3.5_f32;
+    /// let y = -3.5_f32;
+    ///
+    /// assert_eq!(x.abs(), x);
+    /// assert_eq!(y.abs(), -y);
+    ///
+    /// assert!(f32::NAN.abs().is_nan());
+    /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[inline]
+    pub const fn abs(self) -> f32 {
+        // SAFETY: this is actually a safe intrinsic
+        unsafe { intrinsics::fabsf32(self) }
+    }
+
+    /// Returns a number that represents the sign of `self`.
+    ///
+    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
+    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+    /// - NaN if the number is NaN
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let f = 3.5_f32;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f32::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f32::NAN.signum().is_nan());
+    /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[inline]
+    pub const fn signum(self) -> f32 {
+        if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) }
+    }
+
+    /// Returns a number composed of the magnitude of `self` and the sign of
+    /// `sign`.
+    ///
+    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
+    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let f = 3.5_f32;
+    ///
+    /// assert_eq!(f.copysign(0.42), 3.5_f32);
+    /// assert_eq!(f.copysign(-0.42), -3.5_f32);
+    /// assert_eq!((-f).copysign(0.42), 3.5_f32);
+    /// assert_eq!((-f).copysign(-0.42), -3.5_f32);
+    ///
+    /// assert!(f32::NAN.copysign(1.0).is_nan());
+    /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[inline]
+    #[stable(feature = "copysign", since = "1.35.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    pub const fn copysign(self, sign: f32) -> f32 {
+        // SAFETY: this is actually a safe intrinsic
+        unsafe { intrinsics::copysignf32(self, sign) }
+    }
 }
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 5640e71788b..98dcbffd3b4 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -524,15 +524,6 @@ impl f64 {
         self != self
     }
 
-    // FIXME(#50145): `abs` is publicly unavailable in core due to
-    // concerns about portability, so this implementation is for
-    // private use internally.
-    #[inline]
-    pub(crate) const fn abs_private(self) -> f64 {
-        // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`.
-        unsafe { mem::transmute::<u64, f64>(mem::transmute::<f64, u64>(self) & !Self::SIGN_MASK) }
-    }
-
     /// Returns `true` if this value is positive infinity or negative infinity, and
     /// `false` otherwise.
     ///
@@ -577,10 +568,11 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")]
     #[inline]
+    #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs`
     pub const fn is_finite(self) -> bool {
         // There's no need to handle NaN separately: if self is NaN,
         // the comparison is not true, exactly as desired.
-        self.abs_private() < Self::INFINITY
+        self.abs() < Self::INFINITY
     }
 
     /// Returns `true` if the number is [subnormal].
@@ -1022,8 +1014,8 @@ impl f64 {
         const HI: f64 = f64::MAX / 2.;
 
         let (a, b) = (self, other);
-        let abs_a = a.abs_private();
-        let abs_b = b.abs_private();
+        let abs_a = a.abs();
+        let abs_b = b.abs();
 
         if abs_a <= HI && abs_b <= HI {
             // Overflow is impossible
@@ -1424,4 +1416,87 @@ impl f64 {
         }
         self
     }
+
+    /// Computes the absolute value of `self`.
+    ///
+    /// This function always returns the precise result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let x = 3.5_f64;
+    /// let y = -3.5_f64;
+    ///
+    /// assert_eq!(x.abs(), x);
+    /// assert_eq!(y.abs(), -y);
+    ///
+    /// assert!(f64::NAN.abs().is_nan());
+    /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[inline]
+    pub const fn abs(self) -> f64 {
+        // SAFETY: this is actually a safe intrinsic
+        unsafe { intrinsics::fabsf64(self) }
+    }
+
+    /// Returns a number that represents the sign of `self`.
+    ///
+    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
+    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
+    /// - NaN if the number is NaN
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let f = 3.5_f64;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f64::NAN.signum().is_nan());
+    /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[inline]
+    pub const fn signum(self) -> f64 {
+        if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) }
+    }
+
+    /// Returns a number composed of the magnitude of `self` and the sign of
+    /// `sign`.
+    ///
+    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
+    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let f = 3.5_f64;
+    ///
+    /// assert_eq!(f.copysign(0.42), 3.5_f64);
+    /// assert_eq!(f.copysign(-0.42), -3.5_f64);
+    /// assert_eq!((-f).copysign(0.42), 3.5_f64);
+    /// assert_eq!((-f).copysign(-0.42), -3.5_f64);
+    ///
+    /// assert!(f64::NAN.copysign(1.0).is_nan());
+    /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
+    #[stable(feature = "copysign", since = "1.35.0")]
+    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
+    #[inline]
+    pub const fn copysign(self, sign: f64) -> f64 {
+        // SAFETY: this is actually a safe intrinsic
+        unsafe { intrinsics::copysignf64(self, sign) }
+    }
 }
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 440e75c2113..4d24b102096 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1300,7 +1300,7 @@ macro_rules! int_impl {
             }
         }
 
-        /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`
+        /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`.
         ///
         /// If `rhs` is larger or equal to the number of bits in `self`,
         /// the entire value is shifted out, and `0` is returned.
@@ -1423,7 +1423,7 @@ macro_rules! int_impl {
             }
         }
 
-        /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`
+        /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`.
         ///
         /// If `rhs` is larger or equal to the number of bits in `self`,
         /// the entire value is shifted out, which yields `0` for a positive number,
@@ -2389,7 +2389,7 @@ macro_rules! int_impl {
             (res, overflowed ^ (rhs < 0))
         }
 
-        /// Calculates `self` - `rhs`
+        /// Calculates `self` - `rhs`.
         ///
         /// Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic overflow
         /// would occur. If an overflow would have occurred then the wrapped value is returned.
@@ -2470,7 +2470,7 @@ macro_rules! int_impl {
             (c, b != d)
         }
 
-        /// Calculates `self` - `rhs` with an unsigned `rhs`
+        /// Calculates `self` - `rhs` with an unsigned `rhs`.
         ///
         /// Returns a tuple of the subtraction along with a boolean indicating
         /// whether an arithmetic overflow would occur. If an overflow would
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 5a69dc0c724..9d9897b9cf0 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -528,7 +528,7 @@ impl isize {
     midpoint_impl! { isize, signed }
 }
 
-/// If the 6th bit is set ascii is lower case.
+/// If the bit selected by this mask is set, ascii is lower case.
 const ASCII_CASE_MASK: u8 = 0b0010_0000;
 
 impl u8 {
@@ -1433,6 +1433,7 @@ macro_rules! from_str_radix_int_impl {
         #[stable(feature = "rust1", since = "1.0.0")]
         impl FromStr for $t {
             type Err = ParseIntError;
+            #[inline]
             fn from_str(src: &str) -> Result<Self, ParseIntError> {
                 <$t>::from_str_radix(src, 10)
             }
@@ -1505,6 +1506,7 @@ macro_rules! from_str_radix {
             /// ```
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")]
+            #[inline]
             pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
                 use self::IntErrorKind::*;
                 use self::ParseIntError as PIE;
@@ -1649,6 +1651,7 @@ macro_rules! from_str_radix_size_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")]
+        #[inline]
         pub const fn from_str_radix(src: &str, radix: u32) -> Result<$size, ParseIntError> {
             match <$t>::from_str_radix(src, radix) {
                 Ok(x) => Ok(x as $size),
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index c7eb9d0f3fd..b883a0c2ec7 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1233,7 +1233,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
             #[doc = concat!("let three = NonZero::new(3", stringify!($Int), ").unwrap();")]
             /// assert_eq!(three.div_ceil(two), two);
             /// ```
-            #[unstable(feature = "unsigned_nonzero_div_ceil", issue = "none")]
+            #[unstable(feature = "unsigned_nonzero_div_ceil", issue = "132968")]
             #[must_use = "this returns the result of the operation, \
                           without modifying the original"]
             #[inline]
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 550b6a087f9..0a5101884f7 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -763,6 +763,33 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Checked subtraction with a signed integer. Computes `self - rhs`,
+        /// returning `None` if overflow occurred.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(mixed_integer_ops_unsigned_sub)]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub_signed(2), None);")]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub_signed(-2), Some(3));")]
+        #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_sub_signed(-4), None);")]
+        /// ```
+        #[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn checked_sub_signed(self, rhs: $SignedT) -> Option<Self> {
+            let (res, overflow) = self.overflowing_sub_signed(rhs);
+
+            if !overflow {
+                Some(res)
+            } else {
+                None
+            }
+        }
+
         #[doc = concat!(
             "Checked integer subtraction. Computes `self - rhs` and checks if the result fits into an [`",
             stringify!($SignedT), "`], returning `None` if overflow occurred."
@@ -1490,7 +1517,7 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`
+        /// Unbounded shift left. Computes `self << rhs`, without bounding the value of `rhs`.
         ///
         /// If `rhs` is larger or equal to the number of bits in `self`,
         /// the entire value is shifted out, and `0` is returned.
@@ -1613,7 +1640,7 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`
+        /// Unbounded shift right. Computes `self >> rhs`, without bounding the value of `rhs`.
         ///
         /// If `rhs` is larger or equal to the number of bits in `self`,
         /// the entire value is shifted out, and `0` is returned.
@@ -1793,6 +1820,35 @@ macro_rules! uint_impl {
             intrinsics::saturating_sub(self, rhs)
         }
 
+        /// Saturating integer subtraction. Computes `self` - `rhs`, saturating at
+        /// the numeric bounds instead of overflowing.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(mixed_integer_ops_unsigned_sub)]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_sub_signed(2), 0);")]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_sub_signed(-2), 3);")]
+        #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).saturating_sub_signed(-4), ", stringify!($SelfT), "::MAX);")]
+        /// ```
+        #[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn saturating_sub_signed(self, rhs: $SignedT) -> Self {
+            let (res, overflow) = self.overflowing_sub_signed(rhs);
+
+            if !overflow {
+                res
+            } else if rhs < 0 {
+                Self::MAX
+            } else {
+                0
+            }
+        }
+
         /// Saturating integer multiplication. Computes `self * rhs`,
         /// saturating at the numeric bounds instead of overflowing.
         ///
@@ -1926,6 +1982,27 @@ macro_rules! uint_impl {
             intrinsics::wrapping_sub(self, rhs)
         }
 
+        /// Wrapping (modular) subtraction with a signed integer. Computes
+        /// `self - rhs`, wrapping around at the boundary of the type.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(mixed_integer_ops_unsigned_sub)]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_sub_signed(2), ", stringify!($SelfT), "::MAX);")]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_sub_signed(-2), 3);")]
+        #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).wrapping_sub_signed(-4), 1);")]
+        /// ```
+        #[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn wrapping_sub_signed(self, rhs: $SignedT) -> Self {
+            self.wrapping_sub(rhs as Self)
+        }
+
         /// Wrapping (modular) multiplication. Computes `self *
         /// rhs`, wrapping around at the boundary of the type.
         ///
@@ -2222,7 +2299,7 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage
+        /// Basic usage:
         ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));")]
@@ -2312,7 +2389,7 @@ macro_rules! uint_impl {
             (res, overflowed ^ (rhs < 0))
         }
 
-        /// Calculates `self` - `rhs`
+        /// Calculates `self` - `rhs`.
         ///
         /// Returns a tuple of the subtraction along with a boolean indicating
         /// whether an arithmetic overflow would occur. If an overflow would
@@ -2320,7 +2397,7 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage
+        /// Basic usage:
         ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_sub(2), (3, false));")]
@@ -2378,6 +2455,32 @@ macro_rules! uint_impl {
             (c, b || d)
         }
 
+        /// Calculates `self` - `rhs` with a signed `rhs`
+        ///
+        /// Returns a tuple of the subtraction along with a boolean indicating
+        /// whether an arithmetic overflow would occur. If an overflow would
+        /// have occurred then the wrapped value is returned.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(mixed_integer_ops_unsigned_sub)]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_sub_signed(2), (", stringify!($SelfT), "::MAX, true));")]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_sub_signed(-2), (3, false));")]
+        #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).overflowing_sub_signed(-4), (1, true));")]
+        /// ```
+        #[unstable(feature = "mixed_integer_ops_unsigned_sub", issue = "126043")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn overflowing_sub_signed(self, rhs: $SignedT) -> (Self, bool) {
+            let (res, overflow) = self.overflowing_sub(rhs as Self);
+
+            (res, overflow ^ (rhs < 0))
+        }
+
         /// Computes the absolute difference between `self` and `other`.
         ///
         /// # Examples
@@ -2447,7 +2550,7 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage
+        /// Basic usage:
         ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_div(2), (2, false));")]
@@ -2478,7 +2581,7 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage
+        /// Basic usage:
         ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));")]
@@ -2506,7 +2609,7 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage
+        /// Basic usage:
         ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_rem(2), (1, false));")]
@@ -2537,7 +2640,7 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage
+        /// Basic usage:
         ///
         /// ```
         #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));")]
@@ -2561,7 +2664,7 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage
+        /// Basic usage:
         ///
         /// ```
         #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".overflowing_neg(), (0, false));")]
@@ -2586,7 +2689,7 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage
+        /// Basic usage:
         ///
         /// ```
         #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(4), (0x10, false));")]
@@ -2612,7 +2715,7 @@ macro_rules! uint_impl {
         ///
         /// # Examples
         ///
-        /// Basic usage
+        /// Basic usage:
         ///
         /// ```
         #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(4), (0x1, false));")]
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index 1ef9990c00a..45688727c9b 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -294,14 +294,98 @@ unsafe impl<T: ?Sized> DerefPure for &T {}
 #[unstable(feature = "deref_pure_trait", issue = "87121")]
 unsafe impl<T: ?Sized> DerefPure for &mut T {}
 
+/// Indicates that a struct can be used as a method receiver.
+/// That is, a type can use this type as a type of `self`, like this:
+/// ```compile_fail
+/// # // This is currently compile_fail because the compiler-side parts
+/// # // of arbitrary_self_types are not implemented
+/// use std::ops::Receiver;
+///
+/// struct SmartPointer<T>(T);
+///
+/// impl<T> Receiver for SmartPointer<T> {
+///    type Target = T;
+/// }
+///
+/// struct MyContainedType;
+///
+/// impl MyContainedType {
+///   fn method(self: SmartPointer<Self>) {
+///     // ...
+///   }
+/// }
+///
+/// fn main() {
+///   let ptr = SmartPointer(MyContainedType);
+///   ptr.method();
+/// }
+/// ```
+/// This trait is blanket implemented for any type which implements
+/// [`Deref`], which includes stdlib pointer types like `Box<T>`,`Rc<T>`, `&T`,
+/// and `Pin<P>`. For that reason, it's relatively rare to need to
+/// implement this directly. You'll typically do this only if you need
+/// to implement a smart pointer type which can't implement [`Deref`]; perhaps
+/// because you're interfacing with another programming language and can't
+/// guarantee that references comply with Rust's aliasing rules.
+///
+/// When looking for method candidates, Rust will explore a chain of possible
+/// `Receiver`s, so for example each of the following methods work:
+/// ```
+/// use std::boxed::Box;
+/// use std::rc::Rc;
+///
+/// // Both `Box` and `Rc` (indirectly) implement Receiver
+///
+/// struct MyContainedType;
+///
+/// fn main() {
+///   let t = Rc::new(Box::new(MyContainedType));
+///   t.method_a();
+///   t.method_b();
+///   t.method_c();
+/// }
+///
+/// impl MyContainedType {
+///   fn method_a(&self) {
+///
+///   }
+///   fn method_b(self: &Box<Self>) {
+///
+///   }
+///   fn method_c(self: &Rc<Box<Self>>) {
+///
+///   }
+/// }
+/// ```
+#[lang = "receiver"]
+#[cfg(not(bootstrap))]
+#[unstable(feature = "arbitrary_self_types", issue = "44874")]
+pub trait Receiver {
+    /// The target type on which the method may be called.
+    #[cfg(not(bootstrap))]
+    #[rustc_diagnostic_item = "receiver_target"]
+    #[lang = "receiver_target"]
+    #[unstable(feature = "arbitrary_self_types", issue = "44874")]
+    type Target: ?Sized;
+}
+
+#[cfg(not(bootstrap))]
+#[unstable(feature = "arbitrary_self_types", issue = "44874")]
+impl<P: ?Sized, T: ?Sized> Receiver for P
+where
+    P: Deref<Target = T>,
+{
+    type Target = T;
+}
+
 /// Indicates that a struct can be used as a method receiver, without the
 /// `arbitrary_self_types` feature. This is implemented by stdlib pointer types like `Box<T>`,
 /// `Rc<T>`, `&T`, and `Pin<P>`.
 ///
 /// This trait will shortly be removed and replaced with a more generic
 /// facility based around the current "arbitrary self types" unstable feature.
-/// That new facility will use a replacement trait called `Receiver` which is
-/// why this is now named `LegacyReceiver`.
+/// That new facility will use the replacement trait above called `Receiver`
+/// which is why this is now named `LegacyReceiver`.
 #[cfg_attr(bootstrap, lang = "receiver")]
 #[cfg_attr(not(bootstrap), lang = "legacy_receiver")]
 #[unstable(feature = "legacy_receiver_trait", issue = "none")]
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index c9f47e5daad..cea1f84f3fd 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -170,6 +170,9 @@ pub use self::coroutine::{Coroutine, CoroutineState};
 pub use self::deref::DerefPure;
 #[unstable(feature = "legacy_receiver_trait", issue = "none")]
 pub use self::deref::LegacyReceiver;
+#[unstable(feature = "arbitrary_self_types", issue = "44874")]
+#[cfg(not(bootstrap))]
+pub use self::deref::Receiver;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::deref::{Deref, DerefMut};
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 2aa4f172368..29d1956af95 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -563,6 +563,7 @@ use crate::pin::Pin;
 use crate::{cmp, convert, hint, mem, slice};
 
 /// The `Option` type. See [the module level documentation](self) for more.
+#[cfg_attr(not(bootstrap), doc(search_unbox))]
 #[derive(Copy, Eq, Debug, Hash)]
 #[rustc_diagnostic_item = "Option"]
 #[lang = "Option"]
@@ -737,7 +738,7 @@ impl<T> Option<T> {
     #[inline]
     #[must_use]
     #[stable(feature = "pin", since = "1.33.0")]
-    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
+    #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
         // FIXME(const-hack): use `map` once that is possible
         match Pin::get_ref(self).as_ref() {
@@ -754,7 +755,7 @@ impl<T> Option<T> {
     #[inline]
     #[must_use]
     #[stable(feature = "pin", since = "1.33.0")]
-    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
+    #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
         // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`.
         // `x` is guaranteed to be pinned because it comes from `self` which is pinned.
@@ -801,7 +802,7 @@ impl<T> Option<T> {
     #[inline]
     #[must_use]
     #[stable(feature = "option_as_slice", since = "1.75.0")]
-    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
+    #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_slice(&self) -> &[T] {
         // SAFETY: When the `Option` is `Some`, we're using the actual pointer
         // to the payload, with a length of 1, so this is equivalent to
@@ -856,7 +857,7 @@ impl<T> Option<T> {
     #[inline]
     #[must_use]
     #[stable(feature = "option_as_slice", since = "1.75.0")]
-    #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
+    #[rustc_const_stable(feature = "const_option_ext", since = "CURRENT_RUSTC_VERSION")]
     pub const fn as_mut_slice(&mut self) -> &mut [T] {
         // SAFETY: When the `Option` is `Some`, we're using the actual pointer
         // to the payload, with a length of 1, so this is equivalent to
diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs
index f8f3962ce55..e702056f00a 100644
--- a/library/core/src/panic.rs
+++ b/library/core/src/panic.rs
@@ -206,15 +206,16 @@ pub macro const_panic {
         // add the `rustc_allow_const_fn_unstable`. This is okay to do
         // because both variants will panic, just with different messages.
         #[rustc_allow_const_fn_unstable(const_eval_select)]
-        #[inline(always)]
+        #[inline(always)] // inline the wrapper
         #[track_caller]
         #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_panic", since = "CURRENT_RUSTC_VERSION"))]
         const fn do_panic($($arg: $ty),*) -> ! {
             $crate::intrinsics::const_eval_select!(
-                @capture { $($arg: $ty),* } -> !:
-                if const #[track_caller] {
+                @capture { $($arg: $ty = $arg),* } -> !:
+                #[noinline]
+                if const #[track_caller] #[inline] { // Inline this, to prevent codegen
                     $crate::panic!($const_msg)
-                } else #[track_caller] {
+                } else #[track_caller] { // Do not inline this, it makes perf worse
                     $crate::panic!($runtime_msg)
                 }
             )
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 4a6fca5085c..e105ceadff7 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1746,11 +1746,10 @@ mod prim_ref {}
 /// alignment, they might be passed in different registers and hence not be ABI-compatible.
 ///
 /// ABI compatibility as a concern only arises in code that alters the type of function pointers,
-/// code that imports functions via `extern` blocks, and in code that combines `#[target_feature]`
-/// with `extern fn`. Altering the type of function pointers is wildly unsafe (as in, a lot more
-/// unsafe than even [`transmute_copy`][mem::transmute_copy]), and should only occur in the most
-/// exceptional circumstances. Most Rust code just imports functions via `use`. `#[target_feature]`
-/// is also used rarely. So, most likely you do not have to worry about ABI compatibility.
+/// and code that imports functions via `extern` blocks. Altering the type of function pointers is
+/// wildly unsafe (as in, a lot more unsafe than even [`transmute_copy`][mem::transmute_copy]), and
+/// should only occur in the most exceptional circumstances. Most Rust code just imports functions
+/// via `use`. So, most likely you do not have to worry about ABI compatibility.
 ///
 /// But assuming such circumstances, what are the rules? For this section, we are only considering
 /// the ABI of direct Rust-to-Rust calls (with both definition and callsite visible to the
@@ -1762,9 +1761,8 @@ mod prim_ref {}
 /// types from `core::ffi` or `libc`**.
 ///
 /// For two signatures to be considered *ABI-compatible*, they must use a compatible ABI string,
-/// must take the same number of arguments, the individual argument types and the return types must
-/// be ABI-compatible, and the target feature requirements must be met (see the subsection below for
-/// the last point). The ABI string is declared via `extern "ABI" fn(...) -> ...`; note that
+/// must take the same number of arguments, and the individual argument types and the return types
+/// must be ABI-compatible. The ABI string is declared via `extern "ABI" fn(...) -> ...`; note that
 /// `fn name(...) -> ...` implicitly uses the `"Rust"` ABI string and `extern fn name(...) -> ...`
 /// implicitly uses the `"C"` ABI string.
 ///
@@ -1834,24 +1832,6 @@ mod prim_ref {}
 /// Behavior since transmuting `None::<NonZero<i32>>` to `NonZero<i32>` violates the non-zero
 /// requirement.
 ///
-/// #### Requirements concerning target features
-///
-/// Under some conditions, the signature used by the caller and the callee can be ABI-incompatible
-/// even if the exact same ABI string and types are being used. As an example, the
-/// `std::arch::x86_64::__m256` type has a different `extern "C"` ABI when the `avx` feature is
-/// enabled vs when it is not enabled.
-///
-/// Therefore, to ensure ABI compatibility when code using different target features is combined
-/// (such as via `#[target_feature]`), we further require that one of the following conditions is
-/// met:
-///
-/// - The function uses the `"Rust"` ABI string (which is the default without `extern`).
-/// - Caller and callee are using the exact same set of target features. For the callee we consider
-///   the features enabled (via `#[target_feature]` and `-C target-feature`/`-C target-cpu`) at the
-///   declaration site; for the caller we consider the features enabled at the call site.
-/// - Neither any argument nor the return value involves a SIMD type (`#[repr(simd)]`) that is not
-///   behind a pointer indirection (i.e., `*mut __m256` is fine, but `(i32, __m256)` is not).
-///
 /// ### Trait implementations
 ///
 /// In this documentation the shorthand `fn(T₁, T₂, …, Tₙ)` is used to represent non-variadic
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index b98e2b5eac8..603e9044217 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -1407,9 +1407,8 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 /// As a result, using `&packed.unaligned as *const FieldType` causes immediate
 /// *undefined behavior* in your program.
 ///
-/// Instead you must use the [`ptr::addr_of!`](addr_of) macro to
-/// create the pointer. You may use that returned pointer together with this
-/// function.
+/// Instead you must use the `&raw const` syntax to create the pointer.
+/// You may use that constructed pointer together with this function.
 ///
 /// An example of what not to do and how this relates to `read_unaligned` is:
 ///
@@ -1427,7 +1426,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 ///
 /// // Take the address of a 32-bit integer which is not aligned.
 /// // In contrast to `&packed.unaligned as *const _`, this has no undefined behavior.
-/// let unaligned = std::ptr::addr_of!(packed.unaligned);
+/// let unaligned = &raw const packed.unaligned;
 ///
 /// let v = unsafe { std::ptr::read_unaligned(unaligned) };
 /// assert_eq!(v, 0x01020304);
@@ -1615,9 +1614,8 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
 /// As a result, using `&packed.unaligned as *const FieldType` causes immediate
 /// *undefined behavior* in your program.
 ///
-/// Instead, you must use the [`ptr::addr_of_mut!`](addr_of_mut)
-/// macro to create the pointer. You may use that returned pointer together with
-/// this function.
+/// Instead, you must use the `&raw mut` syntax to create the pointer.
+/// You may use that constructed pointer together with this function.
 ///
 /// An example of how to do it and how this relates to `write_unaligned` is:
 ///
@@ -1632,7 +1630,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
 ///
 /// // Take the address of a 32-bit integer which is not aligned.
 /// // In contrast to `&packed.unaligned as *mut _`, this has no undefined behavior.
-/// let unaligned = std::ptr::addr_of_mut!(packed.unaligned);
+/// let unaligned = &raw mut packed.unaligned;
 ///
 /// unsafe { std::ptr::write_unaligned(unaligned, 42) };
 ///
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index ad24e50aa15..b69f8a4b9d3 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -251,7 +251,7 @@ impl<T: ?Sized> NonNull<T> {
     #[unstable(feature = "ptr_metadata", issue = "81513")]
     #[inline]
     pub const fn from_raw_parts(
-        data_pointer: NonNull<()>,
+        data_pointer: NonNull<impl super::Thin>,
         metadata: <T as super::Pointee>::Metadata,
     ) -> NonNull<T> {
         // SAFETY: The result of `ptr::from::raw_parts_mut` is non-null because `data_pointer` is.
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 330d1eb14ed..b450123c5aa 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -520,6 +520,7 @@ use crate::{convert, fmt, hint};
 /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).
 ///
 /// See the [module documentation](self) for details.
+#[cfg_attr(not(bootstrap), doc(search_unbox))]
 #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
 #[must_use = "this `Result` may be an `Err` variant, which should be handled"]
 #[rustc_diagnostic_item = "Result"]
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 52d2179b04d..ef52cc44126 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -4097,7 +4097,23 @@ impl<T> [T] {
     where
         T: PartialOrd,
     {
-        self.is_sorted_by(|a, b| a <= b)
+        // This odd number works the best. 32 + 1 extra due to overlapping chunk boundaries.
+        const CHUNK_SIZE: usize = 33;
+        if self.len() < CHUNK_SIZE {
+            return self.windows(2).all(|w| w[0] <= w[1]);
+        }
+        let mut i = 0;
+        // Check in chunks for autovectorization.
+        while i < self.len() - CHUNK_SIZE {
+            let chunk = &self[i..i + CHUNK_SIZE];
+            if !chunk.windows(2).fold(true, |acc, w| acc & (w[0] <= w[1])) {
+                return false;
+            }
+            // We need to ensure that chunk boundaries are also sorted.
+            // Overlap the next chunk with the last element of our last chunk.
+            i += CHUNK_SIZE - 1;
+        }
+        self[i..].windows(2).all(|w| w[0] <= w[1])
     }
 
     /// Checks if the elements of this slice are sorted using the given comparator function.
@@ -4578,8 +4594,8 @@ impl<T> [T] {
             panic!("elements are zero-sized");
         }
 
-        let self_start = self.as_ptr() as usize;
-        let elem_start = element as *const T as usize;
+        let self_start = self.as_ptr().addr();
+        let elem_start = ptr::from_ref(element).addr();
 
         let byte_offset = elem_start.wrapping_sub(self_start);
 
@@ -4631,8 +4647,8 @@ impl<T> [T] {
             panic!("elements are zero-sized");
         }
 
-        let self_start = self.as_ptr() as usize;
-        let subslice_start = subslice.as_ptr() as usize;
+        let self_start = self.as_ptr().addr();
+        let subslice_start = subslice.as_ptr().addr();
 
         let byte_start = subslice_start.wrapping_sub(self_start);
 
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 0f7c2c999d0..5aecbf303f9 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -2400,7 +2400,7 @@ impl str {
     ///
     /// # Examples
     ///
-    /// Basic usage
+    /// Basic usage:
     ///
     /// ```
     /// let four: u32 = "4".parse().unwrap();
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs
index 4655d35e9c4..7f4826402eb 100644
--- a/library/core/src/unicode/unicode_data.rs
+++ b/library/core/src/unicode/unicode_data.rs
@@ -1,6 +1,7 @@
 ///! This file is generated by `./x run src/tools/unicode-table-generator`; do not edit manually!
 
 #[inline(always)]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))]
 const fn bitset_search<
     const N: usize,
     const CHUNK_SIZE: usize,
@@ -423,6 +424,7 @@ pub mod lowercase {
         (5, 187), (6, 78), (7, 132),
     ];
 
+    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))]
     pub const fn lookup(c: char) -> bool {
         super::bitset_search(
             c as u32,
@@ -547,6 +549,7 @@ pub mod uppercase {
         (2, 146), (2, 20), (3, 146), (3, 140), (3, 134), (4, 178), (4, 171),
     ];
 
+    #[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))]
     pub const fn lookup(c: char) -> bool {
         super::bitset_search(
             c as u32,
diff --git a/library/core/tests/clone.rs b/library/core/tests/clone.rs
index 71a328733b7..054b1d3d498 100644
--- a/library/core/tests/clone.rs
+++ b/library/core/tests/clone.rs
@@ -28,7 +28,7 @@ fn test_clone_to_uninit_slice_success() {
 
     let mut storage: MaybeUninit<[String; 3]> = MaybeUninit::uninit();
     let b: [String; 3] = unsafe {
-        a[..].clone_to_uninit(storage.as_mut_ptr() as *mut [String]);
+        a[..].clone_to_uninit(storage.as_mut_ptr().cast());
         storage.assume_init()
     };
 
@@ -70,7 +70,7 @@ fn test_clone_to_uninit_slice_drops_on_panic() {
         let mut storage: MaybeUninit<[CountsDropsAndPanics; 3]> = MaybeUninit::uninit();
         // This should panic halfway through
         unsafe {
-            a[..].clone_to_uninit(storage.as_mut_ptr() as *mut [CountsDropsAndPanics]);
+            a[..].clone_to_uninit(storage.as_mut_ptr().cast());
         }
     })
     .unwrap_err();
@@ -89,13 +89,13 @@ fn test_clone_to_uninit_str() {
     let a = "hello";
 
     let mut storage: MaybeUninit<[u8; 5]> = MaybeUninit::uninit();
-    unsafe { a.clone_to_uninit(storage.as_mut_ptr() as *mut [u8] as *mut str) };
+    unsafe { a.clone_to_uninit(storage.as_mut_ptr().cast()) };
     assert_eq!(a.as_bytes(), unsafe { storage.assume_init() }.as_slice());
 
     let mut b: Box<str> = "world".into();
     assert_eq!(a.len(), b.len());
     assert_ne!(a, &*b);
-    unsafe { a.clone_to_uninit(ptr::from_mut::<str>(&mut b)) };
+    unsafe { a.clone_to_uninit(ptr::from_mut::<str>(&mut b).cast()) };
     assert_eq!(a, &*b);
 }
 
@@ -104,13 +104,13 @@ fn test_clone_to_uninit_cstr() {
     let a = c"hello";
 
     let mut storage: MaybeUninit<[u8; 6]> = MaybeUninit::uninit();
-    unsafe { a.clone_to_uninit(storage.as_mut_ptr() as *mut [u8] as *mut CStr) };
+    unsafe { a.clone_to_uninit(storage.as_mut_ptr().cast()) };
     assert_eq!(a.to_bytes_with_nul(), unsafe { storage.assume_init() }.as_slice());
 
     let mut b: Box<CStr> = c"world".into();
     assert_eq!(a.count_bytes(), b.count_bytes());
     assert_ne!(a, &*b);
-    unsafe { a.clone_to_uninit(ptr::from_mut::<CStr>(&mut b)) };
+    unsafe { a.clone_to_uninit(ptr::from_mut::<CStr>(&mut b).cast()) };
     assert_eq!(a, &*b);
 }
 
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index b9706ea2a9e..f515e9e4109 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -21,7 +21,6 @@
 #![feature(const_eval_select)]
 #![feature(const_heap)]
 #![feature(const_nonnull_new)]
-#![feature(const_option_ext)]
 #![feature(const_pin_2)]
 #![feature(const_trait_impl)]
 #![feature(core_intrinsics)]
diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml
index 5b10fb5a2bd..f94ea9a6cda 100644
--- a/library/profiler_builtins/Cargo.toml
+++ b/library/profiler_builtins/Cargo.toml
@@ -13,4 +13,5 @@ core = { path = "../core" }
 compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] }
 
 [build-dependencies]
-cc = "1.0.97"
+# FIXME: Pinned due to build error when bumped (#132556)
+cc = "=1.1.22"
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index e1e0eb36d23..f86bcdb4796 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -757,6 +757,47 @@ where
         self.base.get_or_insert_with(value, f)
     }
 
+    /// Gets the given value's corresponding entry in the set for in-place manipulation.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::HashSet;
+    /// use std::collections::hash_set::Entry::*;
+    ///
+    /// let mut singles = HashSet::new();
+    /// let mut dupes = HashSet::new();
+    ///
+    /// for ch in "a short treatise on fungi".chars() {
+    ///     if let Vacant(dupe_entry) = dupes.entry(ch) {
+    ///         // We haven't already seen a duplicate, so
+    ///         // check if we've at least seen it once.
+    ///         match singles.entry(ch) {
+    ///             Vacant(single_entry) => {
+    ///                 // We found a new character for the first time.
+    ///                 single_entry.insert()
+    ///             }
+    ///             Occupied(single_entry) => {
+    ///                 // We've already seen this once, "move" it to dupes.
+    ///                 single_entry.remove();
+    ///                 dupe_entry.insert();
+    ///             }
+    ///         }
+    ///     }
+    /// }
+    ///
+    /// assert!(!singles.contains(&'t') && dupes.contains(&'t'));
+    /// assert!(singles.contains(&'u') && !dupes.contains(&'u'));
+    /// assert!(!singles.contains(&'v') && !dupes.contains(&'v'));
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn entry(&mut self, value: T) -> Entry<'_, T, S> {
+        map_entry(self.base.entry(value))
+    }
+
     /// Returns `true` if `self` has no elements in common with `other`.
     /// This is equivalent to checking for an empty intersection.
     ///
@@ -935,6 +976,14 @@ where
     }
 }
 
+#[inline]
+fn map_entry<'a, K: 'a, V: 'a>(raw: base::Entry<'a, K, V>) -> Entry<'a, K, V> {
+    match raw {
+        base::Entry::Occupied(base) => Entry::Occupied(OccupiedEntry { base }),
+        base::Entry::Vacant(base) => Entry::Vacant(VacantEntry { base }),
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T, S> Clone for HashSet<T, S>
 where
@@ -1865,6 +1914,406 @@ where
     }
 }
 
+/// A view into a single entry in a set, which may either be vacant or occupied.
+///
+/// This `enum` is constructed from the [`entry`] method on [`HashSet`].
+///
+/// [`HashSet`]: struct.HashSet.html
+/// [`entry`]: struct.HashSet.html#method.entry
+///
+/// # Examples
+///
+/// ```
+/// #![feature(hash_set_entry)]
+///
+/// use std::collections::hash_set::HashSet;
+///
+/// let mut set = HashSet::new();
+/// set.extend(["a", "b", "c"]);
+/// assert_eq!(set.len(), 3);
+///
+/// // Existing value (insert)
+/// let entry = set.entry("a");
+/// let _raw_o = entry.insert();
+/// assert_eq!(set.len(), 3);
+/// // Nonexistent value (insert)
+/// set.entry("d").insert();
+///
+/// // Existing value (or_insert)
+/// set.entry("b").or_insert();
+/// // Nonexistent value (or_insert)
+/// set.entry("e").or_insert();
+///
+/// println!("Our HashSet: {:?}", set);
+///
+/// let mut vec: Vec<_> = set.iter().copied().collect();
+/// // The `Iter` iterator produces items in arbitrary order, so the
+/// // items must be sorted to test them against a sorted array.
+/// vec.sort_unstable();
+/// assert_eq!(vec, ["a", "b", "c", "d", "e"]);
+/// ```
+#[unstable(feature = "hash_set_entry", issue = "60896")]
+pub enum Entry<'a, T, S> {
+    /// An occupied entry.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::hash_set::{Entry, HashSet};
+    ///
+    /// let mut set = HashSet::from(["a", "b"]);
+    ///
+    /// match set.entry("a") {
+    ///     Entry::Vacant(_) => unreachable!(),
+    ///     Entry::Occupied(_) => { }
+    /// }
+    /// ```
+    Occupied(OccupiedEntry<'a, T, S>),
+
+    /// A vacant entry.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::hash_set::{Entry, HashSet};
+    ///
+    /// let mut set = HashSet::new();
+    ///
+    /// match set.entry("a") {
+    ///     Entry::Occupied(_) => unreachable!(),
+    ///     Entry::Vacant(_) => { }
+    /// }
+    /// ```
+    Vacant(VacantEntry<'a, T, S>),
+}
+
+#[unstable(feature = "hash_set_entry", issue = "60896")]
+impl<T: fmt::Debug, S> fmt::Debug for Entry<'_, T, S> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
+            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
+        }
+    }
+}
+
+/// A view into an occupied entry in a `HashSet`.
+/// It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
+///
+/// # Examples
+///
+/// ```
+/// #![feature(hash_set_entry)]
+///
+/// use std::collections::hash_set::{Entry, HashSet};
+///
+/// let mut set = HashSet::new();
+/// set.extend(["a", "b", "c"]);
+///
+/// let _entry_o = set.entry("a").insert();
+/// assert_eq!(set.len(), 3);
+///
+/// // Existing key
+/// match set.entry("a") {
+///     Entry::Vacant(_) => unreachable!(),
+///     Entry::Occupied(view) => {
+///         assert_eq!(view.get(), &"a");
+///     }
+/// }
+///
+/// assert_eq!(set.len(), 3);
+///
+/// // Existing key (take)
+/// match set.entry("c") {
+///     Entry::Vacant(_) => unreachable!(),
+///     Entry::Occupied(view) => {
+///         assert_eq!(view.remove(), "c");
+///     }
+/// }
+/// assert_eq!(set.get(&"c"), None);
+/// assert_eq!(set.len(), 2);
+/// ```
+#[unstable(feature = "hash_set_entry", issue = "60896")]
+pub struct OccupiedEntry<'a, T, S> {
+    base: base::OccupiedEntry<'a, T, S>,
+}
+
+#[unstable(feature = "hash_set_entry", issue = "60896")]
+impl<T: fmt::Debug, S> fmt::Debug for OccupiedEntry<'_, T, S> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("OccupiedEntry").field("value", self.get()).finish()
+    }
+}
+
+/// A view into a vacant entry in a `HashSet`.
+/// It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
+///
+/// # Examples
+///
+/// ```
+/// #![feature(hash_set_entry)]
+///
+/// use std::collections::hash_set::{Entry, HashSet};
+///
+/// let mut set = HashSet::<&str>::new();
+///
+/// let entry_v = match set.entry("a") {
+///     Entry::Vacant(view) => view,
+///     Entry::Occupied(_) => unreachable!(),
+/// };
+/// entry_v.insert();
+/// assert!(set.contains("a") && set.len() == 1);
+///
+/// // Nonexistent key (insert)
+/// match set.entry("b") {
+///     Entry::Vacant(view) => view.insert(),
+///     Entry::Occupied(_) => unreachable!(),
+/// }
+/// assert!(set.contains("b") && set.len() == 2);
+/// ```
+#[unstable(feature = "hash_set_entry", issue = "60896")]
+pub struct VacantEntry<'a, T, S> {
+    base: base::VacantEntry<'a, T, S>,
+}
+
+#[unstable(feature = "hash_set_entry", issue = "60896")]
+impl<T: fmt::Debug, S> fmt::Debug for VacantEntry<'_, T, S> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_tuple("VacantEntry").field(self.get()).finish()
+    }
+}
+
+impl<'a, T, S> Entry<'a, T, S> {
+    /// Sets the value of the entry, and returns an OccupiedEntry.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set = HashSet::new();
+    /// let entry = set.entry("horseyland").insert();
+    ///
+    /// assert_eq!(entry.get(), &"horseyland");
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn insert(self) -> OccupiedEntry<'a, T, S>
+    where
+        T: Hash,
+        S: BuildHasher,
+    {
+        match self {
+            Entry::Occupied(entry) => entry,
+            Entry::Vacant(entry) => entry.insert_entry(),
+        }
+    }
+
+    /// Ensures a value is in the entry by inserting if it was vacant.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set = HashSet::new();
+    ///
+    /// // nonexistent key
+    /// set.entry("poneyland").or_insert();
+    /// assert!(set.contains("poneyland"));
+    ///
+    /// // existing key
+    /// set.entry("poneyland").or_insert();
+    /// assert!(set.contains("poneyland"));
+    /// assert_eq!(set.len(), 1);
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn or_insert(self)
+    where
+        T: Hash,
+        S: BuildHasher,
+    {
+        if let Entry::Vacant(entry) = self {
+            entry.insert();
+        }
+    }
+
+    /// Returns a reference to this entry's value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set = HashSet::new();
+    /// set.entry("poneyland").or_insert();
+    ///
+    /// // existing key
+    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
+    /// // nonexistent key
+    /// assert_eq!(set.entry("horseland").get(), &"horseland");
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn get(&self) -> &T {
+        match *self {
+            Entry::Occupied(ref entry) => entry.get(),
+            Entry::Vacant(ref entry) => entry.get(),
+        }
+    }
+}
+
+impl<T, S> OccupiedEntry<'_, T, S> {
+    /// Gets a reference to the value in the entry.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::hash_set::{Entry, HashSet};
+    ///
+    /// let mut set = HashSet::new();
+    /// set.entry("poneyland").or_insert();
+    ///
+    /// match set.entry("poneyland") {
+    ///     Entry::Vacant(_) => panic!(),
+    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
+    /// }
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn get(&self) -> &T {
+        self.base.get()
+    }
+
+    /// Takes the value out of the entry, and returns it.
+    /// Keeps the allocated memory for reuse.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::HashSet;
+    /// use std::collections::hash_set::Entry;
+    ///
+    /// let mut set = HashSet::new();
+    /// // The set is empty
+    /// assert!(set.is_empty() && set.capacity() == 0);
+    ///
+    /// set.entry("poneyland").or_insert();
+    /// let capacity_before_remove = set.capacity();
+    ///
+    /// if let Entry::Occupied(o) = set.entry("poneyland") {
+    ///     assert_eq!(o.remove(), "poneyland");
+    /// }
+    ///
+    /// assert_eq!(set.contains("poneyland"), false);
+    /// // Now set hold none elements but capacity is equal to the old one
+    /// assert!(set.len() == 0 && set.capacity() == capacity_before_remove);
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn remove(self) -> T {
+        self.base.remove()
+    }
+}
+
+impl<'a, T, S> VacantEntry<'a, T, S> {
+    /// Gets a reference to the value that would be used when inserting
+    /// through the `VacantEntry`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set = HashSet::new();
+    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn get(&self) -> &T {
+        self.base.get()
+    }
+
+    /// Take ownership of the value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::hash_set::{Entry, HashSet};
+    ///
+    /// let mut set = HashSet::new();
+    ///
+    /// match set.entry("poneyland") {
+    ///     Entry::Occupied(_) => panic!(),
+    ///     Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"),
+    /// }
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn into_value(self) -> T {
+        self.base.into_value()
+    }
+
+    /// Sets the value of the entry with the VacantEntry's value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::HashSet;
+    /// use std::collections::hash_set::Entry;
+    ///
+    /// let mut set = HashSet::new();
+    ///
+    /// if let Entry::Vacant(o) = set.entry("poneyland") {
+    ///     o.insert();
+    /// }
+    /// assert!(set.contains("poneyland"));
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn insert(self)
+    where
+        T: Hash,
+        S: BuildHasher,
+    {
+        self.base.insert();
+    }
+
+    #[inline]
+    fn insert_entry(self) -> OccupiedEntry<'a, T, S>
+    where
+        T: Hash,
+        S: BuildHasher,
+    {
+        OccupiedEntry { base: self.base.insert() }
+    }
+}
+
 #[allow(dead_code)]
 fn assert_covariance() {
     fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> {
diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs
index 229f979b5b1..e93e915159e 100644
--- a/library/std/src/f128.rs
+++ b/library/std/src/f128.rs
@@ -188,104 +188,6 @@ impl f128 {
         self - self.trunc()
     }
 
-    /// Computes the absolute value of `self`.
-    ///
-    /// This function always returns the precise result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(f128)]
-    /// # #[cfg(reliable_f128)] {
-    ///
-    /// let x = 3.5_f128;
-    /// let y = -3.5_f128;
-    ///
-    /// assert_eq!(x.abs(), x);
-    /// assert_eq!(y.abs(), -y);
-    ///
-    /// assert!(f128::NAN.abs().is_nan());
-    /// # }
-    /// ```
-    #[inline]
-    #[rustc_allow_incoherent_impl]
-    #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    pub const fn abs(self) -> Self {
-        // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available
-        // We don't do this now because LLVM has lowering bugs for f128 math.
-        Self::from_bits(self.to_bits() & !(1 << 127))
-    }
-
-    /// Returns a number that represents the sign of `self`.
-    ///
-    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
-    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
-    /// - NaN if the number is NaN
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(f128)]
-    /// # #[cfg(reliable_f128_math)] {
-    ///
-    /// let f = 3.5_f128;
-    ///
-    /// assert_eq!(f.signum(), 1.0);
-    /// assert_eq!(f128::NEG_INFINITY.signum(), -1.0);
-    ///
-    /// assert!(f128::NAN.signum().is_nan());
-    /// # }
-    /// ```
-    #[inline]
-    #[rustc_allow_incoherent_impl]
-    #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    pub const fn signum(self) -> f128 {
-        if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) }
-    }
-
-    /// Returns a number composed of the magnitude of `self` and the sign of
-    /// `sign`.
-    ///
-    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
-    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
-    /// returned.
-    ///
-    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
-    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
-    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
-    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
-    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
-    /// info.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(f128)]
-    /// # #[cfg(reliable_f128_math)] {
-    ///
-    /// let f = 3.5_f128;
-    ///
-    /// assert_eq!(f.copysign(0.42), 3.5_f128);
-    /// assert_eq!(f.copysign(-0.42), -3.5_f128);
-    /// assert_eq!((-f).copysign(0.42), 3.5_f128);
-    /// assert_eq!((-f).copysign(-0.42), -3.5_f128);
-    ///
-    /// assert!(f128::NAN.copysign(1.0).is_nan());
-    /// # }
-    /// ```
-    #[inline]
-    #[rustc_allow_incoherent_impl]
-    #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    pub const fn copysign(self, sign: f128) -> f128 {
-        unsafe { intrinsics::copysignf128(self, sign) }
-    }
-
     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
     /// error, yielding a more accurate result than an unfused multiply-add.
     ///
diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs
index bed21cda1cd..5b7fcaa28e0 100644
--- a/library/std/src/f16.rs
+++ b/library/std/src/f16.rs
@@ -188,103 +188,6 @@ impl f16 {
         self - self.trunc()
     }
 
-    /// Computes the absolute value of `self`.
-    ///
-    /// This function always returns the precise result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(f16)]
-    /// # #[cfg(reliable_f16)] {
-    ///
-    /// let x = 3.5_f16;
-    /// let y = -3.5_f16;
-    ///
-    /// assert_eq!(x.abs(), x);
-    /// assert_eq!(y.abs(), -y);
-    ///
-    /// assert!(f16::NAN.abs().is_nan());
-    /// # }
-    /// ```
-    #[inline]
-    #[rustc_allow_incoherent_impl]
-    #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    pub const fn abs(self) -> Self {
-        // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available
-        Self::from_bits(self.to_bits() & !(1 << 15))
-    }
-
-    /// Returns a number that represents the sign of `self`.
-    ///
-    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
-    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
-    /// - NaN if the number is NaN
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(f16)]
-    /// # #[cfg(reliable_f16_math)] {
-    ///
-    /// let f = 3.5_f16;
-    ///
-    /// assert_eq!(f.signum(), 1.0);
-    /// assert_eq!(f16::NEG_INFINITY.signum(), -1.0);
-    ///
-    /// assert!(f16::NAN.signum().is_nan());
-    /// # }
-    /// ```
-    #[inline]
-    #[rustc_allow_incoherent_impl]
-    #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    pub const fn signum(self) -> f16 {
-        if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) }
-    }
-
-    /// Returns a number composed of the magnitude of `self` and the sign of
-    /// `sign`.
-    ///
-    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
-    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
-    /// returned.
-    ///
-    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
-    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
-    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
-    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
-    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
-    /// info.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(f16)]
-    /// # #[cfg(reliable_f16_math)] {
-    ///
-    /// let f = 3.5_f16;
-    ///
-    /// assert_eq!(f.copysign(0.42), 3.5_f16);
-    /// assert_eq!(f.copysign(-0.42), -3.5_f16);
-    /// assert_eq!((-f).copysign(0.42), 3.5_f16);
-    /// assert_eq!((-f).copysign(-0.42), -3.5_f16);
-    ///
-    /// assert!(f16::NAN.copysign(1.0).is_nan());
-    /// # }
-    /// ```
-    #[inline]
-    #[rustc_allow_incoherent_impl]
-    #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    pub const fn copysign(self, sign: f16) -> f16 {
-        unsafe { intrinsics::copysignf16(self, sign) }
-    }
-
     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
     /// error, yielding a more accurate result than an unfused multiply-add.
     ///
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index 30cf4e1f756..7cb285bbff5 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -176,90 +176,6 @@ impl f32 {
         self - self.trunc()
     }
 
-    /// Computes the absolute value of `self`.
-    ///
-    /// This function always returns the precise result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let x = 3.5_f32;
-    /// let y = -3.5_f32;
-    ///
-    /// assert_eq!(x.abs(), x);
-    /// assert_eq!(y.abs(), -y);
-    ///
-    /// assert!(f32::NAN.abs().is_nan());
-    /// ```
-    #[rustc_allow_incoherent_impl]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[inline]
-    pub const fn abs(self) -> f32 {
-        unsafe { intrinsics::fabsf32(self) }
-    }
-
-    /// Returns a number that represents the sign of `self`.
-    ///
-    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
-    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
-    /// - NaN if the number is NaN
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let f = 3.5_f32;
-    ///
-    /// assert_eq!(f.signum(), 1.0);
-    /// assert_eq!(f32::NEG_INFINITY.signum(), -1.0);
-    ///
-    /// assert!(f32::NAN.signum().is_nan());
-    /// ```
-    #[rustc_allow_incoherent_impl]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[inline]
-    pub const fn signum(self) -> f32 {
-        if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) }
-    }
-
-    /// Returns a number composed of the magnitude of `self` and the sign of
-    /// `sign`.
-    ///
-    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
-    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
-    /// returned.
-    ///
-    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
-    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
-    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
-    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
-    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
-    /// info.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let f = 3.5_f32;
-    ///
-    /// assert_eq!(f.copysign(0.42), 3.5_f32);
-    /// assert_eq!(f.copysign(-0.42), -3.5_f32);
-    /// assert_eq!((-f).copysign(0.42), 3.5_f32);
-    /// assert_eq!((-f).copysign(-0.42), -3.5_f32);
-    ///
-    /// assert!(f32::NAN.copysign(1.0).is_nan());
-    /// ```
-    #[rustc_allow_incoherent_impl]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    #[inline]
-    #[stable(feature = "copysign", since = "1.35.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    pub const fn copysign(self, sign: f32) -> f32 {
-        unsafe { intrinsics::copysignf32(self, sign) }
-    }
-
     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
     /// error, yielding a more accurate result than an unfused multiply-add.
     ///
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index 51d5476b372..47163c272de 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -176,90 +176,6 @@ impl f64 {
         self - self.trunc()
     }
 
-    /// Computes the absolute value of `self`.
-    ///
-    /// This function always returns the precise result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let x = 3.5_f64;
-    /// let y = -3.5_f64;
-    ///
-    /// assert_eq!(x.abs(), x);
-    /// assert_eq!(y.abs(), -y);
-    ///
-    /// assert!(f64::NAN.abs().is_nan());
-    /// ```
-    #[rustc_allow_incoherent_impl]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[inline]
-    pub const fn abs(self) -> f64 {
-        unsafe { intrinsics::fabsf64(self) }
-    }
-
-    /// Returns a number that represents the sign of `self`.
-    ///
-    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
-    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
-    /// - NaN if the number is NaN
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let f = 3.5_f64;
-    ///
-    /// assert_eq!(f.signum(), 1.0);
-    /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
-    ///
-    /// assert!(f64::NAN.signum().is_nan());
-    /// ```
-    #[rustc_allow_incoherent_impl]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[inline]
-    pub const fn signum(self) -> f64 {
-        if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) }
-    }
-
-    /// Returns a number composed of the magnitude of `self` and the sign of
-    /// `sign`.
-    ///
-    /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
-    /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
-    /// returned.
-    ///
-    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
-    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
-    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
-    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
-    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
-    /// info.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let f = 3.5_f64;
-    ///
-    /// assert_eq!(f.copysign(0.42), 3.5_f64);
-    /// assert_eq!(f.copysign(-0.42), -3.5_f64);
-    /// assert_eq!((-f).copysign(0.42), 3.5_f64);
-    /// assert_eq!((-f).copysign(-0.42), -3.5_f64);
-    ///
-    /// assert!(f64::NAN.copysign(1.0).is_nan());
-    /// ```
-    #[rustc_allow_incoherent_impl]
-    #[must_use = "method returns a new number and does not mutate the original value"]
-    #[stable(feature = "copysign", since = "1.35.0")]
-    #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")]
-    #[inline]
-    pub const fn copysign(self, sign: f64) -> f64 {
-        unsafe { intrinsics::copysignf64(self, sign) }
-    }
-
     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
     /// error, yielding a more accurate result than an unfused multiply-add.
     ///
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index b19d482feaa..79dfb47d0c4 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -112,7 +112,7 @@ impl crate::sealed::Sealed for OsString {}
 /// [conversions]: super#conversions
 #[cfg_attr(not(test), rustc_diagnostic_item = "OsStr")]
 #[stable(feature = "rust1", since = "1.0.0")]
-// `OsStr::from_inner` current implementation relies
+// `OsStr::from_inner` and `impl CloneToUninit for OsStr` current implementation relies
 // on `OsStr` being layout-compatible with `Slice`.
 // However, `OsStr` layout is considered an implementation detail and must not be relied upon.
 #[repr(transparent)]
@@ -1278,9 +1278,9 @@ impl Clone for Box<OsStr> {
 unsafe impl CloneToUninit for OsStr {
     #[inline]
     #[cfg_attr(debug_assertions, track_caller)]
-    unsafe fn clone_to_uninit(&self, dst: *mut Self) {
-        // SAFETY: we're just a wrapper around a platform-specific Slice
-        unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) }
+    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
+        // SAFETY: we're just a transparent wrapper around a platform-specific Slice
+        unsafe { self.inner.clone_to_uninit(dst) }
     }
 }
 
diff --git a/library/std/src/ffi/os_str/tests.rs b/library/std/src/ffi/os_str/tests.rs
index 67147934b4d..cbec44c8626 100644
--- a/library/std/src/ffi/os_str/tests.rs
+++ b/library/std/src/ffi/os_str/tests.rs
@@ -294,12 +294,12 @@ fn clone_to_uninit() {
     let a = OsStr::new("hello.txt");
 
     let mut storage = vec![MaybeUninit::<u8>::uninit(); size_of_val::<OsStr>(a)];
-    unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()) as *mut OsStr) };
+    unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) };
     assert_eq!(a.as_encoded_bytes(), unsafe { MaybeUninit::slice_assume_init_ref(&storage) });
 
     let mut b: Box<OsStr> = OsStr::new("world.exe").into();
     assert_eq!(size_of_val::<OsStr>(a), size_of_val::<OsStr>(&b));
     assert_ne!(a, &*b);
-    unsafe { a.clone_to_uninit(ptr::from_mut::<OsStr>(&mut b)) };
+    unsafe { a.clone_to_uninit(ptr::from_mut::<OsStr>(&mut b).cast()) };
     assert_eq!(a, &*b);
 }
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 3079c8b1d90..76fdb1a4ffd 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -624,6 +624,223 @@ impl File {
         self.inner.datasync()
     }
 
+    /// Acquire an exclusive advisory lock on the file. Blocks until the lock can be acquired.
+    ///
+    /// This acquires an exclusive advisory lock; no other file handle to this file may acquire
+    /// another lock.
+    ///
+    /// If this file handle, or a clone of it, already holds an advisory lock the exact behavior is
+    /// unspecified and platform dependent, including the possibility that it will deadlock.
+    /// However, if this method returns, then an exclusive lock is held.
+    ///
+    /// If the file not open for writing, it is unspecified whether this function returns an error.
+    ///
+    /// Note, this is an advisory lock meant to interact with [`lock_shared`], [`try_lock`],
+    /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`]
+    /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block.
+    ///
+    /// # Platform-specific behavior
+    ///
+    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` flag,
+    /// and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK` flag. Note that,
+    /// this [may change in the future][changes].
+    ///
+    /// [changes]: io#platform-specific-behavior
+    ///
+    /// [`lock_shared`]: File::lock_shared
+    /// [`try_lock`]: File::try_lock
+    /// [`try_lock_shared`]: File::try_lock_shared
+    /// [`unlock`]: File::unlock
+    /// [`read`]: Read::read
+    /// [`write`]: Write::write
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(file_lock)]
+    /// use std::fs::File;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let f = File::open("foo.txt")?;
+    ///     f.lock()?;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "file_lock", issue = "130994")]
+    pub fn lock(&self) -> io::Result<()> {
+        self.inner.lock()
+    }
+
+    /// Acquire a shared advisory lock on the file. Blocks until the lock can be acquired.
+    ///
+    /// This acquires a shared advisory lock; more than one file handle may hold a shared lock, but
+    /// none may hold an exclusive lock.
+    ///
+    /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is
+    /// unspecified and platform dependent, including the possibility that it will deadlock.
+    /// However, if this method returns, then a shared lock is held.
+    ///
+    /// Note, this is an advisory lock meant to interact with [`lock`], [`try_lock`],
+    /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`]
+    /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block.
+    ///
+    /// # Platform-specific behavior
+    ///
+    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` flag,
+    /// and the `LockFileEx` function on Windows. Note that, this
+    /// [may change in the future][changes].
+    ///
+    /// [changes]: io#platform-specific-behavior
+    ///
+    /// [`lock`]: File::lock
+    /// [`try_lock`]: File::try_lock
+    /// [`try_lock_shared`]: File::try_lock_shared
+    /// [`unlock`]: File::unlock
+    /// [`read`]: Read::read
+    /// [`write`]: Write::write
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(file_lock)]
+    /// use std::fs::File;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let f = File::open("foo.txt")?;
+    ///     f.lock_shared()?;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "file_lock", issue = "130994")]
+    pub fn lock_shared(&self) -> io::Result<()> {
+        self.inner.lock_shared()
+    }
+
+    /// Acquire an exclusive advisory lock on the file. Returns `Ok(false)` if the file is locked.
+    ///
+    /// This acquires an exclusive advisory lock; no other file handle to this file may acquire
+    /// another lock.
+    ///
+    /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is
+    /// unspecified and platform dependent, including the possibility that it will deadlock.
+    /// However, if this method returns, then an exclusive lock is held.
+    ///
+    /// If the file not open for writing, it is unspecified whether this function returns an error.
+    ///
+    /// Note, this is an advisory lock meant to interact with [`lock`], [`lock_shared`],
+    /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`]
+    /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block.
+    ///
+    /// # Platform-specific behavior
+    ///
+    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_EX` and
+    /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK`
+    /// and `LOCKFILE_FAIL_IMMEDIATELY` flags. Note that, this
+    /// [may change in the future][changes].
+    ///
+    /// [changes]: io#platform-specific-behavior
+    ///
+    /// [`lock`]: File::lock
+    /// [`lock_shared`]: File::lock_shared
+    /// [`try_lock_shared`]: File::try_lock_shared
+    /// [`unlock`]: File::unlock
+    /// [`read`]: Read::read
+    /// [`write`]: Write::write
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(file_lock)]
+    /// use std::fs::File;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let f = File::open("foo.txt")?;
+    ///     f.try_lock()?;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "file_lock", issue = "130994")]
+    pub fn try_lock(&self) -> io::Result<bool> {
+        self.inner.try_lock()
+    }
+
+    /// Acquire a shared advisory lock on the file.
+    /// Returns `Ok(false)` if the file is exclusively locked.
+    ///
+    /// This acquires a shared advisory lock; more than one file handle may hold a shared lock, but
+    /// none may hold an exclusive lock.
+    ///
+    /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is
+    /// unspecified and platform dependent, including the possibility that it will deadlock.
+    /// However, if this method returns, then a shared lock is held.
+    ///
+    /// Note, this is an advisory lock meant to interact with [`lock`], [`try_lock`],
+    /// [`try_lock`], and [`unlock`]. Its interactions with other methods, such as [`read`]
+    /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block.
+    ///
+    /// # Platform-specific behavior
+    ///
+    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_SH` and
+    /// `LOCK_NB` flags, and the `LockFileEx` function on Windows with the
+    /// `LOCKFILE_FAIL_IMMEDIATELY` flag. Note that, this
+    /// [may change in the future][changes].
+    ///
+    /// [changes]: io#platform-specific-behavior
+    ///
+    /// [`lock`]: File::lock
+    /// [`lock_shared`]: File::lock_shared
+    /// [`try_lock`]: File::try_lock
+    /// [`unlock`]: File::unlock
+    /// [`read`]: Read::read
+    /// [`write`]: Write::write
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(file_lock)]
+    /// use std::fs::File;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let f = File::open("foo.txt")?;
+    ///     f.try_lock_shared()?;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "file_lock", issue = "130994")]
+    pub fn try_lock_shared(&self) -> io::Result<bool> {
+        self.inner.try_lock_shared()
+    }
+
+    /// Release all locks on the file.
+    ///
+    /// All remaining locks are released when the file handle, and all clones of it, are dropped.
+    ///
+    /// # Platform-specific behavior
+    ///
+    /// This function currently corresponds to the `flock` function on Unix with the `LOCK_UN` flag,
+    /// and the `UnlockFile` function on Windows. Note that, this
+    /// [may change in the future][changes].
+    ///
+    /// [changes]: io#platform-specific-behavior
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(file_lock)]
+    /// use std::fs::File;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let f = File::open("foo.txt")?;
+    ///     f.lock()?;
+    ///     f.unlock()?;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "file_lock", issue = "130994")]
+    pub fn unlock(&self) -> io::Result<()> {
+        self.inner.unlock()
+    }
+
     /// Truncates or extends the underlying file, updating the size of
     /// this file to become `size`.
     ///
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 0672fe6f771..018e1958641 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -204,6 +204,152 @@ fn file_test_io_seek_and_write() {
 }
 
 #[test]
+#[cfg(any(
+    windows,
+    target_os = "freebsd",
+    target_os = "linux",
+    target_os = "netbsd",
+    target_vendor = "apple",
+))]
+fn file_lock_multiple_shared() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_lock_multiple_shared_test.txt");
+    let f1 = check!(File::create(filename));
+    let f2 = check!(OpenOptions::new().write(true).open(filename));
+
+    // Check that we can acquire concurrent shared locks
+    check!(f1.lock_shared());
+    check!(f2.lock_shared());
+    check!(f1.unlock());
+    check!(f2.unlock());
+    assert!(check!(f1.try_lock_shared()));
+    assert!(check!(f2.try_lock_shared()));
+}
+
+#[test]
+#[cfg(any(
+    windows,
+    target_os = "freebsd",
+    target_os = "linux",
+    target_os = "netbsd",
+    target_vendor = "apple",
+))]
+fn file_lock_blocking() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_lock_blocking_test.txt");
+    let f1 = check!(File::create(filename));
+    let f2 = check!(OpenOptions::new().write(true).open(filename));
+
+    // Check that shared locks block exclusive locks
+    check!(f1.lock_shared());
+    assert!(!check!(f2.try_lock()));
+    check!(f1.unlock());
+
+    // Check that exclusive locks block shared locks
+    check!(f1.lock());
+    assert!(!check!(f2.try_lock_shared()));
+}
+
+#[test]
+#[cfg(any(
+    windows,
+    target_os = "freebsd",
+    target_os = "linux",
+    target_os = "netbsd",
+    target_vendor = "apple",
+))]
+fn file_lock_drop() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_lock_dup_test.txt");
+    let f1 = check!(File::create(filename));
+    let f2 = check!(OpenOptions::new().write(true).open(filename));
+
+    // Check that locks are released when the File is dropped
+    check!(f1.lock_shared());
+    assert!(!check!(f2.try_lock()));
+    drop(f1);
+    assert!(check!(f2.try_lock()));
+}
+
+#[test]
+#[cfg(any(
+    windows,
+    target_os = "freebsd",
+    target_os = "linux",
+    target_os = "netbsd",
+    target_vendor = "apple",
+))]
+fn file_lock_dup() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_lock_dup_test.txt");
+    let f1 = check!(File::create(filename));
+    let f2 = check!(OpenOptions::new().write(true).open(filename));
+
+    // Check that locks are not dropped if the File has been cloned
+    check!(f1.lock_shared());
+    assert!(!check!(f2.try_lock()));
+    let cloned = check!(f1.try_clone());
+    drop(f1);
+    assert!(!check!(f2.try_lock()));
+    drop(cloned)
+}
+
+#[test]
+#[cfg(windows)]
+fn file_lock_double_unlock() {
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_lock_double_unlock_test.txt");
+    let f1 = check!(File::create(filename));
+    let f2 = check!(OpenOptions::new().write(true).open(filename));
+
+    // On Windows a file handle may acquire both a shared and exclusive lock.
+    // Check that both are released by unlock()
+    check!(f1.lock());
+    check!(f1.lock_shared());
+    assert!(!check!(f2.try_lock()));
+    check!(f1.unlock());
+    assert!(check!(f2.try_lock()));
+}
+
+#[test]
+#[cfg(windows)]
+fn file_lock_blocking_async() {
+    use crate::thread::{sleep, spawn};
+    const FILE_FLAG_OVERLAPPED: u32 = 0x40000000;
+
+    let tmpdir = tmpdir();
+    let filename = &tmpdir.join("file_lock_blocking_async.txt");
+    let f1 = check!(File::create(filename));
+    let f2 =
+        check!(OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).write(true).open(filename));
+
+    check!(f1.lock());
+
+    // Ensure that lock() is synchronous when the file is opened for asynchronous IO
+    let t = spawn(move || {
+        check!(f2.lock());
+    });
+    sleep(Duration::from_secs(1));
+    assert!(!t.is_finished());
+    check!(f1.unlock());
+    t.join().unwrap();
+
+    // Ensure that lock_shared() is synchronous when the file is opened for asynchronous IO
+    let f2 =
+        check!(OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).write(true).open(filename));
+    check!(f1.lock());
+
+    // Ensure that lock() is synchronous when the file is opened for asynchronous IO
+    let t = spawn(move || {
+        check!(f2.lock_shared());
+    });
+    sleep(Duration::from_secs(1));
+    assert!(!t.is_finished());
+    check!(f1.unlock());
+    t.join().unwrap();
+}
+
+#[test]
 fn file_test_io_seek_shakedown() {
     //                   01234567890123
     let initial_msg = "qwer-asdf-zxcv";
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 71dfd0676c9..21e70774954 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1340,6 +1340,25 @@ impl<'a> IoSliceMut<'a> {
             bufs[0].advance(left);
         }
     }
+
+    /// Get the underlying bytes as a mutable slice with the original lifetime.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(io_slice_as_bytes)]
+    /// use std::io::IoSliceMut;
+    ///
+    /// let mut data = *b"abcdef";
+    /// let io_slice = IoSliceMut::new(&mut data);
+    /// io_slice.into_slice()[0] = b'A';
+    ///
+    /// assert_eq!(&data, b"Abcdef");
+    /// ```
+    #[unstable(feature = "io_slice_as_bytes", issue = "132818")]
+    pub const fn into_slice(self) -> &'a mut [u8] {
+        self.0.into_slice()
+    }
 }
 
 #[stable(feature = "iovec", since = "1.36.0")]
@@ -1482,6 +1501,32 @@ impl<'a> IoSlice<'a> {
             bufs[0].advance(left);
         }
     }
+
+    /// Get the underlying bytes as a slice with the original lifetime.
+    ///
+    /// This doesn't borrow from `self`, so is less restrictive than calling
+    /// `.deref()`, which does.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(io_slice_as_bytes)]
+    /// use std::io::IoSlice;
+    ///
+    /// let data = b"abcdef";
+    ///
+    /// let mut io_slice = IoSlice::new(data);
+    /// let tail = &io_slice.as_slice()[3..];
+    ///
+    /// // This works because `tail` doesn't borrow `io_slice`
+    /// io_slice = IoSlice::new(tail);
+    ///
+    /// assert_eq!(io_slice.as_slice(), b"def");
+    /// ```
+    #[unstable(feature = "io_slice_as_bytes", issue = "132818")]
+    pub const fn as_slice(self) -> &'a [u8] {
+        self.0.as_slice()
+    }
 }
 
 #[stable(feature = "iovec", since = "1.36.0")]
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index 56b71c47dc7..89e806c0891 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -531,6 +531,20 @@ fn io_slice_advance_slices_beyond_total_length() {
     assert!(bufs.is_empty());
 }
 
+#[test]
+fn io_slice_as_slice() {
+    let buf = [1; 8];
+    let slice = IoSlice::new(&buf).as_slice();
+    assert_eq!(slice, buf);
+}
+
+#[test]
+fn io_slice_into_slice() {
+    let mut buf = [1; 8];
+    let slice = IoSliceMut::new(&mut buf).into_slice();
+    assert_eq!(slice, [1; 8]);
+}
+
 /// Creates a new writer that reads from at most `n_bufs` and reads
 /// `per_call` bytes (in total) per call to write.
 fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
diff --git a/library/std/src/os/nuttx/raw.rs b/library/std/src/os/nuttx/raw.rs
index 113079cf4ab..431e66d69a3 100644
--- a/library/std/src/os/nuttx/raw.rs
+++ b/library/std/src/os/nuttx/raw.rs
@@ -1,4 +1,4 @@
-//! rtems raw type definitions
+//! NuttX raw type definitions
 
 #![stable(feature = "raw_ext", since = "1.1.0")]
 #![deprecated(
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 5662a44d832..b0291e3aa19 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2128,7 +2128,7 @@ impl AsRef<OsStr> for PathBuf {
 /// ```
 #[cfg_attr(not(test), rustc_diagnostic_item = "Path")]
 #[stable(feature = "rust1", since = "1.0.0")]
-// `Path::new` current implementation relies
+// `Path::new` and `impl CloneToUninit for Path` current implementation relies
 // on `Path` being layout-compatible with `OsStr`.
 // However, `Path` layout is considered an implementation detail and must not be relied upon.
 #[repr(transparent)]
@@ -3170,9 +3170,9 @@ impl Path {
 unsafe impl CloneToUninit for Path {
     #[inline]
     #[cfg_attr(debug_assertions, track_caller)]
-    unsafe fn clone_to_uninit(&self, dst: *mut Self) {
-        // SAFETY: Path is just a wrapper around OsStr
-        unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) }
+    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
+        // SAFETY: Path is just a transparent wrapper around OsStr
+        unsafe { self.inner.clone_to_uninit(dst) }
     }
 }
 
diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs
index b75793d2bc9..ff3f7151bb8 100644
--- a/library/std/src/path/tests.rs
+++ b/library/std/src/path/tests.rs
@@ -2068,7 +2068,7 @@ fn clone_to_uninit() {
     let a = Path::new("hello.txt");
 
     let mut storage = vec![MaybeUninit::<u8>::uninit(); size_of_val::<Path>(a)];
-    unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()) as *mut Path) };
+    unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) };
     assert_eq!(a.as_os_str().as_encoded_bytes(), unsafe {
         MaybeUninit::slice_assume_init_ref(&storage)
     });
@@ -2076,6 +2076,6 @@ fn clone_to_uninit() {
     let mut b: Box<Path> = Path::new("world.exe").into();
     assert_eq!(size_of_val::<Path>(a), size_of_val::<Path>(&b));
     assert_ne!(a, &*b);
-    unsafe { a.clone_to_uninit(ptr::from_mut::<Path>(&mut b)) };
+    unsafe { a.clone_to_uninit(ptr::from_mut::<Path>(&mut b).cast()) };
     assert_eq!(a, &*b);
 }
diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs
index 44e146a89ba..0cf4902d6d5 100644
--- a/library/std/src/sync/mpmc/mod.rs
+++ b/library/std/src/sync/mpmc/mod.rs
@@ -153,6 +153,7 @@ use crate::panic::{RefUnwindSafe, UnwindSafe};
 use crate::time::{Duration, Instant};
 
 /// Creates a new asynchronous channel, returning the sender/receiver halves.
+///
 /// All data sent on the [`Sender`] will become available on the [`Receiver`] in
 /// the same order as it was sent, and no [`send`] will block the calling thread
 /// (this channel has an "infinite buffer", unlike [`sync_channel`], which will
@@ -201,6 +202,7 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
 }
 
 /// Creates a new synchronous, bounded channel.
+///
 /// All data sent on the [`Sender`] will become available on the [`Receiver`]
 /// in the same order as it was sent. Like asynchronous [`channel`]s, the
 /// [`Receiver`] will block until a message becomes available. `sync_channel`
diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs
index 83a93a06369..c86b546e011 100644
--- a/library/std/src/sync/mpsc/mod.rs
+++ b/library/std/src/sync/mpsc/mod.rs
@@ -483,6 +483,7 @@ pub enum TrySendError<T> {
 }
 
 /// Creates a new asynchronous channel, returning the sender/receiver halves.
+///
 /// All data sent on the [`Sender`] will become available on the [`Receiver`] in
 /// the same order as it was sent, and no [`send`] will block the calling thread
 /// (this channel has an "infinite buffer", unlike [`sync_channel`], which will
@@ -527,6 +528,7 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
 }
 
 /// Creates a new synchronous, bounded channel.
+///
 /// All data sent on the [`SyncSender`] will become available on the [`Receiver`]
 /// in the same order as it was sent. Like asynchronous [`channel`]s, the
 /// [`Receiver`] will block until a message becomes available. `sync_channel`
diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs
index 8e0609fe48c..5b65d862be1 100644
--- a/library/std/src/sys/os_str/bytes.rs
+++ b/library/std/src/sys/os_str/bytes.rs
@@ -352,8 +352,8 @@ impl Slice {
 unsafe impl CloneToUninit for Slice {
     #[inline]
     #[cfg_attr(debug_assertions, track_caller)]
-    unsafe fn clone_to_uninit(&self, dst: *mut Self) {
-        // SAFETY: we're just a wrapper around [u8]
-        unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) }
+    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
+        // SAFETY: we're just a transparent wrapper around [u8]
+        unsafe { self.inner.clone_to_uninit(dst) }
     }
 }
diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs
index b3834388df6..a4ad5966afe 100644
--- a/library/std/src/sys/os_str/wtf8.rs
+++ b/library/std/src/sys/os_str/wtf8.rs
@@ -275,8 +275,8 @@ impl Slice {
 unsafe impl CloneToUninit for Slice {
     #[inline]
     #[cfg_attr(debug_assertions, track_caller)]
-    unsafe fn clone_to_uninit(&self, dst: *mut Self) {
-        // SAFETY: we're just a wrapper around Wtf8
-        unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) }
+    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
+        // SAFETY: we're just a transparent wrapper around Wtf8
+        unsafe { self.inner.clone_to_uninit(dst) }
     }
 }
diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/pal/hermit/fs.rs
index 70f6981f717..17d15ed2e50 100644
--- a/library/std/src/sys/pal/hermit/fs.rs
+++ b/library/std/src/sys/pal/hermit/fs.rs
@@ -364,6 +364,26 @@ impl File {
         self.fsync()
     }
 
+    pub fn lock(&self) -> io::Result<()> {
+        unsupported()
+    }
+
+    pub fn lock_shared(&self) -> io::Result<()> {
+        unsupported()
+    }
+
+    pub fn try_lock(&self) -> io::Result<bool> {
+        unsupported()
+    }
+
+    pub fn try_lock_shared(&self) -> io::Result<bool> {
+        unsupported()
+    }
+
+    pub fn unlock(&self) -> io::Result<()> {
+        unsupported()
+    }
+
     pub fn truncate(&self, _size: u64) -> io::Result<()> {
         Err(Error::from_raw_os_error(22))
     }
diff --git a/library/std/src/sys/pal/hermit/io.rs b/library/std/src/sys/pal/hermit/io.rs
index aad1eef71e9..0424a1ac55a 100644
--- a/library/std/src/sys/pal/hermit/io.rs
+++ b/library/std/src/sys/pal/hermit/io.rs
@@ -33,7 +33,7 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
-    pub fn as_slice(&self) -> &[u8] {
+    pub const fn as_slice(&self) -> &'a [u8] {
         unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
     }
 }
@@ -71,6 +71,11 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub const fn into_slice(self) -> &'a mut [u8] {
+        unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+    }
+
+    #[inline]
     pub fn as_mut_slice(&mut self) -> &mut [u8] {
         unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
     }
diff --git a/library/std/src/sys/pal/solid/fs.rs b/library/std/src/sys/pal/solid/fs.rs
index bce9aa6d99c..776a96ff3b7 100644
--- a/library/std/src/sys/pal/solid/fs.rs
+++ b/library/std/src/sys/pal/solid/fs.rs
@@ -350,6 +350,26 @@ impl File {
         self.flush()
     }
 
+    pub fn lock(&self) -> io::Result<()> {
+        unsupported()
+    }
+
+    pub fn lock_shared(&self) -> io::Result<()> {
+        unsupported()
+    }
+
+    pub fn try_lock(&self) -> io::Result<bool> {
+        unsupported()
+    }
+
+    pub fn try_lock_shared(&self) -> io::Result<bool> {
+        unsupported()
+    }
+
+    pub fn unlock(&self) -> io::Result<()> {
+        unsupported()
+    }
+
     pub fn truncate(&self, _size: u64) -> io::Result<()> {
         unsupported()
     }
diff --git a/library/std/src/sys/pal/solid/io.rs b/library/std/src/sys/pal/solid/io.rs
index 4b1f788a492..9ef4b7049b6 100644
--- a/library/std/src/sys/pal/solid/io.rs
+++ b/library/std/src/sys/pal/solid/io.rs
@@ -33,7 +33,7 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
-    pub fn as_slice(&self) -> &[u8] {
+    pub const fn as_slice(&self) -> &'a [u8] {
         unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
     }
 }
@@ -71,6 +71,11 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub const fn into_slice(self) -> &'a mut [u8] {
+        unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+    }
+
+    #[inline]
     pub fn as_mut_slice(&mut self) -> &mut [u8] {
         unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
     }
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index f1f843a5f7a..96f99efb21e 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -1254,6 +1254,123 @@ impl File {
         }
     }
 
+    #[cfg(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    ))]
+    pub fn lock(&self) -> io::Result<()> {
+        cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX) })?;
+        return Ok(());
+    }
+
+    #[cfg(not(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    )))]
+    pub fn lock(&self) -> io::Result<()> {
+        Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock() not supported"))
+    }
+
+    #[cfg(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    ))]
+    pub fn lock_shared(&self) -> io::Result<()> {
+        cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH) })?;
+        return Ok(());
+    }
+
+    #[cfg(not(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    )))]
+    pub fn lock_shared(&self) -> io::Result<()> {
+        Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock_shared() not supported"))
+    }
+
+    #[cfg(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    ))]
+    pub fn try_lock(&self) -> io::Result<bool> {
+        let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) });
+        if let Err(ref err) = result {
+            if err.kind() == io::ErrorKind::WouldBlock {
+                return Ok(false);
+            }
+        }
+        result?;
+        return Ok(true);
+    }
+
+    #[cfg(not(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    )))]
+    pub fn try_lock(&self) -> io::Result<bool> {
+        Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock() not supported"))
+    }
+
+    #[cfg(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    ))]
+    pub fn try_lock_shared(&self) -> io::Result<bool> {
+        let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH | libc::LOCK_NB) });
+        if let Err(ref err) = result {
+            if err.kind() == io::ErrorKind::WouldBlock {
+                return Ok(false);
+            }
+        }
+        result?;
+        return Ok(true);
+    }
+
+    #[cfg(not(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    )))]
+    pub fn try_lock_shared(&self) -> io::Result<bool> {
+        Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported"))
+    }
+
+    #[cfg(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    ))]
+    pub fn unlock(&self) -> io::Result<()> {
+        cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_UN) })?;
+        return Ok(());
+    }
+
+    #[cfg(not(any(
+        target_os = "freebsd",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_vendor = "apple",
+    )))]
+    pub fn unlock(&self) -> io::Result<()> {
+        Err(io::const_io_error!(io::ErrorKind::Unsupported, "unlock() not supported"))
+    }
+
     pub fn truncate(&self, size: u64) -> io::Result<()> {
         let size: off64_t =
             size.try_into().map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
diff --git a/library/std/src/sys/pal/unix/io.rs b/library/std/src/sys/pal/unix/io.rs
index 181c35a971e..0d5a152dc0d 100644
--- a/library/std/src/sys/pal/unix/io.rs
+++ b/library/std/src/sys/pal/unix/io.rs
@@ -33,7 +33,7 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
-    pub fn as_slice(&self) -> &[u8] {
+    pub const fn as_slice(&self) -> &'a [u8] {
         unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
     }
 }
@@ -71,6 +71,11 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub const fn into_slice(self) -> &'a mut [u8] {
+        unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
+    }
+
+    #[inline]
     pub fn as_mut_slice(&mut self) -> &mut [u8] {
         unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
     }
diff --git a/library/std/src/sys/pal/unix/pipe.rs b/library/std/src/sys/pal/unix/pipe.rs
index f0ebc767bad..4a992e32a91 100644
--- a/library/std/src/sys/pal/unix/pipe.rs
+++ b/library/std/src/sys/pal/unix/pipe.rs
@@ -23,6 +23,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
             target_os = "dragonfly",
             target_os = "freebsd",
             target_os = "hurd",
+            target_os = "illumos",
             target_os = "linux",
             target_os = "netbsd",
             target_os = "openbsd",
diff --git a/library/std/src/sys/pal/unsupported/fs.rs b/library/std/src/sys/pal/unsupported/fs.rs
index 474c9fe97d1..9585ec24f68 100644
--- a/library/std/src/sys/pal/unsupported/fs.rs
+++ b/library/std/src/sys/pal/unsupported/fs.rs
@@ -198,6 +198,26 @@ impl File {
         self.0
     }
 
+    pub fn lock(&self) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn lock_shared(&self) -> io::Result<()> {
+        self.0
+    }
+
+    pub fn try_lock(&self) -> io::Result<bool> {
+        self.0
+    }
+
+    pub fn try_lock_shared(&self) -> io::Result<bool> {
+        self.0
+    }
+
+    pub fn unlock(&self) -> io::Result<()> {
+        self.0
+    }
+
     pub fn truncate(&self, _size: u64) -> io::Result<()> {
         self.0
     }
diff --git a/library/std/src/sys/pal/unsupported/io.rs b/library/std/src/sys/pal/unsupported/io.rs
index 6372fca74e0..604735d32d5 100644
--- a/library/std/src/sys/pal/unsupported/io.rs
+++ b/library/std/src/sys/pal/unsupported/io.rs
@@ -15,7 +15,7 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
-    pub fn as_slice(&self) -> &[u8] {
+    pub const fn as_slice(&self) -> &'a [u8] {
         self.0
     }
 }
@@ -41,6 +41,11 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub const fn into_slice(self) -> &'a mut [u8] {
+        self.0
+    }
+
+    #[inline]
     pub fn as_mut_slice(&mut self) -> &mut [u8] {
         self.0
     }
diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs
index 59ecc45b06a..3296c762cca 100644
--- a/library/std/src/sys/pal/wasi/fs.rs
+++ b/library/std/src/sys/pal/wasi/fs.rs
@@ -420,6 +420,26 @@ impl File {
         self.fd.datasync()
     }
 
+    pub fn lock(&self) -> io::Result<()> {
+        unsupported()
+    }
+
+    pub fn lock_shared(&self) -> io::Result<()> {
+        unsupported()
+    }
+
+    pub fn try_lock(&self) -> io::Result<bool> {
+        unsupported()
+    }
+
+    pub fn try_lock_shared(&self) -> io::Result<bool> {
+        unsupported()
+    }
+
+    pub fn unlock(&self) -> io::Result<()> {
+        unsupported()
+    }
+
     pub fn truncate(&self, size: u64) -> io::Result<()> {
         self.fd.filestat_set_size(size)
     }
diff --git a/library/std/src/sys/pal/wasi/io.rs b/library/std/src/sys/pal/wasi/io.rs
index b7c2f03daa0..57f81bc6257 100644
--- a/library/std/src/sys/pal/wasi/io.rs
+++ b/library/std/src/sys/pal/wasi/io.rs
@@ -30,7 +30,7 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
-    pub fn as_slice(&self) -> &[u8] {
+    pub const fn as_slice(&self) -> &'a [u8] {
         unsafe { slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len) }
     }
 }
@@ -68,6 +68,11 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub const fn into_slice(self) -> &'a mut [u8] {
+        unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) }
+    }
+
+    #[inline]
     pub fn as_mut_slice(&mut self) -> &mut [u8] {
         unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) }
     }
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index 192c95fd203..248ce3c9ff6 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2351,6 +2351,9 @@ Windows.Win32.Storage.FileSystem.GetFinalPathNameByHandleW
 Windows.Win32.Storage.FileSystem.GetFullPathNameW
 Windows.Win32.Storage.FileSystem.GetTempPathW
 Windows.Win32.Storage.FileSystem.INVALID_FILE_ATTRIBUTES
+Windows.Win32.Storage.FileSystem.LOCKFILE_EXCLUSIVE_LOCK
+Windows.Win32.Storage.FileSystem.LOCKFILE_FAIL_IMMEDIATELY
+Windows.Win32.Storage.FileSystem.LockFileEx
 Windows.Win32.Storage.FileSystem.LPPROGRESS_ROUTINE
 Windows.Win32.Storage.FileSystem.LPPROGRESS_ROUTINE_CALLBACK_REASON
 Windows.Win32.Storage.FileSystem.MAXIMUM_REPARSE_DATA_BUFFER_SIZE
@@ -2396,6 +2399,7 @@ Windows.Win32.Storage.FileSystem.SYMBOLIC_LINK_FLAG_DIRECTORY
 Windows.Win32.Storage.FileSystem.SYMBOLIC_LINK_FLAGS
 Windows.Win32.Storage.FileSystem.SYNCHRONIZE
 Windows.Win32.Storage.FileSystem.TRUNCATE_EXISTING
+Windows.Win32.Storage.FileSystem.UnlockFile
 Windows.Win32.Storage.FileSystem.VOLUME_NAME_DOS
 Windows.Win32.Storage.FileSystem.VOLUME_NAME_GUID
 Windows.Win32.Storage.FileSystem.VOLUME_NAME_NONE
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index 52444c2c009..19925e59dfe 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -65,6 +65,7 @@ windows_targets::link!("kernel32.dll" "system" fn InitOnceBeginInitialize(lpinit
 windows_targets::link!("kernel32.dll" "system" fn InitOnceComplete(lpinitonce : *mut INIT_ONCE, dwflags : u32, lpcontext : *const core::ffi::c_void) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn InitializeProcThreadAttributeList(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwattributecount : u32, dwflags : u32, lpsize : *mut usize) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn LocalFree(hmem : HLOCAL) -> HLOCAL);
+windows_targets::link!("kernel32.dll" "system" fn LockFileEx(hfile : HANDLE, dwflags : LOCK_FILE_FLAGS, dwreserved : u32, nnumberofbytestolocklow : u32, nnumberofbytestolockhigh : u32, lpoverlapped : *mut OVERLAPPED) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn MoveFileExW(lpexistingfilename : PCWSTR, lpnewfilename : PCWSTR, dwflags : MOVE_FILE_FLAGS) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn MultiByteToWideChar(codepage : u32, dwflags : MULTI_BYTE_TO_WIDE_CHAR_FLAGS, lpmultibytestr : PCSTR, cbmultibyte : i32, lpwidecharstr : PWSTR, cchwidechar : i32) -> i32);
 windows_targets::link!("kernel32.dll" "system" fn QueryPerformanceCounter(lpperformancecount : *mut i64) -> BOOL);
@@ -96,6 +97,7 @@ windows_targets::link!("kernel32.dll" "system" fn TlsGetValue(dwtlsindex : u32)
 windows_targets::link!("kernel32.dll" "system" fn TlsSetValue(dwtlsindex : u32, lptlsvalue : *const core::ffi::c_void) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockExclusive(srwlock : *mut SRWLOCK) -> BOOLEAN);
 windows_targets::link!("kernel32.dll" "system" fn TryAcquireSRWLockShared(srwlock : *mut SRWLOCK) -> BOOLEAN);
+windows_targets::link!("kernel32.dll" "system" fn UnlockFile(hfile : HANDLE, dwfileoffsetlow : u32, dwfileoffsethigh : u32, nnumberofbytestounlocklow : u32, nnumberofbytestounlockhigh : u32) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn UpdateProcThreadAttribute(lpattributelist : LPPROC_THREAD_ATTRIBUTE_LIST, dwflags : u32, attribute : usize, lpvalue : *const core::ffi::c_void, cbsize : usize, lppreviousvalue : *mut core::ffi::c_void, lpreturnsize : *const usize) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn WaitForMultipleObjects(ncount : u32, lphandles : *const HANDLE, bwaitall : BOOL, dwmilliseconds : u32) -> WAIT_EVENT);
 windows_targets::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT);
@@ -2730,6 +2732,9 @@ pub struct LINGER {
     pub l_onoff: u16,
     pub l_linger: u16,
 }
+pub const LOCKFILE_EXCLUSIVE_LOCK: LOCK_FILE_FLAGS = 2u32;
+pub const LOCKFILE_FAIL_IMMEDIATELY: LOCK_FILE_FLAGS = 1u32;
+pub type LOCK_FILE_FLAGS = u32;
 pub type LPOVERLAPPED_COMPLETION_ROUTINE = Option<
     unsafe extern "system" fn(
         dwerrorcode: u32,
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index 5a9bfccc1fa..07e4f93a379 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -346,6 +346,120 @@ impl File {
         self.fsync()
     }
 
+    fn acquire_lock(&self, flags: c::LOCK_FILE_FLAGS) -> io::Result<()> {
+        unsafe {
+            let mut overlapped: c::OVERLAPPED = mem::zeroed();
+            let event = c::CreateEventW(ptr::null_mut(), c::FALSE, c::FALSE, ptr::null());
+            if event.is_null() {
+                return Err(io::Error::last_os_error());
+            }
+            overlapped.hEvent = event;
+            let lock_result = cvt(c::LockFileEx(
+                self.handle.as_raw_handle(),
+                flags,
+                0,
+                u32::MAX,
+                u32::MAX,
+                &mut overlapped,
+            ));
+
+            let final_result = match lock_result {
+                Ok(_) => Ok(()),
+                Err(err) => {
+                    if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) {
+                        // Wait for the lock to be acquired, and get the lock operation status.
+                        // This can happen asynchronously, if the file handle was opened for async IO
+                        let mut bytes_transferred = 0;
+                        cvt(c::GetOverlappedResult(
+                            self.handle.as_raw_handle(),
+                            &mut overlapped,
+                            &mut bytes_transferred,
+                            c::TRUE,
+                        ))
+                        .map(|_| ())
+                    } else {
+                        Err(err)
+                    }
+                }
+            };
+            c::CloseHandle(overlapped.hEvent);
+            final_result
+        }
+    }
+
+    pub fn lock(&self) -> io::Result<()> {
+        self.acquire_lock(c::LOCKFILE_EXCLUSIVE_LOCK)
+    }
+
+    pub fn lock_shared(&self) -> io::Result<()> {
+        self.acquire_lock(0)
+    }
+
+    pub fn try_lock(&self) -> io::Result<bool> {
+        let result = cvt(unsafe {
+            let mut overlapped = mem::zeroed();
+            c::LockFileEx(
+                self.handle.as_raw_handle(),
+                c::LOCKFILE_EXCLUSIVE_LOCK | c::LOCKFILE_FAIL_IMMEDIATELY,
+                0,
+                u32::MAX,
+                u32::MAX,
+                &mut overlapped,
+            )
+        });
+
+        match result {
+            Ok(_) => Ok(true),
+            Err(err)
+                if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32)
+                    || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) =>
+            {
+                Ok(false)
+            }
+            Err(err) => Err(err),
+        }
+    }
+
+    pub fn try_lock_shared(&self) -> io::Result<bool> {
+        let result = cvt(unsafe {
+            let mut overlapped = mem::zeroed();
+            c::LockFileEx(
+                self.handle.as_raw_handle(),
+                c::LOCKFILE_FAIL_IMMEDIATELY,
+                0,
+                u32::MAX,
+                u32::MAX,
+                &mut overlapped,
+            )
+        });
+
+        match result {
+            Ok(_) => Ok(true),
+            Err(err)
+                if err.raw_os_error() == Some(c::ERROR_IO_PENDING as i32)
+                    || err.raw_os_error() == Some(c::ERROR_LOCK_VIOLATION as i32) =>
+            {
+                Ok(false)
+            }
+            Err(err) => Err(err),
+        }
+    }
+
+    pub fn unlock(&self) -> io::Result<()> {
+        // Unlock the handle twice because LockFileEx() allows a file handle to acquire
+        // both an exclusive and shared lock, in which case the documentation states that:
+        // "...two unlock operations are necessary to unlock the region; the first unlock operation
+        // unlocks the exclusive lock, the second unlock operation unlocks the shared lock"
+        cvt(unsafe { c::UnlockFile(self.handle.as_raw_handle(), 0, 0, u32::MAX, u32::MAX) })?;
+        let result =
+            cvt(unsafe { c::UnlockFile(self.handle.as_raw_handle(), 0, 0, u32::MAX, u32::MAX) });
+        match result {
+            Ok(_) => Ok(()),
+            Err(err) if err.raw_os_error() == Some(c::ERROR_NOT_LOCKED as i32) => Ok(()),
+            Err(err) => Err(err),
+        }
+    }
+
     pub fn truncate(&self, size: u64) -> io::Result<()> {
         let info = c::FILE_END_OF_FILE_INFO { EndOfFile: size as i64 };
         api::set_file_information_by_handle(self.handle.as_raw_handle(), &info).io_result()
diff --git a/library/std/src/sys/pal/windows/io.rs b/library/std/src/sys/pal/windows/io.rs
index 1e7d02908f6..f2865d2ffc1 100644
--- a/library/std/src/sys/pal/windows/io.rs
+++ b/library/std/src/sys/pal/windows/io.rs
@@ -36,7 +36,7 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
-    pub fn as_slice(&self) -> &[u8] {
+    pub const fn as_slice(&self) -> &'a [u8] {
         unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
     }
 }
@@ -75,6 +75,11 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub const fn into_slice(self) -> &'a mut [u8] {
+        unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
+    }
+
+    #[inline]
     pub fn as_mut_slice(&mut self) -> &mut [u8] {
         unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
     }
diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs
index 19d4c94f450..666942bb8a1 100644
--- a/library/std/src/sys_common/wtf8.rs
+++ b/library/std/src/sys_common/wtf8.rs
@@ -1052,8 +1052,8 @@ impl Hash for Wtf8 {
 unsafe impl CloneToUninit for Wtf8 {
     #[inline]
     #[cfg_attr(debug_assertions, track_caller)]
-    unsafe fn clone_to_uninit(&self, dst: *mut Self) {
-        // SAFETY: we're just a wrapper around [u8]
-        unsafe { self.bytes.clone_to_uninit(&raw mut (*dst).bytes) }
+    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
+        // SAFETY: we're just a transparent wrapper around [u8]
+        unsafe { self.bytes.clone_to_uninit(dst) }
     }
 }
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index ba505089a00..7950f1004a2 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -40,7 +40,7 @@ test = false
 cc = "=1.1.22"
 cmake = "=0.1.48"
 
-build_helper = { path = "../tools/build_helper" }
+build_helper = { path = "../build_helper" }
 clap = { version = "4.4", default-features = false, features = ["std", "usage", "help", "derive", "error-context"] }
 clap_complete = "4.4"
 fd-lock = "4.0"
diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py
index 706f2c5bf07..70ed12b96e8 100644
--- a/src/bootstrap/bootstrap_test.py
+++ b/src/bootstrap/bootstrap_test.py
@@ -5,6 +5,7 @@ Run these with `x test bootstrap`, or `python -m unittest src/bootstrap/bootstra
 from __future__ import absolute_import, division, print_function
 import os
 import unittest
+from unittest.mock import patch
 import tempfile
 import hashlib
 import sys
@@ -99,6 +100,52 @@ class ProgramOutOfDate(unittest.TestCase):
         self.assertFalse(self.build.program_out_of_date(self.rustc_stamp_path, self.key))
 
 
+class ParseArgsInConfigure(unittest.TestCase):
+    """Test if `parse_args` function in `configure.py` works properly"""
+    @patch("configure.err")
+    def test_unknown_args(self, err):
+        # It should be print an error message if the argument doesn't start with '--'
+        configure.parse_args(["enable-full-tools"])
+        err.assert_called_with("Option 'enable-full-tools' is not recognized")
+        err.reset_mock()
+        # It should be print an error message if the argument is not recognized
+        configure.parse_args(["--some-random-flag"])
+        err.assert_called_with("Option '--some-random-flag' is not recognized")
+
+    @patch("configure.err")
+    def test_need_value_args(self, err):
+        """It should print an error message if a required argument value is missing"""
+        configure.parse_args(["--target"])
+        err.assert_called_with("Option '--target' needs a value (--target=val)")
+
+    @patch("configure.err")
+    def test_option_checking(self, err):
+        # Options should be checked even if `--enable-option-checking` is not passed
+        configure.parse_args(["--target"])
+        err.assert_called_with("Option '--target' needs a value (--target=val)")
+        err.reset_mock()
+        # Options should be checked if `--enable-option-checking` is passed
+        configure.parse_args(["--enable-option-checking", "--target"])
+        err.assert_called_with("Option '--target' needs a value (--target=val)")
+        err.reset_mock()
+        # Options should not be checked if `--disable-option-checking` is passed
+        configure.parse_args(["--disable-option-checking", "--target"])
+        err.assert_not_called()
+
+    @patch("configure.parse_example_config", lambda known_args, _: known_args)
+    def test_known_args(self):
+        # It should contain known and correct arguments
+        known_args = configure.parse_args(["--enable-full-tools"])
+        self.assertTrue(known_args["full-tools"][0][1])
+        known_args = configure.parse_args(["--disable-full-tools"])
+        self.assertFalse(known_args["full-tools"][0][1])
+        # It should contain known arguments and their values
+        known_args = configure.parse_args(["--target=x86_64-unknown-linux-gnu"])
+        self.assertEqual(known_args["target"][0][1], "x86_64-unknown-linux-gnu")
+        known_args = configure.parse_args(["--target", "x86_64-unknown-linux-gnu"])
+        self.assertEqual(known_args["target"][0][1], "x86_64-unknown-linux-gnu")
+
+
 class GenerateAndParseConfig(unittest.TestCase):
     """Test that we can serialize and deserialize a config.toml file"""
     def test_no_args(self):
diff --git a/src/bootstrap/defaults/config.compiler.toml b/src/bootstrap/defaults/config.compiler.toml
index 147939d2047..57a0ca5a718 100644
--- a/src/bootstrap/defaults/config.compiler.toml
+++ b/src/bootstrap/defaults/config.compiler.toml
@@ -19,6 +19,7 @@ lto = "off"
 # Forces frame pointers to be used with `-Cforce-frame-pointers`.
 # This can be helpful for profiling at a small performance cost.
 frame-pointers = true
+download-rustc = false
 
 [llvm]
 # Having this set to true disrupts compiler development workflows for people who use `llvm.download-ci-llvm = true`
diff --git a/src/bootstrap/defaults/config.library.toml b/src/bootstrap/defaults/config.library.toml
index 5447565a4b0..67ceb220524 100644
--- a/src/bootstrap/defaults/config.library.toml
+++ b/src/bootstrap/defaults/config.library.toml
@@ -10,6 +10,7 @@ bench-stage = 0
 incremental = true
 # Make the compiler and standard library faster to build, at the expense of a ~20% runtime slowdown.
 lto = "off"
+download-rustc = false
 
 [llvm]
 # Will download LLVM from CI if available on your platform.
diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs
index 040690623a1..d857de96cce 100644
--- a/src/bootstrap/src/core/build_steps/clean.rs
+++ b/src/bootstrap/src/core/build_steps/clean.rs
@@ -226,6 +226,8 @@ where
         Err(ref e) if e.kind() == ErrorKind::PermissionDenied => {
             let m = t!(path.symlink_metadata());
             let mut p = m.permissions();
+            // this os not unix, so clippy gives FP
+            #[expect(clippy::permissions_set_readonly_false)]
             p.set_readonly(false);
             t!(fs::set_permissions(path, p));
             f(path).unwrap_or_else(|e| {
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index cd198c425c0..0884d86cc6d 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -20,14 +20,12 @@ const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[
     "wrong_self_convention",
 ];
 
-fn lint_args(builder: &Builder<'_>, ignored_rules: &[&str]) -> Vec<String> {
+fn lint_args(builder: &Builder<'_>, config: &LintConfig, ignored_rules: &[&str]) -> Vec<String> {
     fn strings<'a>(arr: &'a [&str]) -> impl Iterator<Item = String> + 'a {
         arr.iter().copied().map(String::from)
     }
 
-    let Subcommand::Clippy { fix, allow_dirty, allow_staged, allow, deny, warn, forbid } =
-        &builder.config.cmd
-    else {
+    let Subcommand::Clippy { fix, allow_dirty, allow_staged, .. } = &builder.config.cmd else {
         unreachable!("clippy::lint_args can only be called from `clippy` subcommands.");
     };
 
@@ -53,12 +51,12 @@ fn lint_args(builder: &Builder<'_>, ignored_rules: &[&str]) -> Vec<String> {
 
     args.extend(strings(&["--"]));
 
-    if deny.is_empty() && forbid.is_empty() {
+    if config.deny.is_empty() && config.forbid.is_empty() {
         args.extend(strings(&["--cap-lints", "warn"]));
     }
 
     let all_args = std::env::args().collect::<Vec<_>>();
-    args.extend(get_clippy_rules_in_order(&all_args, allow, deny, warn, forbid));
+    args.extend(get_clippy_rules_in_order(&all_args, config));
 
     args.extend(ignored_rules.iter().map(|lint| format!("-Aclippy::{}", lint)));
     args.extend(builder.config.free_args.clone());
@@ -68,21 +66,17 @@ fn lint_args(builder: &Builder<'_>, ignored_rules: &[&str]) -> Vec<String> {
 /// We need to keep the order of the given clippy lint rules before passing them.
 /// Since clap doesn't offer any useful interface for this purpose out of the box,
 /// we have to handle it manually.
-pub(crate) fn get_clippy_rules_in_order(
-    all_args: &[String],
-    allow_rules: &[String],
-    deny_rules: &[String],
-    warn_rules: &[String],
-    forbid_rules: &[String],
-) -> Vec<String> {
+pub fn get_clippy_rules_in_order(all_args: &[String], config: &LintConfig) -> Vec<String> {
     let mut result = vec![];
 
     for (prefix, item) in
-        [("-A", allow_rules), ("-D", deny_rules), ("-W", warn_rules), ("-F", forbid_rules)]
+        [("-A", &config.allow), ("-D", &config.deny), ("-W", &config.warn), ("-F", &config.forbid)]
     {
         item.iter().for_each(|v| {
             let rule = format!("{prefix}{v}");
-            let position = all_args.iter().position(|t| t == &rule).unwrap();
+            // Arguments added by bootstrap in LintConfig won't show up in the all_args list, so
+            // put them at the end of the command line.
+            let position = all_args.iter().position(|t| t == &rule || t == v).unwrap_or(usize::MAX);
             result.push((position, rule));
         });
     }
@@ -92,8 +86,41 @@ pub(crate) fn get_clippy_rules_in_order(
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct LintConfig {
+    pub allow: Vec<String>,
+    pub warn: Vec<String>,
+    pub deny: Vec<String>,
+    pub forbid: Vec<String>,
+}
+
+impl LintConfig {
+    fn new(builder: &Builder<'_>) -> Self {
+        match builder.config.cmd.clone() {
+            Subcommand::Clippy { allow, deny, warn, forbid, .. } => {
+                Self { allow, warn, deny, forbid }
+            }
+            _ => unreachable!("LintConfig can only be called from `clippy` subcommands."),
+        }
+    }
+
+    fn merge(&self, other: &Self) -> Self {
+        let merged = |self_attr: &[String], other_attr: &[String]| -> Vec<String> {
+            self_attr.iter().cloned().chain(other_attr.iter().cloned()).collect()
+        };
+        // This is written this way to ensure we get a compiler error if we add a new field.
+        Self {
+            allow: merged(&self.allow, &other.allow),
+            warn: merged(&self.warn, &other.warn),
+            deny: merged(&self.deny, &other.deny),
+            forbid: merged(&self.forbid, &other.forbid),
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Std {
     pub target: TargetSelection,
+    config: LintConfig,
     /// Whether to lint only a subset of crates.
     crates: Vec<String>,
 }
@@ -108,7 +135,8 @@ impl Step for Std {
 
     fn make_run(run: RunConfig<'_>) {
         let crates = std_crates_for_run_make(&run);
-        run.builder.ensure(Std { target: run.target, crates });
+        let config = LintConfig::new(run.builder);
+        run.builder.ensure(Std { target: run.target, config, crates });
     }
 
     fn run(self, builder: &Builder<'_>) {
@@ -138,7 +166,7 @@ impl Step for Std {
         run_cargo(
             builder,
             cargo,
-            lint_args(builder, IGNORED_RULES_FOR_STD_AND_RUSTC),
+            lint_args(builder, &self.config, IGNORED_RULES_FOR_STD_AND_RUSTC),
             &libstd_stamp(builder, compiler, target),
             vec![],
             true,
@@ -150,6 +178,7 @@ impl Step for Std {
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Rustc {
     pub target: TargetSelection,
+    config: LintConfig,
     /// Whether to lint only a subset of crates.
     crates: Vec<String>,
 }
@@ -165,7 +194,8 @@ impl Step for Rustc {
 
     fn make_run(run: RunConfig<'_>) {
         let crates = run.make_run_crates(Alias::Compiler);
-        run.builder.ensure(Rustc { target: run.target, crates });
+        let config = LintConfig::new(run.builder);
+        run.builder.ensure(Rustc { target: run.target, config, crates });
     }
 
     /// Lints the compiler.
@@ -212,7 +242,7 @@ impl Step for Rustc {
         run_cargo(
             builder,
             cargo,
-            lint_args(builder, IGNORED_RULES_FOR_STD_AND_RUSTC),
+            lint_args(builder, &self.config, IGNORED_RULES_FOR_STD_AND_RUSTC),
             &librustc_stamp(builder, compiler, target),
             vec![],
             true,
@@ -232,6 +262,7 @@ macro_rules! lint_any {
         #[derive(Debug, Clone, Hash, PartialEq, Eq)]
         pub struct $name {
             pub target: TargetSelection,
+            config: LintConfig,
         }
 
         impl Step for $name {
@@ -243,8 +274,10 @@ macro_rules! lint_any {
             }
 
             fn make_run(run: RunConfig<'_>) {
+                let config = LintConfig::new(run.builder);
                 run.builder.ensure($name {
                     target: run.target,
+                    config,
                 });
             }
 
@@ -281,7 +314,7 @@ macro_rules! lint_any {
                 run_cargo(
                     builder,
                     cargo,
-                    lint_args(builder, &[]),
+                    lint_args(builder, &self.config, &[]),
                     &stamp,
                     vec![],
                     true,
@@ -295,7 +328,7 @@ macro_rules! lint_any {
 
 lint_any!(
     Bootstrap, "src/bootstrap", "bootstrap";
-    BuildHelper, "src/tools/build_helper", "build_helper";
+    BuildHelper, "src/build_helper", "build_helper";
     BuildManifest, "src/tools/build-manifest", "build-manifest";
     CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri";
     Clippy, "src/tools/clippy", "clippy";
@@ -319,3 +352,58 @@ lint_any!(
     Tidy, "src/tools/tidy", "tidy";
     TestFloatParse, "src/etc/test-float-parse", "test-float-parse";
 );
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct CI {
+    target: TargetSelection,
+    config: LintConfig,
+}
+
+impl Step for CI {
+    type Output = ();
+    const DEFAULT: bool = false;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("ci")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        let config = LintConfig::new(run.builder);
+        run.builder.ensure(CI { target: run.target, config });
+    }
+
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        builder.ensure(Bootstrap {
+            target: self.target,
+            config: self.config.merge(&LintConfig {
+                allow: vec![],
+                warn: vec![],
+                deny: vec!["warnings".into()],
+                forbid: vec![],
+            }),
+        });
+        let library_clippy_cfg = LintConfig {
+            allow: vec!["clippy::all".into()],
+            warn: vec![],
+            deny: vec!["clippy::correctness".into()],
+            forbid: vec![],
+        };
+        let compiler_clippy_cfg = LintConfig {
+            allow: vec!["clippy::all".into()],
+            warn: vec![],
+            deny: vec!["clippy::correctness".into(), "clippy::clone_on_ref_ptr".into()],
+            forbid: vec![],
+        };
+
+        builder.ensure(Std {
+            target: self.target,
+            config: self.config.merge(&library_clippy_cfg),
+            crates: vec![],
+        });
+        builder.ensure(Rustc {
+            target: self.target,
+            config: self.config.merge(&compiler_clippy_cfg),
+            crates: vec![],
+        });
+    }
+}
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 3394f2a84a0..24be705f481 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1976,9 +1976,13 @@ impl Step for Assemble {
             }
         }
 
-        {
-            // `llvm-strip` is used by rustc, which is actually just a symlink to `llvm-objcopy`,
-            // so copy and rename `llvm-objcopy`.
+        if builder.config.llvm_enabled(target_compiler.host) && builder.config.llvm_tools_enabled {
+            // `llvm-strip` is used by rustc, which is actually just a symlink to `llvm-objcopy`, so
+            // copy and rename `llvm-objcopy`.
+            //
+            // But only do so if llvm-tools are enabled, as bootstrap compiler might not contain any
+            // LLVM tools, e.g. for cg_clif.
+            // See <https://github.com/rust-lang/rust/issues/132719>.
             let src_exe = exe("llvm-objcopy", target_compiler.host);
             let dst_exe = exe("rust-objcopy", target_compiler.host);
             builder.copy_link(&libdir_bin.join(src_exe), &libdir_bin.join(dst_exe));
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 69ec832a44a..8a9321f8e79 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -1030,7 +1030,7 @@ macro_rules! tool_doc {
 // NOTE: make sure to register these in `Builder::get_step_description`.
 tool_doc!(
     BuildHelper,
-    "src/tools/build_helper",
+    "src/build_helper",
     rustc_tool = false,
     is_library = true,
     crates = ["build_helper"]
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 2c36d8bab82..532c8f767eb 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1354,7 +1354,7 @@ impl Step for CrateBuildHelper {
     const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.path("src/tools/build_helper")
+        run.path("src/build_helper")
     }
 
     fn make_run(run: RunConfig<'_>) {
@@ -1372,7 +1372,7 @@ impl Step for CrateBuildHelper {
             Mode::ToolBootstrap,
             host,
             Kind::Test,
-            "src/tools/build_helper",
+            "src/build_helper",
             SourceType::InTree,
             &[],
         );
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index 134da5db96d..0688a1d6892 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -1198,15 +1198,6 @@ impl Builder<'_> {
             rustflags.arg("-Zinline-mir-preserve-debug");
         }
 
-        if self.config.rustc_parallel
-            && matches!(mode, Mode::ToolRustc | Mode::Rustc | Mode::Codegen)
-        {
-            // keep in sync with `bootstrap/lib.rs:Build::rustc_features`
-            // `cfg` option for rustc, `features` option for cargo, for conditional compilation
-            rustflags.arg("--cfg=parallel_compiler");
-            rustdocflags.arg("--cfg=parallel_compiler");
-        }
-
         Cargo {
             command: cargo,
             compiler,
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index f1b3cf6da13..d59e0fa7288 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -839,6 +839,7 @@ impl<'a> Builder<'a> {
                 clippy::RustInstaller,
                 clippy::TestFloatParse,
                 clippy::Tidy,
+                clippy::CI,
             ),
             Kind::Check | Kind::Fix => describe!(
                 check::Std,
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index a93038d51d3..95b1303fa71 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -28,6 +28,24 @@ use crate::utils::cache::{INTERNER, Interned};
 use crate::utils::channel::{self, GitInfo};
 use crate::utils::helpers::{self, exe, output, t};
 
+/// Each path in this list is considered "allowed" in the `download-rustc="if-unchanged"` logic.
+/// This means they can be modified and changes to these paths should never trigger a compiler build
+/// when "if-unchanged" is set.
+///
+/// NOTE: Paths must have the ":!" prefix to tell git to ignore changes in those paths during
+/// the diff check.
+///
+/// WARNING: Be cautious when adding paths to this list. If a path that influences the compiler build
+/// is added here, it will cause bootstrap to skip necessary rebuilds, which may lead to risky results.
+/// For example, "src/bootstrap" should never be included in this list as it plays a crucial role in the
+/// final output/compiler, which can be significantly affected by changes made to the bootstrap sources.
+#[rustfmt::skip] // We don't want rustfmt to oneline this list
+pub(crate) const RUSTC_IF_UNCHANGED_ALLOWED_PATHS: &[&str] = &[
+    ":!src/tools",
+    ":!tests",
+    ":!triagebot.toml",
+];
+
 macro_rules! check_ci_llvm {
     ($name:expr) => {
         assert!(
@@ -278,7 +296,6 @@ pub struct Config {
     pub rust_strip: bool,
     pub rust_frame_pointers: bool,
     pub rust_stack_protector: Option<String>,
-    pub rustc_parallel: bool,
     pub rustc_default_linker: Option<String>,
     pub rust_optimize_tests: bool,
     pub rust_dist_src: bool,
@@ -1224,7 +1241,6 @@ impl Config {
             bindir: "bin".into(),
             dist_include_mingw_linker: true,
             dist_compression_profile: "fast".into(),
-            rustc_parallel: true,
 
             stdout_is_tty: std::io::stdout().is_terminal(),
             stderr_is_tty: std::io::stderr().is_terminal(),
@@ -1668,6 +1684,14 @@ impl Config {
         let mut lld_enabled = None;
         let mut std_features = None;
 
+        let is_user_configured_rust_channel =
+            if let Some(channel) = toml.rust.as_ref().and_then(|r| r.channel.clone()) {
+                config.channel = channel;
+                true
+            } else {
+                false
+            };
+
         let default = config.channel == "dev";
         config.omit_git_hash = toml.rust.as_ref().and_then(|r| r.omit_git_hash).unwrap_or(default);
 
@@ -1685,8 +1709,6 @@ impl Config {
         config.in_tree_llvm_info = GitInfo::new(false, &config.src.join("src/llvm-project"));
         config.in_tree_gcc_info = GitInfo::new(false, &config.src.join("src/gcc"));
 
-        let mut is_user_configured_rust_channel = false;
-
         if let Some(rust) = toml.rust {
             let Rust {
                 optimize: optimize_toml,
@@ -1708,7 +1730,7 @@ impl Config {
                 parallel_compiler,
                 randomize_layout,
                 default_linker,
-                channel,
+                channel: _, // already handled above
                 description,
                 musl_root,
                 rpath,
@@ -1745,9 +1767,6 @@ impl Config {
                 std_features: std_features_toml,
             } = rust;
 
-            is_user_configured_rust_channel = channel.is_some();
-            set(&mut config.channel, channel.clone());
-
             config.download_rustc_commit =
                 config.download_ci_rustc_commit(download_rustc, config.llvm_assertions);
 
@@ -1788,8 +1807,14 @@ impl Config {
 
             config.rust_randomize_layout = randomize_layout.unwrap_or_default();
             config.llvm_tools_enabled = llvm_tools.unwrap_or(true);
-            config.rustc_parallel =
-                parallel_compiler.unwrap_or(config.channel == "dev" || config.channel == "nightly");
+
+            // FIXME: Remove this option at the end of 2024.
+            if parallel_compiler.is_some() {
+                println!(
+                    "WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default"
+                );
+            }
+
             config.llvm_enzyme =
                 llvm_enzyme.unwrap_or(config.channel == "dev" || config.channel == "nightly");
             config.rustc_default_linker = default_linker;
@@ -2775,32 +2800,33 @@ impl Config {
             }
         };
 
-        let mut files_to_track = vec!["compiler", "src/version", "src/stage0", "src/ci/channel"];
+        // RUSTC_IF_UNCHANGED_ALLOWED_PATHS
+        let mut allowed_paths = RUSTC_IF_UNCHANGED_ALLOWED_PATHS.to_vec();
 
-        // In CI, disable ci-rustc if there are changes in the library tree. But for non-CI, ignore
+        // In CI, disable ci-rustc if there are changes in the library tree. But for non-CI, allow
         // these changes to speed up the build process for library developers. This provides consistent
         // functionality for library developers between `download-rustc=true` and `download-rustc="if-unchanged"`
         // options.
-        if CiEnv::is_ci() {
-            files_to_track.push("library");
+        if !CiEnv::is_ci() {
+            allowed_paths.push(":!library");
         }
 
         // Look for a version to compare to based on the current commit.
         // Only commits merged by bors will have CI artifacts.
-        let commit =
-            match self.last_modified_commit(&files_to_track, "download-rustc", if_unchanged) {
-                Some(commit) => commit,
-                None => {
-                    if if_unchanged {
-                        return None;
-                    }
-                    println!("ERROR: could not find commit hash for downloading rustc");
-                    println!("HELP: maybe your repository history is too shallow?");
-                    println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
-                    println!("HELP: or fetch enough history to include one upstream commit");
-                    crate::exit!(1);
+        let commit = match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged)
+        {
+            Some(commit) => commit,
+            None => {
+                if if_unchanged {
+                    return None;
                 }
-            };
+                println!("ERROR: could not find commit hash for downloading rustc");
+                println!("HELP: maybe your repository history is too shallow?");
+                println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
+                println!("HELP: or fetch enough history to include one upstream commit");
+                crate::exit!(1);
+            }
+        };
 
         if CiEnv::is_ci() && {
             let head_sha =
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index b6523a458e2..24f932a1724 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -8,8 +8,8 @@ use clap::CommandFactory;
 use serde::Deserialize;
 
 use super::flags::Flags;
-use super::{ChangeIdWrapper, Config};
-use crate::core::build_steps::clippy::get_clippy_rules_in_order;
+use super::{ChangeIdWrapper, Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS};
+use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order};
 use crate::core::build_steps::llvm;
 use crate::core::config::{LldMode, Target, TargetSelection, TomlConfig};
 
@@ -309,9 +309,10 @@ fn order_of_clippy_rules() {
     ];
     let config = Config::parse(Flags::parse(&args));
 
-    let actual = match &config.cmd {
+    let actual = match config.cmd.clone() {
         crate::Subcommand::Clippy { allow, deny, warn, forbid, .. } => {
-            get_clippy_rules_in_order(&args, &allow, &deny, &warn, &forbid)
+            let cfg = LintConfig { allow, deny, warn, forbid };
+            get_clippy_rules_in_order(&args, &cfg)
         }
         _ => panic!("invalid subcommand"),
     };
@@ -327,6 +328,24 @@ fn order_of_clippy_rules() {
 }
 
 #[test]
+fn clippy_rule_separate_prefix() {
+    let args =
+        vec!["clippy".to_string(), "-A clippy:all".to_string(), "-W clippy::style".to_string()];
+    let config = Config::parse(Flags::parse(&args));
+
+    let actual = match config.cmd.clone() {
+        crate::Subcommand::Clippy { allow, deny, warn, forbid, .. } => {
+            let cfg = LintConfig { allow, deny, warn, forbid };
+            get_clippy_rules_in_order(&args, &cfg)
+        }
+        _ => panic!("invalid subcommand"),
+    };
+
+    let expected = vec!["-A clippy:all".to_string(), "-W clippy::style".to_string()];
+    assert_eq!(expected, actual);
+}
+
+#[test]
 fn verbose_tests_default_value() {
     let config = Config::parse(Flags::parse(&["build".into(), "compiler".into()]));
     assert_eq!(config.verbose_tests, false);
@@ -413,3 +432,18 @@ fn jobs_precedence() {
     );
     assert_eq!(config.jobs, Some(123));
 }
+
+#[test]
+fn check_rustc_if_unchanged_paths() {
+    let config = parse("");
+    let normalised_allowed_paths: Vec<_> = RUSTC_IF_UNCHANGED_ALLOWED_PATHS
+        .iter()
+        .map(|t| {
+            t.strip_prefix(":!").expect(&format!("{t} doesn't have ':!' prefix, but it should."))
+        })
+        .collect();
+
+    for p in normalised_allowed_paths {
+        assert!(config.src.join(p).exists(), "{p} doesn't exist.");
+    }
+}
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index ba74cabcd30..c384fd6bf43 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -80,11 +80,8 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     (Some(Mode::Rustc), "llvm_enzyme", None),
     (Some(Mode::Codegen), "llvm_enzyme", None),
     (Some(Mode::ToolRustc), "llvm_enzyme", None),
-    (Some(Mode::Rustc), "parallel_compiler", None),
-    (Some(Mode::ToolRustc), "parallel_compiler", None),
     (Some(Mode::ToolRustc), "rust_analyzer", None),
     (Some(Mode::ToolStd), "rust_analyzer", None),
-    (Some(Mode::Codegen), "parallel_compiler", None),
     // Any library specific cfgs like `target_os`, `target_arch` should be put in
     // priority the `[lints.rust.unexpected_cfgs.check-cfg]` table
     // in the appropriate `library/{std,alloc,core}/Cargo.toml`
@@ -695,9 +692,6 @@ impl Build {
             features.push("llvm");
         }
         // keep in sync with `bootstrap/compile.rs:rustc_cargo_env`
-        if self.config.rustc_parallel && check("rustc_use_parallel_compiler") {
-            features.push("rustc_use_parallel_compiler");
-        }
         if self.config.rust_randomize_layout {
             features.push("rustc_randomized_layouts");
         }
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 0915ec15a2f..1d05f94e3be 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -291,6 +291,11 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         summary: "New option `llvm.offload` to control whether the llvm offload runtime for GPU support is built. Implicitly enables the openmp runtime as dependency.",
     },
     ChangeInfo {
+        change_id: 132282,
+        severity: ChangeSeverity::Warning,
+        summary: "Deprecated `rust.parallel_compiler` as the compiler now always defaults to being parallel (with 1 thread)",
+    },
+    ChangeInfo {
         change_id: 132494,
         severity: ChangeSeverity::Info,
         summary: "`download-rustc='if-unchanged'` is now a default option for library profile.",
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 7162007e9f0..3fb2330469a 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -145,7 +145,7 @@ pub fn symlink_dir(config: &Config, original: &Path, link: &Path) -> io::Result<
 
     #[cfg(windows)]
     fn symlink_dir_inner(target: &Path, junction: &Path) -> io::Result<()> {
-        junction::create(&target, &junction)
+        junction::create(target, junction)
     }
 }
 
diff --git a/src/tools/build_helper/Cargo.toml b/src/build_helper/Cargo.toml
index 66894e1abc4..66894e1abc4 100644
--- a/src/tools/build_helper/Cargo.toml
+++ b/src/build_helper/Cargo.toml
diff --git a/src/tools/build_helper/README.md b/src/build_helper/README.md
index f81b631c3fd..f81b631c3fd 100644
--- a/src/tools/build_helper/README.md
+++ b/src/build_helper/README.md
diff --git a/src/tools/build_helper/src/ci.rs b/src/build_helper/src/ci.rs
index 60f319129a0..60f319129a0 100644
--- a/src/tools/build_helper/src/ci.rs
+++ b/src/build_helper/src/ci.rs
diff --git a/src/tools/build_helper/src/drop_bomb/mod.rs b/src/build_helper/src/drop_bomb/mod.rs
index 0a5bb04b55b..0a5bb04b55b 100644
--- a/src/tools/build_helper/src/drop_bomb/mod.rs
+++ b/src/build_helper/src/drop_bomb/mod.rs
diff --git a/src/tools/build_helper/src/drop_bomb/tests.rs b/src/build_helper/src/drop_bomb/tests.rs
index 4a488c0f670..4a488c0f670 100644
--- a/src/tools/build_helper/src/drop_bomb/tests.rs
+++ b/src/build_helper/src/drop_bomb/tests.rs
diff --git a/src/tools/build_helper/src/git.rs b/src/build_helper/src/git.rs
index 2aad5650fa8..2aad5650fa8 100644
--- a/src/tools/build_helper/src/git.rs
+++ b/src/build_helper/src/git.rs
diff --git a/src/tools/build_helper/src/lib.rs b/src/build_helper/src/lib.rs
index 4a4f0ca2a9d..4a4f0ca2a9d 100644
--- a/src/tools/build_helper/src/lib.rs
+++ b/src/build_helper/src/lib.rs
diff --git a/src/tools/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs
index 2d0c66a8f33..2d0c66a8f33 100644
--- a/src/tools/build_helper/src/metrics.rs
+++ b/src/build_helper/src/metrics.rs
diff --git a/src/tools/build_helper/src/stage0_parser.rs b/src/build_helper/src/stage0_parser.rs
index ff05b116989..2a0c12a1c91 100644
--- a/src/tools/build_helper/src/stage0_parser.rs
+++ b/src/build_helper/src/stage0_parser.rs
@@ -25,7 +25,7 @@ pub struct Stage0Config {
 }
 
 pub fn parse_stage0_file() -> Stage0 {
-    let stage0_content = include_str!("../../../stage0");
+    let stage0_content = include_str!("../../stage0");
 
     let mut stage0 = Stage0::default();
     for line in stage0_content.lines() {
diff --git a/src/tools/build_helper/src/util.rs b/src/build_helper/src/util.rs
index 72c05c4c48a..72c05c4c48a 100644
--- a/src/tools/build_helper/src/util.rs
+++ b/src/build_helper/src/util.rs
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index fdc8a7310c8..f0afb570cc4 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -50,9 +50,7 @@ ENV SCRIPT \
            python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \
            /scripts/check-default-config-profiles.sh && \
            python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
-           python3 ../x.py clippy bootstrap -Dwarnings && \
-           python3 ../x.py clippy library -Aclippy::all -Dclippy::correctness && \
-           python3 ../x.py clippy compiler -Aclippy::all -Dclippy::correctness -Dclippy::clone_on_ref_ptr && \
+           python3 ../x.py clippy ci && \
            python3 ../x.py build --stage 0 src/tools/build-manifest && \
            python3 ../x.py test --stage 0 src/tools/compiletest && \
            python3 ../x.py test --stage 0 core alloc std test proc_macro && \
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 28487bce482..d554186df4c 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -96,7 +96,9 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
     docker --version
 
     REGISTRY=ghcr.io
-    REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER:-rust-lang-ci}
+    # Hardcode username to reuse cache between auto and pr jobs
+    # FIXME: should be changed after move from rust-lang-ci
+    REGISTRY_USERNAME=rust-lang-ci
     # Tag used to push the final Docker image, so that it can be pulled by e.g. rustup
     IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum}
     # Tag used to cache the Docker build
diff --git a/src/ci/run.sh b/src/ci/run.sh
index 8e2f525db68..5690d8edea6 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -115,14 +115,16 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNE
 if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
   RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.remap-debuginfo"
-  RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level-std=1"
+
+  if [ "$DEPLOY_ALT" != "" ]; then
+    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level=2"
+  else
+    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level-std=1"
+  fi
 
   if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
   elif [ "$DEPLOY_ALT" != "" ]; then
-    if [ "$ALT_PARALLEL_COMPILER" = "" ]; then
-      RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler=false"
-    fi
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions"
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
   fi
@@ -261,7 +263,7 @@ fi
 
 if [ "$RUN_CHECK_WITH_PARALLEL_QUERIES" != "" ]; then
   rm -f config.toml
-  $SRC/configure --set change-id=99999999 --set rust.parallel-compiler
+  $SRC/configure --set change-id=99999999
 
   # Save the build metrics before we wipe the directory
   if [ "$HAS_METRICS" = 1 ]; then
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 9db78608b17d5f4a6c033b8a3038466b87d6320
+Subproject e1d1f2cdcee4d52b9a01ff7c448be4372a377b7
diff --git a/src/doc/rustdoc/src/read-documentation/search.md b/src/doc/rustdoc/src/read-documentation/search.md
index e912ca0fe5b..718d2201c3a 100644
--- a/src/doc/rustdoc/src/read-documentation/search.md
+++ b/src/doc/rustdoc/src/read-documentation/search.md
@@ -130,29 +130,31 @@ pub trait MyTrait {
 /// This function can be found using the following search queries:
 ///
 ///     MyTrait<First=u8, Second=u32> -> bool
-///     MyTrait<u32, First=u8> -> bool
 ///     MyTrait<Second=u32> -> bool
-///     MyTrait<u32, u8> -> bool
 ///
 /// The following queries, however, will *not* match it:
 ///
 ///     MyTrait<First=u32> -> bool
 ///     MyTrait<u32, u32> -> bool
+///     MyTrait<u32, First=u8> -> bool
+///     MyTrait<u32, u8> -> bool
 pub fn my_fn(x: impl MyTrait<First=u8, Second=u32>) -> bool { true }
 ```
 
-Generics and function parameters are order-agnostic, but sensitive to nesting
+Function parameters are order-agnostic, but sensitive to nesting
 and number of matches. For example, a function with the signature
 `fn read_all(&mut self: impl Read) -> Result<Vec<u8>, Error>`
 will match these queries:
 
 * `&mut Read -> Result<Vec<u8>, Error>`
 * `Read -> Result<Vec<u8>, Error>`
-* `Read -> Result<Error, Vec>`
 * `Read -> Result<Vec<u8>>`
 * `Read -> u8`
 
-But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`.
+But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`,
+because those are nested incorrectly, and it does not match
+`Result<Error, Vec<u8>>` or `Result<Error>`, because those are
+in the wrong order.
 
 To search for a function that accepts a function as a parameter,
 like `Iterator::all`, wrap the nested signature in parenthesis,
diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
index f00a0fe7287..01de12bb90e 100644
--- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
+++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
@@ -18,7 +18,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 - MSP430
 - M68k
 - CSKY
-- Arm64EC
 - SPARC
 
 ## Register classes
@@ -53,9 +52,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | CSKY         | `freg`         | `f[0-31]`                          | `f`                  |
 | SPARC        | `reg`          | `r[2-29]`                          | `r`                  |
 | SPARC        | `yreg`         | `y`                                | Only clobbers        |
-| Arm64EC      | `reg`          | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r`            |
-| Arm64EC      | `vreg`         | `v[0-15]`                          | `w`                  |
-| Arm64EC      | `vreg_low16`   | `v[0-15]`                          | `x`                  |
 
 > **Notes**:
 > - NVPTX doesn't have a fixed register set, so named registers are not supported.
@@ -92,8 +88,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | CSKY         | `freg`                          | None           | `f32`,                                  |
 | SPARC        | `reg`                           | None           | `i8`, `i16`, `i32`, `i64` (SPARC64 only) |
 | SPARC        | `yreg`                          | N/A            | Only clobbers                           |
-| Arm64EC      | `reg`                           | None           | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
-| Arm64EC      | `vreg`                          | None           | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
 
 ## Register aliases
 
@@ -134,12 +128,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | SPARC        | `r[8-15]`     | `o[0-7]`  |
 | SPARC        | `r[16-23]`    | `l[0-7]`  |
 | SPARC        | `r[24-31]`    | `i[0-7]`  |
-| Arm64EC      | `x[0-30]`     | `w[0-30]` |
-| Arm64EC      | `x29`         | `fp`      |
-| Arm64EC      | `x30`         | `lr`      |
-| Arm64EC      | `sp`          | `wsp`     |
-| Arm64EC      | `xzr`         | `wzr`     |
-| Arm64EC      | `v[0-15]`     | `b[0-15]`, `h[0-15]`, `s[0-15]`, `d[0-15]`, `q[0-15]` |
 
 > **Notes**:
 > - TI does not mandate a frame pointer for MSP430, but toolchains are allowed
@@ -150,8 +138,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | Architecture | Unsupported register                    | Reason                                                                                                                                                                              |
 | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 | All          | `sp`, `r14`/`o6` (SPARC)                | The stack pointer must be restored to its original value at the end of an asm code block.                                                                                           |
-| All          | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC), `x29` (Arm64EC) | The frame pointer cannot be used as an input or output.                                            |
-| All          | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC), `x19` (Arm64EC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames.                                                             |
+| All          | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output.                                                             |
+| All          | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames.                                                                              |
 | MIPS         | `$0` or `$zero`                         | This is a constant zero register which can't be modified.                                                                                                                           |
 | MIPS         | `$1` or `$at`                           | Reserved for assembler.                                                                                                                                                             |
 | MIPS         | `$26`/`$k0`, `$27`/`$k1`                | OS-reserved registers.                                                                                                                                                              |
@@ -176,9 +164,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | SPARC        | `r5`/`g5`                               | Reserved for system. (SPARC32 only) |
 | SPARC        | `r6`/`g6`, `r7`/`g7`                    | Reserved for system. |
 | SPARC        | `r31`/`i7`                              | Return address cannot be used as inputs or outputs. |
-| Arm64EC      | `xzr`                                   | This is a constant zero register which can't be modified. |
-| Arm64EC      | `x18`                                   | This is an OS-reserved register. |
-| Arm64EC      | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]` | These are AArch64 registers that are not supported for Arm64EC. |
 
 
 ## Template modifiers
@@ -197,16 +182,6 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | SPARC        | `reg`          | None     | `%o0`          | None          |
 | CSKY         | `reg`          | None     | `r0`           | None          |
 | CSKY         | `freg`         | None     | `f0`           | None          |
-| Arm64EC      | `reg`          | None     | `x0`           | `x`           |
-| Arm64EC      | `reg`          | `w`      | `w0`           | `w`           |
-| Arm64EC      | `reg`          | `x`      | `x0`           | `x`           |
-| Arm64EC      | `vreg`         | None     | `v0`           | None          |
-| Arm64EC      | `vreg`         | `v`      | `v0`           | None          |
-| Arm64EC      | `vreg`         | `b`      | `b0`           | `b`           |
-| Arm64EC      | `vreg`         | `h`      | `h0`           | `h`           |
-| Arm64EC      | `vreg`         | `s`      | `s0`           | `s`           |
-| Arm64EC      | `vreg`         | `d`      | `d0`           | `d`           |
-| Arm64EC      | `vreg`         | `q`      | `q0`           | `q`           |
 
 # Flags covered by `preserves_flags`
 
@@ -220,6 +195,3 @@ These flags registers must be restored upon exiting the asm block if the `preser
 - SPARC
   - Integer condition codes (`icc` and `xcc`)
   - Floating-point condition codes (`fcc[0-3]`)
-- Arm64EC
-  - Condition flags (`NZCV` register).
-  - Floating-point status (`FPSR` register).
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 57b6de67ee8..70749f7cb17 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -13,7 +13,7 @@ rinja = { version = "0.3", default-features = false, features = ["config"] }
 base64 = "0.21.7"
 itertools = "0.12"
 indexmap = "2"
-minifier = "0.3.1"
+minifier = { version = "0.3.2", default-features = false }
 pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false }
 regex = "1"
 rustdoc-json-types = { path = "../rustdoc-json-types" }
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 97529e420e3..5ddd6188c2d 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -134,11 +134,7 @@ pub(crate) fn try_inline(
             })
         }
         Res::Def(DefKind::Macro(kind), did) => {
-            let is_doc_hidden = cx.tcx.is_doc_hidden(did)
-                || attrs_without_docs
-                    .map(|(attrs, _)| attrs)
-                    .is_some_and(|attrs| utils::attrs_have_doc_flag(attrs.iter(), sym::hidden));
-            let mac = build_macro(cx, did, name, import_def_id, kind, is_doc_hidden);
+            let mac = build_macro(cx, did, name, kind);
 
             let type_kind = match kind {
                 MacroKind::Bang => ItemType::Macro,
@@ -740,18 +736,14 @@ fn build_macro(
     cx: &mut DocContext<'_>,
     def_id: DefId,
     name: Symbol,
-    import_def_id: Option<LocalDefId>,
     macro_kind: MacroKind,
-    is_doc_hidden: bool,
 ) -> clean::ItemKind {
     match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) {
         LoadedMacro::MacroDef { def, .. } => match macro_kind {
-            MacroKind::Bang => {
-                let vis = cx.tcx.visibility(import_def_id.map(|d| d.to_def_id()).unwrap_or(def_id));
-                clean::MacroItem(clean::Macro {
-                    source: utils::display_macro_source(cx, name, &def, def_id, vis, is_doc_hidden),
-                })
-            }
+            MacroKind::Bang => clean::MacroItem(clean::Macro {
+                source: utils::display_macro_source(cx, name, &def),
+                macro_rules: def.macro_rules,
+            }),
             MacroKind::Derive | MacroKind::Attr => {
                 clean::ProcMacroItem(clean::ProcMacro { kind: macro_kind, helpers: Vec::new() })
             }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 6b6142a6eaa..9e11360cab4 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2119,7 +2119,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
                 })
                 .collect::<Vec<_>>();
 
-            let bindings = obj
+            let constraints = obj
                 .projection_bounds()
                 .map(|pb| AssocItemConstraint {
                     assoc: projection_to_path_segment(
@@ -2155,7 +2155,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
                 .collect();
             let late_bound_regions = late_bound_regions.into_iter().collect();
 
-            let path = clean_middle_path(cx, did, false, bindings, args);
+            let path = clean_middle_path(cx, did, false, constraints, args);
             bounds.insert(0, PolyTrait { trait_: path, generic_params: late_bound_regions });
 
             DynTrait(bounds, lifetime)
@@ -2787,13 +2787,10 @@ fn clean_maybe_renamed_item<'tcx>(
                 fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
             }),
             ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx),
-            ItemKind::Macro(macro_def, MacroKind::Bang) => {
-                let ty_vis = cx.tcx.visibility(def_id);
-                MacroItem(Macro {
-                    // FIXME this shouldn't be false
-                    source: display_macro_source(cx, name, macro_def, def_id, ty_vis, false),
-                })
-            }
+            ItemKind::Macro(macro_def, MacroKind::Bang) => MacroItem(Macro {
+                source: display_macro_source(cx, name, macro_def),
+                macro_rules: macro_def.macro_rules,
+            }),
             ItemKind::Macro(_, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx),
             // proc macros can have a name set by attributes
             ItemKind::Fn(ref sig, generics, body_id) => {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index e5c9539b5e7..e3a0dbe1a7f 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -2543,6 +2543,8 @@ pub(crate) struct ImportSource {
 #[derive(Clone, Debug)]
 pub(crate) struct Macro {
     pub(crate) source: String,
+    /// Whether the macro was defined via `macro_rules!` as opposed to `macro`.
+    pub(crate) macro_rules: bool,
 }
 
 #[derive(Clone, Debug)]
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 560831197f0..e551e0170c6 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -24,7 +24,6 @@ use crate::clean::{
     clean_middle_ty, inline,
 };
 use crate::core::DocContext;
-use crate::html::format::visibility_to_src_with_space;
 
 #[cfg(test)]
 mod tests;
@@ -112,7 +111,6 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
             return None;
         }
 
-        // Elide internal host effect args.
         let param = generics.param_at(index, cx.tcx);
         let arg = ty::Binder::bind_with_vars(arg, bound_vars);
 
@@ -201,35 +199,30 @@ fn clean_middle_generic_args_with_constraints<'tcx>(
     cx: &mut DocContext<'tcx>,
     did: DefId,
     has_self: bool,
-    constraints: ThinVec<AssocItemConstraint>,
-    ty_args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
+    mut constraints: ThinVec<AssocItemConstraint>,
+    args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
 ) -> GenericArgs {
-    let args = clean_middle_generic_args(cx, ty_args.map_bound(|args| &args[..]), has_self, did);
-
-    if cx.tcx.is_trait(did) && cx.tcx.trait_def(did).paren_sugar {
-        let ty = ty_args
+    if cx.tcx.is_trait(did)
+        && cx.tcx.trait_def(did).paren_sugar
+        && let ty::Tuple(tys) = args.skip_binder().type_at(has_self as usize).kind()
+    {
+        let inputs = tys
             .iter()
-            .nth(if has_self { 1 } else { 0 })
-            .unwrap()
-            .map_bound(|arg| arg.expect_ty());
-        let inputs =
-            // The trait's first substitution is the one after self, if there is one.
-            match ty.skip_binder().kind() {
-                ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None, None)).collect::<Vec<_>>().into(),
-                _ => return GenericArgs::AngleBracketed { args: args.into(), constraints },
-            };
-        let output = constraints.into_iter().next().and_then(|binding| match binding.kind {
-            AssocItemConstraintKind::Equality { term: Term::Type(ty) }
-                if ty != Type::Tuple(Vec::new()) =>
-            {
+            .map(|ty| clean_middle_ty(args.rebind(ty), cx, None, None))
+            .collect::<Vec<_>>()
+            .into();
+        let output = constraints.pop().and_then(|constraint| match constraint.kind {
+            AssocItemConstraintKind::Equality { term: Term::Type(ty) } if !ty.is_unit() => {
                 Some(Box::new(ty))
             }
             _ => None,
         });
-        GenericArgs::Parenthesized { inputs, output }
-    } else {
-        GenericArgs::AngleBracketed { args: args.into(), constraints }
+        return GenericArgs::Parenthesized { inputs, output };
     }
+
+    let args = clean_middle_generic_args(cx, args.map_bound(|args| &args[..]), has_self, did);
+
+    GenericArgs::AngleBracketed { args: args.into(), constraints }
 }
 
 pub(super) fn clean_middle_path<'tcx>(
@@ -599,7 +592,7 @@ pub(crate) static DOC_CHANNEL: Lazy<&'static str> =
 
 /// Render a sequence of macro arms in a format suitable for displaying to the user
 /// as part of an item declaration.
-pub(super) fn render_macro_arms<'a>(
+fn render_macro_arms<'a>(
     tcx: TyCtxt<'_>,
     matchers: impl Iterator<Item = &'a TokenTree>,
     arm_delim: &str,
@@ -620,9 +613,6 @@ pub(super) fn display_macro_source(
     cx: &mut DocContext<'_>,
     name: Symbol,
     def: &ast::MacroDef,
-    def_id: DefId,
-    vis: ty::Visibility<DefId>,
-    is_doc_hidden: bool,
 ) -> String {
     // Extract the spans of all matchers. They represent the "interface" of the macro.
     let matchers = def.body.tokens.chunks(4).map(|arm| &arm[0]);
@@ -632,18 +622,13 @@ pub(super) fn display_macro_source(
     } else {
         if matchers.len() <= 1 {
             format!(
-                "{vis}macro {name}{matchers} {{\n    ...\n}}",
-                vis = visibility_to_src_with_space(Some(vis), cx.tcx, def_id, is_doc_hidden),
+                "macro {name}{matchers} {{\n    ...\n}}",
                 matchers = matchers
                     .map(|matcher| render_macro_matcher(cx.tcx, matcher))
                     .collect::<String>(),
             )
         } else {
-            format!(
-                "{vis}macro {name} {{\n{arms}}}",
-                vis = visibility_to_src_with_space(Some(vis), cx.tcx, def_id, is_doc_hidden),
-                arms = render_macro_arms(cx.tcx, matchers, ","),
-            )
+            format!("macro {name} {{\n{arms}}}", arms = render_macro_arms(cx.tcx, matchers, ","))
         }
     }
 }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 7ba3cfb66bd..d5f6bfe415d 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -6,7 +6,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::codes::*;
-use rustc_errors::emitter::{DynEmitter, HumanEmitter, stderr_destination};
+use rustc_errors::emitter::{
+    DynEmitter, HumanEmitter, HumanReadableErrorType, OutputTheme, stderr_destination,
+};
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::{ErrorGuaranteed, TerminalUrl};
 use rustc_feature::UnstableFeatures;
@@ -154,6 +156,11 @@ pub(crate) fn new_dcx(
                     .teach(unstable_opts.teach)
                     .diagnostic_width(diagnostic_width)
                     .track_diagnostics(unstable_opts.track_diagnostics)
+                    .theme(if let HumanReadableErrorType::Unicode = kind {
+                        OutputTheme::Unicode
+                    } else {
+                        OutputTheme::Ascii
+                    })
                     .ui_testing(unstable_opts.ui_testing),
             )
         }
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 11d8f1947d6..25e576e9e63 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -15,6 +15,7 @@ pub(crate) use make::DocTestBuilder;
 pub(crate) use markdown::test as test_markdown;
 use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
+use rustc_errors::emitter::HumanReadableErrorType;
 use rustc_errors::{ColorConfig, DiagCtxtHandle, ErrorGuaranteed, FatalError};
 use rustc_hir::CRATE_HIR_ID;
 use rustc_hir::def_id::LOCAL_CRATE;
@@ -520,10 +521,14 @@ fn run_test(
     });
     if let ErrorOutputType::HumanReadable(kind, color_config) = rustdoc_options.error_format {
         let short = kind.short();
+        let unicode = kind == HumanReadableErrorType::Unicode;
 
         if short {
             compiler.arg("--error-format").arg("short");
         }
+        if unicode {
+            compiler.arg("--error-format").arg("human-unicode");
+        }
 
         match color_config {
             ColorConfig::Never => {
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index e9d5ba2ea57..2f9e7976ca1 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1615,47 +1615,6 @@ pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
     })
 }
 
-/// This function is the same as print_with_space, except that it renders no links.
-/// It's used for macros' rendered source view, which is syntax highlighted and cannot have
-/// any HTML in it.
-pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>(
-    visibility: Option<ty::Visibility<DefId>>,
-    tcx: TyCtxt<'tcx>,
-    item_did: DefId,
-    is_doc_hidden: bool,
-) -> impl Display + 'a + Captures<'tcx> {
-    let vis: Cow<'static, str> = match visibility {
-        None => "".into(),
-        Some(ty::Visibility::Public) => "pub ".into(),
-        Some(ty::Visibility::Restricted(vis_did)) => {
-            // FIXME(camelid): This may not work correctly if `item_did` is a module.
-            //                 However, rustdoc currently never displays a module's
-            //                 visibility, so it shouldn't matter.
-            let parent_module = find_nearest_parent_module(tcx, item_did);
-
-            if vis_did.is_crate_root() {
-                "pub(crate) ".into()
-            } else if parent_module == Some(vis_did) {
-                // `pub(in foo)` where `foo` is the parent module
-                // is the same as no visibility modifier
-                "".into()
-            } else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent))
-                == Some(vis_did)
-            {
-                "pub(super) ".into()
-            } else {
-                format!("pub(in {}) ", tcx.def_path_str(vis_did)).into()
-            }
-        }
-    };
-    display_fn(move |f| {
-        if is_doc_hidden {
-            f.write_str("#[doc(hidden)] ")?;
-        }
-        f.write_str(&vis)
-    })
-}
-
 pub(crate) trait PrintWithSpace {
     fn print_with_space(&self) -> &str;
 }
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index b68b7295096..4def80764ea 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -58,13 +58,6 @@ pub(crate) fn render_example_with_highlighting(
     write_footer(out, playground_button);
 }
 
-/// Highlights `src` as an item-decl, returning the HTML output.
-pub(crate) fn render_item_decl_with_highlighting(src: &str, out: &mut Buffer) {
-    write!(out, "<pre class=\"rust item-decl\">");
-    write_code(out, src, None, None);
-    write!(out, "</pre>");
-}
-
 fn write_header(
     out: &mut Buffer,
     class: &str,
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 7826a5d8394..1d42ec8eec7 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1333,12 +1333,14 @@ impl Markdown<'_> {
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
-        let p = HeadingLinks::new(p, None, ids, heading_offset);
-        let p = footnotes::Footnotes::new(p);
-        let p = LinkReplacer::new(p.map(|(ev, _)| ev), links);
-        let p = TableWrapper::new(p);
-        let p = CodeBlocks::new(p, codes, edition, playground);
-        html::push_html(&mut s, p);
+        ids.handle_footnotes(|ids, existing_footnotes| {
+            let p = HeadingLinks::new(p, None, ids, heading_offset);
+            let p = footnotes::Footnotes::new(p, existing_footnotes);
+            let p = LinkReplacer::new(p.map(|(ev, _)| ev), links);
+            let p = TableWrapper::new(p);
+            let p = CodeBlocks::new(p, codes, edition, playground);
+            html::push_html(&mut s, p);
+        });
 
         s
     }
@@ -1367,13 +1369,13 @@ impl MarkdownWithToc<'_> {
 
         let mut toc = TocBuilder::new();
 
-        {
+        ids.handle_footnotes(|ids, existing_footnotes| {
             let p = HeadingLinks::new(p, Some(&mut toc), ids, HeadingOffset::H1);
-            let p = footnotes::Footnotes::new(p);
+            let p = footnotes::Footnotes::new(p, existing_footnotes);
             let p = TableWrapper::new(p.map(|(ev, _)| ev));
             let p = CodeBlocks::new(p, codes, edition, playground);
             html::push_html(&mut s, p);
-        }
+        });
 
         (toc.into_toc(), s)
     }
@@ -1401,13 +1403,15 @@ impl MarkdownItemInfo<'_> {
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
-        let p = HeadingLinks::new(p, None, ids, HeadingOffset::H1);
-        let p = footnotes::Footnotes::new(p);
-        let p = TableWrapper::new(p.map(|(ev, _)| ev));
-        let p = p.filter(|event| {
-            !matches!(event, Event::Start(Tag::Paragraph) | Event::End(TagEnd::Paragraph))
+        ids.handle_footnotes(|ids, existing_footnotes| {
+            let p = HeadingLinks::new(p, None, ids, HeadingOffset::H1);
+            let p = footnotes::Footnotes::new(p, existing_footnotes);
+            let p = TableWrapper::new(p.map(|(ev, _)| ev));
+            let p = p.filter(|event| {
+                !matches!(event, Event::Start(Tag::Paragraph) | Event::End(TagEnd::Paragraph))
+            });
+            html::push_html(&mut s, p);
         });
-        html::push_html(&mut s, p);
 
         s
     }
@@ -1882,6 +1886,7 @@ pub(crate) fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec<Rust
 #[derive(Clone, Default, Debug)]
 pub struct IdMap {
     map: FxHashMap<Cow<'static, str>, usize>,
+    existing_footnotes: usize,
 }
 
 // The map is pre-initialized and cloned each time to avoid reinitializing it repeatedly.
@@ -1943,7 +1948,7 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
 
 impl IdMap {
     pub fn new() -> Self {
-        IdMap { map: DEFAULT_ID_MAP.get_or_init(init_id_map).clone() }
+        IdMap { map: DEFAULT_ID_MAP.get_or_init(init_id_map).clone(), existing_footnotes: 0 }
     }
 
     pub(crate) fn derive<S: AsRef<str> + ToString>(&mut self, candidate: S) -> String {
@@ -1959,4 +1964,13 @@ impl IdMap {
         self.map.insert(id.clone().into(), 1);
         id
     }
+
+    /// Method to handle `existing_footnotes` increment automatically (to prevent forgetting
+    /// about it).
+    pub(crate) fn handle_footnotes<F: FnOnce(&mut Self, &mut usize)>(&mut self, closure: F) {
+        let mut existing_footnotes = self.existing_footnotes;
+
+        closure(self, &mut existing_footnotes);
+        self.existing_footnotes = existing_footnotes;
+    }
 }
diff --git a/src/librustdoc/html/markdown/footnotes.rs b/src/librustdoc/html/markdown/footnotes.rs
index 3f0e586b8e3..fcb8a174a95 100644
--- a/src/librustdoc/html/markdown/footnotes.rs
+++ b/src/librustdoc/html/markdown/footnotes.rs
@@ -1,60 +1,83 @@
 //! Markdown footnote handling.
 use std::fmt::Write as _;
 
-use pulldown_cmark::{Event, Tag, TagEnd, html};
+use pulldown_cmark::{CowStr, Event, Tag, TagEnd, html};
 use rustc_data_structures::fx::FxIndexMap;
 
 use super::SpannedEvent;
 
 /// Moves all footnote definitions to the end and add back links to the
 /// references.
-pub(super) struct Footnotes<'a, I> {
+pub(super) struct Footnotes<'a, 'b, I> {
     inner: I,
     footnotes: FxIndexMap<String, FootnoteDef<'a>>,
+    existing_footnotes: &'b mut usize,
 }
 
 /// The definition of a single footnote.
 struct FootnoteDef<'a> {
     content: Vec<Event<'a>>,
     /// The number that appears in the footnote reference and list.
-    id: u16,
+    id: usize,
 }
 
-impl<'a, I> Footnotes<'a, I> {
-    pub(super) fn new(iter: I) -> Self {
-        Footnotes { inner: iter, footnotes: FxIndexMap::default() }
+impl<'a, 'b, I: Iterator<Item = SpannedEvent<'a>>> Footnotes<'a, 'b, I> {
+    pub(super) fn new(iter: I, existing_footnotes: &'b mut usize) -> Self {
+        Footnotes { inner: iter, footnotes: FxIndexMap::default(), existing_footnotes }
     }
 
-    fn get_entry(&mut self, key: &str) -> (&mut Vec<Event<'a>>, u16) {
-        let new_id = self.footnotes.len() + 1;
+    fn get_entry(&mut self, key: &str) -> (&mut Vec<Event<'a>>, usize) {
+        let new_id = self.footnotes.len() + 1 + *self.existing_footnotes;
         let key = key.to_owned();
-        let FootnoteDef { content, id } = self
-            .footnotes
-            .entry(key)
-            .or_insert(FootnoteDef { content: Vec::new(), id: new_id as u16 });
+        let FootnoteDef { content, id } =
+            self.footnotes.entry(key).or_insert(FootnoteDef { content: Vec::new(), id: new_id });
         // Don't allow changing the ID of existing entrys, but allow changing the contents.
         (content, *id)
     }
+
+    fn handle_footnote_reference(&mut self, reference: &CowStr<'a>) -> Event<'a> {
+        // When we see a reference (to a footnote we may not know) the definition of,
+        // reserve a number for it, and emit a link to that number.
+        let (_, id) = self.get_entry(reference);
+        let reference = format!(
+            "<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{1}</a></sup>",
+            id,
+            // Although the ID count is for the whole page, the footnote reference
+            // are local to the item so we make this ID "local" when displayed.
+            id - *self.existing_footnotes
+        );
+        Event::Html(reference.into())
+    }
+
+    fn collect_footnote_def(&mut self) -> Vec<Event<'a>> {
+        let mut content = Vec::new();
+        while let Some((event, _)) = self.inner.next() {
+            match event {
+                Event::End(TagEnd::FootnoteDefinition) => break,
+                Event::FootnoteReference(ref reference) => {
+                    content.push(self.handle_footnote_reference(reference));
+                }
+                event => content.push(event),
+            }
+        }
+        content
+    }
 }
 
-impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
+impl<'a, 'b, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, 'b, I> {
     type Item = SpannedEvent<'a>;
 
     fn next(&mut self) -> Option<Self::Item> {
         loop {
-            match self.inner.next() {
+            let next = self.inner.next();
+            match next {
                 Some((Event::FootnoteReference(ref reference), range)) => {
-                    // When we see a reference (to a footnote we may not know) the definition of,
-                    // reserve a number for it, and emit a link to that number.
-                    let (_, id) = self.get_entry(reference);
-                    let reference =
-                        format!("<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>", id);
-                    return Some((Event::Html(reference.into()), range));
+                    return Some((self.handle_footnote_reference(reference), range));
                 }
                 Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => {
                     // When we see a footnote definition, collect the assocated content, and store
                     // that for rendering later.
-                    let content = collect_footnote_def(&mut self.inner);
+                    let content = self.collect_footnote_def();
                     let (entry_content, _) = self.get_entry(&def);
                     *entry_content = content;
                 }
@@ -64,6 +87,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
                         // After all the markdown is emmited, emit an <hr> then all the footnotes
                         // in a list.
                         let defs: Vec<_> = self.footnotes.drain(..).map(|(_, x)| x).collect();
+                        *self.existing_footnotes += defs.len();
                         let defs_html = render_footnotes_defs(defs);
                         return Some((Event::Html(defs_html.into()), 0..0));
                     } else {
@@ -75,17 +99,6 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
     }
 }
 
-fn collect_footnote_def<'a>(events: impl Iterator<Item = SpannedEvent<'a>>) -> Vec<Event<'a>> {
-    let mut content = Vec::new();
-    for (event, _) in events {
-        if let Event::End(TagEnd::FootnoteDefinition) = event {
-            break;
-        }
-        content.push(event);
-    }
-    content
-}
-
 fn render_footnotes_defs(mut footnotes: Vec<FootnoteDef<'_>>) -> String {
     let mut ret = String::from("<div class=\"footnotes\"><hr><ol>");
 
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index dc4d45e592e..5f255c18ec6 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -76,9 +76,9 @@ pub(crate) struct Context<'tcx> {
 
 // `Context` is cloned a lot, so we don't want the size to grow unexpectedly.
 #[cfg(all(not(windows), target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Context<'_>, 184);
-#[cfg(all(windows, target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Context<'_>, 192);
+#[cfg(all(windows, target_pointer_width = "64"))]
+rustc_data_structures::static_assert_size!(Context<'_>, 200);
 
 /// Shared mutable state used in [`Context`] and elsewhere.
 pub(crate) struct SharedContext<'tcx> {
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 8446235fb18..f11356b44d8 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -204,6 +204,7 @@ pub(crate) struct IndexItemFunctionType {
     inputs: Vec<RenderType>,
     output: Vec<RenderType>,
     where_clause: Vec<Vec<RenderType>>,
+    param_names: Vec<Symbol>,
 }
 
 impl IndexItemFunctionType {
@@ -1010,9 +1011,7 @@ fn render_stability_since_raw_with_extra(
                 // don't display const unstable if entirely unstable
                 None
             } else {
-                let unstable = if let Some(n) = issue
-                    && let Some(feature) = feature
-                {
+                let unstable = if let Some(n) = issue {
                     format!(
                         "<a \
                         href=\"https://github.com/rust-lang/rust/issues/{n}\" \
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index c6a2d87cbd0..d247e90d298 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -35,7 +35,6 @@ use crate::html::format::{
     Buffer, Ending, PrintWithSpace, display_fn, join_with_double_colon, print_abi_with_space,
     print_constness_with_space, print_where_clause, visibility_print_with_space,
 };
-use crate::html::highlight;
 use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
 use crate::html::render::{document_full, document_item_info};
 use crate::html::url_parts_builder::UrlPartsBuilder;
@@ -1745,7 +1744,13 @@ fn item_variants(
 }
 
 fn item_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Macro) {
-    highlight::render_item_decl_with_highlighting(&t.source, w);
+    wrap_item(w, |w| {
+        // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`.
+        if !t.macro_rules {
+            write!(w, "{}", visibility_print_with_space(it, cx));
+        }
+        write!(w, "{}", Escape(&t.source));
+    });
     write!(w, "{}", document(cx, it, None, HeadingOffset::H2))
 }
 
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index d1939adc1a5..f91fdfa1fb5 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -13,8 +13,8 @@ use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer};
 use thin_vec::ThinVec;
 use tracing::instrument;
 
-use crate::clean;
 use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate};
+use crate::clean::{self, utils};
 use crate::formats::cache::{Cache, OrphanImplItem};
 use crate::formats::item_type::ItemType;
 use crate::html::format::join_with_double_colon;
@@ -66,7 +66,7 @@ pub(crate) fn build_index<'tcx>(
     let mut associated_types = FxHashMap::default();
 
     // item type, display path, re-exported internal path
-    let mut crate_paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)> = vec![];
+    let mut crate_paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)> = vec![];
 
     // Attach all orphan items to the type's definition if the type
     // has since been learned.
@@ -132,10 +132,11 @@ pub(crate) fn build_index<'tcx>(
             map: &mut FxHashMap<F, isize>,
             itemid: F,
             lastpathid: &mut isize,
-            crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>,
+            crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)>,
             item_type: ItemType,
             path: &[Symbol],
             exact_path: Option<&[Symbol]>,
+            search_unbox: bool,
         ) -> RenderTypeId {
             match map.entry(itemid) {
                 Entry::Occupied(entry) => RenderTypeId::Index(*entry.get()),
@@ -147,6 +148,7 @@ pub(crate) fn build_index<'tcx>(
                         item_type,
                         path.to_vec(),
                         exact_path.map(|path| path.to_vec()),
+                        search_unbox,
                     ));
                     RenderTypeId::Index(pathid)
                 }
@@ -160,9 +162,21 @@ pub(crate) fn build_index<'tcx>(
             primitives: &mut FxHashMap<Symbol, isize>,
             associated_types: &mut FxHashMap<Symbol, isize>,
             lastpathid: &mut isize,
-            crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>,
+            crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)>,
+            tcx: TyCtxt<'_>,
         ) -> Option<RenderTypeId> {
+            use crate::clean::PrimitiveType;
             let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache;
+            let search_unbox = match id {
+                RenderTypeId::Mut => false,
+                RenderTypeId::DefId(defid) => utils::has_doc_flag(tcx, defid, sym::search_unbox),
+                RenderTypeId::Primitive(PrimitiveType::Reference | PrimitiveType::Tuple) => true,
+                RenderTypeId::Primitive(..) => false,
+                RenderTypeId::AssociatedType(..) => false,
+                // this bool is only used by `insert_into_map`, so it doesn't matter what we set here
+                // because Index means we've already inserted into the map
+                RenderTypeId::Index(_) => false,
+            };
             match id {
                 RenderTypeId::Mut => Some(insert_into_map(
                     primitives,
@@ -172,6 +186,7 @@ pub(crate) fn build_index<'tcx>(
                     ItemType::Keyword,
                     &[kw::Mut],
                     None,
+                    search_unbox,
                 )),
                 RenderTypeId::DefId(defid) => {
                     if let Some(&(ref fqp, item_type)) =
@@ -195,6 +210,7 @@ pub(crate) fn build_index<'tcx>(
                             item_type,
                             fqp,
                             exact_fqp.map(|x| &x[..]).filter(|exact_fqp| exact_fqp != fqp),
+                            search_unbox,
                         ))
                     } else {
                         None
@@ -210,6 +226,7 @@ pub(crate) fn build_index<'tcx>(
                         ItemType::Primitive,
                         &[sym],
                         None,
+                        search_unbox,
                     ))
                 }
                 RenderTypeId::Index(_) => Some(id),
@@ -221,6 +238,7 @@ pub(crate) fn build_index<'tcx>(
                     ItemType::AssocType,
                     &[sym],
                     None,
+                    search_unbox,
                 )),
             }
         }
@@ -232,7 +250,8 @@ pub(crate) fn build_index<'tcx>(
             primitives: &mut FxHashMap<Symbol, isize>,
             associated_types: &mut FxHashMap<Symbol, isize>,
             lastpathid: &mut isize,
-            crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>,
+            crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)>,
+            tcx: TyCtxt<'_>,
         ) {
             if let Some(generics) = &mut ty.generics {
                 for item in generics {
@@ -244,6 +263,7 @@ pub(crate) fn build_index<'tcx>(
                         associated_types,
                         lastpathid,
                         crate_paths,
+                        tcx,
                     );
                 }
             }
@@ -257,6 +277,7 @@ pub(crate) fn build_index<'tcx>(
                         associated_types,
                         lastpathid,
                         crate_paths,
+                        tcx,
                     );
                     let Some(converted_associated_type) = converted_associated_type else {
                         return false;
@@ -271,6 +292,7 @@ pub(crate) fn build_index<'tcx>(
                             associated_types,
                             lastpathid,
                             crate_paths,
+                            tcx,
                         );
                     }
                     true
@@ -288,6 +310,7 @@ pub(crate) fn build_index<'tcx>(
                 associated_types,
                 lastpathid,
                 crate_paths,
+                tcx,
             );
         }
         if let Some(search_type) = &mut item.search_type {
@@ -300,6 +323,7 @@ pub(crate) fn build_index<'tcx>(
                     &mut associated_types,
                     &mut lastpathid,
                     &mut crate_paths,
+                    tcx,
                 );
             }
             for item in &mut search_type.output {
@@ -311,6 +335,7 @@ pub(crate) fn build_index<'tcx>(
                     &mut associated_types,
                     &mut lastpathid,
                     &mut crate_paths,
+                    tcx,
                 );
             }
             for constraint in &mut search_type.where_clause {
@@ -323,6 +348,7 @@ pub(crate) fn build_index<'tcx>(
                         &mut associated_types,
                         &mut lastpathid,
                         &mut crate_paths,
+                        tcx,
                     );
                 }
             }
@@ -350,7 +376,12 @@ pub(crate) fn build_index<'tcx>(
                                 .filter(|exact_fqp| {
                                     exact_fqp.last() == Some(&item.name) && *exact_fqp != fqp
                                 });
-                            crate_paths.push((short, fqp.clone(), exact_fqp.cloned()));
+                            crate_paths.push((
+                                short,
+                                fqp.clone(),
+                                exact_fqp.cloned(),
+                                utils::has_doc_flag(tcx, defid, sym::search_unbox),
+                            ));
                             Some(pathid)
                         } else {
                             None
@@ -431,7 +462,7 @@ pub(crate) fn build_index<'tcx>(
 
     struct CrateData<'a> {
         items: Vec<&'a IndexItem>,
-        paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>,
+        paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)>,
         // The String is alias name and the vec is the list of the elements with this alias.
         //
         // To be noted: the `usize` elements are indexes to `items`.
@@ -450,6 +481,7 @@ pub(crate) fn build_index<'tcx>(
         name: Symbol,
         path: Option<usize>,
         exact_path: Option<usize>,
+        search_unbox: bool,
     }
 
     impl Serialize for Paths {
@@ -467,6 +499,15 @@ pub(crate) fn build_index<'tcx>(
                 assert!(self.path.is_some());
                 seq.serialize_element(path)?;
             }
+            if self.search_unbox {
+                if self.path.is_none() {
+                    seq.serialize_element(&None::<u8>)?;
+                }
+                if self.exact_path.is_none() {
+                    seq.serialize_element(&None::<u8>)?;
+                }
+                seq.serialize_element(&1)?;
+            }
             seq.end()
         }
     }
@@ -489,9 +530,15 @@ pub(crate) fn build_index<'tcx>(
                 mod_paths.insert(&item.path, index);
             }
             let mut paths = Vec::with_capacity(self.paths.len());
-            for (ty, path, exact) in &self.paths {
+            for &(ty, ref path, ref exact, search_unbox) in &self.paths {
                 if path.len() < 2 {
-                    paths.push(Paths { ty: *ty, name: path[0], path: None, exact_path: None });
+                    paths.push(Paths {
+                        ty,
+                        name: path[0],
+                        path: None,
+                        exact_path: None,
+                        search_unbox,
+                    });
                     continue;
                 }
                 let full_path = join_with_double_colon(&path[..path.len() - 1]);
@@ -517,10 +564,11 @@ pub(crate) fn build_index<'tcx>(
                 });
                 if let Some(index) = mod_paths.get(&full_path) {
                     paths.push(Paths {
-                        ty: *ty,
+                        ty,
                         name: *path.last().unwrap(),
                         path: Some(*index),
                         exact_path,
+                        search_unbox,
                     });
                     continue;
                 }
@@ -532,10 +580,11 @@ pub(crate) fn build_index<'tcx>(
                 match extra_paths.entry(full_path.clone()) {
                     Entry::Occupied(entry) => {
                         paths.push(Paths {
-                            ty: *ty,
+                            ty,
                             name: *path.last().unwrap(),
                             path: Some(*entry.get()),
                             exact_path,
+                            search_unbox,
                         });
                     }
                     Entry::Vacant(entry) => {
@@ -544,10 +593,11 @@ pub(crate) fn build_index<'tcx>(
                             revert_extra_paths.insert(index, full_path);
                         }
                         paths.push(Paths {
-                            ty: *ty,
+                            ty,
                             name: *path.last().unwrap(),
                             path: Some(index),
                             exact_path,
+                            search_unbox,
                         });
                     }
                 }
@@ -646,9 +696,25 @@ pub(crate) fn build_index<'tcx>(
                 full_paths.push((*index, path));
             }
 
+            let param_names: Vec<(usize, String)> = {
+                let mut prev = Vec::new();
+                let mut result = Vec::new();
+                for (index, item) in self.items.iter().enumerate() {
+                    if let Some(ty) = &item.search_type
+                        && let my =
+                            ty.param_names.iter().map(|sym| sym.as_str()).collect::<Vec<_>>()
+                        && my != prev
+                    {
+                        result.push((index, my.join(",")));
+                        prev = my;
+                    }
+                }
+                result
+            };
+
             let has_aliases = !self.aliases.is_empty();
             let mut crate_data =
-                serializer.serialize_struct("CrateData", if has_aliases { 9 } else { 8 })?;
+                serializer.serialize_struct("CrateData", if has_aliases { 13 } else { 12 })?;
             crate_data.serialize_field("t", &types)?;
             crate_data.serialize_field("n", &names)?;
             crate_data.serialize_field("q", &full_paths)?;
@@ -660,6 +726,7 @@ pub(crate) fn build_index<'tcx>(
             crate_data.serialize_field("b", &self.associated_item_disambiguators)?;
             crate_data.serialize_field("c", &bitmap_to_string(&deprecated))?;
             crate_data.serialize_field("e", &bitmap_to_string(&self.empty_desc))?;
+            crate_data.serialize_field("P", &param_names)?;
             if has_aliases {
                 crate_data.serialize_field("a", &self.aliases)?;
             }
@@ -758,7 +825,7 @@ pub(crate) fn get_function_type_for_search<'tcx>(
             None
         }
     });
-    let (mut inputs, mut output, where_clause) = match item.kind {
+    let (mut inputs, mut output, param_names, where_clause) = match item.kind {
         clean::ForeignFunctionItem(ref f, _)
         | clean::FunctionItem(ref f)
         | clean::MethodItem(ref f, _)
@@ -771,7 +838,7 @@ pub(crate) fn get_function_type_for_search<'tcx>(
     inputs.retain(|a| a.id.is_some() || a.generics.is_some());
     output.retain(|a| a.id.is_some() || a.generics.is_some());
 
-    Some(IndexItemFunctionType { inputs, output, where_clause })
+    Some(IndexItemFunctionType { inputs, output, where_clause, param_names })
 }
 
 fn get_index_type(
@@ -1285,7 +1352,7 @@ fn get_fn_inputs_and_outputs<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_or_trait_generics: Option<&(clean::Type, clean::Generics)>,
     cache: &Cache,
-) -> (Vec<RenderType>, Vec<RenderType>, Vec<Vec<RenderType>>) {
+) -> (Vec<RenderType>, Vec<RenderType>, Vec<Symbol>, Vec<Vec<RenderType>>) {
     let decl = &func.decl;
 
     let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> = Default::default();
@@ -1331,7 +1398,21 @@ fn get_fn_inputs_and_outputs<'tcx>(
     let mut ret_types = Vec::new();
     simplify_fn_type(self_, generics, &decl.output, tcx, 0, &mut ret_types, &mut rgen, true, cache);
 
-    let mut simplified_params = rgen.into_values().collect::<Vec<_>>();
-    simplified_params.sort_by_key(|(idx, _)| -idx);
-    (arg_types, ret_types, simplified_params.into_iter().map(|(_idx, traits)| traits).collect())
+    let mut simplified_params = rgen.into_iter().collect::<Vec<_>>();
+    simplified_params.sort_by_key(|(_, (idx, _))| -idx);
+    (
+        arg_types,
+        ret_types,
+        simplified_params
+            .iter()
+            .map(|(name, (_idx, _traits))| match name {
+                SimplifiedParam::Symbol(name) => *name,
+                SimplifiedParam::Anonymous(_) => kw::Empty,
+                SimplifiedParam::AssociatedType(def_id, name) => {
+                    Symbol::intern(&format!("{}::{}", tcx.item_name(*def_id), name))
+                }
+            })
+            .collect(),
+        simplified_params.into_iter().map(|(_name, (_idx, traits))| traits).collect(),
+    )
 }
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 1042d254749..66a8a198928 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -264,6 +264,7 @@ a.anchor,
 .mobile-topbar h2 a,
 h1 a,
 .search-results a,
+.search-results li,
 .stab,
 .result-name i {
 	color: var(--main-color);
@@ -379,7 +380,7 @@ details:not(.toggle) summary {
 	margin-bottom: .6em;
 }
 
-code, pre, .code-header {
+code, pre, .code-header, .type-signature {
 	font-family: "Source Code Pro", monospace;
 }
 .docblock code, .docblock-short code {
@@ -1205,22 +1206,28 @@ so that we can apply CSS-filters to change the arrow color in themes */
 
 .search-results.active {
 	display: block;
+	margin: 0;
+	padding: 0;
 }
 
 .search-results > a {
-	display: flex;
+	display: grid;
+	grid-template-areas:
+		"search-result-name search-result-desc"
+		"search-result-type-signature search-result-type-signature";
+	grid-template-columns: .6fr .4fr;
 	/* A little margin ensures the browser's outlining of focused links has room to display. */
 	margin-left: 2px;
 	margin-right: 2px;
 	border-bottom: 1px solid var(--search-result-border-color);
-	gap: 1em;
+	column-gap: 1em;
 }
 
 .search-results > a > div.desc {
 	white-space: nowrap;
 	text-overflow: ellipsis;
 	overflow: hidden;
-	flex: 2;
+	grid-area: search-result-desc;
 }
 
 .search-results a:hover,
@@ -1232,7 +1239,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	display: flex;
 	align-items: center;
 	justify-content: start;
-	flex: 3;
+	grid-area: search-result-name;
 }
 .search-results .result-name .alias {
 	color: var(--search-results-alias-color);
@@ -1253,6 +1260,10 @@ so that we can apply CSS-filters to change the arrow color in themes */
 .search-results .result-name .path > * {
 	display: inline;
 }
+.search-results .type-signature {
+	grid-area: search-result-type-signature;
+	white-space: pre-wrap;
+}
 
 .popover {
 	position: absolute;
diff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js
index 3d3e0a8f838..c4faca1c0c3 100644
--- a/src/librustdoc/html/static/js/externs.js
+++ b/src/librustdoc/html/static/js/externs.js
@@ -9,12 +9,12 @@ function initSearch(searchIndex){}
 /**
  * @typedef {{
  *     name: string,
- *     id: integer|null,
+ *     id: number|null,
  *     fullPath: Array<string>,
  *     pathWithoutLast: Array<string>,
  *     pathLast: string,
  *     generics: Array<QueryElement>,
- *     bindings: Map<integer, Array<QueryElement>>,
+ *     bindings: Map<number, Array<QueryElement>>,
  * }}
  */
 let QueryElement;
@@ -92,6 +92,9 @@ let Results;
  *     parent: (Object|undefined),
  *     path: string,
  *     ty: number,
+ *     type: FunctionSearchType?,
+ *     displayType: Promise<Array<Array<string>>>|null,
+ *     displayTypeMappedNames: Promise<Array<[string, Array<string>]>>|null,
  * }}
  */
 let ResultObject;
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index eed64d024c0..6d118ae5784 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -15,7 +15,16 @@ if (!Array.prototype.toSpliced) {
     };
 }
 
-(function() {
+function onEachBtwn(arr, func, funcBtwn) {
+    let skipped = true;
+    for (const value of arr) {
+        if (!skipped) {
+            funcBtwn(value);
+        }
+        skipped = func(value);
+    }
+}
+
 // ==================== Core search logic begin ====================
 // This mapping table should match the discriminants of
 // `rustdoc::formats::item_type::ItemType` type in Rust.
@@ -50,8 +59,10 @@ const itemTypes = [
 ];
 
 // used for special search precedence
+const TY_PRIMITIVE = itemTypes.indexOf("primitive");
 const TY_GENERIC = itemTypes.indexOf("generic");
 const TY_IMPORT = itemTypes.indexOf("import");
+const TY_TRAIT = itemTypes.indexOf("trait");
 const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";
 
 // Hard limit on how deep to recurse into generics when doing type-driven search.
@@ -276,7 +287,7 @@ function getFilteredNextElem(query, parserState, elems, isInGenerics) {
         // The type filter doesn't count as an element since it's a modifier.
         const typeFilterElem = elems.pop();
         checkExtraTypeFilterCharacters(start, parserState);
-        parserState.typeFilter = typeFilterElem.name;
+        parserState.typeFilter = typeFilterElem.normalizedPathLast;
         parserState.pos += 1;
         parserState.totalElems -= 1;
         query.literalSearch = false;
@@ -686,7 +697,7 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
     } else if (quadcolon !== null) {
         throw ["Unexpected ", quadcolon[0]];
     }
-    const pathSegments = path.split(/(?:::\s*)|(?:\s+(?:::\s*)?)/);
+    const pathSegments = path.split(/(?:::\s*)|(?:\s+(?:::\s*)?)/).map(x => x.toLowerCase());
     // In case we only have something like `<p>`, there is no name.
     if (pathSegments.length === 0
         || (pathSegments.length === 1 && pathSegments[0] === "")) {
@@ -726,7 +737,10 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
                 if (gen.name !== null) {
                     gen.bindingName.generics.unshift(gen);
                 }
-                bindings.set(gen.bindingName.name, gen.bindingName.generics);
+                bindings.set(
+                    gen.bindingName.name.toLowerCase().replace(/_/g, ""),
+                    gen.bindingName.generics,
+                );
                 return false;
             }
             return true;
@@ -1092,6 +1106,153 @@ class RoaringBitmapBits {
     }
 }
 
+/**
+ * A prefix tree, used for name-based search.
+ *
+ * This data structure is used to drive prefix matches,
+ * such as matching the query "link" to `LinkedList`,
+ * and Lev-distance matches, such as matching the
+ * query "hahsmap" to `HashMap`. Substring matches,
+ * such as "list" to `LinkedList`, are done with a
+ * tailTable that deep-links into this trie.
+ *
+ * children
+ * : A [sparse array] of subtrees. The array index
+ *   is a charCode.
+ *
+ *   [sparse array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/
+ *     Indexed_collections#sparse_arrays
+ *
+ * matches
+ * : A list of search index IDs for this node.
+ *
+ * @typedef {{
+ *     children: [NameTrie],
+ *     matches: [number],
+ * }}
+ */
+class NameTrie {
+    constructor() {
+        this.children = [];
+        this.matches = [];
+    }
+    insert(name, id, tailTable) {
+        this.insertSubstring(name, 0, id, tailTable);
+    }
+    insertSubstring(name, substart, id, tailTable) {
+        const l = name.length;
+        if (substart === l) {
+            this.matches.push(id);
+        } else {
+            const sb = name.charCodeAt(substart);
+            let child;
+            if (this.children[sb] !== undefined) {
+                child = this.children[sb];
+            } else {
+                child = new NameTrie();
+                this.children[sb] = child;
+                let sste;
+                if (substart >= 2) {
+                    const tail = name.substring(substart - 2, substart + 1);
+                    if (tailTable.has(tail)) {
+                        sste = tailTable.get(tail);
+                    } else {
+                        sste = [];
+                        tailTable.set(tail, sste);
+                    }
+                    sste.push(child);
+                }
+            }
+            child.insertSubstring(name, substart + 1, id, tailTable);
+        }
+    }
+    search(name, tailTable) {
+        const results = new Set();
+        this.searchSubstringPrefix(name, 0, results);
+        if (results.size < MAX_RESULTS && name.length >= 3) {
+            const levParams = name.length >= 6 ?
+                new Lev2TParametricDescription(name.length) :
+                new Lev1TParametricDescription(name.length);
+            this.searchLev(name, 0, levParams, results);
+            const tail = name.substring(0, 3);
+            if (tailTable.has(tail)) {
+                for (const entry of tailTable.get(tail)) {
+                    entry.searchSubstringPrefix(name, 3, results);
+                }
+            }
+        }
+        return [...results];
+    }
+    searchSubstringPrefix(name, substart, results) {
+        const l = name.length;
+        if (substart === l) {
+            for (const match of this.matches) {
+                results.add(match);
+            }
+            // breadth-first traversal orders prefix matches by length
+            let unprocessedChildren = [];
+            for (const child of this.children) {
+                if (child) {
+                    unprocessedChildren.push(child);
+                }
+            }
+            let nextSet = [];
+            while (unprocessedChildren.length !== 0) {
+                const next = unprocessedChildren.pop();
+                for (const child of next.children) {
+                    if (child) {
+                        nextSet.push(child);
+                    }
+                }
+                for (const match of next.matches) {
+                    results.add(match);
+                }
+                if (unprocessedChildren.length === 0) {
+                    const tmp = unprocessedChildren;
+                    unprocessedChildren = nextSet;
+                    nextSet = tmp;
+                }
+            }
+        } else {
+            const sb = name.charCodeAt(substart);
+            if (this.children[sb] !== undefined) {
+                this.children[sb].searchSubstringPrefix(name, substart + 1, results);
+            }
+        }
+    }
+    searchLev(name, substart, levParams, results) {
+        const stack = [[this, 0]];
+        const n = levParams.n;
+        while (stack.length !== 0) {
+            const [trie, levState] = stack.pop();
+            for (const [charCode, child] of trie.children.entries()) {
+                if (!child) {
+                    continue;
+                }
+                const levPos = levParams.getPosition(levState);
+                const vector = levParams.getVector(
+                    name,
+                    charCode,
+                    levPos,
+                    Math.min(name.length, levPos + (2 * n) + 1),
+                );
+                const newLevState = levParams.transition(
+                    levState,
+                    levPos,
+                    vector,
+                );
+                if (newLevState >= 0) {
+                    stack.push([child, newLevState]);
+                    if (levParams.isAccept(newLevState)) {
+                        for (const match of child.matches) {
+                            results.add(match);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
 
 class DocSearch {
     constructor(rawSearchIndex, rootPath, searchState) {
@@ -1114,6 +1275,13 @@ class DocSearch {
          * @type {Map<string, {id: integer, assocOnly: boolean}>}
          */
         this.typeNameIdMap = new Map();
+        /**
+         * Map from type ID to associated type name. Used for display,
+         * not for search.
+         *
+         * @type {Map<integer, string>}
+         */
+        this.assocTypeIdNameMap = new Map();
         this.ALIASES = new Map();
         this.rootPath = rootPath;
         this.searchState = searchState;
@@ -1158,6 +1326,14 @@ class DocSearch {
          * Special type name IDs for searching higher order functions (`->` syntax).
          */
         this.typeNameIdOfHof = this.buildTypeMapIndex("->");
+        /**
+         * Special type name IDs the output assoc type.
+         */
+        this.typeNameIdOfOutput = this.buildTypeMapIndex("output", true);
+        /**
+         * Special type name IDs for searching by reference.
+         */
+        this.typeNameIdOfReference = this.buildTypeMapIndex("reference");
 
         /**
          * Empty, immutable map used in item search types with no bindings.
@@ -1182,6 +1358,20 @@ class DocSearch {
         this.TYPES_POOL = new Map();
 
         /**
+         * A trie for finding items by name.
+         * This is used for edit distance and prefix finding.
+         *
+         * @type {NameTrie}
+         */
+        this.nameTrie = new NameTrie();
+
+        /**
+         * Find items by 3-substring. This is a map from three-char
+         * prefixes into lists of subtries.
+         */
+        this.tailTable = new Map();
+
+        /**
          *  @type {Array<Row>}
          */
         this.searchIndex = this.buildIndex(rawSearchIndex);
@@ -1234,9 +1424,9 @@ class DocSearch {
      *
      * @return {Array<FunctionSearchType>}
      */
-    buildItemSearchTypeAll(types, lowercasePaths) {
+    buildItemSearchTypeAll(types, paths, lowercasePaths) {
         return types.length > 0 ?
-            types.map(type => this.buildItemSearchType(type, lowercasePaths)) :
+            types.map(type => this.buildItemSearchType(type, paths, lowercasePaths)) :
             this.EMPTY_GENERICS_ARRAY;
     }
 
@@ -1245,7 +1435,7 @@ class DocSearch {
      *
      * @param {RawFunctionType} type
      */
-    buildItemSearchType(type, lowercasePaths, isAssocType) {
+    buildItemSearchType(type, paths, lowercasePaths, isAssocType) {
         const PATH_INDEX_DATA = 0;
         const GENERICS_DATA = 1;
         const BINDINGS_DATA = 2;
@@ -1258,6 +1448,7 @@ class DocSearch {
             pathIndex = type[PATH_INDEX_DATA];
             generics = this.buildItemSearchTypeAll(
                 type[GENERICS_DATA],
+                paths,
                 lowercasePaths,
             );
             if (type.length > BINDINGS_DATA && type[BINDINGS_DATA].length > 0) {
@@ -1274,8 +1465,8 @@ class DocSearch {
                     //
                     // As a result, the key should never have generics on it.
                     return [
-                        this.buildItemSearchType(assocType, lowercasePaths, true).id,
-                        this.buildItemSearchTypeAll(constraints, lowercasePaths),
+                        this.buildItemSearchType(assocType, paths, lowercasePaths, true).id,
+                        this.buildItemSearchTypeAll(constraints, paths, lowercasePaths),
                     ];
                 }));
             } else {
@@ -1291,31 +1482,41 @@ class DocSearch {
             // the actual names of generic parameters aren't stored, since they aren't API
             result = {
                 id: pathIndex,
+                name: "",
                 ty: TY_GENERIC,
                 path: null,
                 exactPath: null,
                 generics,
                 bindings,
+                unboxFlag: true,
             };
         } else if (pathIndex === 0) {
             // `0` is used as a sentinel because it's fewer bytes than `null`
             result = {
                 id: null,
+                name: "",
                 ty: null,
                 path: null,
                 exactPath: null,
                 generics,
                 bindings,
+                unboxFlag: true,
             };
         } else {
             const item = lowercasePaths[pathIndex - 1];
+            const id = this.buildTypeMapIndex(item.name, isAssocType);
+            if (isAssocType) {
+                this.assocTypeIdNameMap.set(id, paths[pathIndex - 1].name);
+            }
             result = {
-                id: this.buildTypeMapIndex(item.name, isAssocType),
+                id,
+                name: paths[pathIndex - 1].name,
                 ty: item.ty,
                 path: item.path,
                 exactPath: item.exactPath,
                 generics,
                 bindings,
+                unboxFlag: item.unboxFlag,
             };
         }
         const cr = this.TYPES_POOL.get(result.id);
@@ -1352,7 +1553,8 @@ class DocSearch {
             }
             if (cr.ty === result.ty && cr.path === result.path
                 && cr.bindings === result.bindings && cr.generics === result.generics
-                && cr.ty === result.ty
+                && cr.ty === result.ty && cr.name === result.name
+                && cr.unboxFlag === result.unboxFlag
             ) {
                 return cr;
             }
@@ -1371,7 +1573,7 @@ class DocSearch {
      *   query fingerprint. If any bits are set in the query but not in the function, it can't
      *   match.
      *
-     * - The fourth section has the number of distinct items in the set.
+     * - The fourth section has the number of items in the set.
      *   This is the distance function, used for filtering and for sorting.
      *
      * [^1]: Distance is the relatively naive metric of counting the number of distinct items in
@@ -1379,9 +1581,8 @@ class DocSearch {
      *
      * @param {FunctionType|QueryElement} type - a single type
      * @param {Uint32Array} output - write the fingerprint to this data structure: uses 128 bits
-     * @param {Set<number>} fps - Set of distinct items
      */
-    buildFunctionTypeFingerprint(type, output, fps) {
+    buildFunctionTypeFingerprint(type, output) {
         let input = type.id;
         // All forms of `[]`/`()`/`->` get collapsed down to one thing in the bloom filter.
         // Differentiating between arrays and slices, if the user asks for it, is
@@ -1427,10 +1628,11 @@ class DocSearch {
             output[0] |= (1 << (h0a % 32)) | (1 << (h1b % 32));
             output[1] |= (1 << (h1a % 32)) | (1 << (h2b % 32));
             output[2] |= (1 << (h2a % 32)) | (1 << (h0b % 32));
-            fps.add(input);
+            // output[3] is the total number of items in the type signature
+            output[3] += 1;
         }
         for (const g of type.generics) {
-            this.buildFunctionTypeFingerprint(g, output, fps);
+            this.buildFunctionTypeFingerprint(g, output);
         }
         const fb = {
             id: null,
@@ -1441,9 +1643,8 @@ class DocSearch {
         for (const [k, v] of type.bindings.entries()) {
             fb.id = k;
             fb.generics = v;
-            this.buildFunctionTypeFingerprint(fb, output, fps);
+            this.buildFunctionTypeFingerprint(fb, output);
         }
-        output[3] = fps.size;
     }
 
     /**
@@ -1463,11 +1664,12 @@ class DocSearch {
          * The raw function search type format is generated using serde in
          * librustdoc/html/render/mod.rs: IndexItemFunctionType::write_to_string
          *
+         * @param {Array<{name: string, ty: number}>} paths
          * @param {Array<{name: string, ty: number}>} lowercasePaths
          *
          * @return {null|FunctionSearchType}
          */
-        const buildFunctionSearchTypeCallback = lowercasePaths => {
+        const buildFunctionSearchTypeCallback = (paths, lowercasePaths) => {
             return functionSearchType => {
                 if (functionSearchType === 0) {
                     return null;
@@ -1477,11 +1679,16 @@ class DocSearch {
                 let inputs, output;
                 if (typeof functionSearchType[INPUTS_DATA] === "number") {
                     inputs = [
-                        this.buildItemSearchType(functionSearchType[INPUTS_DATA], lowercasePaths),
+                        this.buildItemSearchType(
+                            functionSearchType[INPUTS_DATA],
+                            paths,
+                            lowercasePaths,
+                        ),
                     ];
                 } else {
                     inputs = this.buildItemSearchTypeAll(
                         functionSearchType[INPUTS_DATA],
+                        paths,
                         lowercasePaths,
                     );
                 }
@@ -1490,12 +1697,14 @@ class DocSearch {
                         output = [
                             this.buildItemSearchType(
                                 functionSearchType[OUTPUT_DATA],
+                                paths,
                                 lowercasePaths,
                             ),
                         ];
                     } else {
                         output = this.buildItemSearchTypeAll(
                             functionSearchType[OUTPUT_DATA],
+                            paths,
                             lowercasePaths,
                         );
                     }
@@ -1506,8 +1715,12 @@ class DocSearch {
                 const l = functionSearchType.length;
                 for (let i = 2; i < l; ++i) {
                     where_clause.push(typeof functionSearchType[i] === "number"
-                        ? [this.buildItemSearchType(functionSearchType[i], lowercasePaths)]
-                        : this.buildItemSearchTypeAll(functionSearchType[i], lowercasePaths));
+                        ? [this.buildItemSearchType(functionSearchType[i], paths, lowercasePaths)]
+                        : this.buildItemSearchTypeAll(
+                            functionSearchType[i],
+                            paths,
+                            lowercasePaths,
+                        ));
                 }
                 return {
                     inputs, output, where_clause,
@@ -1551,9 +1764,17 @@ class DocSearch {
             this.searchIndexEmptyDesc.set(crate, new RoaringBitmap(crateCorpus.e));
             let descIndex = 0;
 
+            /**
+             * List of generic function type parameter names.
+             * Used for display, not for searching.
+             * @type {[string]}
+             */
+            let lastParamNames = [];
+
             // This object should have exactly the same set of fields as the "row"
             // object defined below. Your JavaScript runtime will thank you.
             // https://mathiasbynens.be/notes/shapes-ics
+            let normalizedName = crate.indexOf("_") === -1 ? crate : crate.replace(/_/g, "");
             const crateRow = {
                 crate,
                 ty: 3, // == ExternCrate
@@ -1565,12 +1786,14 @@ class DocSearch {
                 desc: crateCorpus.doc,
                 parent: undefined,
                 type: null,
+                paramNames: lastParamNames,
                 id,
                 word: crate,
-                normalizedName: crate.indexOf("_") === -1 ? crate : crate.replace(/_/g, ""),
+                normalizedName,
                 bitIndex: 0,
                 implDisambiguator: null,
             };
+            this.nameTrie.insert(normalizedName, id, this.tailTable);
             id += 1;
             searchIndex.push(crateRow);
             currentIndex += 1;
@@ -1601,6 +1824,10 @@ class DocSearch {
             // an array of [(String) alias name
             //             [Number] index to items]
             const aliases = crateCorpus.a;
+            // an array of [(Number) item index,
+            //              (String) comma-separated list of function generic param names]
+            // an item whose index is not present will fall back to the previous present path
+            const itemParamNames = new Map(crateCorpus.P);
 
             // an array of [{name: String, ty: Number}]
             const lowercasePaths = [];
@@ -1608,7 +1835,7 @@ class DocSearch {
             // a string representing the list of function types
             const itemFunctionDecoder = new VlqHexDecoder(
                 crateCorpus.f,
-                buildFunctionSearchTypeCallback(lowercasePaths),
+                buildFunctionSearchTypeCallback(paths, lowercasePaths),
             );
 
             // convert `rawPaths` entries into object form
@@ -1620,14 +1847,17 @@ class DocSearch {
                 const ty = elem[0];
                 const name = elem[1];
                 let path = null;
-                if (elem.length > 2) {
+                if (elem.length > 2 && elem[2] !== null) {
                     path = itemPaths.has(elem[2]) ? itemPaths.get(elem[2]) : lastPath;
                     lastPath = path;
                 }
-                const exactPath = elem.length > 3 ? itemPaths.get(elem[3]) : path;
+                const exactPath = elem.length > 3 && elem[3] !== null ?
+                    itemPaths.get(elem[3]) :
+                    path;
+                const unboxFlag = elem.length > 4 && !!elem[4];
 
-                lowercasePaths.push({ ty, name: name.toLowerCase(), path, exactPath });
-                paths[i] = { ty, name, path, exactPath };
+                lowercasePaths.push({ ty, name: name.toLowerCase(), path, exactPath, unboxFlag });
+                paths[i] = { ty, name, path, exactPath, unboxFlag };
             }
 
             // convert `item*` into an object form, and construct word indices.
@@ -1659,20 +1889,22 @@ class DocSearch {
                 const name = itemNames[i] === "" ? lastName : itemNames[i];
                 const word = itemNames[i] === "" ? lastWord : itemNames[i].toLowerCase();
                 const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath;
+                const paramNames = itemParamNames.has(i) ?
+                    itemParamNames.get(i).split(",") :
+                    lastParamNames;
                 const type = itemFunctionDecoder.next();
                 if (type !== null) {
                     if (type) {
                         const fp = this.functionTypeFingerprint.subarray(id * 4, (id + 1) * 4);
-                        const fps = new Set();
                         for (const t of type.inputs) {
-                            this.buildFunctionTypeFingerprint(t, fp, fps);
+                            this.buildFunctionTypeFingerprint(t, fp);
                         }
                         for (const t of type.output) {
-                            this.buildFunctionTypeFingerprint(t, fp, fps);
+                            this.buildFunctionTypeFingerprint(t, fp);
                         }
                         for (const w of type.where_clause) {
                             for (const t of w) {
-                                this.buildFunctionTypeFingerprint(t, fp, fps);
+                                this.buildFunctionTypeFingerprint(t, fp);
                             }
                         }
                     }
@@ -1680,6 +1912,7 @@ class DocSearch {
                 // This object should have exactly the same set of fields as the "crateRow"
                 // object defined above.
                 const itemParentIdx = itemParentIdxDecoder.next();
+                normalizedName = word.indexOf("_") === -1 ? word : word.replace(/_/g, "");
                 const row = {
                     crate,
                     ty: itemTypes.charCodeAt(i) - 65, // 65 = "A"
@@ -1691,16 +1924,19 @@ class DocSearch {
                         itemPaths.get(itemReexports.get(i)) : path,
                     parent: itemParentIdx > 0 ? paths[itemParentIdx - 1] : undefined,
                     type,
+                    paramNames,
                     id,
                     word,
-                    normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""),
+                    normalizedName,
                     bitIndex,
                     implDisambiguator: implDisambiguator.has(i) ?
                         implDisambiguator.get(i) : null,
                 };
+                this.nameTrie.insert(normalizedName, id, this.tailTable);
                 id += 1;
                 searchIndex.push(row);
                 lastPath = row.path;
+                lastParamNames = row.paramNames;
                 if (!this.searchIndexEmptyDesc.get(crate).contains(bitIndex)) {
                     descIndex += 1;
                 }
@@ -1786,8 +2022,7 @@ class DocSearch {
          */
         function newParsedQuery(userQuery) {
             return {
-                original: userQuery,
-                userQuery: userQuery.toLowerCase(),
+                userQuery,
                 elems: [],
                 returned: [],
                 // Total number of "top" elements (does not include generics).
@@ -1909,7 +2144,7 @@ class DocSearch {
             genericsElems: 0,
             typeFilter: null,
             isInBinding: null,
-            userQuery: userQuery.toLowerCase(),
+            userQuery,
         };
         let query = newParsedQuery(userQuery);
 
@@ -1990,6 +2225,7 @@ class DocSearch {
                     "/index.html#reexport." + name;
             } else if (type === "primitive" || type === "keyword") {
                 displayPath = "";
+                exactPath = "";
                 href = this.rootPath + path.replace(/::/g, "/") +
                     "/" + type + "." + name + ".html";
             } else if (type === "externcrate") {
@@ -2005,6 +2241,7 @@ class DocSearch {
 
                 if (parentType === "primitive") {
                     displayPath = myparent.name + "::";
+                    exactPath = myparent.name;
                 } else if (type === "structfield" && parentType === "variant") {
                     // Structfields belonging to variants are special: the
                     // final path element is the enum name.
@@ -2046,18 +2283,21 @@ class DocSearch {
          * marked for removal.
          *
          * @param {[ResultObject]} results
+         * @param {"sig"|"elems"|"returned"|null} typeInfo
+         * @param {ParsedQuery} query
          * @returns {[ResultObject]}
          */
-        const transformResults = results => {
+        const transformResults = (results, typeInfo) => {
             const duplicates = new Set();
             const out = [];
 
             for (const result of results) {
                 if (result.id !== -1) {
-                    const obj = this.searchIndex[result.id];
-                    obj.dist = result.dist;
-                    const res = buildHrefAndPath(obj);
-                    obj.displayPath = pathSplitter(res[0]);
+                    const res = buildHrefAndPath(this.searchIndex[result.id]);
+                    const obj = Object.assign({
+                        dist: result.dist,
+                        displayPath: pathSplitter(res[0]),
+                    }, this.searchIndex[result.id]);
 
                     // To be sure than it some items aren't considered as duplicate.
                     obj.fullPath = res[2] + "|" + obj.ty;
@@ -2076,6 +2316,11 @@ class DocSearch {
                     duplicates.add(obj.fullPath);
                     duplicates.add(res[2]);
 
+                    if (typeInfo !== null) {
+                        obj.displayTypeSignature =
+                            this.formatDisplayTypeSignature(obj, typeInfo);
+                    }
+
                     obj.href = res[1];
                     out.push(obj);
                     if (out.length >= MAX_RESULTS) {
@@ -2087,6 +2332,330 @@ class DocSearch {
         };
 
         /**
+         * Add extra data to result objects, and filter items that have been
+         * marked for removal.
+         *
+         * The output is formatted as an array of hunks, where odd numbered
+         * hunks are highlighted and even numbered ones are not.
+         *
+         * @param {ResultObject} obj
+         * @param {"sig"|"elems"|"returned"|null} typeInfo
+         * @param {ParsedQuery} query
+         * @returns Promise<
+         *   "type": Array<string>,
+         *   "mappedNames": Map<string, string>,
+         *   "whereClause": Map<string, Array<string>>,
+         * >
+         */
+        this.formatDisplayTypeSignature = async(obj, typeInfo) => {
+            let fnInputs = null;
+            let fnOutput = null;
+            let mgens = null;
+            if (typeInfo !== "elems" && typeInfo !== "returned") {
+                fnInputs = unifyFunctionTypes(
+                    obj.type.inputs,
+                    parsedQuery.elems,
+                    obj.type.where_clause,
+                    null,
+                    mgensScratch => {
+                        fnOutput = unifyFunctionTypes(
+                            obj.type.output,
+                            parsedQuery.returned,
+                            obj.type.where_clause,
+                            mgensScratch,
+                            mgensOut => {
+                                mgens = mgensOut;
+                                return true;
+                            },
+                            0,
+                        );
+                        return !!fnOutput;
+                    },
+                    0,
+                );
+            } else {
+                const arr = typeInfo === "elems" ? obj.type.inputs : obj.type.output;
+                const highlighted = unifyFunctionTypes(
+                    arr,
+                    parsedQuery.elems,
+                    obj.type.where_clause,
+                    null,
+                    mgensOut => {
+                        mgens = mgensOut;
+                        return true;
+                    },
+                    0,
+                );
+                if (typeInfo === "elems") {
+                    fnInputs = highlighted;
+                } else {
+                    fnOutput = highlighted;
+                }
+            }
+            if (!fnInputs) {
+                fnInputs = obj.type.inputs;
+            }
+            if (!fnOutput) {
+                fnOutput = obj.type.output;
+            }
+            const mappedNames = new Map();
+            const whereClause = new Map();
+
+            const fnParamNames = obj.paramNames;
+            const queryParamNames = [];
+            /**
+             * Recursively writes a map of IDs to query generic names,
+             * which are later used to map query generic names to function generic names.
+             * For example, when the user writes `X -> Option<X>` and the function
+             * is actually written as `T -> Option<T>`, this function stores the
+             * mapping `(-1, "X")`, and the writeFn function looks up the entry
+             * for -1 to form the final, user-visible mapping of "X is T".
+             *
+             * @param {QueryElement} queryElem
+             */
+            const remapQuery = queryElem => {
+                if (queryElem.id < 0) {
+                    queryParamNames[-1 - queryElem.id] = queryElem.name;
+                }
+                if (queryElem.generics.length > 0) {
+                    queryElem.generics.forEach(remapQuery);
+                }
+                if (queryElem.bindings.size > 0) {
+                    [...queryElem.bindings.values()].flat().forEach(remapQuery);
+                }
+            };
+
+            parsedQuery.elems.forEach(remapQuery);
+            parsedQuery.returned.forEach(remapQuery);
+
+            /**
+             * Write text to a highlighting array.
+             * Index 0 is not highlighted, index 1 is highlighted,
+             * index 2 is not highlighted, etc.
+             *
+             * @param {{name: string, highlighted: bool|undefined}} fnType - input
+             * @param {[string]} result
+             */
+            const pushText = (fnType, result) => {
+                // If !!(result.length % 2) == false, then pushing a new slot starts an even
+                // numbered slot. Even numbered slots are not highlighted.
+                //
+                // `highlighted` will not be defined if an entire subtree is not highlighted,
+                // so `!!` is used to coerce it to boolean. `result.length % 2` is used to
+                // check if the number is even, but it evaluates to a number, so it also
+                // needs coerced to a boolean.
+                if (!!(result.length % 2) === !!fnType.highlighted) {
+                    result.push("");
+                } else if (result.length === 0 && !!fnType.highlighted) {
+                    result.push("");
+                    result.push("");
+                }
+
+                result[result.length - 1] += fnType.name;
+            };
+
+            /**
+             * Write a higher order function type: either a function pointer
+             * or a trait bound on Fn, FnMut, or FnOnce.
+             *
+             * @param {FunctionType} fnType - input
+             * @param {[string]} result
+             */
+            const writeHof = (fnType, result) => {
+                const hofOutput = fnType.bindings.get(this.typeNameIdOfOutput) || [];
+                const hofInputs = fnType.generics;
+                pushText(fnType, result);
+                pushText({name: " (", highlighted: false}, result);
+                let needsComma = false;
+                for (const fnType of hofInputs) {
+                    if (needsComma) {
+                        pushText({ name: ", ", highlighted: false }, result);
+                    }
+                    needsComma = true;
+                    writeFn(fnType, result);
+                }
+                pushText({
+                    name: hofOutput.length === 0 ? ")" : ") -> ",
+                    highlighted: false,
+                }, result);
+                if (hofOutput.length > 1) {
+                    pushText({name: "(", highlighted: false}, result);
+                }
+                needsComma = false;
+                for (const fnType of hofOutput) {
+                    if (needsComma) {
+                        pushText({ name: ", ", highlighted: false }, result);
+                    }
+                    needsComma = true;
+                    writeFn(fnType, result);
+                }
+                if (hofOutput.length > 1) {
+                    pushText({name: ")", highlighted: false}, result);
+                }
+            };
+
+            /**
+             * Write a primitive type with special syntax, like `!` or `[T]`.
+             * Returns `false` if the supplied type isn't special.
+             *
+             * @param {FunctionType} fnType
+             * @param {[string]} result
+             */
+            const writeSpecialPrimitive = (fnType, result) => {
+                if (fnType.id === this.typeNameIdOfArray || fnType.id === this.typeNameIdOfSlice ||
+                    fnType.id === this.typeNameIdOfTuple || fnType.id === this.typeNameIdOfUnit) {
+                    const [ob, sb] =
+                        fnType.id === this.typeNameIdOfArray ||
+                            fnType.id === this.typeNameIdOfSlice ?
+                        ["[", "]"] :
+                        ["(", ")"];
+                    pushText({ name: ob, highlighted: fnType.highlighted }, result);
+                    onEachBtwn(
+                        fnType.generics,
+                        nested => writeFn(nested, result),
+                        () => pushText({ name: ", ", highlighted: false }, result),
+                    );
+                    pushText({ name: sb, highlighted: fnType.highlighted }, result);
+                    return true;
+                } else if (fnType.id === this.typeNameIdOfReference) {
+                    pushText({ name: "&", highlighted: fnType.highlighted }, result);
+                    let prevHighlighted = false;
+                    onEachBtwn(
+                        fnType.generics,
+                        value => {
+                            prevHighlighted = value.highlighted;
+                            writeFn(value, result);
+                        },
+                        value => pushText({
+                            name: " ",
+                            highlighted: prevHighlighted && value.highlighted,
+                        }, result),
+                    );
+                    return true;
+                } else if (fnType.id === this.typeNameIdOfFn) {
+                    writeHof(fnType, result);
+                    return true;
+                }
+                return false;
+            };
+            /**
+             * Write a type. This function checks for special types,
+             * like slices, with their own formatting. It also handles
+             * updating the where clause and generic type param map.
+             *
+             * @param {FunctionType} fnType
+             * @param {[string]} result
+             */
+            const writeFn = (fnType, result) => {
+                if (fnType.id < 0) {
+                    if (fnParamNames[-1 - fnType.id] === "") {
+                        for (const nested of fnType.generics) {
+                            writeFn(nested, result);
+                        }
+                        return;
+                    } else if (mgens) {
+                        for (const [queryId, fnId] of mgens) {
+                            if (fnId === fnType.id) {
+                                mappedNames.set(
+                                    queryParamNames[-1 - queryId],
+                                    fnParamNames[-1 - fnType.id],
+                                );
+                            }
+                        }
+                    }
+                    pushText({
+                        name: fnParamNames[-1 - fnType.id],
+                        highlighted: !!fnType.highlighted,
+                    }, result);
+                    const where = [];
+                    onEachBtwn(
+                        fnType.generics,
+                        nested => writeFn(nested, where),
+                        () => pushText({ name: " + ", highlighted: false }, where),
+                    );
+                    if (where.length > 0) {
+                        whereClause.set(fnParamNames[-1 - fnType.id], where);
+                    }
+                } else {
+                    if (fnType.ty === TY_PRIMITIVE) {
+                        if (writeSpecialPrimitive(fnType, result)) {
+                            return;
+                        }
+                    } else if (fnType.ty === TY_TRAIT && (
+                        fnType.id === this.typeNameIdOfFn ||
+                            fnType.id === this.typeNameIdOfFnMut ||
+                            fnType.id === this.typeNameIdOfFnOnce)) {
+                        writeHof(fnType, result);
+                        return;
+                    }
+                    pushText(fnType, result);
+                    let hasBindings = false;
+                    if (fnType.bindings.size > 0) {
+                        onEachBtwn(
+                            fnType.bindings,
+                            ([key, values]) => {
+                                const name = this.assocTypeIdNameMap.get(key);
+                                if (values.length === 1 && values[0].id < 0 &&
+                                    `${fnType.name}::${name}` === fnParamNames[-1 - values[0].id]) {
+                                    // the internal `Item=Iterator::Item` type variable should be
+                                    // shown in the where clause and name mapping output, but is
+                                    // redundant in this spot
+                                    for (const value of values) {
+                                        writeFn(value, []);
+                                    }
+                                    return true;
+                                }
+                                if (!hasBindings) {
+                                    hasBindings = true;
+                                    pushText({ name: "<", highlighted: false }, result);
+                                }
+                                pushText({ name, highlighted: false }, result);
+                                pushText({
+                                    name: values.length !== 1 ? "=(" : "=",
+                                    highlighted: false,
+                                }, result);
+                                onEachBtwn(
+                                    values || [],
+                                    value => writeFn(value, result),
+                                    () => pushText({ name: " + ",  highlighted: false }, result),
+                                );
+                                if (values.length !== 1) {
+                                    pushText({ name: ")", highlighted: false }, result);
+                                }
+                            },
+                            () => pushText({ name: ", ",  highlighted: false }, result),
+                        );
+                    }
+                    if (fnType.generics.length > 0) {
+                        pushText({ name: hasBindings ? ", " : "<", highlighted: false }, result);
+                    }
+                    onEachBtwn(
+                        fnType.generics,
+                        value => writeFn(value, result),
+                        () => pushText({ name: ", ",  highlighted: false }, result),
+                    );
+                    if (hasBindings || fnType.generics.length > 0) {
+                        pushText({ name: ">", highlighted: false }, result);
+                    }
+                }
+            };
+            const type = [];
+            onEachBtwn(
+                fnInputs,
+                fnType => writeFn(fnType, type),
+                () => pushText({ name: ", ",  highlighted: false }, type),
+            );
+            pushText({ name: " -> ", highlighted: false }, type);
+            onEachBtwn(
+                fnOutput,
+                fnType => writeFn(fnType, type),
+                () => pushText({ name: ", ",  highlighted: false }, type),
+            );
+
+            return {type, mappedNames, whereClause};
+        };
+
+        /**
          * This function takes a result map, and sorts it by various criteria, including edit
          * distance, substring match, and the crate it comes from.
          *
@@ -2095,9 +2664,10 @@ class DocSearch {
          * @param {string} preferredCrate
          * @returns {Promise<[ResultObject]>}
          */
-        const sortResults = async(results, isType, preferredCrate) => {
+        const sortResults = async(results, typeInfo, preferredCrate) => {
             const userQuery = parsedQuery.userQuery;
-            const casedUserQuery = parsedQuery.original;
+            const normalizedUserQuery = parsedQuery.userQuery.toLowerCase();
+            const isMixedCase = normalizedUserQuery !== userQuery;
             const result_list = [];
             for (const result of results.values()) {
                 result.item = this.searchIndex[result.id];
@@ -2109,15 +2679,17 @@ class DocSearch {
                 let a, b;
 
                 // sort by exact case-sensitive match
-                a = (aaa.item.name !== casedUserQuery);
-                b = (bbb.item.name !== casedUserQuery);
-                if (a !== b) {
-                    return a - b;
+                if (isMixedCase) {
+                    a = (aaa.item.name !== userQuery);
+                    b = (bbb.item.name !== userQuery);
+                    if (a !== b) {
+                        return a - b;
+                    }
                 }
 
                 // sort by exact match with regard to the last word (mismatch goes later)
-                a = (aaa.word !== userQuery);
-                b = (bbb.word !== userQuery);
+                a = (aaa.word !== normalizedUserQuery);
+                b = (bbb.word !== normalizedUserQuery);
                 if (a !== b) {
                     return a - b;
                 }
@@ -2205,30 +2777,30 @@ class DocSearch {
                 return 0;
             });
 
-            return transformResults(result_list);
+            return transformResults(result_list, typeInfo);
         };
 
         /**
          * This function checks if a list of search query `queryElems` can all be found in the
          * search index (`fnTypes`).
          *
-         * This function returns `true` on a match, or `false` if none. If `solutionCb` is
+         * This function returns highlighted results on a match, or `null`. If `solutionCb` is
          * supplied, it will call that function with mgens, and that callback can accept or
-         * reject the result bu returning `true` or `false`. If the callback returns false,
-         * then this function will try with a different solution, or bail with false if it
+         * reject the result by returning `true` or `false`. If the callback returns false,
+         * then this function will try with a different solution, or bail with null if it
          * runs out of candidates.
          *
          * @param {Array<FunctionType>} fnTypesIn - The objects to check.
          * @param {Array<QueryElement>} queryElems - The elements from the parsed query.
          * @param {[FunctionType]} whereClause - Trait bounds for generic items.
          * @param {Map<number,number>|null} mgensIn
-         *     - Map functions generics to query generics (never modified).
-         * @param {null|Map<number,number> -> bool} solutionCb - Called for each `mgens` solution.
+         *     - Map query generics to function generics (never modified).
+         * @param {Map<number,number> -> bool} solutionCb - Called for each `mgens` solution.
          * @param {number} unboxingDepth
          *     - Limit checks that Ty matches Vec<Ty>,
          *       but not Vec<ParamEnvAnd<WithInfcx<ConstTy<Interner<Ty=Ty>>>>>
          *
-         * @return {boolean} - Returns true if a match, false otherwise.
+         * @return {[FunctionType]|null} - Returns highlighed results if a match, null otherwise.
          */
         function unifyFunctionTypes(
             fnTypesIn,
@@ -2239,17 +2811,17 @@ class DocSearch {
             unboxingDepth,
         ) {
             if (unboxingDepth >= UNBOXING_LIMIT) {
-                return false;
+                return null;
             }
             /**
              * @type Map<integer, integer>|null
              */
             const mgens = mgensIn === null ? null : new Map(mgensIn);
             if (queryElems.length === 0) {
-                return !solutionCb || solutionCb(mgens);
+                return solutionCb(mgens) ? fnTypesIn : null;
             }
             if (!fnTypesIn || fnTypesIn.length === 0) {
-                return false;
+                return null;
             }
             const ql = queryElems.length;
             const fl = fnTypesIn.length;
@@ -2258,26 +2830,45 @@ class DocSearch {
             if (ql === 1 && queryElems[0].generics.length === 0
                 && queryElems[0].bindings.size === 0) {
                 const queryElem = queryElems[0];
-                for (const fnType of fnTypesIn) {
+                for (const [i, fnType] of fnTypesIn.entries()) {
                     if (!unifyFunctionTypeIsMatchCandidate(fnType, queryElem, mgens)) {
                         continue;
                     }
                     if (fnType.id < 0 && queryElem.id < 0) {
-                        if (mgens && mgens.has(fnType.id) &&
-                            mgens.get(fnType.id) !== queryElem.id) {
+                        if (mgens && mgens.has(queryElem.id) &&
+                            mgens.get(queryElem.id) !== fnType.id) {
                             continue;
                         }
                         const mgensScratch = new Map(mgens);
-                        mgensScratch.set(fnType.id, queryElem.id);
+                        mgensScratch.set(queryElem.id, fnType.id);
                         if (!solutionCb || solutionCb(mgensScratch)) {
-                            return true;
+                            const highlighted = [...fnTypesIn];
+                            highlighted[i] = Object.assign({
+                                highlighted: true,
+                            }, fnType, {
+                                generics: whereClause[-1 - fnType.id],
+                            });
+                            return highlighted;
                         }
-                    } else if (!solutionCb || solutionCb(mgens ? new Map(mgens) : null)) {
+                    } else if (solutionCb(mgens ? new Map(mgens) : null)) {
                         // unifyFunctionTypeIsMatchCandidate already checks that ids match
-                        return true;
+                        const highlighted = [...fnTypesIn];
+                        highlighted[i] = Object.assign({
+                            highlighted: true,
+                        }, fnType, {
+                            generics: unifyGenericTypes(
+                                fnType.generics,
+                                queryElem.generics,
+                                whereClause,
+                                mgens ? new Map(mgens) : null,
+                                solutionCb,
+                                unboxingDepth,
+                            ) || fnType.generics,
+                        });
+                        return highlighted;
                     }
                 }
-                for (const fnType of fnTypesIn) {
+                for (const [i, fnType] of fnTypesIn.entries()) {
                     if (!unifyFunctionTypeIsUnboxCandidate(
                         fnType,
                         queryElem,
@@ -2288,31 +2879,42 @@ class DocSearch {
                         continue;
                     }
                     if (fnType.id < 0) {
-                        if (mgens && mgens.has(fnType.id) &&
-                            mgens.get(fnType.id) !== 0) {
-                            continue;
-                        }
-                        const mgensScratch = new Map(mgens);
-                        mgensScratch.set(fnType.id, 0);
-                        if (unifyFunctionTypes(
+                        const highlightedGenerics = unifyFunctionTypes(
                             whereClause[(-fnType.id) - 1],
                             queryElems,
                             whereClause,
-                            mgensScratch,
+                            mgens,
                             solutionCb,
                             unboxingDepth + 1,
-                        )) {
-                            return true;
+                        );
+                        if (highlightedGenerics) {
+                            const highlighted = [...fnTypesIn];
+                            highlighted[i] = Object.assign({
+                                highlighted: true,
+                            }, fnType, {
+                                generics: highlightedGenerics,
+                            });
+                            return highlighted;
+                        }
+                    } else {
+                        const highlightedGenerics = unifyFunctionTypes(
+                            [...Array.from(fnType.bindings.values()).flat(), ...fnType.generics],
+                            queryElems,
+                            whereClause,
+                            mgens ? new Map(mgens) : null,
+                            solutionCb,
+                            unboxingDepth + 1,
+                        );
+                        if (highlightedGenerics) {
+                            const highlighted = [...fnTypesIn];
+                            highlighted[i] = Object.assign({}, fnType, {
+                                generics: highlightedGenerics,
+                                bindings: new Map([...fnType.bindings.entries()].map(([k, v]) => {
+                                    return [k, highlightedGenerics.splice(0, v.length)];
+                                })),
+                            });
+                            return highlighted;
                         }
-                    } else if (unifyFunctionTypes(
-                        [...fnType.generics, ...Array.from(fnType.bindings.values()).flat()],
-                        queryElems,
-                        whereClause,
-                        mgens ? new Map(mgens) : null,
-                        solutionCb,
-                        unboxingDepth + 1,
-                    )) {
-                        return true;
                     }
                 }
                 return false;
@@ -2352,11 +2954,11 @@ class DocSearch {
                 let mgensScratch;
                 if (fnType.id < 0) {
                     mgensScratch = new Map(mgens);
-                    if (mgensScratch.has(fnType.id)
-                        && mgensScratch.get(fnType.id) !== queryElem.id) {
+                    if (mgensScratch.has(queryElem.id)
+                        && mgensScratch.get(queryElem.id) !== fnType.id) {
                         continue;
                     }
-                    mgensScratch.set(fnType.id, queryElem.id);
+                    mgensScratch.set(queryElem.id, fnType.id);
                 } else {
                     mgensScratch = mgens;
                 }
@@ -2369,6 +2971,8 @@ class DocSearch {
                 if (!queryElemsTmp) {
                     queryElemsTmp = queryElems.slice(0, qlast);
                 }
+                let unifiedGenerics = [];
+                let unifiedGenericsMgens = null;
                 const passesUnification = unifyFunctionTypes(
                     fnTypes,
                     queryElemsTmp,
@@ -2377,7 +2981,7 @@ class DocSearch {
                     mgensScratch => {
                         if (fnType.generics.length === 0 && queryElem.generics.length === 0
                             && fnType.bindings.size === 0 && queryElem.bindings.size === 0) {
-                            return !solutionCb || solutionCb(mgensScratch);
+                            return solutionCb(mgensScratch);
                         }
                         const solution = unifyFunctionTypeCheckBindings(
                             fnType,
@@ -2391,7 +2995,7 @@ class DocSearch {
                         }
                         const simplifiedGenerics = solution.simplifiedGenerics;
                         for (const simplifiedMgens of solution.mgens) {
-                            const passesUnification = unifyFunctionTypes(
+                            unifiedGenerics = unifyGenericTypes(
                                 simplifiedGenerics,
                                 queryElem.generics,
                                 whereClause,
@@ -2399,7 +3003,8 @@ class DocSearch {
                                 solutionCb,
                                 unboxingDepth,
                             );
-                            if (passesUnification) {
+                            if (unifiedGenerics !== null) {
+                                unifiedGenericsMgens = simplifiedMgens;
                                 return true;
                             }
                         }
@@ -2408,7 +3013,23 @@ class DocSearch {
                     unboxingDepth,
                 );
                 if (passesUnification) {
-                    return true;
+                    passesUnification.length = fl;
+                    passesUnification[flast] = passesUnification[i];
+                    passesUnification[i] = Object.assign({}, fnType, {
+                        highlighted: true,
+                        generics: unifiedGenerics,
+                        bindings: new Map([...fnType.bindings.entries()].map(([k, v]) => {
+                            return [k, queryElem.bindings.has(k) ? unifyFunctionTypes(
+                                v,
+                                queryElem.bindings.get(k),
+                                whereClause,
+                                unifiedGenericsMgens,
+                                solutionCb,
+                                unboxingDepth,
+                            ) : unifiedGenerics.splice(0, v.length)];
+                        })),
+                    });
+                    return passesUnification;
                 }
                 // backtrack
                 fnTypes[flast] = fnTypes[i];
@@ -2426,16 +3047,6 @@ class DocSearch {
                 )) {
                     continue;
                 }
-                let mgensScratch;
-                if (fnType.id < 0) {
-                    mgensScratch = new Map(mgens);
-                    if (mgensScratch.has(fnType.id) && mgensScratch.get(fnType.id) !== 0) {
-                        continue;
-                    }
-                    mgensScratch.set(fnType.id, 0);
-                } else {
-                    mgensScratch = mgens;
-                }
                 const generics = fnType.id < 0 ?
                     whereClause[(-fnType.id) - 1] :
                     fnType.generics;
@@ -2443,18 +3054,225 @@ class DocSearch {
                     Array.from(fnType.bindings.values()).flat() :
                     [];
                 const passesUnification = unifyFunctionTypes(
-                    fnTypes.toSpliced(i, 1, ...generics, ...bindings),
+                    fnTypes.toSpliced(i, 1, ...bindings, ...generics),
                     queryElems,
                     whereClause,
-                    mgensScratch,
+                    mgens,
                     solutionCb,
                     unboxingDepth + 1,
                 );
                 if (passesUnification) {
-                    return true;
+                    const highlightedGenerics = passesUnification.slice(
+                        i,
+                        i + generics.length + bindings.length,
+                    );
+                    const highlightedFnType = Object.assign({}, fnType, {
+                        generics: highlightedGenerics,
+                        bindings: new Map([...fnType.bindings.entries()].map(([k, v]) => {
+                            return [k, highlightedGenerics.splice(0, v.length)];
+                        })),
+                    });
+                    return passesUnification.toSpliced(
+                        i,
+                        generics.length + bindings.length,
+                        highlightedFnType,
+                    );
                 }
             }
-            return false;
+            return null;
+        }
+        /**
+         * This function compares two lists of generics.
+         *
+         * This function behaves very similarly to `unifyFunctionTypes`, except that it
+         * doesn't skip or reorder anything. This is intended to match the behavior of
+         * the ordinary Rust type system, so that `Vec<Allocator>` only matches an actual
+         * `Vec` of `Allocators` and not the implicit `Allocator` parameter that every
+         * `Vec` has.
+         *
+         * @param {Array<FunctionType>} fnTypesIn - The objects to check.
+         * @param {Array<QueryElement>} queryElems - The elements from the parsed query.
+         * @param {[FunctionType]} whereClause - Trait bounds for generic items.
+         * @param {Map<number,number>|null} mgensIn
+         *     - Map functions generics to query generics (never modified).
+         * @param {Map<number,number> -> bool} solutionCb - Called for each `mgens` solution.
+         * @param {number} unboxingDepth
+         *     - Limit checks that Ty matches Vec<Ty>,
+         *       but not Vec<ParamEnvAnd<WithInfcx<ConstTy<Interner<Ty=Ty>>>>>
+         *
+         * @return {[FunctionType]|null} - Returns highlighed results if a match, null otherwise.
+         */
+        function unifyGenericTypes(
+            fnTypesIn,
+            queryElems,
+            whereClause,
+            mgensIn,
+            solutionCb,
+            unboxingDepth,
+        ) {
+            if (unboxingDepth >= UNBOXING_LIMIT) {
+                return null;
+            }
+            /**
+             * @type Map<integer, integer>|null
+             */
+            const mgens = mgensIn === null ? null : new Map(mgensIn);
+            if (queryElems.length === 0) {
+                return solutionCb(mgens) ? fnTypesIn : null;
+            }
+            if (!fnTypesIn || fnTypesIn.length === 0) {
+                return null;
+            }
+            const fnType = fnTypesIn[0];
+            const queryElem = queryElems[0];
+            if (unifyFunctionTypeIsMatchCandidate(fnType, queryElem, mgens)) {
+                if (fnType.id < 0 && queryElem.id < 0) {
+                    if (!mgens || !mgens.has(queryElem.id) ||
+                        mgens.get(queryElem.id) === fnType.id
+                    ) {
+                        const mgensScratch = new Map(mgens);
+                        mgensScratch.set(queryElem.id, fnType.id);
+                        const fnTypesRemaining = unifyGenericTypes(
+                            fnTypesIn.slice(1),
+                            queryElems.slice(1),
+                            whereClause,
+                            mgensScratch,
+                            solutionCb,
+                            unboxingDepth,
+                        );
+                        if (fnTypesRemaining) {
+                            const highlighted = [fnType, ...fnTypesRemaining];
+                            highlighted[0] = Object.assign({
+                                highlighted: true,
+                            }, fnType, {
+                                generics: whereClause[-1 - fnType.id],
+                            });
+                            return highlighted;
+                        }
+                    }
+                } else {
+                    let unifiedGenerics;
+                    const fnTypesRemaining = unifyGenericTypes(
+                        fnTypesIn.slice(1),
+                        queryElems.slice(1),
+                        whereClause,
+                        mgens,
+                        mgensScratch => {
+                            const solution = unifyFunctionTypeCheckBindings(
+                                fnType,
+                                queryElem,
+                                whereClause,
+                                mgensScratch,
+                                unboxingDepth,
+                            );
+                            if (!solution) {
+                                return false;
+                            }
+                            const simplifiedGenerics = solution.simplifiedGenerics;
+                            for (const simplifiedMgens of solution.mgens) {
+                                unifiedGenerics = unifyGenericTypes(
+                                    simplifiedGenerics,
+                                    queryElem.generics,
+                                    whereClause,
+                                    simplifiedMgens,
+                                    solutionCb,
+                                    unboxingDepth,
+                                );
+                                if (unifiedGenerics !== null) {
+                                    return true;
+                                }
+                            }
+                        },
+                        unboxingDepth,
+                    );
+                    if (fnTypesRemaining) {
+                        const highlighted = [fnType, ...fnTypesRemaining];
+                        highlighted[0] = Object.assign({
+                            highlighted: true,
+                        }, fnType, {
+                            generics: unifiedGenerics || fnType.generics,
+                        });
+                        return highlighted;
+                    }
+                }
+            }
+            if (unifyFunctionTypeIsUnboxCandidate(
+                fnType,
+                queryElem,
+                whereClause,
+                mgens,
+                unboxingDepth + 1,
+            )) {
+                let highlightedRemaining;
+                if (fnType.id < 0) {
+                    // Where clause corresponds to `F: A + B`
+                    //                                 ^^^^^
+                    // The order of the constraints doesn't matter, so
+                    // use order-agnostic matching for it.
+                    const highlightedGenerics = unifyFunctionTypes(
+                        whereClause[(-fnType.id) - 1],
+                        [queryElem],
+                        whereClause,
+                        mgens,
+                        mgensScratch => {
+                            const hl = unifyGenericTypes(
+                                fnTypesIn.slice(1),
+                                queryElems.slice(1),
+                                whereClause,
+                                mgensScratch,
+                                solutionCb,
+                                unboxingDepth,
+                            );
+                            if (hl) {
+                                highlightedRemaining = hl;
+                            }
+                            return hl;
+                        },
+                        unboxingDepth + 1,
+                    );
+                    if (highlightedGenerics) {
+                        return [Object.assign({
+                            highlighted: true,
+                        }, fnType, {
+                            generics: highlightedGenerics,
+                        }), ...highlightedRemaining];
+                    }
+                } else {
+                    const highlightedGenerics = unifyGenericTypes(
+                        [
+                            ...Array.from(fnType.bindings.values()).flat(),
+                            ...fnType.generics,
+                        ],
+                        [queryElem],
+                        whereClause,
+                        mgens,
+                        mgensScratch => {
+                            const hl = unifyGenericTypes(
+                                fnTypesIn.slice(1),
+                                queryElems.slice(1),
+                                whereClause,
+                                mgensScratch,
+                                solutionCb,
+                                unboxingDepth,
+                            );
+                            if (hl) {
+                                highlightedRemaining = hl;
+                            }
+                            return hl;
+                        },
+                        unboxingDepth + 1,
+                    );
+                    if (highlightedGenerics) {
+                        return [Object.assign({}, fnType, {
+                            generics: highlightedGenerics,
+                            bindings: new Map([...fnType.bindings.entries()].map(([k, v]) => {
+                                return [k, highlightedGenerics.splice(0, v.length)];
+                            })),
+                        }), ...highlightedRemaining];
+                    }
+                }
+            }
+            return null;
         }
         /**
          * Check if this function is a match candidate.
@@ -2467,7 +3285,7 @@ class DocSearch {
          *
          * @param {FunctionType} fnType
          * @param {QueryElement} queryElem
-         * @param {Map<number,number>|null} mgensIn - Map functions generics to query generics.
+         * @param {Map<number,number>|null} mgensIn - Map query generics to function generics.
          * @returns {boolean}
          */
         const unifyFunctionTypeIsMatchCandidate = (fnType, queryElem, mgensIn) => {
@@ -2477,22 +3295,13 @@ class DocSearch {
             }
             // fnType.id < 0 means generic
             // queryElem.id < 0 does too
-            // mgensIn[fnType.id] = queryElem.id
-            // or, if mgensIn[fnType.id] = 0, then we've matched this generic with a bare trait
-            // and should make that same decision everywhere it appears
+            // mgensIn[queryElem.id] = fnType.id
             if (fnType.id < 0 && queryElem.id < 0) {
-                if (mgensIn) {
-                    if (mgensIn.has(fnType.id) && mgensIn.get(fnType.id) !== queryElem.id) {
-                        return false;
-                    }
-                    for (const [fid, qid] of mgensIn.entries()) {
-                        if (fnType.id !== fid && queryElem.id === qid) {
-                            return false;
-                        }
-                        if (fnType.id === fid && queryElem.id !== qid) {
-                            return false;
-                        }
-                    }
+                if (
+                    mgensIn && mgensIn.has(queryElem.id) &&
+                    mgensIn.get(queryElem.id) !== fnType.id
+                ) {
+                    return false;
                 }
                 return true;
             } else {
@@ -2569,7 +3378,7 @@ class DocSearch {
          * @param {FunctionType} fnType
          * @param {QueryElement} queryElem
          * @param {[FunctionType]} whereClause - Trait bounds for generic items.
-         * @param {Map<number,number>} mgensIn - Map functions generics to query generics.
+         * @param {Map<number,number>} mgensIn - Map query generics to function generics.
          *                                            Never modified.
          * @param {number} unboxingDepth
          * @returns {false|{mgens: [Map<number,number>], simplifiedGenerics: [FunctionType]}}
@@ -2625,7 +3434,7 @@ class DocSearch {
                     }
                 });
                 if (simplifiedGenerics.length > 0) {
-                    simplifiedGenerics = [...simplifiedGenerics, ...binds];
+                    simplifiedGenerics = [...binds, ...simplifiedGenerics];
                 } else {
                     simplifiedGenerics = binds;
                 }
@@ -2637,7 +3446,7 @@ class DocSearch {
          * @param {FunctionType} fnType
          * @param {QueryElement} queryElem
          * @param {[FunctionType]} whereClause - Trait bounds for generic items.
-         * @param {Map<number,number>|null} mgens - Map functions generics to query generics.
+         * @param {Map<number,number>|null} mgens - Map query generics to function generics.
          * @param {number} unboxingDepth
          * @returns {boolean}
          */
@@ -2651,19 +3460,10 @@ class DocSearch {
             if (unboxingDepth >= UNBOXING_LIMIT) {
                 return false;
             }
-            if (fnType.id < 0 && queryElem.id >= 0) {
+            if (fnType.id < 0) {
                 if (!whereClause) {
                     return false;
                 }
-                // mgens[fnType.id] === 0 indicates that we committed to unboxing this generic
-                // mgens[fnType.id] === null indicates that we haven't decided yet
-                if (mgens && mgens.has(fnType.id) && mgens.get(fnType.id) !== 0) {
-                    return false;
-                }
-                // Where clauses can represent cyclical data.
-                // `null` prevents it from trying to unbox in an infinite loop
-                const mgensTmp = new Map(mgens);
-                mgensTmp.set(fnType.id, null);
                 // This is only a potential unbox if the search query appears in the where clause
                 // for example, searching `Read -> usize` should find
                 // `fn read_all<R: Read>(R) -> Result<usize>`
@@ -2672,10 +3472,11 @@ class DocSearch {
                     whereClause[(-fnType.id) - 1],
                     queryElem,
                     whereClause,
-                    mgensTmp,
+                    mgens,
                     unboxingDepth,
                 );
-            } else if (fnType.generics.length > 0 || fnType.bindings.size > 0) {
+            } else if (fnType.unboxFlag &&
+                (fnType.generics.length > 0 || fnType.bindings.size > 0)) {
                 const simplifiedGenerics = [
                     ...fnType.generics,
                     ...Array.from(fnType.bindings.values()).flat(),
@@ -2719,7 +3520,7 @@ class DocSearch {
          * @param {Row} row
          * @param {QueryElement} elem          - The element from the parsed query.
          * @param {[FunctionType]} whereClause - Trait bounds for generic items.
-         * @param {Map<number,number>|null} mgens - Map functions generics to query generics.
+         * @param {Map<number,number>|null} mgens - Map query generics to function generics.
          *
          * @return {boolean} - Returns true if the type matches, false otherwise.
          */
@@ -2727,33 +3528,42 @@ class DocSearch {
             if (unboxingDepth >= UNBOXING_LIMIT) {
                 return false;
             }
-            if (row.bindings.size === 0 && elem.bindings.size === 0) {
-                if (elem.id < 0 && mgens === null) {
-                    return row.id < 0 || checkIfInList(
-                        row.generics,
-                        elem,
-                        whereClause,
-                        mgens,
-                        unboxingDepth + 1,
-                    );
-                }
-                if (row.id > 0 && elem.id > 0 && elem.pathWithoutLast.length === 0 &&
-                    typePassesFilter(elem.typeFilter, row.ty) && elem.generics.length === 0 &&
-                    // special case
-                    elem.id !== this.typeNameIdOfArrayOrSlice
-                    && elem.id !== this.typeNameIdOfTupleOrUnit
-                    && elem.id !== this.typeNameIdOfHof
-                ) {
-                    return row.id === elem.id || checkIfInList(
-                        row.generics,
-                        elem,
-                        whereClause,
-                        mgens,
-                        unboxingDepth,
-                    );
+            if (row.id > 0 && elem.id > 0 && elem.pathWithoutLast.length === 0 &&
+                row.generics.length === 0 && elem.generics.length === 0 &&
+                row.bindings.size === 0 && elem.bindings.size === 0 &&
+                // special case
+                elem.id !== this.typeNameIdOfArrayOrSlice &&
+                elem.id !== this.typeNameIdOfHof &&
+                elem.id !== this.typeNameIdOfTupleOrUnit
+            ) {
+                return row.id === elem.id && typePassesFilter(elem.typeFilter, row.ty);
+            } else {
+                return unifyFunctionTypes(
+                    [row],
+                    [elem],
+                    whereClause,
+                    mgens,
+                    () => true,
+                    unboxingDepth,
+                );
+            }
+        };
+
+        /**
+         * Check a query solution for conflicting generics.
+         */
+        const checkTypeMgensForConflict = mgens => {
+            if (!mgens) {
+                return true;
+            }
+            const fnTypes = new Set();
+            for (const [_qid, fid] of mgens) {
+                if (fnTypes.has(fid)) {
+                    return false;
                 }
+                fnTypes.add(fid);
             }
-            return unifyFunctionTypes([row], [elem], whereClause, mgens, null, unboxingDepth);
+            return true;
         };
 
         /**
@@ -2949,96 +3759,6 @@ class DocSearch {
         }
 
         /**
-         * This function is called in case the query is only one element (with or without generics).
-         * This element will be compared to arguments' and returned values' items and also to items.
-         *
-         * Other important thing to note: since there is only one element, we use edit
-         * distance for name comparisons.
-         *
-         * @param {Row} row
-         * @param {integer} pos              - Position in the `searchIndex`.
-         * @param {QueryElement} elem        - The element from the parsed query.
-         * @param {Results} results_others   - Unqualified results (not in arguments nor in
-         *                                     returned values).
-         * @param {Results} results_in_args  - Matching arguments results.
-         * @param {Results} results_returned - Matching returned arguments results.
-         */
-        function handleSingleArg(
-            row,
-            pos,
-            elem,
-            results_others,
-            results_in_args,
-            results_returned,
-            maxEditDistance,
-        ) {
-            if (!row || (filterCrates !== null && row.crate !== filterCrates)) {
-                return;
-            }
-            let path_dist = 0;
-            const fullId = row.id;
-
-            // fpDist is a minimum possible type distance, where "type distance" is the number of
-            // atoms in the function not present in the query
-            const tfpDist = compareTypeFingerprints(
-                fullId,
-                parsedQuery.typeFingerprint,
-            );
-            if (tfpDist !== null) {
-                const in_args = row.type && row.type.inputs
-                    && checkIfInList(row.type.inputs, elem, row.type.where_clause, null, 0);
-                const returned = row.type && row.type.output
-                    && checkIfInList(row.type.output, elem, row.type.where_clause, null, 0);
-                if (in_args) {
-                    results_in_args.max_dist = Math.max(results_in_args.max_dist || 0, tfpDist);
-                    const maxDist = results_in_args.size < MAX_RESULTS ?
-                        (tfpDist + 1) :
-                        results_in_args.max_dist;
-                    addIntoResults(results_in_args, fullId, pos, -1, tfpDist, 0, maxDist);
-                }
-                if (returned) {
-                    results_returned.max_dist = Math.max(results_returned.max_dist || 0, tfpDist);
-                    const maxDist = results_returned.size < MAX_RESULTS ?
-                        (tfpDist + 1) :
-                        results_returned.max_dist;
-                    addIntoResults(results_returned, fullId, pos, -1, tfpDist, 0, maxDist);
-                }
-            }
-
-            if (!typePassesFilter(elem.typeFilter, row.ty)) {
-                return;
-            }
-
-            let index = row.word.indexOf(elem.pathLast);
-            const normalizedIndex = row.normalizedName.indexOf(elem.pathLast);
-            if (index === -1 || (index > normalizedIndex && normalizedIndex !== -1)) {
-                index = normalizedIndex;
-            }
-
-            if (elem.fullPath.length > 1) {
-                path_dist = checkPath(elem.pathWithoutLast, row);
-                if (path_dist === null) {
-                    return;
-                }
-            }
-
-            if (parsedQuery.literalSearch) {
-                if (row.word === elem.pathLast) {
-                    addIntoResults(results_others, fullId, pos, index, 0, path_dist);
-                }
-                return;
-            }
-
-            const dist = editDistance(row.normalizedName, elem.normalizedPathLast, maxEditDistance);
-
-            if (index === -1 && dist > maxEditDistance) {
-                return;
-            }
-
-            addIntoResults(results_others, fullId, pos, index, dist, path_dist, maxEditDistance);
-        }
-
-        /**
          * This function is called in case the query has more than one element. In this case, it'll
          * try to match the items which validates all the elements. For `aa -> bb` will look for
          * functions which have a parameter `aa` and has `bb` in its returned values.
@@ -3075,7 +3795,7 @@ class DocSearch {
                         parsedQuery.returned,
                         row.type.where_clause,
                         mgens,
-                        null,
+                        checkTypeMgensForConflict,
                         0, // unboxing depth
                     );
                 },
@@ -3178,21 +3898,25 @@ class DocSearch {
                 if ((elem.id === null && parsedQuery.totalElems > 1 && elem.typeFilter === -1
                     && elem.generics.length === 0 && elem.bindings.size === 0)
                     || elem.typeFilter === TY_GENERIC) {
-                    if (genericSymbols.has(elem.name)) {
-                        elem.id = genericSymbols.get(elem.name);
+                    if (genericSymbols.has(elem.normalizedPathLast)) {
+                        elem.id = genericSymbols.get(elem.normalizedPathLast);
                     } else {
                         elem.id = -(genericSymbols.size + 1);
-                        genericSymbols.set(elem.name, elem.id);
+                        genericSymbols.set(elem.normalizedPathLast, elem.id);
                     }
-                    if (elem.typeFilter === -1 && elem.name.length >= 3) {
+                    if (elem.typeFilter === -1 && elem.normalizedPathLast.length >= 3) {
                         // Silly heuristic to catch if the user probably meant
                         // to not write a generic parameter. We don't use it,
                         // just bring it up.
-                        const maxPartDistance = Math.floor(elem.name.length / 3);
+                        const maxPartDistance = Math.floor(elem.normalizedPathLast.length / 3);
                         let matchDist = maxPartDistance + 1;
                         let matchName = "";
                         for (const name of this.typeNameIdMap.keys()) {
-                            const dist = editDistance(name, elem.name, maxPartDistance);
+                            const dist = editDistance(
+                                name,
+                                elem.normalizedPathLast,
+                                maxPartDistance,
+                            );
                             if (dist <= matchDist && dist <= maxPartDistance) {
                                 if (dist === matchDist && matchName > name) {
                                     continue;
@@ -3239,34 +3963,89 @@ class DocSearch {
                 );
             };
 
-            const fps = new Set();
             for (const elem of parsedQuery.elems) {
                 convertNameToId(elem);
-                this.buildFunctionTypeFingerprint(elem, parsedQuery.typeFingerprint, fps);
+                this.buildFunctionTypeFingerprint(elem, parsedQuery.typeFingerprint);
             }
             for (const elem of parsedQuery.returned) {
                 convertNameToId(elem);
-                this.buildFunctionTypeFingerprint(elem, parsedQuery.typeFingerprint, fps);
+                this.buildFunctionTypeFingerprint(elem, parsedQuery.typeFingerprint);
             }
 
             if (parsedQuery.foundElems === 1 && !parsedQuery.hasReturnArrow) {
-                if (parsedQuery.elems.length === 1) {
-                    const elem = parsedQuery.elems[0];
-                    const length = this.searchIndex.length;
-                    for (let i = 0, nSearchIndex = length; i < nSearchIndex; ++i) {
-                        // It means we want to check for this element everywhere (in names, args and
-                        // returned).
-                        handleSingleArg(
-                            this.searchIndex[i],
-                            i,
-                            elem,
+                const elem = parsedQuery.elems[0];
+                for (const id of this.nameTrie.search(elem.normalizedPathLast, this.tailTable)) {
+                    const row = this.searchIndex[id];
+                    if (!typePassesFilter(elem.typeFilter, row.ty) ||
+                        (filterCrates !== null && row.crate !== filterCrates)) {
+                        continue;
+                    }
+
+                    let pathDist = 0;
+                    if (elem.fullPath.length > 1) {
+                        pathDist = checkPath(elem.pathWithoutLast, row);
+                        if (pathDist === null) {
+                            continue;
+                        }
+                    }
+
+                    if (parsedQuery.literalSearch) {
+                        if (row.word === elem.pathLast) {
+                            addIntoResults(results_others, row.id, id, 0, 0, pathDist);
+                        }
+                    } else {
+                        addIntoResults(
                             results_others,
-                            results_in_args,
-                            results_returned,
+                            row.id,
+                            id,
+                            row.normalizedName.indexOf(elem.normalizedPathLast),
+                            editDistance(
+                                row.normalizedName,
+                                elem.normalizedPathLast,
+                                maxEditDistance,
+                            ),
+                            pathDist,
                             maxEditDistance,
                         );
                     }
                 }
+                const length = this.searchIndex.length;
+                for (let i = 0, nSearchIndex = length; i < nSearchIndex; ++i) {
+                    const row = this.searchIndex[i];
+                    if (filterCrates !== null && row.crate !== filterCrates) {
+                        continue;
+                    }
+                    const tfpDist = compareTypeFingerprints(
+                        row.id,
+                        parsedQuery.typeFingerprint,
+                    );
+                    if (tfpDist !== null) {
+                        const in_args = row.type && row.type.inputs
+                            && checkIfInList(row.type.inputs, elem, row.type.where_clause, null, 0);
+                        const returned = row.type && row.type.output
+                            && checkIfInList(row.type.output, elem, row.type.where_clause, null, 0);
+                        if (in_args) {
+                            results_in_args.max_dist = Math.max(
+                                results_in_args.max_dist || 0,
+                                tfpDist,
+                            );
+                            const maxDist = results_in_args.size < MAX_RESULTS ?
+                                (tfpDist + 1) :
+                                results_in_args.max_dist;
+                            addIntoResults(results_in_args, row.id, i, -1, tfpDist, 0, maxDist);
+                        }
+                        if (returned) {
+                            results_returned.max_dist = Math.max(
+                                results_returned.max_dist || 0,
+                                tfpDist,
+                            );
+                            const maxDist = results_returned.size < MAX_RESULTS ?
+                                (tfpDist + 1) :
+                                results_returned.max_dist;
+                            addIntoResults(results_returned, row.id, i, -1, tfpDist, 0, maxDist);
+                        }
+                    }
+                }
             } else if (parsedQuery.foundElems > 0) {
                 // Sort input and output so that generic type variables go first and
                 // types with generic parameters go last.
@@ -3294,17 +4073,18 @@ class DocSearch {
             innerRunQuery();
         }
 
+        const isType = parsedQuery.foundElems !== 1 || parsedQuery.hasReturnArrow;
         const [sorted_in_args, sorted_returned, sorted_others] = await Promise.all([
-            sortResults(results_in_args, true, currentCrate),
-            sortResults(results_returned, true, currentCrate),
-            sortResults(results_others, false, currentCrate),
+            sortResults(results_in_args, "elems", currentCrate),
+            sortResults(results_returned, "returned", currentCrate),
+            sortResults(results_others, (isType ? "query" : null), currentCrate),
         ]);
         const ret = createQueryResults(
             sorted_in_args,
             sorted_returned,
             sorted_others,
             parsedQuery);
-        await handleAliases(ret, parsedQuery.original.replace(/"/g, ""),
+        await handleAliases(ret, parsedQuery.userQuery.replace(/"/g, ""),
             filterCrates, currentCrate);
         await Promise.all([ret.others, ret.returned, ret.in_args].map(async list => {
             const descs = await Promise.all(list.map(result => {
@@ -3324,6 +4104,7 @@ class DocSearch {
     }
 }
 
+
 // ==================== Core search logic end ====================
 
 let rawSearchIndex;
@@ -3455,15 +4236,18 @@ function focusSearchResult() {
  * @param {Array<?>}    array   - The search results for this tab
  * @param {ParsedQuery} query
  * @param {boolean}     display - True if this is the active tab
+ * @param {"sig"|"elems"|"returned"|null} typeInfo
  */
 async function addTab(array, query, display) {
     const extraClass = display ? " active" : "";
 
-    const output = document.createElement("div");
+    const output = document.createElement(
+        array.length === 0 && query.error === null ? "div" : "ul",
+    );
     if (array.length > 0) {
         output.className = "search-results " + extraClass;
 
-        for (const item of array) {
+        const lis = Promise.all(array.map(async item => {
             const name = item.name;
             const type = itemTypes[item.ty];
             const longType = longItemTypes[item.ty];
@@ -3473,7 +4257,7 @@ async function addTab(array, query, display) {
             link.className = "result-" + type;
             link.href = item.href;
 
-            const resultName = document.createElement("div");
+            const resultName = document.createElement("span");
             resultName.className = "result-name";
 
             resultName.insertAdjacentHTML(
@@ -3496,10 +4280,73 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             const description = document.createElement("div");
             description.className = "desc";
             description.insertAdjacentHTML("beforeend", item.desc);
+            if (item.displayTypeSignature) {
+                const {type, mappedNames, whereClause} = await item.displayTypeSignature;
+                const displayType = document.createElement("div");
+                type.forEach((value, index) => {
+                    if (index % 2 !== 0) {
+                        const highlight = document.createElement("strong");
+                        highlight.appendChild(document.createTextNode(value));
+                        displayType.appendChild(highlight);
+                    } else {
+                        displayType.appendChild(document.createTextNode(value));
+                    }
+                });
+                if (mappedNames.size > 0 || whereClause.size > 0) {
+                    let addWhereLineFn = () => {
+                        const line = document.createElement("div");
+                        line.className = "where";
+                        line.appendChild(document.createTextNode("where"));
+                        displayType.appendChild(line);
+                        addWhereLineFn = () => {};
+                    };
+                    for (const [qname, name] of mappedNames) {
+                        // don't care unless the generic name is different
+                        if (name === qname) {
+                            continue;
+                        }
+                        addWhereLineFn();
+                        const line = document.createElement("div");
+                        line.className = "where";
+                        line.appendChild(document.createTextNode(`    ${qname} matches `));
+                        const lineStrong = document.createElement("strong");
+                        lineStrong.appendChild(document.createTextNode(name));
+                        line.appendChild(lineStrong);
+                        displayType.appendChild(line);
+                    }
+                    for (const [name, innerType] of whereClause) {
+                        // don't care unless there's at least one highlighted entry
+                        if (innerType.length <= 1) {
+                            continue;
+                        }
+                        addWhereLineFn();
+                        const line = document.createElement("div");
+                        line.className = "where";
+                        line.appendChild(document.createTextNode(`    ${name}: `));
+                        innerType.forEach((value, index) => {
+                            if (index % 2 !== 0) {
+                                const highlight = document.createElement("strong");
+                                highlight.appendChild(document.createTextNode(value));
+                                line.appendChild(highlight);
+                            } else {
+                                line.appendChild(document.createTextNode(value));
+                            }
+                        });
+                        displayType.appendChild(line);
+                    }
+                }
+                displayType.className = "type-signature";
+                link.appendChild(displayType);
+            }
 
             link.appendChild(description);
-            output.appendChild(link);
-        }
+            return link;
+        }));
+        lis.then(lis => {
+            for (const li of lis) {
+                output.appendChild(li);
+            }
+        });
     } else if (query.error === null) {
         output.className = "search-failed" + extraClass;
         output.innerHTML = "No results :(<br/>" +
@@ -3516,7 +4363,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
             "href=\"https://docs.rs\">Docs.rs</a> for documentation of crates released on" +
             " <a href=\"https://crates.io/\">crates.io</a>.</li></ul>";
     }
-    return [output, array.length];
+    return output;
 }
 
 function makeTabHeader(tabNb, text, nbElems) {
@@ -3573,24 +4420,18 @@ async function showResults(results, go_to_first, filterCrates) {
 
     currentResults = results.query.userQuery;
 
-    const [ret_others, ret_in_args, ret_returned] = await Promise.all([
-        addTab(results.others, results.query, true),
-        addTab(results.in_args, results.query, false),
-        addTab(results.returned, results.query, false),
-    ]);
-
     // Navigate to the relevant tab if the current tab is empty, like in case users search
     // for "-> String". If they had selected another tab previously, they have to click on
     // it again.
     let currentTab = searchState.currentTab;
-    if ((currentTab === 0 && ret_others[1] === 0) ||
-        (currentTab === 1 && ret_in_args[1] === 0) ||
-        (currentTab === 2 && ret_returned[1] === 0)) {
-        if (ret_others[1] !== 0) {
+    if ((currentTab === 0 && results.others.length === 0) ||
+        (currentTab === 1 && results.in_args.length === 0) ||
+        (currentTab === 2 && results.returned.length === 0)) {
+        if (results.others.length !== 0) {
             currentTab = 0;
-        } else if (ret_in_args[1] !== 0) {
+        } else if (results.in_args.length) {
             currentTab = 1;
-        } else if (ret_returned[1] !== 0) {
+        } else if (results.returned.length) {
             currentTab = 2;
         }
     }
@@ -3619,14 +4460,14 @@ async function showResults(results, go_to_first, filterCrates) {
         });
         output += `<h3 class="error">Query parser error: "${error.join("")}".</h3>`;
         output += "<div id=\"search-tabs\">" +
-            makeTabHeader(0, "In Names", ret_others[1]) +
+            makeTabHeader(0, "In Names", results.others.length) +
             "</div>";
         currentTab = 0;
     } else if (results.query.foundElems <= 1 && results.query.returned.length === 0) {
         output += "<div id=\"search-tabs\">" +
-            makeTabHeader(0, "In Names", ret_others[1]) +
-            makeTabHeader(1, "In Parameters", ret_in_args[1]) +
-            makeTabHeader(2, "In Return Types", ret_returned[1]) +
+            makeTabHeader(0, "In Names", results.others.length) +
+            makeTabHeader(1, "In Parameters", results.in_args.length) +
+            makeTabHeader(2, "In Return Types", results.returned.length) +
             "</div>";
     } else {
         const signatureTabTitle =
@@ -3634,7 +4475,7 @@ async function showResults(results, go_to_first, filterCrates) {
                 results.query.returned.length === 0 ? "In Function Parameters" :
                     "In Function Signatures";
         output += "<div id=\"search-tabs\">" +
-            makeTabHeader(0, signatureTabTitle, ret_others[1]) +
+            makeTabHeader(0, signatureTabTitle, results.others.length) +
             "</div>";
         currentTab = 0;
     }
@@ -3656,11 +4497,17 @@ async function showResults(results, go_to_first, filterCrates) {
             `Consider searching for "${targ}" instead.</h3>`;
     }
 
+    const [ret_others, ret_in_args, ret_returned] = await Promise.all([
+        addTab(results.others, results.query, currentTab === 0),
+        addTab(results.in_args, results.query, currentTab === 1),
+        addTab(results.returned, results.query, currentTab === 2),
+    ]);
+
     const resultsElem = document.createElement("div");
     resultsElem.id = "results";
-    resultsElem.appendChild(ret_others[0]);
-    resultsElem.appendChild(ret_in_args[0]);
-    resultsElem.appendChild(ret_returned[0]);
+    resultsElem.appendChild(ret_others);
+    resultsElem.appendChild(ret_in_args);
+    resultsElem.appendChild(ret_returned);
 
     search.innerHTML = output;
     if (searchState.rustdocToolbar) {
@@ -3724,11 +4571,11 @@ async function search(forced) {
     }
 
     // Update document title to maintain a meaningful browser history
-    searchState.title = "\"" + query.original + "\" Search - Rust";
+    searchState.title = "\"" + query.userQuery + "\" Search - Rust";
 
     // Because searching is incremental by character, only the most
     // recent search query is added to the browser history.
-    updateSearchHistory(buildUrl(query.original, filterCrates));
+    updateSearchHistory(buildUrl(query.userQuery, filterCrates));
 
     await showResults(
         await docSearch.execQuery(query, filterCrates, window.currentCrate),
@@ -3942,4 +4789,477 @@ if (typeof window !== "undefined") {
     // exports.
     initSearch(new Map());
 }
-})();
+
+// Parts of this code are based on Lucene, which is licensed under the
+// Apache/2.0 license.
+// More information found here:
+// https://fossies.org/linux/lucene/lucene/core/src/java/org/apache/lucene/util/automaton/
+//   LevenshteinAutomata.java
+class ParametricDescription {
+    constructor(w, n, minErrors) {
+        this.w = w;
+        this.n = n;
+        this.minErrors = minErrors;
+    }
+    isAccept(absState) {
+        const state = Math.floor(absState / (this.w + 1));
+        const offset = absState % (this.w + 1);
+        return this.w - offset + this.minErrors[state] <= this.n;
+    }
+    getPosition(absState) {
+        return absState % (this.w + 1);
+    }
+    getVector(name, charCode, pos, end) {
+        let vector = 0;
+        for (let i = pos; i < end; i += 1) {
+            vector = vector << 1;
+            if (name.charCodeAt(i) === charCode) {
+                vector |= 1;
+            }
+        }
+        return vector;
+    }
+    unpack(data, index, bitsPerValue) {
+        const bitLoc = (bitsPerValue * index);
+        const dataLoc = bitLoc >> 5;
+        const bitStart = bitLoc & 31;
+        if (bitStart + bitsPerValue <= 32) {
+            // not split
+            return ((data[dataLoc] >> bitStart) & this.MASKS[bitsPerValue - 1]);
+        } else {
+            // split
+            const part = 32 - bitStart;
+            return ~~(((data[dataLoc] >> bitStart) & this.MASKS[part - 1]) +
+                ((data[1 + dataLoc] & this.MASKS[bitsPerValue - part - 1]) << part));
+        }
+    }
+}
+ParametricDescription.prototype.MASKS = new Int32Array([
+    0x1, 0x3, 0x7, 0xF,
+    0x1F, 0x3F, 0x7F, 0xFF,
+    0x1FF, 0x3F, 0x7FF, 0xFFF,
+    0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,
+    0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF,
+    0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF,
+    0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF,
+    0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF,
+]);
+
+// The following code was generated with the moman/finenight pkg
+// This package is available under the MIT License, see NOTICE.txt
+// for more details.
+// This class is auto-generated, Please do not modify it directly.
+// You should modify the https://gitlab.com/notriddle/createAutomata.py instead.
+// The following code was generated with the moman/finenight pkg
+// This package is available under the MIT License, see NOTICE.txt
+// for more details.
+// This class is auto-generated, Please do not modify it directly.
+// You should modify https://gitlab.com/notriddle/moman-rustdoc instead.
+
+class Lev2TParametricDescription extends ParametricDescription {
+    /**
+     * @param {number} absState
+     * @param {number} position
+     * @param {number} vector
+     * @returns {number}
+    */
+    transition(absState, position, vector) {
+        let state = Math.floor(absState / (this.w + 1));
+        let offset = absState % (this.w + 1);
+
+        if (position === this.w) {
+            if (state < 3) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 3) + state;
+                offset += this.unpack(this.offsetIncrs0, loc, 1);
+                state = this.unpack(this.toStates0, loc, 2) - 1;
+            }
+        } else if (position === this.w - 1) {
+            if (state < 5) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 5) + state;
+                offset += this.unpack(this.offsetIncrs1, loc, 1);
+                state = this.unpack(this.toStates1, loc, 3) - 1;
+            }
+        } else if (position === this.w - 2) {
+            if (state < 13) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 13) + state;
+                offset += this.unpack(this.offsetIncrs2, loc, 2);
+                state = this.unpack(this.toStates2, loc, 4) - 1;
+            }
+        } else if (position === this.w - 3) {
+            if (state < 28) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 28) + state;
+                offset += this.unpack(this.offsetIncrs3, loc, 2);
+                state = this.unpack(this.toStates3, loc, 5) - 1;
+            }
+        } else if (position === this.w - 4) {
+            if (state < 45) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 45) + state;
+                offset += this.unpack(this.offsetIncrs4, loc, 3);
+                state = this.unpack(this.toStates4, loc, 6) - 1;
+            }
+        } else {
+            if (state < 45) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 45) + state;
+                offset += this.unpack(this.offsetIncrs5, loc, 3);
+                state = this.unpack(this.toStates5, loc, 6) - 1;
+            }
+        }
+
+        if (state === -1) {
+            // null state
+            return -1;
+        } else {
+            // translate back to abs
+            return Math.imul(state, this.w + 1) + offset;
+        }
+    }
+
+    // state map
+    //   0 -> [(0, 0)]
+    //   1 -> [(0, 1)]
+    //   2 -> [(0, 2)]
+    //   3 -> [(0, 1), (1, 1)]
+    //   4 -> [(0, 2), (1, 2)]
+    //   5 -> [(0, 1), (1, 1), (2, 1)]
+    //   6 -> [(0, 2), (1, 2), (2, 2)]
+    //   7 -> [(0, 1), (2, 1)]
+    //   8 -> [(0, 1), (2, 2)]
+    //   9 -> [(0, 2), (2, 1)]
+    //   10 -> [(0, 2), (2, 2)]
+    //   11 -> [t(0, 1), (0, 1), (1, 1), (2, 1)]
+    //   12 -> [t(0, 2), (0, 2), (1, 2), (2, 2)]
+    //   13 -> [(0, 2), (1, 2), (2, 2), (3, 2)]
+    //   14 -> [(0, 1), (1, 1), (3, 2)]
+    //   15 -> [(0, 1), (2, 2), (3, 2)]
+    //   16 -> [(0, 1), (3, 2)]
+    //   17 -> [(0, 1), t(1, 2), (2, 2), (3, 2)]
+    //   18 -> [(0, 2), (1, 2), (3, 1)]
+    //   19 -> [(0, 2), (1, 2), (3, 2)]
+    //   20 -> [(0, 2), (1, 2), t(1, 2), (2, 2), (3, 2)]
+    //   21 -> [(0, 2), (2, 1), (3, 1)]
+    //   22 -> [(0, 2), (2, 2), (3, 2)]
+    //   23 -> [(0, 2), (3, 1)]
+    //   24 -> [(0, 2), (3, 2)]
+    //   25 -> [(0, 2), t(1, 2), (1, 2), (2, 2), (3, 2)]
+    //   26 -> [t(0, 2), (0, 2), (1, 2), (2, 2), (3, 2)]
+    //   27 -> [t(0, 2), (0, 2), (1, 2), (3, 1)]
+    //   28 -> [(0, 2), (1, 2), (2, 2), (3, 2), (4, 2)]
+    //   29 -> [(0, 2), (1, 2), (2, 2), (4, 2)]
+    //   30 -> [(0, 2), (1, 2), (2, 2), t(2, 2), (3, 2), (4, 2)]
+    //   31 -> [(0, 2), (1, 2), (3, 2), (4, 2)]
+    //   32 -> [(0, 2), (1, 2), (4, 2)]
+    //   33 -> [(0, 2), (1, 2), t(1, 2), (2, 2), (3, 2), (4, 2)]
+    //   34 -> [(0, 2), (1, 2), t(2, 2), (2, 2), (3, 2), (4, 2)]
+    //   35 -> [(0, 2), (2, 1), (4, 2)]
+    //   36 -> [(0, 2), (2, 2), (3, 2), (4, 2)]
+    //   37 -> [(0, 2), (2, 2), (4, 2)]
+    //   38 -> [(0, 2), (3, 2), (4, 2)]
+    //   39 -> [(0, 2), (4, 2)]
+    //   40 -> [(0, 2), t(1, 2), (1, 2), (2, 2), (3, 2), (4, 2)]
+    //   41 -> [(0, 2), t(2, 2), (2, 2), (3, 2), (4, 2)]
+    //   42 -> [t(0, 2), (0, 2), (1, 2), (2, 2), (3, 2), (4, 2)]
+    //   43 -> [t(0, 2), (0, 2), (1, 2), (2, 2), (4, 2)]
+    //   44 -> [t(0, 2), (0, 2), (1, 2), (2, 2), t(2, 2), (3, 2), (4, 2)]
+
+
+    /** @param {number} w - length of word being checked */
+    constructor(w) {
+        super(w, 2, new Int32Array([
+            0,1,2,0,1,-1,0,-1,0,-1,0,-1,0,-1,-1,-1,-1,-1,-2,-1,-1,-2,-1,-2,
+            -1,-1,-1,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
+        ]));
+    }
+}
+
+Lev2TParametricDescription.prototype.toStates0 = /*2 bits per value */ new Int32Array([
+    0xe,
+]);
+Lev2TParametricDescription.prototype.offsetIncrs0 = /*1 bits per value */ new Int32Array([
+    0x0,
+]);
+
+Lev2TParametricDescription.prototype.toStates1 = /*3 bits per value */ new Int32Array([
+    0x1a688a2c,
+]);
+Lev2TParametricDescription.prototype.offsetIncrs1 = /*1 bits per value */ new Int32Array([
+    0x3e0,
+]);
+
+Lev2TParametricDescription.prototype.toStates2 = /*4 bits per value */ new Int32Array([
+    0x70707054,0xdc07035,0x3dd3a3a,0x2323213a,
+    0x15435223,0x22545432,0x5435,
+]);
+Lev2TParametricDescription.prototype.offsetIncrs2 = /*2 bits per value */ new Int32Array([
+    0x80000,0x55582088,0x55555555,0x55,
+]);
+
+Lev2TParametricDescription.prototype.toStates3 = /*5 bits per value */ new Int32Array([
+    0x1c0380a4,0x700a570,0xca529c0,0x180a00,
+    0xa80af180,0xc5498e60,0x5a546398,0x8c4300e8,
+    0xac18c601,0xd8d43501,0x863500ad,0x51976d6a,
+    0x8ca0180a,0xc3501ac2,0xb0c5be16,0x76dda8a5,
+    0x18c4519,0xc41294a,0xe248d231,0x1086520c,
+    0xce31ac42,0x13946358,0x2d0348c4,0x6732d494,
+    0x1ad224a5,0xd635ad4b,0x520c4139,0xce24948,
+    0x22110a52,0x58ce729d,0xc41394e3,0x941cc520,
+    0x90e732d4,0x4729d224,0x39ce35ad,
+]);
+Lev2TParametricDescription.prototype.offsetIncrs3 = /*2 bits per value */ new Int32Array([
+    0x80000,0xc0c830,0x300f3c30,0x2200fcff,
+    0xcaa00a08,0x3c2200a8,0xa8fea00a,0x55555555,
+    0x55555555,0x55555555,0x55555555,0x55555555,
+    0x55555555,0x55555555,
+]);
+
+Lev2TParametricDescription.prototype.toStates4 = /*6 bits per value */ new Int32Array([
+    0x801c0144,0x1453803,0x14700038,0xc0005145,
+    0x1401,0x14,0x140000,0x0,
+    0x510000,0x6301f007,0x301f00d1,0xa186178,
+    0xc20ca0c3,0xc20c30,0xc30030c,0xc00c00cd,
+    0xf0c00c30,0x4c054014,0xc30944c3,0x55150c34,
+    0x8300550,0x430c0143,0x50c31,0xc30850c,
+    0xc3143000,0x50053c50,0x5130d301,0x850d30c2,
+    0x30a08608,0xc214414,0x43142145,0x21450031,
+    0x1400c314,0x4c143145,0x32832803,0x28014d6c,
+    0xcd34a0c3,0x1c50c76,0x1c314014,0x430c30c3,
+    0x1431,0xc300500,0xca00d303,0xd36d0e40,
+    0x90b0e400,0xcb2abb2c,0x70c20ca1,0x2c32ca2c,
+    0xcd2c70cb,0x31c00c00,0x34c2c32c,0x5583280,
+    0x558309b7,0x6cd6ca14,0x430850c7,0x51c51401,
+    0x1430c714,0xc3087,0x71451450,0xca00d30,
+    0xc26dc156,0xb9071560,0x1cb2abb2,0xc70c2144,
+    0xb1c51ca1,0x1421c70c,0xc51c00c3,0x30811c51,
+    0x24324308,0xc51031c2,0x70820820,0x5c33830d,
+    0xc33850c3,0x30c30c30,0xc30c31c,0x451450c3,
+    0x20c20c20,0xda0920d,0x5145914f,0x36596114,
+    0x51965865,0xd9643653,0x365a6590,0x51964364,
+    0x43081505,0x920b2032,0x2c718b28,0xd7242249,
+    0x35cb28b0,0x2cb3872c,0x972c30d7,0xb0c32cb2,
+    0x4e1c75c,0xc80c90c2,0x62ca2482,0x4504171c,
+    0xd65d9610,0x33976585,0xd95cb5d,0x4b5ca5d7,
+    0x73975c36,0x10308138,0xc2245105,0x41451031,
+    0x14e24208,0xc35c3387,0x51453851,0x1c51c514,
+    0xc70c30c3,0x20451450,0x14f1440c,0x4f0da092,
+    0x4513d41,0x6533944d,0x1350e658,0xe1545055,
+    0x64365a50,0x5519383,0x51030815,0x28920718,
+    0x441c718b,0x714e2422,0x1c35cb28,0x4e1c7387,
+    0xb28e1c51,0x5c70c32c,0xc204e1c7,0x81c61440,
+    0x1c62ca24,0xd04503ce,0x85d63944,0x39338e65,
+    0x8e154387,0x364b5ca3,0x38739738,
+]);
+Lev2TParametricDescription.prototype.offsetIncrs4 = /*3 bits per value */ new Int32Array([
+    0x10000000,0xc00000,0x60061,0x400,
+    0x0,0x80010008,0x249248a4,0x8229048,
+    0x2092,0x6c3603,0xb61b6c30,0x6db6036d,
+    0xdb6c0,0x361b0180,0x91b72000,0xdb11b71b,
+    0x6db6236,0x1008200,0x12480012,0x24924906,
+    0x48200049,0x80410002,0x24000900,0x4924a489,
+    0x10822492,0x20800125,0x48360,0x9241b692,
+    0x6da4924,0x40009268,0x241b010,0x291b4900,
+    0x6d249249,0x49493423,0x92492492,0x24924924,
+    0x49249249,0x92492492,0x24924924,0x49249249,
+    0x92492492,0x24924924,0x49249249,0x92492492,
+    0x24924924,0x49249249,0x92492492,0x24924924,
+    0x49249249,0x92492492,0x24924924,0x49249249,
+    0x92492492,0x24924924,0x49249249,0x92492492,
+    0x24924924,0x49249249,0x92492492,0x24924924,
+    0x49249249,0x92492492,0x24924924,0x49249249,
+    0x92492492,0x24924924,0x49249249,0x2492,
+]);
+
+Lev2TParametricDescription.prototype.toStates5 = /*6 bits per value */ new Int32Array([
+    0x801c0144,0x1453803,0x14700038,0xc0005145,
+    0x1401,0x14,0x140000,0x0,
+    0x510000,0x4e00e007,0xe0051,0x3451451c,
+    0xd015000,0x30cd0000,0xc30c30c,0xc30c30d4,
+    0x40c30c30,0x7c01c014,0xc03458c0,0x185e0c07,
+    0x2830c286,0x830c3083,0xc30030,0x33430c,
+    0x30c3003,0x70051030,0x16301f00,0x8301f00d,
+    0x30a18617,0xc20ca0c,0x431420c3,0xb1450c51,
+    0x14314315,0x4f143145,0x34c05401,0x4c30944c,
+    0x55150c3,0x30830055,0x1430c014,0xc00050c3,
+    0xc30850,0xc314300,0x150053c5,0x25130d30,
+    0x5430d30c,0xc0354154,0x300d0c90,0x1cb2cd0c,
+    0xc91cb0c3,0x72c30cb2,0x14f1cb2c,0xc34c0540,
+    0x34c30944,0x82182214,0x851050c2,0x50851430,
+    0x1400c50c,0x30c5085,0x50c51450,0x150053c,
+    0xc25130d3,0x8850d30,0x1430a086,0x450c2144,
+    0x51cb1c21,0x1c91c70c,0xc71c314b,0x34c1cb1,
+    0x6c328328,0xc328014d,0x76cd34a0,0x1401c50c,
+    0xc31c3140,0x31430c30,0x14,0x30c3005,
+    0xa0ca00d3,0x535b0c,0x4d2830ca,0x514369b3,
+    0xc500d01,0x5965965a,0x30d46546,0x6435030c,
+    0x8034c659,0xdb439032,0x2c390034,0xcaaecb24,
+    0x30832872,0xcb28b1c,0x4b1c32cb,0x70030033,
+    0x30b0cb0c,0xe40ca00d,0x400d36d0,0xb2c90b0e,
+    0xca1cb2ab,0xa2c70c20,0x6575d95c,0x4315b5ce,
+    0x95c53831,0x28034c5d,0x9b705583,0xa1455830,
+    0xc76cd6c,0x40143085,0x71451c51,0x871430c,
+    0x450000c3,0xd3071451,0x1560ca00,0x560c26dc,
+    0xb35b2851,0xc914369,0x1a14500d,0x46593945,
+    0xcb2c939,0x94507503,0x328034c3,0x9b70558,
+    0xe41c5583,0x72caaeca,0x1c308510,0xc7147287,
+    0x50871c32,0x1470030c,0xd307147,0xc1560ca0,
+    0x1560c26d,0xabb2b907,0x21441cb2,0x38a1c70c,
+    0x8e657394,0x314b1c93,0x39438738,0x43083081,
+    0x31c22432,0x820c510,0x830d7082,0x50c35c33,
+    0xc30c338,0xc31c30c3,0x50c30c30,0xc204514,
+    0x890c90c2,0x31440c70,0xa8208208,0xea0df0c3,
+    0x8a231430,0xa28a28a2,0x28a28a1e,0x1861868a,
+    0x48308308,0xc3682483,0x14516453,0x4d965845,
+    0xd4659619,0x36590d94,0xd969964,0x546590d9,
+    0x20c20541,0x920d20c,0x5914f0da,0x96114514,
+    0x65865365,0xe89d3519,0x99e7a279,0x9e89e89e,
+    0x81821827,0xb2032430,0x18b28920,0x422492c7,
+    0xb28b0d72,0x3872c35c,0xc30d72cb,0x32cb2972,
+    0x1c75cb0c,0xc90c204e,0xa2482c80,0x24b1c62c,
+    0xc3a89089,0xb0ea2e42,0x9669a31c,0xa4966a28,
+    0x59a8a269,0x8175e7a,0xb203243,0x718b2892,
+    0x4114105c,0x17597658,0x74ce5d96,0x5c36572d,
+    0xd92d7297,0xe1ce5d70,0xc90c204,0xca2482c8,
+    0x4171c62,0x5d961045,0x976585d6,0x79669533,
+    0x964965a2,0x659689e6,0x308175e7,0x24510510,
+    0x451031c2,0xe2420841,0x5c338714,0x453851c3,
+    0x51c51451,0xc30c31c,0x451450c7,0x41440c20,
+    0xc708914,0x82105144,0xf1c58c90,0x1470ea0d,
+    0x61861863,0x8a1e85e8,0x8687a8a2,0x3081861,
+    0x24853c51,0x5053c368,0x1341144f,0x96194ce5,
+    0x1544d439,0x94385514,0xe0d90d96,0x5415464,
+    0x4f1440c2,0xf0da0921,0x4513d414,0x533944d0,
+    0x350e6586,0x86082181,0xe89e981d,0x18277689,
+    0x10308182,0x89207185,0x41c718b2,0x14e24224,
+    0xc35cb287,0xe1c73871,0x28e1c514,0xc70c32cb,
+    0x204e1c75,0x1c61440c,0xc62ca248,0x90891071,
+    0x2e41c58c,0xa31c70ea,0xe86175e7,0xa269a475,
+    0x5e7a57a8,0x51030817,0x28920718,0xf38718b,
+    0xe5134114,0x39961758,0xe1ce4ce,0x728e3855,
+    0x5ce0d92d,0xc204e1ce,0x81c61440,0x1c62ca24,
+    0xd04503ce,0x85d63944,0x75338e65,0x5d86075e,
+    0x89e69647,0x75e76576,
+]);
+Lev2TParametricDescription.prototype.offsetIncrs5 = /*3 bits per value */ new Int32Array([
+    0x10000000,0xc00000,0x60061,0x400,
+    0x0,0x60000008,0x6b003080,0xdb6ab6db,
+    0x2db6,0x800400,0x49245240,0x11482412,
+    0x104904,0x40020000,0x92292000,0xa4b25924,
+    0x9649658,0xd80c000,0xdb0c001b,0x80db6d86,
+    0x6db01b6d,0xc0600003,0x86000d86,0x6db6c36d,
+    0xddadb6ed,0x300001b6,0x6c360,0xe37236e4,
+    0x46db6236,0xdb6c,0x361b018,0xb91b7200,
+    0x6dbb1b71,0x6db763,0x20100820,0x61248001,
+    0x92492490,0x24820004,0x8041000,0x92400090,
+    0x24924830,0x555b6a49,0x2080012,0x20004804,
+    0x49252449,0x84112492,0x4000928,0x240201,
+    0x92922490,0x58924924,0x49456,0x120d8082,
+    0x6da4800,0x69249249,0x249a01b,0x6c04100,
+    0x6d240009,0x92492483,0x24d5adb4,0x60208001,
+    0x92000483,0x24925236,0x6846da49,0x10400092,
+    0x241b0,0x49291b49,0x636d2492,0x92494935,
+    0x24924924,0x49249249,0x92492492,0x24924924,
+    0x49249249,0x92492492,0x24924924,0x49249249,
+    0x92492492,0x24924924,0x49249249,0x92492492,
+    0x24924924,0x49249249,0x92492492,0x24924924,
+    0x49249249,0x92492492,0x24924924,0x49249249,
+    0x92492492,0x24924924,0x49249249,0x92492492,
+    0x24924924,0x49249249,0x92492492,0x24924924,
+    0x49249249,0x92492492,0x24924924,0x49249249,
+    0x92492492,0x24924924,0x49249249,0x92492492,
+    0x24924924,0x49249249,0x92492492,0x24924924,
+    0x49249249,0x92492492,0x24924924,0x49249249,
+    0x92492492,0x24924924,0x49249249,0x92492492,
+    0x24924924,0x49249249,0x92492492,0x24924924,
+    0x49249249,0x92492492,0x24924924,0x49249249,
+    0x92492492,0x24924924,0x49249249,0x92492492,
+    0x24924924,0x49249249,0x92492492,0x24924924,
+    0x49249249,0x92492492,0x24924924,
+]);
+
+class Lev1TParametricDescription extends ParametricDescription {
+    /**
+     * @param {number} absState
+     * @param {number} position
+     * @param {number} vector
+     * @returns {number}
+    */
+    transition(absState, position, vector) {
+        let state = Math.floor(absState / (this.w + 1));
+        let offset = absState % (this.w + 1);
+
+        if (position === this.w) {
+            if (state < 2) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 2) + state;
+                offset += this.unpack(this.offsetIncrs0, loc, 1);
+                state = this.unpack(this.toStates0, loc, 2) - 1;
+            }
+        } else if (position === this.w - 1) {
+            if (state < 3) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 3) + state;
+                offset += this.unpack(this.offsetIncrs1, loc, 1);
+                state = this.unpack(this.toStates1, loc, 2) - 1;
+            }
+        } else if (position === this.w - 2) {
+            if (state < 6) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 6) + state;
+                offset += this.unpack(this.offsetIncrs2, loc, 2);
+                state = this.unpack(this.toStates2, loc, 3) - 1;
+            }
+        } else {
+            if (state < 6) { // eslint-disable-line no-lonely-if
+                const loc = Math.imul(vector, 6) + state;
+                offset += this.unpack(this.offsetIncrs3, loc, 2);
+                state = this.unpack(this.toStates3, loc, 3) - 1;
+            }
+        }
+
+        if (state === -1) {
+            // null state
+            return -1;
+        } else {
+            // translate back to abs
+            return Math.imul(state, this.w + 1) + offset;
+        }
+    }
+
+    // state map
+    //   0 -> [(0, 0)]
+    //   1 -> [(0, 1)]
+    //   2 -> [(0, 1), (1, 1)]
+    //   3 -> [(0, 1), (1, 1), (2, 1)]
+    //   4 -> [(0, 1), (2, 1)]
+    //   5 -> [t(0, 1), (0, 1), (1, 1), (2, 1)]
+
+
+    /** @param {number} w - length of word being checked */
+    constructor(w) {
+        super(w, 1, new Int32Array([0,1,0,-1,-1,-1]));
+    }
+}
+
+Lev1TParametricDescription.prototype.toStates0 = /*2 bits per value */ new Int32Array([
+    0x2,
+]);
+Lev1TParametricDescription.prototype.offsetIncrs0 = /*1 bits per value */ new Int32Array([
+    0x0,
+]);
+
+Lev1TParametricDescription.prototype.toStates1 = /*2 bits per value */ new Int32Array([
+    0xa43,
+]);
+Lev1TParametricDescription.prototype.offsetIncrs1 = /*1 bits per value */ new Int32Array([
+    0x38,
+]);
+
+Lev1TParametricDescription.prototype.toStates2 = /*3 bits per value */ new Int32Array([
+    0x12180003,0xb45a4914,0x69,
+]);
+Lev1TParametricDescription.prototype.offsetIncrs2 = /*2 bits per value */ new Int32Array([
+    0x558a0000,0x5555,
+]);
+
+Lev1TParametricDescription.prototype.toStates3 = /*3 bits per value */ new Int32Array([
+    0x900c0003,0xa1904864,0x45a49169,0x5a6d196a,
+    0x9634,
+]);
+Lev1TParametricDescription.prototype.offsetIncrs3 = /*2 bits per value */ new Int32Array([
+    0xa0fc0000,0x5555ba08,0x55555555,
+]);
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 78dc0b8e2f9..436d36d899e 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -206,7 +206,7 @@ fn init_logging(early_dcx: &EarlyDiagCtxt) {
         .with_verbose_exit(true)
         .with_verbose_entry(true)
         .with_indent_amount(2);
-    #[cfg(all(parallel_compiler, debug_assertions))]
+    #[cfg(debug_assertions)]
     let layer = layer.with_thread_ids(true).with_thread_names(true);
 
     use tracing_subscriber::layer::SubscriberExt;
diff --git a/src/tools/bump-stage0/Cargo.toml b/src/tools/bump-stage0/Cargo.toml
index de5d821133d..6ee7a831839 100644
--- a/src/tools/bump-stage0/Cargo.toml
+++ b/src/tools/bump-stage0/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 
 [dependencies]
 anyhow = "1.0.34"
-build_helper = { path = "../build_helper" }
+build_helper = { path = "../../build_helper" }
 curl = "0.4.38"
 indexmap = { version = "2.0.0", features = ["serde"] }
 serde = { version = "1.0.125", features = ["derive"] }
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 161fa630ed4..dd3124ee9a3 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6071,6 +6071,7 @@ Released 2018-09-13
 [`unnecessary_literal_bound`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_bound
 [`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap
 [`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_on_constructor
+[`unnecessary_map_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or
 [`unnecessary_min_or_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_min_or_max
 [`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
 [`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation
diff --git a/src/tools/clippy/clippy_dev/src/setup/vscode.rs b/src/tools/clippy/clippy_dev/src/setup/vscode.rs
index 204f4af2cf1..a37c873eed4 100644
--- a/src/tools/clippy/clippy_dev/src/setup/vscode.rs
+++ b/src/tools/clippy/clippy_dev/src/setup/vscode.rs
@@ -84,7 +84,7 @@ fn delete_vs_task_file(path: &Path) -> bool {
 /// It may fail silently.
 fn try_delete_vs_directory_if_empty() {
     let path = Path::new(VSCODE_DIR);
-    if path.read_dir().map_or(false, |mut iter| iter.next().is_none()) {
+    if path.read_dir().is_ok_and(|mut iter| iter.next().is_none()) {
         // The directory is empty. We just try to delete it but allow a silence
         // fail as an empty `.vscode` directory is still valid
         let _silence_result = fs::remove_dir(path);
diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
index dc5a6857089..e21853598c3 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -16,7 +16,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
             return;
         }
         if let Some(lint_list) = &attr.meta_item_list() {
-            if attr.ident().map_or(false, |ident| is_lint_level(ident.name, attr.id)) {
+            if attr.ident().is_some_and(|ident| is_lint_level(ident.name, attr.id)) {
                 for lint in lint_list {
                     match item.kind {
                         ItemKind::Use(..) => {
diff --git a/src/tools/clippy/clippy_lints/src/attrs/utils.rs b/src/tools/clippy/clippy_lints/src/attrs/utils.rs
index 9b10ae83651..3bb02688bf2 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/utils.rs
@@ -50,7 +50,7 @@ fn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_
         block
             .expr
             .as_ref()
-            .map_or(false, |e| is_relevant_expr(cx, typeck_results, e)),
+            .is_some_and(|e| is_relevant_expr(cx, typeck_results, e)),
         |stmt| match &stmt.kind {
             StmtKind::Let(_) => true,
             StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),
@@ -60,7 +60,7 @@ fn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_
 }
 
 fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, expr: &Expr<'_>) -> bool {
-    if macro_backtrace(expr.span).last().map_or(false, |macro_call| {
+    if macro_backtrace(expr.span).last().is_some_and(|macro_call| {
         is_panic(cx, macro_call.def_id) || cx.tcx.item_name(macro_call.def_id) == sym::unreachable
     }) {
         return false;
diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
index db5792188dd..7d89195eeca 100644
--- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
+++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
@@ -60,8 +60,8 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
                 trait_id,
             )
         })
-        .map_or(false, |assoc_item| {
-            let proj = Ty::new_projection_from_args(cx.tcx, assoc_item.def_id, cx.tcx.mk_args_trait(ty, []));
+        .is_some_and(|assoc_item| {
+            let proj = Ty::new_projection(cx.tcx, assoc_item.def_id, cx.tcx.mk_args_trait(ty, []));
             let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj);
 
             nty.is_bool()
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 26a20bc99a0..896bd5fd03d 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -667,5 +667,5 @@ fn implements_ord(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     let ty = cx.typeck_results().expr_ty(expr);
     cx.tcx
         .get_diagnostic_item(sym::Ord)
-        .map_or(false, |id| implements_trait(cx, ty, id, &[]))
+        .is_some_and(|id| implements_trait(cx, ty, id, &[]))
 }
diff --git a/src/tools/clippy/clippy_lints/src/box_default.rs b/src/tools/clippy/clippy_lints/src/box_default.rs
index bf1d077fec2..a1ca23e65ff 100644
--- a/src/tools/clippy/clippy_lints/src/box_default.rs
+++ b/src/tools/clippy/clippy_lints/src/box_default.rs
@@ -45,7 +45,7 @@ impl LateLintPass<'_> for BoxDefault {
             // And that method is `new`
             && seg.ident.name == sym::new
             // And the call is that of a `Box` method
-            && path_def_id(cx, ty).map_or(false, |id| Some(id) == cx.tcx.lang_items().owned_box())
+            && path_def_id(cx, ty).is_some_and(|id| Some(id) == cx.tcx.lang_items().owned_box())
             // And the single argument to the call is another function call
             // This is the `T::default()` (or default equivalent) of `Box::new(T::default())`
             && let ExprKind::Call(arg_path, _) = arg.kind
@@ -83,9 +83,9 @@ fn is_plain_default(cx: &LateContext<'_>, arg_path: &Expr<'_>) -> bool {
 }
 
 fn is_local_vec_expn(cx: &LateContext<'_>, expr: &Expr<'_>, ref_expr: &Expr<'_>) -> bool {
-    macro_backtrace(expr.span).next().map_or(false, |call| {
-        cx.tcx.is_diagnostic_item(sym::vec_macro, call.def_id) && call.span.eq_ctxt(ref_expr.span)
-    })
+    macro_backtrace(expr.span)
+        .next()
+        .is_some_and(|call| cx.tcx.is_diagnostic_item(sym::vec_macro, call.def_id) && call.span.eq_ctxt(ref_expr.span))
 }
 
 #[derive(Default)]
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index abd80abffe6..332e897def7 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -159,8 +159,7 @@ pub(super) fn check<'tcx>(
         // The same is true if the expression encompassing the cast expression is a unary
         // expression or an addressof expression.
         let needs_block = matches!(cast_expr.kind, ExprKind::Unary(..) | ExprKind::AddrOf(..))
-            || get_parent_expr(cx, expr)
-                .map_or(false, |e| matches!(e.kind, ExprKind::Unary(..) | ExprKind::AddrOf(..)));
+            || get_parent_expr(cx, expr).is_some_and(|e| matches!(e.kind, ExprKind::Unary(..) | ExprKind::AddrOf(..)));
 
         span_lint_and_sugg(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/comparison_chain.rs b/src/tools/clippy/clippy_lints/src/comparison_chain.rs
index b9baf9af248..c85e3500ebd 100644
--- a/src/tools/clippy/clippy_lints/src/comparison_chain.rs
+++ b/src/tools/clippy/clippy_lints/src/comparison_chain.rs
@@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for ComparisonChain {
                 let is_ord = cx
                     .tcx
                     .get_diagnostic_item(sym::Ord)
-                    .map_or(false, |id| implements_trait(cx, ty, id, &[]));
+                    .is_some_and(|id| implements_trait(cx, ty, id, &[]));
 
                 if !is_ord {
                     return;
diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs
index c4afdc757d8..3ecd36d3711 100644
--- a/src/tools/clippy/clippy_lints/src/copies.rs
+++ b/src/tools/clippy/clippy_lints/src/copies.rs
@@ -345,7 +345,7 @@ fn eq_binding_names(s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool {
         let mut i = 0usize;
         let mut res = true;
         l.pat.each_binding_or_first(&mut |_, _, _, name| {
-            if names.get(i).map_or(false, |&(_, n)| n == name.name) {
+            if names.get(i).is_some_and(|&(_, n)| n == name.name) {
                 i += 1;
             } else {
                 res = false;
@@ -389,12 +389,10 @@ fn eq_stmts(
         let new_bindings = &moved_bindings[old_count..];
         blocks
             .iter()
-            .all(|b| get_stmt(b).map_or(false, |s| eq_binding_names(s, new_bindings)))
+            .all(|b| get_stmt(b).is_some_and(|s| eq_binding_names(s, new_bindings)))
     } else {
         true
-    }) && blocks
-        .iter()
-        .all(|b| get_stmt(b).map_or(false, |s| eq.eq_stmt(s, stmt)))
+    }) && blocks.iter().all(|b| get_stmt(b).is_some_and(|s| eq.eq_stmt(s, stmt)))
 }
 
 #[expect(clippy::too_many_lines)]
@@ -451,9 +449,7 @@ fn scan_block_for_eq<'tcx>(
     //     x + 50
     let expr_hash_eq = if let Some(e) = block.expr {
         let hash = hash_expr(cx, e);
-        blocks
-            .iter()
-            .all(|b| b.expr.map_or(false, |e| hash_expr(cx, e) == hash))
+        blocks.iter().all(|b| b.expr.is_some_and(|e| hash_expr(cx, e) == hash))
     } else {
         blocks.iter().all(|b| b.expr.is_none())
     };
@@ -514,7 +510,7 @@ fn scan_block_for_eq<'tcx>(
         });
     if let Some(e) = block.expr {
         for block in blocks {
-            if block.expr.map_or(false, |expr| !eq.eq_expr(expr, e)) {
+            if block.expr.is_some_and(|expr| !eq.eq_expr(expr, e)) {
                 moved_locals.truncate(moved_locals_at_start);
                 return BlockEq {
                     start_end_eq,
@@ -533,7 +529,7 @@ fn scan_block_for_eq<'tcx>(
 }
 
 fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbol)], if_expr: &Expr<'_>) -> bool {
-    get_enclosing_block(cx, if_expr.hir_id).map_or(false, |block| {
+    get_enclosing_block(cx, if_expr.hir_id).is_some_and(|block| {
         let ignore_span = block.span.shrink_to_lo().to(if_expr.span);
 
         symbols
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index edb52851e0c..dff60f76b74 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -481,6 +481,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::methods::UNNECESSARY_JOIN_INFO,
     crate::methods::UNNECESSARY_LAZY_EVALUATIONS_INFO,
     crate::methods::UNNECESSARY_LITERAL_UNWRAP_INFO,
+    crate::methods::UNNECESSARY_MAP_OR_INFO,
     crate::methods::UNNECESSARY_MIN_OR_MAX_INFO,
     crate::methods::UNNECESSARY_RESULT_MAP_OR_ELSE_INFO,
     crate::methods::UNNECESSARY_SORT_BY_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
index 4808c372754..ef6b141920d 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -253,6 +253,6 @@ impl<'tcx> From<Ty<'tcx>> for ExplicitTyBound {
 
 impl<'tcx> From<Option<Ty<'tcx>>> for ExplicitTyBound {
     fn from(v: Option<Ty<'tcx>>) -> Self {
-        Self(v.map_or(false, Ty::is_numeric))
+        Self(v.is_some_and(Ty::is_numeric))
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 2b6bfafe695..767dda552bc 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -81,7 +81,7 @@ fn is_path_self(e: &Expr<'_>) -> bool {
 fn contains_trait_object(ty: Ty<'_>) -> bool {
     match ty.kind() {
         ty::Ref(_, ty, _) => contains_trait_object(*ty),
-        ty::Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object),
+        ty::Adt(def, args) => def.is_box() && args[0].as_type().is_some_and(contains_trait_object),
         ty::Dynamic(..) => true,
         _ => false,
     }
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index e569c4dc786..0db6a822ec0 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -327,7 +327,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
     // there's a Copy impl for any instance of the adt.
     if !is_copy(cx, ty) {
         if ty_subs.non_erasable_generics().next().is_some() {
-            let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).map_or(false, |impls| {
+            let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).is_some_and(|impls| {
                 impls.iter().any(|&id| {
                     matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)
                                         if ty_adt.did() == adt.did())
diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
index c9173030a55..40377dd841e 100644
--- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
@@ -47,7 +47,7 @@ pub fn check(
         ),
         _ => (),
     }
-    if !headers.panics && panic_info.map_or(false, |el| !el.1) {
+    if !headers.panics && panic_info.is_some_and(|el| !el.1) {
         span_lint_and_note(
             cx,
             MISSING_PANICS_DOC,
diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
index c7dd7292a14..55afdbf22e1 100644
--- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
@@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
                             MEM_FORGET,
                             Cow::Owned(format!(
                                 "usage of `mem::forget` on {}",
-                                if arg_ty.ty_adt_def().map_or(false, |def| def.has_dtor(cx.tcx)) {
+                                if arg_ty.ty_adt_def().is_some_and(|def| def.has_dtor(cx.tcx)) {
                                     "`Drop` type"
                                 } else {
                                     "type with `Drop` fields"
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index de10b7bf533..6c87a05ace3 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -196,7 +196,7 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
             {
                 span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
                     if let Some(mut snippet) = snippet_opt(cx, callee.span) {
-                        if path_to_local(callee).map_or(false, |l| {
+                        if path_to_local(callee).is_some_and(|l| {
                             // FIXME: Do we really need this `local_used_in` check?
                             // Isn't it checking something like... `callee(callee)`?
                             // If somehow this check is needed, add some test for it,
diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
index c2b40ae01d4..4986a311eba 100644
--- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
@@ -87,7 +87,7 @@ fn raw_ptr_arg(cx: &LateContext<'_>, arg: &hir::Param<'_>) -> Option<HirId> {
 }
 
 fn check_arg(cx: &LateContext<'_>, raw_ptrs: &HirIdSet, arg: &hir::Expr<'_>) {
-    if path_to_local(arg).map_or(false, |id| raw_ptrs.contains(&id)) {
+    if path_to_local(arg).is_some_and(|id| raw_ptrs.contains(&id)) {
         span_lint(
             cx,
             NOT_UNSAFE_PTR_ARG_DEREF,
diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs
index 48874d6064b..d3aade31f14 100644
--- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs
@@ -171,13 +171,13 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
             if let ExprKind::Path(ref qpath) = path.kind {
                 cx.qpath_res(qpath, path.hir_id)
                     .opt_def_id()
-                    .map_or(false, |id| cx.tcx.is_diagnostic_item(sym::iter_repeat, id))
+                    .is_some_and(|id| cx.tcx.is_diagnostic_item(sym::iter_repeat, id))
                     .into()
             } else {
                 Finite
             }
         },
-        ExprKind::Struct(..) => higher::Range::hir(expr).map_or(false, |r| r.end.is_none()).into(),
+        ExprKind::Struct(..) => higher::Range::hir(expr).is_some_and(|r| r.end.is_none()).into(),
         _ => Finite,
     }
 }
@@ -228,9 +228,7 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
                 let not_double_ended = cx
                     .tcx
                     .get_diagnostic_item(sym::DoubleEndedIterator)
-                    .map_or(false, |id| {
-                        !implements_trait(cx, cx.typeck_results().expr_ty(receiver), id, &[])
-                    });
+                    .is_some_and(|id| !implements_trait(cx, cx.typeck_results().expr_ty(receiver), id, &[]));
                 if not_double_ended {
                     return is_infinite(cx, receiver);
                 }
diff --git a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
index dd90e2a6e94..6363f717a5c 100644
--- a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
+++ b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
@@ -309,8 +309,8 @@ fn check_enum_start(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>
     let item_name_chars = item_name.chars().count();
 
     if count_match_start(item_name, name).char_count == item_name_chars
-        && name.chars().nth(item_name_chars).map_or(false, |c| !c.is_lowercase())
-        && name.chars().nth(item_name_chars + 1).map_or(false, |c| !c.is_numeric())
+        && name.chars().nth(item_name_chars).is_some_and(|c| !c.is_lowercase())
+        && name.chars().nth(item_name_chars + 1).is_some_and(|c| !c.is_numeric())
     {
         span_lint_hir(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
index b19b348c743..25105817ad9 100644
--- a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
@@ -75,7 +75,7 @@ fn check_sig(cx: &LateContext<'_>, name: Symbol, sig: &FnSig<'_>, fn_id: LocalDe
         if cx
             .tcx
             .get_diagnostic_item(sym::Iterator)
-            .map_or(false, |iter_id| !implements_trait(cx, ret_ty, iter_id, &[]))
+            .is_some_and(|iter_id| !implements_trait(cx, ret_ty, iter_id, &[]))
         {
             span_lint(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
index aa8b4d88d2f..c5a2760234f 100644
--- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
@@ -56,7 +56,8 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
             && !item.span.from_expansion()
             && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
             && let ty::Array(element_type, cst) = ty.kind()
-            && let Ok((_, ty::ValTree::Leaf(element_count))) = cst.eval_valtree(cx.tcx, ParamEnv::empty(), item.span)
+            && let Some((ty::ValTree::Leaf(element_count), _)) = cx.tcx
+                .try_normalize_erasing_regions(ParamEnv::empty(), *cst).unwrap_or(*cst).try_to_valtree()
             && let element_count = element_count.to_target_usize(cx.tcx)
             && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
             && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)
diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs
index ab3d19f89c3..4f22931a4de 100644
--- a/src/tools/clippy/clippy_lints/src/large_include_file.rs
+++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs
@@ -94,6 +94,8 @@ impl LateLintPass<'_> for LargeIncludeFile {
             // Currently, rustc limits the usage of macro at the top-level of attributes,
             // so we don't need to recurse into each level.
             && let AttrKind::Normal(ref normal) = attr.kind
+            && let Some(doc) = attr.doc_str()
+            && doc.as_str().len() as u64 > self.max_file_size
             && let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args
             && !attr.span.contains(meta.span)
             // Since the `include_str` is already expanded at this point, we can only take the
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index b7887ef76a5..3ea758e176f 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -622,7 +622,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 
     let ty = &cx.typeck_results().expr_ty(expr).peel_refs();
     match ty.kind() {
-        ty::Dynamic(tt, ..) => tt.principal().map_or(false, |principal| {
+        ty::Dynamic(tt, ..) => tt.principal().is_some_and(|principal| {
             let is_empty = sym!(is_empty);
             cx.tcx
                 .associated_items(principal.def_id())
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index d55be2b036a..ce0e1a24a7b 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -737,7 +737,7 @@ fn elision_suggestions(
     suggestions.extend(
         usages
             .iter()
-            .filter(|usage| named_lifetime(usage).map_or(false, |id| elidable_lts.contains(&id)))
+            .filter(|usage| named_lifetime(usage).is_some_and(|id| elidable_lts.contains(&id)))
             .map(|usage| {
                 match cx.tcx.parent_hir_node(usage.hir_id) {
                     Node::Ty(Ty {
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs
index bfe2e68b5d1..1721f569541 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs
@@ -58,7 +58,7 @@ pub(super) fn check<'tcx>(
             .tcx
             .lang_items()
             .copy_trait()
-            .map_or(false, |id| implements_trait(cx, ty, id, &[]))
+            .is_some_and(|id| implements_trait(cx, ty, id, &[]))
         {
             snippet.push_str(
                 &format!(
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index af089451759..701567a7d84 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -416,7 +416,7 @@ fn get_assignments<'a, 'tcx>(
         .chain(*expr)
         .filter(move |e| {
             if let ExprKind::AssignOp(_, place, _) = e.kind {
-                path_to_local(place).map_or(false, |id| {
+                path_to_local(place).is_some_and(|id| {
                     !loop_counters
                         .iter()
                         // skip the first item which should be `StartKind::Range`
diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
index 094b1947324..39e5e140b7a 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
@@ -126,7 +126,7 @@ impl BreakAfterExprVisitor {
             break_after_expr: false,
         };
 
-        get_enclosing_block(cx, hir_id).map_or(false, |block| {
+        get_enclosing_block(cx, hir_id).is_some_and(|block| {
             visitor.visit_block(block);
             visitor.break_after_expr
         })
diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
index d255fea3af2..951ebc9caef 100644
--- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
@@ -50,7 +50,7 @@ pub(super) fn check<'tcx>(
             .tcx
             .lang_items()
             .clone_trait()
-            .map_or(false, |id| implements_trait(cx, ty, id, &[]))
+            .is_some_and(|id| implements_trait(cx, ty, id, &[]))
     {
         // Make sure that the push does not involve possibly mutating values
         match pushed_item.kind {
diff --git a/src/tools/clippy/clippy_lints/src/loops/utils.rs b/src/tools/clippy/clippy_lints/src/loops/utils.rs
index c4c504e1ae4..51fde5288ab 100644
--- a/src/tools/clippy/clippy_lints/src/loops/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/utils.rs
@@ -256,9 +256,10 @@ fn is_conditional(expr: &Expr<'_>) -> bool {
 /// If `arg` was the argument to a `for` loop, return the "cleanest" way of writing the
 /// actual `Iterator` that the loop uses.
 pub(super) fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applic_ref: &mut Applicability) -> String {
-    let impls_iterator = cx.tcx.get_diagnostic_item(sym::Iterator).map_or(false, |id| {
-        implements_trait(cx, cx.typeck_results().expr_ty(arg), id, &[])
-    });
+    let impls_iterator = cx
+        .tcx
+        .get_diagnostic_item(sym::Iterator)
+        .is_some_and(|id| implements_trait(cx, cx.typeck_results().expr_ty(arg), id, &[]));
     if impls_iterator {
         format!(
             "{}",
diff --git a/src/tools/clippy/clippy_lints/src/manual_clamp.rs b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
index fd66cacdfe9..016ec7320a6 100644
--- a/src/tools/clippy/clippy_lints/src/manual_clamp.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
@@ -226,7 +226,7 @@ impl TypeClampability {
         } else if cx
             .tcx
             .get_diagnostic_item(sym::Ord)
-            .map_or(false, |id| implements_trait(cx, ty, id, &[]))
+            .is_some_and(|id| implements_trait(cx, ty, id, &[]))
         {
             Some(TypeClampability::Ord)
         } else {
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index 828c5a3f6ff..3f401eff6bd 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -162,9 +162,9 @@ fn eq_pattern_length<'tcx>(cx: &LateContext<'tcx>, pattern: &Expr<'_>, expr: &'t
         ..
     }) = expr.kind
     {
-        constant_length(cx, pattern).map_or(false, |length| *n == length)
+        constant_length(cx, pattern).is_some_and(|length| *n == length)
     } else {
-        len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg))
+        len_arg(cx, expr).is_some_and(|arg| eq_expr_value(cx, pattern, arg))
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
index 6d62b530ae7..47472ab831f 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
@@ -74,7 +74,7 @@ where
         && b0 != b1
         && (first_guard.is_none() || iter.len() == 0)
         && first_attrs.is_empty()
-        && iter.all(|arm| find_bool_lit(&arm.2.kind).map_or(false, |b| b == b0) && arm.3.is_none() && arm.0.is_empty())
+        && iter.all(|arm| find_bool_lit(&arm.2.kind).is_some_and(|b| b == b0) && arm.3.is_none() && arm.0.is_empty())
     {
         if let Some(last_pat) = last_pat_opt {
             if !is_wild(last_pat) {
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
index ca45ed6ea59..264458a86ef 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
@@ -447,7 +447,7 @@ fn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expecte
             .tcx
             .lang_items()
             .get(expected_lang_item)
-            .map_or(false, |expected_id| cx.tcx.parent(id) == expected_id),
+            .is_some_and(|expected_id| cx.tcx.parent(id) == expected_id),
         Item::Diag(expected_ty, expected_variant) => {
             let ty = cx.typeck_results().pat_ty(pat);
 
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 2aea25b5f12..95a4bf6f60d 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -175,7 +175,7 @@ impl<'tcx> Visitor<'tcx> for PatVisitor<'tcx> {
         if matches!(pat.kind, PatKind::Binding(..)) {
             ControlFlow::Break(())
         } else {
-            self.has_enum |= self.typeck.pat_ty(pat).ty_adt_def().map_or(false, AdtDef::is_enum);
+            self.has_enum |= self.typeck.pat_ty(pat).ty_adt_def().is_some_and(AdtDef::is_enum);
             walk_pat(self, pat)
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/matches/try_err.rs b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
index c7e1b70d19e..6c02207af49 100644
--- a/src/tools/clippy/clippy_lints/src/matches/try_err.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
@@ -58,7 +58,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine
                 let span = hygiene::walk_chain(err_arg.span, try_arg.span.ctxt());
                 let mut applicability = Applicability::MachineApplicable;
                 let origin_snippet = snippet_with_applicability(cx, span, "_", &mut applicability);
-                let ret_prefix = if get_parent_expr(cx, expr).map_or(false, |e| matches!(e.kind, ExprKind::Ret(_))) {
+                let ret_prefix = if get_parent_expr(cx, expr).is_some_and(|e| matches!(e.kind, ExprKind::Ret(_))) {
                     "" // already returns
                 } else {
                     "return "
diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
index c288dbdabe9..6dc48c26ba9 100644
--- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
@@ -83,7 +83,7 @@ pub(super) fn check<'tcx>(
             hir::ExprKind::MethodCall(..) => {
                 cx.typeck_results()
                     .type_dependent_def_id(arg.hir_id)
-                    .map_or(false, |method_id| {
+                    .is_some_and(|method_id| {
                         matches!(
                             cx.tcx.fn_sig(method_id).instantiate_identity().output().skip_binder().kind(),
                             ty::Ref(re, ..) if re.is_static()
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
index e697ba656f5..6c1a14fc882 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
@@ -32,9 +32,10 @@ pub(super) fn check<'tcx>(
     filter_arg: &'tcx hir::Expr<'_>,
 ) {
     // lint if caller of `.filter().next()` is an Iterator
-    let recv_impls_iterator = cx.tcx.get_diagnostic_item(sym::Iterator).map_or(false, |id| {
-        implements_trait(cx, cx.typeck_results().expr_ty(recv), id, &[])
-    });
+    let recv_impls_iterator = cx
+        .tcx
+        .get_diagnostic_item(sym::Iterator)
+        .is_some_and(|id| implements_trait(cx, cx.typeck_results().expr_ty(recv), id, &[]));
     if recv_impls_iterator {
         let msg = "called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling \
                    `.find(..)` instead";
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_next_back.rs b/src/tools/clippy/clippy_lints/src/methods/manual_next_back.rs
index 5f3fec53827..9a03559b223 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_next_back.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_next_back.rs
@@ -19,9 +19,7 @@ pub(super) fn check<'tcx>(
     if cx
         .tcx
         .get_diagnostic_item(sym::DoubleEndedIterator)
-        .map_or(false, |double_ended_iterator| {
-            implements_trait(cx, rev_recv_ty, double_ended_iterator, &[])
-        })
+        .is_some_and(|double_ended_iterator| implements_trait(cx, rev_recv_ty, double_ended_iterator, &[]))
         && is_trait_method(cx, rev_call, sym::Iterator)
         && is_trait_method(cx, expr, sym::Iterator)
     {
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs
index 61e74369cb0..098721dc046 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_str_repeat.rs
@@ -36,8 +36,8 @@ fn parse_repeat_arg(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<RepeatKind> {
     } else {
         let ty = cx.typeck_results().expr_ty(e);
         if is_type_lang_item(cx, ty, LangItem::String)
-            || (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, Ty::is_str))
-            || (is_type_diagnostic_item(cx, ty, sym::Cow) && get_ty_param(ty).map_or(false, Ty::is_str))
+            || (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).is_some_and(Ty::is_str))
+            || (is_type_diagnostic_item(cx, ty, sym::Cow) && get_ty_param(ty).is_some_and(Ty::is_str))
         {
             Some(RepeatKind::String)
         } else {
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
index 515d4a11ed5..d5594b21db5 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
@@ -70,7 +70,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_
                                 if ident_eq(name, obj) && method.ident.name == sym::clone
                                 && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id)
                                 && let Some(trait_id) = cx.tcx.trait_of_item(fn_id)
-                                && cx.tcx.lang_items().clone_trait().map_or(false, |id| id == trait_id)
+                                && cx.tcx.lang_items().clone_trait() == Some(trait_id)
                                 // no autoderefs
                                 && !cx.typeck_results().expr_adjustments(obj).iter()
                                     .any(|a| matches!(a.kind, Adjust::Deref(Some(..))))
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index b1809796355..795e041ffd9 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -121,6 +121,7 @@ mod unnecessary_iter_cloned;
 mod unnecessary_join;
 mod unnecessary_lazy_eval;
 mod unnecessary_literal_unwrap;
+mod unnecessary_map_or;
 mod unnecessary_min_or_max;
 mod unnecessary_result_map_or_else;
 mod unnecessary_sort_by;
@@ -4101,6 +4102,33 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
+    /// Converts some constructs mapping an Enum value for equality comparison.
+    ///
+    /// ### Why is this bad?
+    /// Calls such as `opt.map_or(false, |val| val == 5)` are needlessly long and cumbersome,
+    /// and can be reduced to, for example, `opt == Some(5)` assuming `opt` implements `PartialEq`.
+    /// This lint offers readability and conciseness improvements.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// pub fn a(x: Option<i32>) -> bool {
+    ///     x.map_or(false, |n| n == 5)
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// pub fn a(x: Option<i32>) -> bool {
+    ///     x == Some(5)
+    /// }
+    /// ```
+    #[clippy::version = "1.75.0"]
+    pub UNNECESSARY_MAP_OR,
+    style,
+    "reduce unnecessary pattern matching for constructs that implement `PartialEq`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
     /// Checks if an iterator is used to check if a string is ascii.
     ///
     /// ### Why is this bad?
@@ -4417,6 +4445,7 @@ impl_lint_pass!(Methods => [
     NEEDLESS_AS_BYTES,
     MAP_ALL_ANY_IDENTITY,
     MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
+    UNNECESSARY_MAP_OR,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -4950,6 +4979,7 @@ impl Methods {
                     option_map_or_none::check(cx, expr, recv, def, map);
                     manual_ok_or::check(cx, expr, recv, def, map);
                     option_map_or_err_ok::check(cx, expr, recv, def, map);
+                    unnecessary_map_or::check(cx, expr, recv, def, map, &self.msrv);
                 },
                 ("map_or_else", [def, map]) => {
                     result_map_or_else_none::check(cx, expr, recv, def, map);
@@ -5343,7 +5373,7 @@ impl SelfKind {
                 boxed_ty == parent_ty
             } else if is_type_diagnostic_item(cx, ty, sym::Rc) || is_type_diagnostic_item(cx, ty, sym::Arc) {
                 if let ty::Adt(_, args) = ty.kind() {
-                    args.types().next().map_or(false, |t| t == parent_ty)
+                    args.types().next() == Some(parent_ty)
                 } else {
                     false
                 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index 055107068ae..9c41528e647 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -193,7 +193,7 @@ fn check_collect_into_intoiterator<'tcx>(
 
 /// Checks if the given method call matches the expected signature of `([&[mut]] self) -> bool`
 fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool {
-    cx.typeck_results().type_dependent_def_id(call_id).map_or(false, |id| {
+    cx.typeck_results().type_dependent_def_id(call_id).is_some_and(|id| {
         let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_binder();
         sig.inputs().len() == 1 && sig.output().is_bool()
     })
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
index 389e02056b2..998bdee0157 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -45,7 +45,7 @@ pub(super) fn check(
         hir::ExprKind::Path(ref expr_qpath) => {
             cx.qpath_res(expr_qpath, map_arg.hir_id)
                 .opt_def_id()
-                .map_or(false, |fun_def_id| {
+                .is_some_and(|fun_def_id| {
                     cx.tcx.is_diagnostic_item(sym::deref_method, fun_def_id)
                         || cx.tcx.is_diagnostic_item(sym::deref_mut_method, fun_def_id)
                         || deref_aliases
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index b685a466b72..6b39b753885 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -59,9 +59,7 @@ pub(super) fn check<'tcx>(
                 let output_ty = cx.tcx.fn_sig(def_id).instantiate(cx.tcx, args).skip_binder().output();
                 cx.tcx
                     .get_diagnostic_item(sym::Default)
-                    .map_or(false, |default_trait_id| {
-                        implements_trait(cx, output_ty, default_trait_id, &[])
-                    })
+                    .is_some_and(|default_trait_id| implements_trait(cx, output_ty, default_trait_id, &[]))
             } else {
                 false
             }
diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
index a2a7de905ca..1cee28e1986 100644
--- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
@@ -348,7 +348,7 @@ fn parse_iter_usage<'tcx>(
                     && cx
                         .typeck_results()
                         .type_dependent_def_id(e.hir_id)
-                        .map_or(false, |id| is_diag_item_method(cx, id, sym::Option)) =>
+                        .is_some_and(|id| is_diag_item_method(cx, id, sym::Option)) =>
             {
                 (Some(UnwrapKind::Unwrap), e.span)
             },
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
new file mode 100644
index 00000000000..adc27cd437f
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
@@ -0,0 +1,131 @@
+use std::borrow::Cow;
+
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::eager_or_lazy::switch_to_eager_eval;
+use clippy_utils::source::snippet_opt;
+use clippy_utils::sugg::{Sugg, make_binop};
+use clippy_utils::ty::{get_type_diagnostic_name, implements_trait};
+use clippy_utils::visitors::is_local_used;
+use clippy_utils::{is_from_proc_macro, path_to_local_id};
+use rustc_ast::LitKind::Bool;
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind, PatKind};
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::UNNECESSARY_MAP_OR;
+
+pub(super) enum Variant {
+    Ok,
+    Some,
+}
+impl Variant {
+    pub fn variant_name(&self) -> &'static str {
+        match self {
+            Variant::Ok => "Ok",
+            Variant::Some => "Some",
+        }
+    }
+
+    pub fn method_name(&self) -> &'static str {
+        match self {
+            Variant::Ok => "is_ok_and",
+            Variant::Some => "is_some_and",
+        }
+    }
+}
+
+pub(super) fn check<'a>(
+    cx: &LateContext<'a>,
+    expr: &Expr<'a>,
+    recv: &Expr<'_>,
+    def: &Expr<'_>,
+    map: &Expr<'_>,
+    msrv: &Msrv,
+) {
+    let ExprKind::Lit(def_kind) = def.kind else {
+        return;
+    };
+
+    let recv_ty = cx.typeck_results().expr_ty(recv);
+
+    let Bool(def_bool) = def_kind.node else {
+        return;
+    };
+
+    let variant = match get_type_diagnostic_name(cx, recv_ty) {
+        Some(sym::Option) => Variant::Some,
+        Some(sym::Result) => Variant::Ok,
+        Some(_) | None => return,
+    };
+
+    let (sugg, method) = if let ExprKind::Closure(map_closure) = map.kind
+            && let closure_body = cx.tcx.hir().body(map_closure.body)
+            && let closure_body_value = closure_body.value.peel_blocks()
+            && let ExprKind::Binary(op, l, r) = closure_body_value.kind
+            && let Some(param) = closure_body.params.first()
+            && let PatKind::Binding(_, hir_id, _, _) = param.pat.kind
+            // checking that map_or is one of the following:
+            // .map_or(false, |x| x == y)
+            // .map_or(false, |x| y == x) - swapped comparison
+            // .map_or(true, |x| x != y)
+            // .map_or(true, |x| y != x) - swapped comparison
+            && ((BinOpKind::Eq == op.node && !def_bool) || (BinOpKind::Ne == op.node && def_bool))
+            && let non_binding_location = if path_to_local_id(l, hir_id) { r } else { l }
+            && switch_to_eager_eval(cx, non_binding_location)
+            // xor, because if its both then thats a strange edge case and
+            // we can just ignore it, since by default clippy will error on this
+            && (path_to_local_id(l, hir_id) ^ path_to_local_id(r, hir_id))
+            && !is_local_used(cx, non_binding_location, hir_id)
+            && let typeck_results = cx.typeck_results()
+            && typeck_results.expr_ty(l) == typeck_results.expr_ty(r)
+            && let Some(partial_eq) = cx.tcx.get_diagnostic_item(sym::PartialEq)
+            && implements_trait(cx, recv_ty, partial_eq, &[recv_ty.into()])
+    {
+        let wrap = variant.variant_name();
+
+        // we may need to add parens around the suggestion
+        // in case the parent expression has additional method calls,
+        // since for example `Some(5).map_or(false, |x| x == 5).then(|| 1)`
+        // being converted to `Some(5) == Some(5).then(|| 1)` isnt
+        // the same thing
+
+        let inner_non_binding = Sugg::NonParen(Cow::Owned(format!(
+            "{wrap}({})",
+            Sugg::hir(cx, non_binding_location, "")
+        )));
+
+        let binop = make_binop(op.node, &Sugg::hir(cx, recv, ".."), &inner_non_binding)
+            .maybe_par()
+            .into_string();
+
+        (binop, "a standard comparison")
+    } else if !def_bool
+        && msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND)
+        && let Some(recv_callsite) = snippet_opt(cx, recv.span.source_callsite())
+        && let Some(span_callsite) = snippet_opt(cx, map.span.source_callsite())
+    {
+        let suggested_name = variant.method_name();
+        (
+            format!("{recv_callsite}.{suggested_name}({span_callsite})",),
+            suggested_name,
+        )
+    } else {
+        return;
+    };
+
+    if is_from_proc_macro(cx, expr) {
+        return;
+    }
+
+    span_lint_and_sugg(
+        cx,
+        UNNECESSARY_MAP_OR,
+        expr.span,
+        "this `map_or` is redundant",
+        format!("use {method} instead"),
+        sugg,
+        Applicability::MaybeIncorrect,
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
index 6911da69b94..603916e06c9 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
@@ -166,9 +166,10 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp
             },
         )) = &left_expr.kind
             && left_name == left_ident
-            && cx.tcx.get_diagnostic_item(sym::Ord).map_or(false, |id| {
-                implements_trait(cx, cx.typeck_results().expr_ty(left_expr), id, &[])
-            })
+            && cx
+                .tcx
+                .get_diagnostic_item(sym::Ord)
+                .is_some_and(|id| implements_trait(cx, cx.typeck_results().expr_ty(left_expr), id, &[]))
         {
             return Some(LintTrigger::Sort(SortDetection { vec_name }));
         }
diff --git a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
index c309e778116..82313257e5c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
@@ -124,7 +124,7 @@ fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
                         && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id)
                         && let Some(trait_id) = cx.tcx.trait_of_item(fn_id)
                         // We check it's the `Clone` trait.
-                        && cx.tcx.lang_items().clone_trait().map_or(false, |id| id == trait_id)
+                        && cx.tcx.lang_items().clone_trait().is_some_and(|id| id == trait_id)
                         // no autoderefs
                         && !cx.typeck_results().expr_adjustments(obj).iter()
                             .any(|a| matches!(a.kind, Adjust::Deref(Some(..))))
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
index 4cba13a05c2..37d7427f9a5 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
@@ -427,7 +427,7 @@ impl MiscEarlyLints {
         // See <https://github.com/rust-lang/rust-clippy/issues/4507> for a regression.
         // FIXME: Find a better way to detect those cases.
         let lit_snip = match snippet_opt(cx, span) {
-            Some(snip) if snip.chars().next().map_or(false, |c| c.is_ascii_digit()) => snip,
+            Some(snip) if snip.chars().next().is_some_and(|c| c.is_ascii_digit()) => snip,
             _ => return,
         };
 
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
index f7fa31d83aa..c1424b9f1dc 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -134,9 +134,11 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
     }
 
     fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'_>) {
-        if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| {
-            local_def_id == cx.tcx.hir().body_owner_def_id(body.id())
-        }) {
+        if self
+            .possible_borrowers
+            .last()
+            .is_some_and(|&(local_def_id, _)| local_def_id == cx.tcx.hir().body_owner_def_id(body.id()))
+        {
             self.possible_borrowers.pop();
         }
     }
@@ -232,7 +234,7 @@ fn needless_borrow_count<'tcx>(
     let mut check_reference_and_referent = |reference: &Expr<'tcx>, referent: &Expr<'tcx>| {
         if let ExprKind::Field(base, _) = &referent.kind {
             let base_ty = cx.typeck_results().expr_ty(base);
-            if drop_trait_def_id.map_or(false, |id| implements_trait(cx, base_ty, id, &[])) {
+            if drop_trait_def_id.is_some_and(|id| implements_trait(cx, base_ty, id, &[])) {
                 return false;
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/needless_continue.rs b/src/tools/clippy/clippy_lints/src/needless_continue.rs
index c4836772933..c48232f9905 100644
--- a/src/tools/clippy/clippy_lints/src/needless_continue.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_continue.rs
@@ -153,7 +153,7 @@ fn needless_continue_in_else(else_expr: &ast::Expr, label: Option<&ast::Label>)
 }
 
 fn is_first_block_stmt_continue(block: &ast::Block, label: Option<&ast::Label>) -> bool {
-    block.stmts.first().map_or(false, |stmt| match stmt.kind {
+    block.stmts.first().is_some_and(|stmt| match stmt.kind {
         ast::StmtKind::Semi(ref e) | ast::StmtKind::Expr(ref e) => {
             if let ast::ExprKind::Continue(ref l) = e.kind {
                 compare_labels(label, l.as_ref())
@@ -390,7 +390,7 @@ fn check_and_warn(cx: &EarlyContext<'_>, expr: &ast::Expr) {
 #[must_use]
 fn erode_from_back(s: &str) -> String {
     let mut ret = s.to_string();
-    while ret.pop().map_or(false, |c| c != '}') {}
+    while ret.pop().is_some_and(|c| c != '}') {}
     while let Some(c) = ret.pop() {
         if !c.is_whitespace() {
             ret.push(c);
diff --git a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
index a13391a5945..83f7d931969 100644
--- a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
+++ b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
@@ -88,7 +88,7 @@ fn is_offending_macro(cx: &EarlyContext<'_>, span: Span, mac_braces: &MacroBrace
             || span
                 .macro_backtrace()
                 .last()
-                .map_or(false, |e| e.macro_def_id.map_or(false, DefId::is_local))
+                .is_some_and(|e| e.macro_def_id.is_some_and(DefId::is_local))
     };
     let span_call_site = span.ctxt().outer_expn_data().call_site;
     if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span.ctxt().outer_expn_data().kind
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 372128ac16f..13b3d240700 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
@@ -290,7 +290,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
                     Some((Node::Expr(parent), child_id)) => match parent.kind {
                         // Recursive call. Track which index the parameter is used in.
                         ExprKind::Call(callee, args)
-                            if path_def_id(cx, callee).map_or(false, |id| {
+                            if path_def_id(cx, callee).is_some_and(|id| {
                                 id == param.fn_id && has_matching_args(param.fn_kind, typeck.node_args(callee.hir_id))
                             }) =>
                         {
@@ -300,7 +300,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
                             return;
                         },
                         ExprKind::MethodCall(_, receiver, args, _)
-                            if typeck.type_dependent_def_id(parent.hir_id).map_or(false, |id| {
+                            if typeck.type_dependent_def_id(parent.hir_id).is_some_and(|id| {
                                 id == param.fn_id && has_matching_args(param.fn_kind, typeck.node_args(parent.hir_id))
                             }) =>
                         {
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index 8b9f899d82d..65ef56fd211 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -325,7 +325,7 @@ impl ArithmeticSideEffects {
     fn should_skip_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) -> bool {
         is_lint_allowed(cx, ARITHMETIC_SIDE_EFFECTS, expr.hir_id)
             || self.expr_span.is_some()
-            || self.const_span.map_or(false, |sp| sp.contains(expr.span))
+            || self.const_span.is_some_and(|sp| sp.contains(expr.span))
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
index 208b20a7a06..b0d872e98fd 100644
--- a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
@@ -42,14 +42,12 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool)
             if typeck
                 .type_dependent_def_id(expr.hir_id)
                 .and_then(|id| cx.tcx.trait_of_item(id))
-                .map_or(false, |id| {
-                    matches!(cx.tcx.get_diagnostic_name(id), Some(sym::ToString | sym::ToOwned))
-                }) =>
+                .is_some_and(|id| matches!(cx.tcx.get_diagnostic_name(id), Some(sym::ToString | sym::ToOwned))) =>
         {
             (arg, arg.span)
         },
         ExprKind::Call(path, [arg])
-            if path_def_id(cx, path).map_or(false, |did| {
+            if path_def_id(cx, path).is_some_and(|did| {
                 if cx.tcx.is_diagnostic_item(sym::from_str_method, did) {
                     true
                 } else if cx.tcx.is_diagnostic_item(sym::from_fn, did) {
diff --git a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs
index 830be50c8ba..1c2d6e90fc9 100644
--- a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs
@@ -42,83 +42,43 @@ pub(crate) fn check<'tcx>(
 
     match op {
         BinOpKind::Add | BinOpKind::BitOr | BinOpKind::BitXor => {
-            let _ = check_op(
-                cx,
-                left,
-                0,
-                expr.span,
-                peeled_right_span,
-                needs_parenthesis(cx, expr, right),
-                right_is_coerced_to_value,
-            ) || check_op(
-                cx,
-                right,
-                0,
-                expr.span,
-                peeled_left_span,
-                Parens::Unneeded,
-                left_is_coerced_to_value,
-            );
+            if is_redundant_op(cx, left, 0) {
+                let paren = needs_parenthesis(cx, expr, right);
+                span_ineffective_operation(cx, expr.span, peeled_right_span, paren, right_is_coerced_to_value);
+            } else if is_redundant_op(cx, right, 0) {
+                let paren = needs_parenthesis(cx, expr, left);
+                span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);
+            }
         },
         BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Sub => {
-            let _ = check_op(
-                cx,
-                right,
-                0,
-                expr.span,
-                peeled_left_span,
-                Parens::Unneeded,
-                left_is_coerced_to_value,
-            );
+            if is_redundant_op(cx, right, 0) {
+                let paren = needs_parenthesis(cx, expr, left);
+                span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);
+            }
         },
         BinOpKind::Mul => {
-            let _ = check_op(
-                cx,
-                left,
-                1,
-                expr.span,
-                peeled_right_span,
-                needs_parenthesis(cx, expr, right),
-                right_is_coerced_to_value,
-            ) || check_op(
-                cx,
-                right,
-                1,
-                expr.span,
-                peeled_left_span,
-                Parens::Unneeded,
-                left_is_coerced_to_value,
-            );
+            if is_redundant_op(cx, left, 1) {
+                let paren = needs_parenthesis(cx, expr, right);
+                span_ineffective_operation(cx, expr.span, peeled_right_span, paren, right_is_coerced_to_value);
+            } else if is_redundant_op(cx, right, 1) {
+                let paren = needs_parenthesis(cx, expr, left);
+                span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);
+            }
         },
         BinOpKind::Div => {
-            let _ = check_op(
-                cx,
-                right,
-                1,
-                expr.span,
-                peeled_left_span,
-                Parens::Unneeded,
-                left_is_coerced_to_value,
-            );
+            if is_redundant_op(cx, right, 1) {
+                let paren = needs_parenthesis(cx, expr, left);
+                span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);
+            }
         },
         BinOpKind::BitAnd => {
-            let _ = check_op(
-                cx,
-                left,
-                -1,
-                expr.span,
-                peeled_right_span,
-                needs_parenthesis(cx, expr, right),
-                right_is_coerced_to_value,
-            ) || check_op(
-                cx,
-                right,
-                -1,
-                expr.span,
-                peeled_left_span,
-                Parens::Unneeded,
-                left_is_coerced_to_value,
-            );
+            if is_redundant_op(cx, left, -1) {
+                let paren = needs_parenthesis(cx, expr, right);
+                span_ineffective_operation(cx, expr.span, peeled_right_span, paren, right_is_coerced_to_value);
+            } else if is_redundant_op(cx, right, -1) {
+                let paren = needs_parenthesis(cx, expr, left);
+                span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);
+            }
         },
         BinOpKind::Rem => check_remainder(cx, left, right, expr.span, left.span),
         _ => (),
@@ -138,43 +98,70 @@ enum Parens {
     Unneeded,
 }
 
-/// Checks if `left op right` needs parenthesis when reduced to `right`
+/// Checks if a binary expression needs parenthesis when reduced to just its
+/// right or left child.
+///
+/// e.g. `-(x + y + 0)` cannot be reduced to `-x + y`, as the behavior changes silently.
+/// e.g. `1u64 + ((x + y + 0i32) as u64)` cannot be reduced to `1u64 + x + y as u64`, since
+/// the the cast expression will not apply to the same expression.
 /// e.g. `0 + if b { 1 } else { 2 } + if b { 3 } else { 4 }` cannot be reduced
 /// to `if b { 1 } else { 2 } + if b { 3 } else { 4 }` where the `if` could be
-/// interpreted as a statement
+/// interpreted as a statement. The same behavior happens for `match`, `loop`,
+/// and blocks.
+/// e.g.  `2 * (0 + { a })` can be reduced to `2 * { a }` without the need for parenthesis,
+/// but `1 * ({ a } + 4)` cannot be reduced to `{ a } + 4`, as a block at the start of a line
+/// will be interpreted as a statement instead of an expression.
 ///
-/// See #8724
-fn needs_parenthesis(cx: &LateContext<'_>, binary: &Expr<'_>, right: &Expr<'_>) -> Parens {
-    match right.kind {
+/// See #8724, #13470
+fn needs_parenthesis(cx: &LateContext<'_>, binary: &Expr<'_>, child: &Expr<'_>) -> Parens {
+    match child.kind {
         ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) => {
-            // ensure we're checking against the leftmost expression of `right`
-            //
-            //     ~~~ `lhs`
-            // 0 + {4} * 2
-            //     ~~~~~~~ `right`
-            return needs_parenthesis(cx, binary, lhs);
+            // For casts and binary expressions, we want to add parenthesis if
+            // the parent HIR node is an expression, or if the parent HIR node
+            // is a Block or Stmt, and the new left hand side would need
+            // parenthesis be treated as a statement rather than an expression.
+            if let Some((_, parent)) = cx.tcx.hir().parent_iter(binary.hir_id).next() {
+                match parent {
+                    Node::Expr(_) => return Parens::Needed,
+                    Node::Block(_) | Node::Stmt(_) => {
+                        // ensure we're checking against the leftmost expression of `child`
+                        //
+                        // ~~~~~~~~~~~ `binary`
+                        //     ~~~ `lhs`
+                        // 0 + {4} * 2
+                        //     ~~~~~~~ `child`
+                        return needs_parenthesis(cx, binary, lhs);
+                    },
+                    _ => return Parens::Unneeded,
+                }
+            }
+        },
+        ExprKind::If(..) | ExprKind::Match(..) | ExprKind::Block(..) | ExprKind::Loop(..) => {
+            // For if, match, block, and loop expressions, we want to add parenthesis if
+            // the closest ancestor node that is not an expression is a block or statement.
+            // This would mean that the rustfix suggestion will appear at the start of a line, which causes
+            // these expressions to be interpreted as statements if they do not have parenthesis.
+            let mut prev_id = binary.hir_id;
+            for (_, parent) in cx.tcx.hir().parent_iter(binary.hir_id) {
+                if let Node::Expr(expr) = parent
+                    && let ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) | ExprKind::Unary(_, lhs) = expr.kind
+                    && lhs.hir_id == prev_id
+                {
+                    // keep going until we find a node that encompasses left of `binary`
+                    prev_id = expr.hir_id;
+                    continue;
+                }
+
+                match parent {
+                    Node::Block(_) | Node::Stmt(_) => return Parens::Needed,
+                    _ => return Parens::Unneeded,
+                };
+            }
+        },
+        _ => {
+            return Parens::Unneeded;
         },
-        ExprKind::If(..) | ExprKind::Match(..) | ExprKind::Block(..) | ExprKind::Loop(..) => {},
-        _ => return Parens::Unneeded,
-    }
-
-    let mut prev_id = binary.hir_id;
-    for (_, node) in cx.tcx.hir().parent_iter(binary.hir_id) {
-        if let Node::Expr(expr) = node
-            && let ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) = expr.kind
-            && lhs.hir_id == prev_id
-        {
-            // keep going until we find a node that encompasses left of `binary`
-            prev_id = expr.hir_id;
-            continue;
-        }
-
-        match node {
-            Node::Block(_) | Node::Stmt(_) => break,
-            _ => return Parens::Unneeded,
-        };
     }
-
     Parens::Needed
 }
 
@@ -199,7 +186,7 @@ fn check_remainder(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>, span
     }
 }
 
-fn check_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span, parens: Parens, is_erased: bool) -> bool {
+fn is_redundant_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8) -> bool {
     if let Some(Constant::Int(v)) = ConstEvalCtxt::new(cx).eval_simple(e).map(Constant::peel_refs) {
         let check = match *cx.typeck_results().expr_ty(e).peel_refs().kind() {
             ty::Int(ity) => unsext(cx.tcx, -1_i128, ity),
@@ -212,7 +199,6 @@ fn check_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span, pa
             1 => v == 1,
             _ => unreachable!(),
         } {
-            span_ineffective_operation(cx, span, arg, parens, is_erased);
             return true;
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs
index 565294bb40a..d369978b8be 100644
--- a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs
@@ -14,7 +14,7 @@ pub struct Context {
 }
 impl Context {
     fn skip_expr(&mut self, e: &hir::Expr<'_>) -> bool {
-        self.expr_id.is_some() || self.const_span.map_or(false, |span| span.contains(e.span))
+        self.expr_id.is_some() || self.const_span.is_some_and(|span| span.contains(e.span))
     }
 
     pub fn check_binary<'tcx>(
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index 1bddfab39c6..b2089487a9f 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -192,7 +192,7 @@ impl PassByRefOrValue {
                                 continue;
                             }
                         }
-                        let value_type = if fn_body.and_then(|body| body.params.get(index)).map_or(false, is_self) {
+                        let value_type = if fn_body.and_then(|body| body.params.get(index)).is_some_and(is_self) {
                             "self".into()
                         } else {
                             snippet(cx, decl_ty.span, "_").into()
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index a548c6ef3b1..ecc095f3859 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -727,9 +727,8 @@ fn get_ref_lm<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> Option<(&'tcx Lifetime, Mutabili
 
 fn is_null_path(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     if let ExprKind::Call(pathexp, []) = expr.kind {
-        path_def_id(cx, pathexp).map_or(false, |id| {
-            matches!(cx.tcx.get_diagnostic_name(id), Some(sym::ptr_null | sym::ptr_null_mut))
-        })
+        path_def_id(cx, pathexp)
+            .is_some_and(|id| matches!(cx.tcx.get_diagnostic_name(id), Some(sym::ptr_null | sym::ptr_null_mut)))
     } else {
         false
     }
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index cb374fcf20e..a00fd01a62e 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -8,18 +8,18 @@ use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use clippy_utils::{
     eq_expr_value, higher, is_else_clause, is_in_const_context, is_lint_allowed, is_path_lang_item, is_res_lang_ctor,
-    pat_and_expr_can_be_question_mark, path_to_local, path_to_local_id, peel_blocks, peel_blocks_with_stmt,
-    span_contains_comment,
+    pat_and_expr_can_be_question_mark, path_res, path_to_local, path_to_local_id, peel_blocks, peel_blocks_with_stmt,
+    span_contains_cfg, span_contains_comment,
 };
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};
 use rustc_hir::def::Res;
 use rustc_hir::{
-    BindingMode, Block, Body, ByRef, Expr, ExprKind, LetStmt, Mutability, Node, PatKind, PathSegment, QPath, Stmt,
-    StmtKind,
+    Arm, BindingMode, Block, Body, ByRef, Expr, ExprKind, FnRetTy, HirId, LetStmt, MatchSource, Mutability, Node, Pat,
+    PatKind, PathSegment, QPath, Stmt, StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::sym;
 use rustc_span::symbol::Symbol;
@@ -58,6 +58,9 @@ pub struct QuestionMark {
     /// if it is greater than zero.
     /// As for why we need this in the first place: <https://github.com/rust-lang/rust-clippy/issues/8628>
     try_block_depth_stack: Vec<u32>,
+    /// Keeps track of the number of inferred return type closures we are inside, to avoid problems
+    /// with the `Err(x.into())` expansion being ambiguious.
+    inferred_ret_closure_stack: u16,
 }
 
 impl_lint_pass!(QuestionMark => [QUESTION_MARK, MANUAL_LET_ELSE]);
@@ -68,6 +71,7 @@ impl QuestionMark {
             msrv: conf.msrv.clone(),
             matches_behaviour: conf.matches_for_let_else,
             try_block_depth_stack: Vec::new(),
+            inferred_ret_closure_stack: 0,
         }
     }
 }
@@ -125,7 +129,7 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
         cx.tcx
             .lang_items()
             .try_trait()
-            .map_or(false, |did| implements_trait(cx, init_ty, did, &[]))
+            .is_some_and(|did| implements_trait(cx, init_ty, did, &[]))
     }
 
     if let StmtKind::Let(LetStmt {
@@ -271,6 +275,135 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex
     }
 }
 
+#[derive(Clone, Copy, Debug)]
+enum TryMode {
+    Result,
+    Option,
+}
+
+fn find_try_mode<'tcx>(cx: &LateContext<'tcx>, scrutinee: &Expr<'tcx>) -> Option<TryMode> {
+    let scrutinee_ty = cx.typeck_results().expr_ty_adjusted(scrutinee);
+    let ty::Adt(scrutinee_adt_def, _) = scrutinee_ty.kind() else {
+        return None;
+    };
+
+    match cx.tcx.get_diagnostic_name(scrutinee_adt_def.did())? {
+        sym::Result => Some(TryMode::Result),
+        sym::Option => Some(TryMode::Option),
+        _ => None,
+    }
+}
+
+// Check that `pat` is `{ctor_lang_item}(val)`, returning `val`.
+fn extract_ctor_call<'a, 'tcx>(
+    cx: &LateContext<'tcx>,
+    expected_ctor: LangItem,
+    pat: &'a Pat<'tcx>,
+) -> Option<&'a Pat<'tcx>> {
+    if let PatKind::TupleStruct(variant_path, [val_binding], _) = &pat.kind
+        && is_res_lang_ctor(cx, cx.qpath_res(variant_path, pat.hir_id), expected_ctor)
+    {
+        Some(val_binding)
+    } else {
+        None
+    }
+}
+
+// Extracts the local ID of a plain `val` pattern.
+fn extract_binding_pat(pat: &Pat<'_>) -> Option<HirId> {
+    if let PatKind::Binding(BindingMode::NONE, binding, _, None) = pat.kind {
+        Some(binding)
+    } else {
+        None
+    }
+}
+
+fn check_arm_is_some_or_ok<'tcx>(cx: &LateContext<'tcx>, mode: TryMode, arm: &Arm<'tcx>) -> bool {
+    let happy_ctor = match mode {
+        TryMode::Result => ResultOk,
+        TryMode::Option => OptionSome,
+    };
+
+    // Check for `Ok(val)` or `Some(val)`
+    if arm.guard.is_none()
+        && let Some(val_binding) = extract_ctor_call(cx, happy_ctor, arm.pat)
+        // Extract out `val`
+        && let Some(binding) = extract_binding_pat(val_binding)
+        // Check body is just `=> val`
+        && path_to_local_id(peel_blocks(arm.body), binding)
+    {
+        true
+    } else {
+        false
+    }
+}
+
+fn check_arm_is_none_or_err<'tcx>(cx: &LateContext<'tcx>, mode: TryMode, arm: &Arm<'tcx>) -> bool {
+    if arm.guard.is_some() {
+        return false;
+    }
+
+    let arm_body = peel_blocks(arm.body);
+    match mode {
+        TryMode::Result => {
+            // Check that pat is Err(val)
+            if let Some(ok_pat) = extract_ctor_call(cx, ResultErr, arm.pat)
+                && let Some(ok_val) = extract_binding_pat(ok_pat)
+                // check `=> return Err(...)`
+                && let ExprKind::Ret(Some(wrapped_ret_expr)) = arm_body.kind
+                && let ExprKind::Call(ok_ctor, [ret_expr]) = wrapped_ret_expr.kind
+                && is_res_lang_ctor(cx, path_res(cx, ok_ctor), ResultErr)
+                // check `...` is `val` from binding
+                && path_to_local_id(ret_expr, ok_val)
+            {
+                true
+            } else {
+                false
+            }
+        },
+        TryMode::Option => {
+            // Check the pat is `None`
+            if is_res_lang_ctor(cx, path_res(cx, arm.pat), OptionNone)
+                // Check `=> return None`
+                && let ExprKind::Ret(Some(ret_expr)) = arm_body.kind
+                && is_res_lang_ctor(cx, path_res(cx, ret_expr), OptionNone)
+                && !ret_expr.span.from_expansion()
+            {
+                true
+            } else {
+                false
+            }
+        },
+    }
+}
+
+fn check_arms_are_try<'tcx>(cx: &LateContext<'tcx>, mode: TryMode, arm1: &Arm<'tcx>, arm2: &Arm<'tcx>) -> bool {
+    (check_arm_is_some_or_ok(cx, mode, arm1) && check_arm_is_none_or_err(cx, mode, arm2))
+        || (check_arm_is_some_or_ok(cx, mode, arm2) && check_arm_is_none_or_err(cx, mode, arm1))
+}
+
+fn check_if_try_match<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
+    if let ExprKind::Match(scrutinee, [arm1, arm2], MatchSource::Normal | MatchSource::Postfix) = expr.kind
+        && !expr.span.from_expansion()
+        && let Some(mode) = find_try_mode(cx, scrutinee)
+        && !span_contains_cfg(cx, expr.span)
+        && check_arms_are_try(cx, mode, arm1, arm2)
+    {
+        let mut applicability = Applicability::MachineApplicable;
+        let snippet = snippet_with_applicability(cx, scrutinee.span.source_callsite(), "..", &mut applicability);
+
+        span_lint_and_sugg(
+            cx,
+            QUESTION_MARK,
+            expr.span,
+            "this `match` expression can be replaced with `?`",
+            "try instead",
+            snippet.into_owned() + "?",
+            applicability,
+        );
+    }
+}
+
 fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
     if let Some(higher::IfLet {
         let_pat,
@@ -339,6 +472,17 @@ fn is_try_block(cx: &LateContext<'_>, bl: &Block<'_>) -> bool {
     }
 }
 
+fn is_inferred_ret_closure(expr: &Expr<'_>) -> bool {
+    let ExprKind::Closure(closure) = expr.kind else {
+        return false;
+    };
+
+    match closure.fn_decl.output {
+        FnRetTy::Return(ret_ty) => ret_ty.is_suggestable_infer_ty(),
+        FnRetTy::DefaultReturn(_) => true,
+    }
+}
+
 impl<'tcx> LateLintPass<'tcx> for QuestionMark {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
         if !is_lint_allowed(cx, QUESTION_MARK_USED, stmt.hir_id) {
@@ -350,11 +494,27 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
         }
         self.check_manual_let_else(cx, stmt);
     }
+
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if is_inferred_ret_closure(expr) {
+            self.inferred_ret_closure_stack += 1;
+            return;
+        }
+
         if !self.inside_try_block() && !is_in_const_context(cx) && is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id)
         {
             check_is_none_or_err_and_early_return(cx, expr);
             check_if_let_some_or_err_and_early_return(cx, expr);
+
+            if self.inferred_ret_closure_stack == 0 {
+                check_if_try_match(cx, expr);
+            }
+        }
+    }
+
+    fn check_expr_post(&mut self, _: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if is_inferred_ret_closure(expr) {
+            self.inferred_ret_closure_stack -= 1;
         }
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
index 030df535c35..dc66fb28fa8 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
@@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
             let (expr_ty, expr_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(expr));
             let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed));
             let parent_expr = get_parent_expr(cx, expr);
-            let needs_parens_for_prefix = parent_expr.map_or(false, |parent| parent.precedence().order() > PREC_PREFIX);
+            let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence().order() > PREC_PREFIX);
 
             if expr_ty == indexed_ty {
                 if expr_ref_count > indexed_ref_count {
@@ -107,7 +107,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
                         kind: ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _),
                         ..
                     })
-                ) || cx.typeck_results().expr_adjustments(expr).first().map_or(false, |a| {
+                ) || cx.typeck_results().expr_adjustments(expr).first().is_some_and(|a| {
                     matches!(
                         a.kind,
                         Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. }))
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index 23362506cca..78f0b7d121c 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -412,9 +412,7 @@ impl<'tcx> IndexBinding<'_, 'tcx> {
                 }
                 Self::is_used_slice_indexed(lhs, idx_ident) || Self::is_used_slice_indexed(rhs, idx_ident)
             },
-            ExprKind::Path(QPath::Resolved(_, path)) => {
-                path.segments.first().map_or(false, |idx| idx.ident == idx_ident)
-            },
+            ExprKind::Path(QPath::Resolved(_, path)) => path.segments.first().is_some_and(|idx| idx.ident == idx_ident),
             _ => false,
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
index eb7ffbbe360..bde88ab61ad 100644
--- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
@@ -51,8 +51,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
                         format!("&{ltopt}({inner_snippet})")
                     },
                     TyKind::Path(qpath)
-                        if get_bounds_if_impl_trait(cx, qpath, inner.hir_id)
-                            .map_or(false, |bounds| bounds.len() > 1) =>
+                        if get_bounds_if_impl_trait(cx, qpath, inner.hir_id).is_some_and(|bounds| bounds.len() > 1) =>
                     {
                         format!("&{ltopt}({inner_snippet})")
                     },
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
index 1a1284ce9c4..6eef582b4b2 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -38,7 +38,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
             return;
         }
 
-        if (local.ty.map_or(false, |ty| !matches!(ty.kind, TyKind::Infer))
+        if (local.ty.is_some_and(|ty| !matches!(ty.kind, TyKind::Infer))
             || matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none()))
             && expr_needs_inferred_result(cx, init)
         {
diff --git a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
index 91dff5a9523..cbc6885ae5d 100644
--- a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
@@ -98,7 +98,7 @@ impl VecPushSearcher {
                     needs_mut |= cx.typeck_results().expr_ty_adjusted(last_place).ref_mutability()
                         == Some(Mutability::Mut)
                         || get_parent_expr(cx, last_place)
-                            .map_or(false, |e| matches!(e.kind, ExprKind::AddrOf(_, Mutability::Mut, _)));
+                            .is_some_and(|e| matches!(e.kind, ExprKind::AddrOf(_, Mutability::Mut, _)));
                 },
                 ExprKind::MethodCall(_, recv, ..)
                     if recv.hir_id == e.hir_id
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index 1dd46ed5a89..a42ddcdae35 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -295,7 +295,7 @@ impl<'tcx> LateLintPass<'tcx> for Write {
             .opts
             .crate_name
             .as_ref()
-            .map_or(false, |crate_name| crate_name == "build_script_build");
+            .is_some_and(|crate_name| crate_name == "build_script_build");
 
         let allowed_in_tests = self.allow_print_in_tests && is_in_test(cx.tcx, expr.hir_id);
         match diag_name {
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 75169e05734..3269bf758ac 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -51,7 +51,7 @@ fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) ->
         return false;
     };
     let end = span.hi() - pos.sf.start_pos;
-    src.get(pos.pos.0 as usize..end.0 as usize).map_or(false, |s| {
+    src.get(pos.pos.0 as usize..end.0 as usize).is_some_and(|s| {
         // Spans can be wrapped in a mixture or parenthesis, whitespace, and trailing commas.
         let start_str = s.trim_start_matches(|c: char| c.is_whitespace() || c == '(');
         let end_str = s.trim_end_matches(|c: char| c.is_whitespace() || c == ')' || c == ',');
@@ -60,13 +60,13 @@ fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) ->
             Pat::MultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
             Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
             Pat::Sym(sym) => start_str.starts_with(sym.as_str()),
-            Pat::Num => start_str.as_bytes().first().map_or(false, u8::is_ascii_digit),
+            Pat::Num => start_str.as_bytes().first().is_some_and(u8::is_ascii_digit),
         } && match end_pat {
             Pat::Str(text) => end_str.ends_with(text),
             Pat::MultiStr(texts) => texts.iter().any(|s| end_str.ends_with(s)),
             Pat::OwnedMultiStr(texts) => texts.iter().any(|s| end_str.ends_with(s)),
             Pat::Sym(sym) => end_str.ends_with(sym.as_str()),
-            Pat::Num => end_str.as_bytes().last().map_or(false, u8::is_ascii_hexdigit),
+            Pat::Num => end_str.as_bytes().last().is_some_and(u8::is_ascii_hexdigit),
         })
     })
 }
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index cb69f8e5a0e..c73ab4bfa68 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -258,7 +258,7 @@ impl HirEqInterExpr<'_, '_, '_> {
     }
 
     fn should_ignore(&mut self, expr: &Expr<'_>) -> bool {
-        macro_backtrace(expr.span).last().map_or(false, |macro_call| {
+        macro_backtrace(expr.span).last().is_some_and(|macro_call| {
             matches!(
                 &self.inner.cx.tcx.get_diagnostic_name(macro_call.def_id),
                 Some(sym::todo_macro | sym::unimplemented_macro)
@@ -322,7 +322,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::Block(l, _), &ExprKind::Block(r, _)) => self.eq_block(l, r),
             (&ExprKind::Binary(l_op, ll, lr), &ExprKind::Binary(r_op, rl, rr)) => {
                 l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
-                    || swap_binop(l_op.node, ll, lr).map_or(false, |(l_op, ll, lr)| {
+                    || swap_binop(l_op.node, ll, lr).is_some_and(|(l_op, ll, lr)| {
                         l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)
                     })
             },
@@ -444,7 +444,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             ) => false,
         };
         (is_eq && (!self.should_ignore(left) || !self.should_ignore(right)))
-            || self.inner.expr_fallback.as_mut().map_or(false, |f| f(left, right))
+            || self.inner.expr_fallback.as_mut().is_some_and(|f| f(left, right))
     }
 
     fn eq_exprs(&mut self, left: &[Expr<'_>], right: &[Expr<'_>]) -> bool {
@@ -724,7 +724,7 @@ fn swap_binop<'a>(
 /// `eq_fn`.
 pub fn both<X>(l: Option<&X>, r: Option<&X>, mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {
     l.as_ref()
-        .map_or_else(|| r.is_none(), |x| r.as_ref().map_or(false, |y| eq_fn(x, y)))
+        .map_or_else(|| r.is_none(), |x| r.as_ref().is_some_and(|y| eq_fn(x, y)))
 }
 
 /// Checks if two slices are equal as per `eq_fn`.
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 50d334acf18..19316a90683 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -342,10 +342,9 @@ pub fn is_ty_alias(qpath: &QPath<'_>) -> bool {
 /// Checks if the method call given in `expr` belongs to the given trait.
 /// This is a deprecated function, consider using [`is_trait_method`].
 pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool {
-    cx.typeck_results()
-        .type_dependent_def_id(expr.hir_id)
-        .and_then(|defid| cx.tcx.trait_of_item(defid))
-        .map_or(false, |trt_id| match_def_path(cx, trt_id, path))
+    let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
+    let trt_id = cx.tcx.trait_of_item(def_id);
+    trt_id.is_some_and(|trt_id| match_def_path(cx, trt_id, path))
 }
 
 /// Checks if the given method call expression calls an inherent method.
@@ -379,7 +378,7 @@ pub fn is_diag_trait_item(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol
 pub fn is_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) -> bool {
     cx.typeck_results()
         .type_dependent_def_id(expr.hir_id)
-        .map_or(false, |did| is_diag_trait_item(cx, did, diag_item))
+        .is_some_and(|did| is_diag_trait_item(cx, did, diag_item))
 }
 
 /// Checks if the `def_id` belongs to a function that is part of a trait impl.
@@ -406,7 +405,7 @@ pub fn is_trait_item(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) -
     if let ExprKind::Path(ref qpath) = expr.kind {
         cx.qpath_res(qpath, expr.hir_id)
             .opt_def_id()
-            .map_or(false, |def_id| is_diag_trait_item(cx, def_id, diag_item))
+            .is_some_and(|def_id| is_diag_trait_item(cx, def_id, diag_item))
     } else {
         false
     }
@@ -466,13 +465,13 @@ pub fn match_qpath(path: &QPath<'_>, segments: &[&str]) -> bool {
 ///
 /// Please use `is_path_diagnostic_item` if the target is a diagnostic item.
 pub fn is_expr_path_def_path(cx: &LateContext<'_>, expr: &Expr<'_>, segments: &[&str]) -> bool {
-    path_def_id(cx, expr).map_or(false, |id| match_def_path(cx, id, segments))
+    path_def_id(cx, expr).is_some_and(|id| match_def_path(cx, id, segments))
 }
 
 /// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
 /// it matches the given lang item.
 pub fn is_path_lang_item<'tcx>(cx: &LateContext<'_>, maybe_path: &impl MaybePath<'tcx>, lang_item: LangItem) -> bool {
-    path_def_id(cx, maybe_path).map_or(false, |id| cx.tcx.lang_items().get(lang_item) == Some(id))
+    path_def_id(cx, maybe_path).is_some_and(|id| cx.tcx.lang_items().get(lang_item) == Some(id))
 }
 
 /// If `maybe_path` is a path node which resolves to an item, resolves it to a `DefId` and checks if
@@ -482,7 +481,7 @@ pub fn is_path_diagnostic_item<'tcx>(
     maybe_path: &impl MaybePath<'tcx>,
     diag_item: Symbol,
 ) -> bool {
-    path_def_id(cx, maybe_path).map_or(false, |id| cx.tcx.is_diagnostic_item(diag_item, id))
+    path_def_id(cx, maybe_path).is_some_and(|id| cx.tcx.is_diagnostic_item(diag_item, id))
 }
 
 /// THIS METHOD IS DEPRECATED. Matches a `Path` against a slice of segment string literals.
@@ -1315,7 +1314,7 @@ pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[&str]) -> Option<Vec
 pub fn is_entrypoint_fn(cx: &LateContext<'_>, def_id: DefId) -> bool {
     cx.tcx
         .entry_fn(())
-        .map_or(false, |(entry_fn_def_id, _)| def_id == entry_fn_def_id)
+        .is_some_and(|(entry_fn_def_id, _)| def_id == entry_fn_def_id)
 }
 
 /// Returns `true` if the expression is in the program's `#[panic_handler]`.
@@ -1753,8 +1752,8 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
 
     match pat.kind {
         PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.
-        PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)),
-        PatKind::Box(pat) | PatKind::Deref(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
+        PatKind::Binding(_, _, _, pat) => pat.is_some_and(|pat| is_refutable(cx, pat)),
+        PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
         PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
         PatKind::Or(pats) => {
             // TODO: should be the honest check, that pats is exhaustive set
@@ -1778,7 +1777,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
                 },
             }
         },
-        PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) => true,
+        PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) | PatKind::Deref(_) => true,
     }
 }
 
@@ -2021,7 +2020,7 @@ pub fn match_libc_symbol(cx: &LateContext<'_>, did: DefId, name: &str) -> bool {
     let path = cx.get_def_path(did);
     // libc is meant to be used as a flat list of names, but they're all actually defined in different
     // modules based on the target platform. Ignore everything but crate name and the item name.
-    path.first().map_or(false, |s| s.as_str() == "libc") && path.last().map_or(false, |s| s.as_str() == name)
+    path.first().is_some_and(|s| s.as_str() == "libc") && path.last().is_some_and(|s| s.as_str() == name)
 }
 
 /// Returns the list of condition expressions and the list of blocks in a
@@ -2104,7 +2103,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
         _ => None,
     };
 
-    did.map_or(false, |did| cx.tcx.has_attr(did, sym::must_use))
+    did.is_some_and(|did| cx.tcx.has_attr(did, sym::must_use))
 }
 
 /// Checks if a function's body represents the identity function. Looks for bodies of the form:
@@ -2211,7 +2210,7 @@ pub fn is_expr_untyped_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>)
 pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     match expr.kind {
         ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir().body(body)),
-        _ => path_def_id(cx, expr).map_or(false, |id| cx.tcx.is_diagnostic_item(sym::convert_identity, id)),
+        _ => path_def_id(cx, expr).is_some_and(|id| cx.tcx.is_diagnostic_item(sym::convert_identity, id)),
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/numeric_literal.rs b/src/tools/clippy/clippy_utils/src/numeric_literal.rs
index c5a34160e3d..2c49df9d807 100644
--- a/src/tools/clippy/clippy_utils/src/numeric_literal.rs
+++ b/src/tools/clippy/clippy_utils/src/numeric_literal.rs
@@ -53,7 +53,7 @@ impl<'a> NumericLiteral<'a> {
                 .trim_start()
                 .chars()
                 .next()
-                .map_or(false, |c| c.is_ascii_digit())
+                .is_some_and(|c| c.is_ascii_digit())
         {
             let (unsuffixed, suffix) = split_suffix(src, lit_kind);
             let float = matches!(lit_kind, LitKind::Float(..));
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 666ec8df930..971f8eeb1b3 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -393,12 +393,8 @@ fn is_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
 
                 msrv.meets(const_stab_rust_version)
             } else {
-                // Unstable const fn, check if the feature is enabled. We need both the regular stability
-                // feature and (if set) the const stability feature to const-call this function.
-                let stab = tcx.lookup_stability(def_id);
-                let is_enabled = stab.is_some_and(|s| s.is_stable() || tcx.features().enabled(s.feature))
-                    && const_stab.feature.is_none_or(|f| tcx.features().enabled(f));
-                is_enabled && msrv.current().is_none()
+                // Unstable const fn, check if the feature is enabled.
+                tcx.features().enabled(const_stab.feature) && msrv.current().is_none()
             }
         })
 }
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 3255c51d009..25ebe879192 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -905,7 +905,7 @@ impl<'tcx> DerefDelegate<'_, 'tcx> {
             _ => return false,
         };
 
-        ty.map_or(false, |ty| matches!(ty.kind(), ty::Ref(_, inner, _) if inner.is_ref()))
+        ty.is_some_and(|ty| matches!(ty.kind(), ty::Ref(_, inner, _) if inner.is_ref()))
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index ce1a20e0066..770cd9c3786 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -45,7 +45,7 @@ pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
 pub fn has_debug_impl<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
     cx.tcx
         .get_diagnostic_item(sym::Debug)
-        .map_or(false, |debug| implements_trait(cx, ty, debug, &[]))
+        .is_some_and(|debug| implements_trait(cx, ty, debug, &[]))
 }
 
 /// Checks whether a type can be partially moved.
@@ -487,7 +487,7 @@ pub fn needs_ordered_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
             .tcx
             .lang_items()
             .drop_trait()
-            .map_or(false, |id| implements_trait(cx, ty, id, &[]))
+            .is_some_and(|id| implements_trait(cx, ty, id, &[]))
         {
             // This type doesn't implement drop, so no side effects here.
             // Check if any component type has any.
@@ -718,7 +718,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
                 {
                     let output = bounds
                         .projection_bounds()
-                        .find(|p| lang_items.fn_once_output().map_or(false, |id| id == p.item_def_id()))
+                        .find(|p| lang_items.fn_once_output().is_some_and(|id| id == p.item_def_id()))
                         .map(|p| p.map_bound(|p| p.term.expect_type()));
                     Some(ExprFnSig::Trait(bound.map_bound(|b| b.args.type_at(0)), output, None))
                 },
@@ -753,7 +753,7 @@ fn sig_from_bounds<'tcx>(
                     && p.self_ty() == ty =>
             {
                 let i = pred.kind().rebind(p.trait_ref.args.type_at(1));
-                if inputs.map_or(false, |inputs| i != inputs) {
+                if inputs.is_some_and(|inputs| i != inputs) {
                     // Multiple different fn trait impls. Is this even allowed?
                     return None;
                 }
@@ -794,7 +794,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option
             {
                 let i = pred.kind().rebind(p.trait_ref.args.type_at(1));
 
-                if inputs.map_or(false, |inputs| inputs != i) {
+                if inputs.is_some_and(|inputs| inputs != i) {
                     // Multiple different fn trait impls. Is this even allowed?
                     return None;
                 }
@@ -1291,7 +1291,7 @@ pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>
 
 /// Checks if the type is `core::mem::ManuallyDrop<_>`
 pub fn is_manually_drop(ty: Ty<'_>) -> bool {
-    ty.ty_adt_def().map_or(false, AdtDef::is_manually_drop)
+    ty.ty_adt_def().is_some_and(AdtDef::is_manually_drop)
 }
 
 /// Returns the deref chain of a type, starting with the type itself.
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 8f5ec185bf1..a79be5ca7d4 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -344,13 +344,13 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
                     .cx
                     .qpath_res(p, hir_id)
                     .opt_def_id()
-                    .map_or(false, |id| self.cx.tcx.is_const_fn(id)) => {},
+                    .is_some_and(|id| self.cx.tcx.is_const_fn(id)) => {},
                 ExprKind::MethodCall(..)
                     if self
                         .cx
                         .typeck_results()
                         .type_dependent_def_id(e.hir_id)
-                        .map_or(false, |id| self.cx.tcx.is_const_fn(id)) => {},
+                        .is_some_and(|id| self.cx.tcx.is_const_fn(id)) => {},
                 ExprKind::Binary(_, lhs, rhs)
                     if self.cx.typeck_results().expr_ty(lhs).peel_refs().is_primitive_ty()
                         && self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},
@@ -426,9 +426,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
                         .cx
                         .typeck_results()
                         .type_dependent_def_id(e.hir_id)
-                        .map_or(false, |id| {
-                            self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe
-                        }) =>
+                        .is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe) =>
                 {
                     ControlFlow::Break(())
                 },
@@ -444,7 +442,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
                         .cx
                         .qpath_res(p, e.hir_id)
                         .opt_def_id()
-                        .map_or(false, |id| self.cx.tcx.is_mutable_static(id)) =>
+                        .is_some_and(|id| self.cx.tcx.is_mutable_static(id)) =>
                 {
                     ControlFlow::Break(())
                 },
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 37d9cce2465..e32e0cb3604 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,4 +1,4 @@
 [toolchain]
-channel = "nightly-2024-11-07"
+channel = "nightly-2024-11-14"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
index 0a994842834..d3fab60f9e3 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
@@ -1,6 +1,7 @@
 //@aux-build:paths.rs
 #![deny(clippy::internal)]
 #![feature(rustc_private)]
+#![allow(clippy::unnecessary_map_or)]
 
 extern crate clippy_utils;
 extern crate paths;
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
index ba68de6c6d0..1b36f6b09e9 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
@@ -1,6 +1,7 @@
 //@aux-build:paths.rs
 #![deny(clippy::internal)]
 #![feature(rustc_private)]
+#![allow(clippy::unnecessary_map_or)]
 
 extern crate clippy_utils;
 extern crate paths;
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
index 79da1731613..79521c5037a 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
@@ -1,5 +1,5 @@
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:36:13
+  --> tests/ui-internal/unnecessary_def_path.rs:37:13
    |
 LL |     let _ = match_type(cx, ty, &OPTION);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Option)`
@@ -12,61 +12,61 @@ LL | #![deny(clippy::internal)]
    = note: `#[deny(clippy::unnecessary_def_path)]` implied by `#[deny(clippy::internal)]`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:37:13
+  --> tests/ui-internal/unnecessary_def_path.rs:38:13
    |
 LL |     let _ = match_type(cx, ty, RESULT);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:38:13
+  --> tests/ui-internal/unnecessary_def_path.rs:39:13
    |
 LL |     let _ = match_type(cx, ty, &["core", "result", "Result"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:42:13
+  --> tests/ui-internal/unnecessary_def_path.rs:43:13
    |
 LL |     let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Rc)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:44:13
+  --> tests/ui-internal/unnecessary_def_path.rs:45:13
    |
 LL |     let _ = match_type(cx, ty, &paths::OPTION);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Option)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:45:13
+  --> tests/ui-internal/unnecessary_def_path.rs:46:13
    |
 LL |     let _ = match_type(cx, ty, paths::RESULT);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:47:13
+  --> tests/ui-internal/unnecessary_def_path.rs:48:13
    |
 LL |     let _ = match_type(cx, ty, &["alloc", "boxed", "Box"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_lang_item(cx, ty, LangItem::OwnedBox)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:48:13
+  --> tests/ui-internal/unnecessary_def_path.rs:49:13
    |
 LL |     let _ = match_type(cx, ty, &["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit)`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:50:13
+  --> tests/ui-internal/unnecessary_def_path.rs:51:13
    |
 LL |     let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:51:13
+  --> tests/ui-internal/unnecessary_def_path.rs:52:13
    |
 LL |     let _ = match_def_path(cx, did, &["core", "option", "Option"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.is_diagnostic_item(sym::Option, did)`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:52:13
+  --> tests/ui-internal/unnecessary_def_path.rs:53:13
    |
 LL |     let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did)`
@@ -74,25 +74,25 @@ LL |     let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
    = help: if this `DefId` came from a constructor expression or pattern then the parent `DefId` should be used instead
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:54:13
+  --> tests/ui-internal/unnecessary_def_path.rs:55:13
    |
 LL |     let _ = match_trait_method(cx, expr, &["core", "convert", "AsRef"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_trait_method(cx, expr, sym::AsRef)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:56:13
+  --> tests/ui-internal/unnecessary_def_path.rs:57:13
    |
 LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_path_diagnostic_item(cx, expr, sym::Option)`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:57:13
+  --> tests/ui-internal/unnecessary_def_path.rs:58:13
    |
 LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id))`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:58:13
+  --> tests/ui-internal/unnecessary_def_path.rs:59:13
    |
 LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option", "Some"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome)`
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/empty.txt b/src/tools/clippy/tests/ui-toml/large_include_file/empty.txt
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/empty.txt
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs
index dc9349f75a0..8a6dd36501c 100644
--- a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs
@@ -15,5 +15,9 @@ const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
 const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
 //~^ large_include_file
 
-#[doc = include_str!("too_big.txt")] //~ large_include_file
+#[doc = include_str!("too_big.txt")]
+//~^ large_include_file
+// Should not lint!
+// Regression test for <https://github.com/rust-lang/rust-clippy/issues/13670>.
+#[doc = include_str!("empty.txt")]
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed
index 8b4a165a97c..c4d77f24f12 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed
@@ -1,4 +1,5 @@
 #![warn(clippy::case_sensitive_file_extension_comparisons)]
+#![allow(clippy::unnecessary_map_or)]
 
 use std::string::String;
 
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
index e4b8178110b..690e93c2639 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::case_sensitive_file_extension_comparisons)]
+#![allow(clippy::unnecessary_map_or)]
 
 use std::string::String;
 
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
index d203f91b832..e21815f251b 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr
@@ -1,5 +1,5 @@
 error: case-sensitive file extension comparison
-  --> tests/ui/case_sensitive_file_extension_comparisons.rs:13:5
+  --> tests/ui/case_sensitive_file_extension_comparisons.rs:14:5
    |
 LL |     filename.ends_with(".rs")
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL +         .map_or(false, |ext| ext.eq_ignore_ascii_case("rs"))
    |
 
 error: case-sensitive file extension comparison
-  --> tests/ui/case_sensitive_file_extension_comparisons.rs:18:13
+  --> tests/ui/case_sensitive_file_extension_comparisons.rs:19:13
    |
 LL |     let _ = String::new().ends_with(".ext12");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -29,7 +29,7 @@ LL ~         .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12"));
    |
 
 error: case-sensitive file extension comparison
-  --> tests/ui/case_sensitive_file_extension_comparisons.rs:19:13
+  --> tests/ui/case_sensitive_file_extension_comparisons.rs:20:13
    |
 LL |     let _ = "str".ends_with(".ext12");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,7 +43,7 @@ LL ~         .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12"));
    |
 
 error: case-sensitive file extension comparison
-  --> tests/ui/case_sensitive_file_extension_comparisons.rs:23:17
+  --> tests/ui/case_sensitive_file_extension_comparisons.rs:24:17
    |
 LL |         let _ = "str".ends_with(".ext12");
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -57,7 +57,7 @@ LL ~             .map_or(false, |ext| ext.eq_ignore_ascii_case("ext12"));
    |
 
 error: case-sensitive file extension comparison
-  --> tests/ui/case_sensitive_file_extension_comparisons.rs:30:13
+  --> tests/ui/case_sensitive_file_extension_comparisons.rs:31:13
    |
 LL |     let _ = String::new().ends_with(".EXT12");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -71,7 +71,7 @@ LL ~         .map_or(false, |ext| ext.eq_ignore_ascii_case("EXT12"));
    |
 
 error: case-sensitive file extension comparison
-  --> tests/ui/case_sensitive_file_extension_comparisons.rs:31:13
+  --> tests/ui/case_sensitive_file_extension_comparisons.rs:32:13
    |
 LL |     let _ = "str".ends_with(".EXT12");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
index c238b4c9a17..2852e26680f 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
@@ -3,7 +3,7 @@ error: empty line after doc comment
    |
 LL | / /// for the crate
 LL | |
-   | |_
+   | |_^
 LL |   fn first_in_crate() {}
    |   ------------------- the comment documents this function
    |
@@ -22,7 +22,7 @@ error: empty line after doc comment
    |
 LL | /     /// for the module
 LL | |
-   | |_
+   | |_^
 LL |       fn first_in_module() {}
    |       -------------------- the comment documents this function
    |
@@ -39,7 +39,7 @@ error: empty line after doc comment
    |
 LL | /     /// # Indented
 LL | |
-   | |_
+   | |_^
 LL |       /// Blank line
 LL |       fn indented() {}
    |       ------------- the comment documents this function
@@ -55,7 +55,7 @@ error: empty line after doc comment
    |
 LL | / /// This should produce a warning
 LL | |
-   | |_
+   | |_^
 LL |   fn with_doc_and_newline() {}
    |   ------------------------- the comment documents this function
    |
@@ -69,7 +69,7 @@ LL | |
 LL | | /** This is also a doc comment and is part of the warning
 LL | |  */
 LL | |
-   | |_
+   | |_^
 ...
 LL |   fn three_attributes() {}
    |   --------------------- the comment documents this function
@@ -82,7 +82,7 @@ error: empty line after doc comment
 LL | /     /// docs for `old_code`
 LL | |     // fn old_code() {}
 LL | |
-   | |_
+   | |_^
 LL |       fn new_code() {}
    |       ------------- the comment documents this function
    |
@@ -102,7 +102,7 @@ LL | |     /// Docs
 LL | |     /// for OldB
 LL | |     // struct OldB;
 LL | |
-   | |_
+   | |_^
 ...
 LL |       struct Multiple;
    |       --------------- the comment documents this struct
@@ -125,7 +125,7 @@ LL | /     /**
 LL | |      * Meant to be inner doc comment
 LL | |      */
 LL | |
-   | |_
+   | |_^
 LL |       fn first_in_module() {}
    |       -------------------- the comment documents this function
    |
@@ -143,7 +143,7 @@ LL | |      * Docs for `old_code`
 LL | |      */
 LL | |     /* fn old_code() {} */
 LL | |
-   | |_
+   | |_^
 ...
 LL |       fn new_code() {}
    |       ------------- the comment documents this function
@@ -161,7 +161,7 @@ error: empty line after doc comment
 LL | /     /// Docs for `old_code2`
 LL | |     /* fn old_code2() {} */
 LL | |
-   | |_
+   | |_^
 LL |       /// Docs for `new_code2`
 LL |       fn new_code2() {}
    |       -------------- the comment documents this function
diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
index 958b40424a9..75fc23e9e7e 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
@@ -3,7 +3,7 @@ error: empty line after outer attribute
    |
 LL | / #[crate_type = "lib"]
 LL | |
-   | |_
+   | |_^
 LL |   fn first_in_crate() {}
    |   ------------------- the attribute applies to this function
    |
@@ -20,7 +20,7 @@ error: empty line after outer attribute
    |
 LL | / #[inline]
 LL | |
-   | |_
+   | |_^
 LL |   /// some comment
 LL |   fn with_one_newline_and_comment() {}
    |   --------------------------------- the attribute applies to this function
@@ -32,7 +32,7 @@ error: empty line after outer attribute
    |
 LL | / #[inline]
 LL | |
-   | |_
+   | |_^
 LL |   fn with_one_newline() {}
    |   --------------------- the attribute applies to this function
    |
@@ -44,7 +44,7 @@ error: empty lines after outer attribute
 LL | /     #[crate_type = "lib"]
 LL | |
 LL | |
-   | |_
+   | |_^
 LL |       fn with_two_newlines() {}
    |       ---------------------- the attribute applies to this function
    |
@@ -59,7 +59,7 @@ error: empty line after outer attribute
    |
 LL | / #[doc = "doc attributes should be considered attributes"]
 LL | |
-   | |_
+   | |_^
 LL |   enum Baz {
    |   -------- the attribute applies to this enum
    |
@@ -70,7 +70,7 @@ error: empty line after outer attribute
    |
 LL | / #[repr(C)]
 LL | |
-   | |_
+   | |_^
 LL |   struct Foo {
    |   ---------- the attribute applies to this struct
    |
@@ -81,7 +81,7 @@ error: empty line after outer attribute
    |
 LL | / #[allow(dead_code)]
 LL | |
-   | |_
+   | |_^
 LL |   mod foo {}
    |   ------- the attribute applies to this module
    |
@@ -93,7 +93,7 @@ error: empty line after outer attribute
 LL | / #[inline]
 LL | | // Still lint cases where the empty line does not immediately follow the attribute
 LL | |
-   | |_
+   | |_^
 LL |   fn comment_before_empty_line() {}
    |   ------------------------------ the attribute applies to this function
    |
@@ -106,7 +106,7 @@ LL | / #[allow(unused)]
 LL | |
 LL | | // This comment is isolated
 LL | |
-   | |_
+   | |_^
 LL |   pub fn isolated_comment() {}
    |   ------------------------- the attribute applies to this function
    |
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes.stderr b/src/tools/clippy/tests/ui/four_forward_slashes.stderr
index a2218ea4d10..3606a2227a0 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes.stderr
+++ b/src/tools/clippy/tests/ui/four_forward_slashes.stderr
@@ -3,7 +3,7 @@ error: this item has comments with 4 forward slashes (`////`). These look like d
    |
 LL | / //// whoops
 LL | | fn a() {}
-   | |_
+   | |_^
    |
    = note: `-D clippy::four-forward-slashes` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`
@@ -18,7 +18,7 @@ error: this item has comments with 4 forward slashes (`////`). These look like d
 LL | / //// whoops
 LL | | #[allow(dead_code)]
 LL | | fn b() {}
-   | |_
+   | |_^
    |
 help: make this a doc comment by removing one `/`
    |
@@ -32,7 +32,7 @@ LL | / //// whoops
 LL | | //// two borked comments!
 LL | | #[track_caller]
 LL | | fn c() {}
-   | |_
+   | |_^
    |
 help: turn these into doc comments by removing one `/`
    |
@@ -46,7 +46,7 @@ error: this item has comments with 4 forward slashes (`////`). These look like d
 LL | / //// between attributes
 LL | | #[allow(dead_code)]
 LL | | fn g() {}
-   | |_
+   | |_^
    |
 help: make this a doc comment by removing one `/`
    |
@@ -58,7 +58,7 @@ error: this item has comments with 4 forward slashes (`////`). These look like d
    |
 LL | /     //// not very start of contents
 LL | | fn h() {}
-   | |_
+   | |_^
    |
 help: make this a doc comment by removing one `/`
    |
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr
index 23937034b7e..81732346412 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr
+++ b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr
@@ -3,7 +3,7 @@ error: this item has comments with 4 forward slashes (`////`). These look like d
    |
 LL | / //// borked doc comment on the first line. doesn't combust!
 LL | | fn a() {}
-   | |_
+   | |_^
    |
    = note: `-D clippy::four-forward-slashes` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`
diff --git a/src/tools/clippy/tests/ui/identity_op.fixed b/src/tools/clippy/tests/ui/identity_op.fixed
index b18d8560f6f..2e8e2366de6 100644
--- a/src/tools/clippy/tests/ui/identity_op.fixed
+++ b/src/tools/clippy/tests/ui/identity_op.fixed
@@ -116,7 +116,7 @@ fn main() {
     //~^ ERROR: this operation has no effect
     (match a { 0 => 10, _ => 20 }) + if b { 3 } else { 4 };
     //~^ ERROR: this operation has no effect
-    (if b { 1 } else { 2 });
+    ((if b { 1 } else { 2 }));
     //~^ ERROR: this operation has no effect
 
     ({ a }) + 3;
@@ -212,3 +212,47 @@ fn issue_12050() {
         //~^ ERROR: this operation has no effect
     }
 }
+
+fn issue_13470() {
+    let x = 1i32;
+    let y = 1i32;
+    // Removes the + 0i32 while keeping the parentheses around x + y so the cast operation works
+    let _: u64 = (x + y) as u64;
+    //~^ ERROR: this operation has no effect
+    // both of the next two lines should look the same after rustfix
+    let _: u64 = 1u64 & (x + y) as u64;
+    //~^ ERROR: this operation has no effect
+    // Same as above, but with extra redundant parenthesis
+    let _: u64 = 1u64 & ((x + y)) as u64;
+    //~^ ERROR: this operation has no effect
+    // Should maintain parenthesis even if the surrounding expr has the same precedence
+    let _: u64 = 5u64 + ((x + y)) as u64;
+    //~^ ERROR: this operation has no effect
+
+    // If we don't maintain the parens here, the behavior changes
+    let _ = -(x + y);
+    //~^ ERROR: this operation has no effect
+    // Similarly, we need to maintain parens here
+    let _ = -(x / y);
+    //~^ ERROR: this operation has no effect
+    // Maintain parenthesis if the parent expr is of higher precedence
+    let _ = 2i32 * (x + y);
+    //~^ ERROR: this operation has no effect
+    // Maintain parenthesis if the parent expr is the same precedence
+    // as not all operations are associative
+    let _ = 2i32 - (x - y);
+    //~^ ERROR: this operation has no effect
+    // But make sure that inner parens still exist
+    let z = 1i32;
+    let _ = 2 + (x + (y * z));
+    //~^ ERROR: this operation has no effect
+    // Maintain parenthesis if the parent expr is of lower precedence
+    // This is for clarity, and clippy will not warn on these being unnecessary
+    let _ = 2i32 + (x * y);
+    //~^ ERROR: this operation has no effect
+
+    let x = 1i16;
+    let y = 1i16;
+    let _: u64 = 1u64 + ((x as i32 + y as i32) as u64);
+    //~^ ERROR: this operation has no effect
+}
diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs
index f1f01b42447..3e20fa6f2b8 100644
--- a/src/tools/clippy/tests/ui/identity_op.rs
+++ b/src/tools/clippy/tests/ui/identity_op.rs
@@ -212,3 +212,47 @@ fn issue_12050() {
         //~^ ERROR: this operation has no effect
     }
 }
+
+fn issue_13470() {
+    let x = 1i32;
+    let y = 1i32;
+    // Removes the + 0i32 while keeping the parentheses around x + y so the cast operation works
+    let _: u64 = (x + y + 0i32) as u64;
+    //~^ ERROR: this operation has no effect
+    // both of the next two lines should look the same after rustfix
+    let _: u64 = 1u64 & (x + y + 0i32) as u64;
+    //~^ ERROR: this operation has no effect
+    // Same as above, but with extra redundant parenthesis
+    let _: u64 = 1u64 & ((x + y) + 0i32) as u64;
+    //~^ ERROR: this operation has no effect
+    // Should maintain parenthesis even if the surrounding expr has the same precedence
+    let _: u64 = 5u64 + ((x + y) + 0i32) as u64;
+    //~^ ERROR: this operation has no effect
+
+    // If we don't maintain the parens here, the behavior changes
+    let _ = -(x + y + 0i32);
+    //~^ ERROR: this operation has no effect
+    // Similarly, we need to maintain parens here
+    let _ = -(x / y / 1i32);
+    //~^ ERROR: this operation has no effect
+    // Maintain parenthesis if the parent expr is of higher precedence
+    let _ = 2i32 * (x + y + 0i32);
+    //~^ ERROR: this operation has no effect
+    // Maintain parenthesis if the parent expr is the same precedence
+    // as not all operations are associative
+    let _ = 2i32 - (x - y - 0i32);
+    //~^ ERROR: this operation has no effect
+    // But make sure that inner parens still exist
+    let z = 1i32;
+    let _ = 2 + (x + (y * z) + 0);
+    //~^ ERROR: this operation has no effect
+    // Maintain parenthesis if the parent expr is of lower precedence
+    // This is for clarity, and clippy will not warn on these being unnecessary
+    let _ = 2i32 + (x * y * 1i32);
+    //~^ ERROR: this operation has no effect
+
+    let x = 1i16;
+    let y = 1i16;
+    let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64);
+    //~^ ERROR: this operation has no effect
+}
diff --git a/src/tools/clippy/tests/ui/identity_op.stderr b/src/tools/clippy/tests/ui/identity_op.stderr
index 9fff86b86f9..99a58ef2c1b 100644
--- a/src/tools/clippy/tests/ui/identity_op.stderr
+++ b/src/tools/clippy/tests/ui/identity_op.stderr
@@ -149,7 +149,7 @@ error: this operation has no effect
   --> tests/ui/identity_op.rs:119:5
    |
 LL |     (if b { 1 } else { 2 }) + 0;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `((if b { 1 } else { 2 }))`
 
 error: this operation has no effect
   --> tests/ui/identity_op.rs:122:5
@@ -313,5 +313,71 @@ error: this operation has no effect
 LL |         let _: i32 = **&&*&x + 0;
    |                      ^^^^^^^^^^^ help: consider reducing it to: `***&&*&x`
 
-error: aborting due to 52 previous errors
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:220:18
+   |
+LL |     let _: u64 = (x + y + 0i32) as u64;
+   |                  ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:223:25
+   |
+LL |     let _: u64 = 1u64 & (x + y + 0i32) as u64;
+   |                         ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:226:25
+   |
+LL |     let _: u64 = 1u64 & ((x + y) + 0i32) as u64;
+   |                         ^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x + y))`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:229:25
+   |
+LL |     let _: u64 = 5u64 + ((x + y) + 0i32) as u64;
+   |                         ^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x + y))`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:233:14
+   |
+LL |     let _ = -(x + y + 0i32);
+   |              ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:236:14
+   |
+LL |     let _ = -(x / y / 1i32);
+   |              ^^^^^^^^^^^^^^ help: consider reducing it to: `(x / y)`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:239:20
+   |
+LL |     let _ = 2i32 * (x + y + 0i32);
+   |                    ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:243:20
+   |
+LL |     let _ = 2i32 - (x - y - 0i32);
+   |                    ^^^^^^^^^^^^^^ help: consider reducing it to: `(x - y)`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:247:17
+   |
+LL |     let _ = 2 + (x + (y * z) + 0);
+   |                 ^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(x + (y * z))`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:251:20
+   |
+LL |     let _ = 2i32 + (x * y * 1i32);
+   |                    ^^^^^^^^^^^^^^ help: consider reducing it to: `(x * y)`
+
+error: this operation has no effect
+  --> tests/ui/identity_op.rs:256:25
+   |
+LL |     let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64);
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x as i32 + y as i32) as u64)`
+
+error: aborting due to 63 previous errors
 
diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed
index 679388372e6..b6e148e9f77 100644
--- a/src/tools/clippy/tests/ui/question_mark.fixed
+++ b/src/tools/clippy/tests/ui/question_mark.fixed
@@ -96,12 +96,42 @@ impl MoveStruct {
 }
 
 fn func() -> Option<i32> {
+    macro_rules! opt_none {
+        () => {
+            None
+        };
+    }
+
     fn f() -> Option<String> {
         Some(String::new())
     }
 
     f()?;
 
+    let _val = f()?;
+
+    let s: &str = match &Some(String::new()) {
+        Some(v) => v,
+        None => return None,
+    };
+
+    f()?;
+
+    opt_none!()?;
+
+    match f() {
+        Some(x) => x,
+        None => return opt_none!(),
+    };
+
+    match f() {
+        Some(val) => {
+            println!("{val}");
+            val
+        },
+        None => return None,
+    };
+
     Some(0)
 }
 
@@ -114,6 +144,10 @@ fn result_func(x: Result<i32, i32>) -> Result<i32, i32> {
 
     x?;
 
+    let _val = func_returning_result()?;
+
+    func_returning_result()?;
+
     // No warning
     let y = if let Ok(x) = x {
         x
@@ -157,6 +191,28 @@ fn result_func(x: Result<i32, i32>) -> Result<i32, i32> {
     Ok(y)
 }
 
+fn infer_check() {
+    let closure = |x: Result<u8, ()>| {
+        // `?` would fail here, as it expands to `Err(val.into())` which is not constrained.
+        let _val = match x {
+            Ok(val) => val,
+            Err(val) => return Err(val),
+        };
+
+        Ok(())
+    };
+
+    let closure = |x: Result<u8, ()>| -> Result<(), _> {
+        // `?` would fail here, as it expands to `Err(val.into())` which is not constrained.
+        let _val = match x {
+            Ok(val) => val,
+            Err(val) => return Err(val),
+        };
+
+        Ok(())
+    };
+}
+
 // see issue #8019
 pub enum NotOption {
     None,
diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs
index 601ab78bf5a..48dc9eb0a62 100644
--- a/src/tools/clippy/tests/ui/question_mark.rs
+++ b/src/tools/clippy/tests/ui/question_mark.rs
@@ -124,6 +124,12 @@ impl MoveStruct {
 }
 
 fn func() -> Option<i32> {
+    macro_rules! opt_none {
+        () => {
+            None
+        };
+    }
+
     fn f() -> Option<String> {
         Some(String::new())
     }
@@ -132,6 +138,39 @@ fn func() -> Option<i32> {
         return None;
     }
 
+    let _val = match f() {
+        Some(val) => val,
+        None => return None,
+    };
+
+    let s: &str = match &Some(String::new()) {
+        Some(v) => v,
+        None => return None,
+    };
+
+    match f() {
+        Some(val) => val,
+        None => return None,
+    };
+
+    match opt_none!() {
+        Some(x) => x,
+        None => return None,
+    };
+
+    match f() {
+        Some(x) => x,
+        None => return opt_none!(),
+    };
+
+    match f() {
+        Some(val) => {
+            println!("{val}");
+            val
+        },
+        None => return None,
+    };
+
     Some(0)
 }
 
@@ -146,6 +185,16 @@ fn result_func(x: Result<i32, i32>) -> Result<i32, i32> {
         return x;
     }
 
+    let _val = match func_returning_result() {
+        Ok(val) => val,
+        Err(err) => return Err(err),
+    };
+
+    match func_returning_result() {
+        Ok(val) => val,
+        Err(err) => return Err(err),
+    };
+
     // No warning
     let y = if let Ok(x) = x {
         x
@@ -189,6 +238,28 @@ fn result_func(x: Result<i32, i32>) -> Result<i32, i32> {
     Ok(y)
 }
 
+fn infer_check() {
+    let closure = |x: Result<u8, ()>| {
+        // `?` would fail here, as it expands to `Err(val.into())` which is not constrained.
+        let _val = match x {
+            Ok(val) => val,
+            Err(val) => return Err(val),
+        };
+
+        Ok(())
+    };
+
+    let closure = |x: Result<u8, ()>| -> Result<(), _> {
+        // `?` would fail here, as it expands to `Err(val.into())` which is not constrained.
+        let _val = match x {
+            Ok(val) => val,
+            Err(val) => return Err(val),
+        };
+
+        Ok(())
+    };
+}
+
 // see issue #8019
 pub enum NotOption {
     None,
diff --git a/src/tools/clippy/tests/ui/question_mark.stderr b/src/tools/clippy/tests/ui/question_mark.stderr
index 5f26a7ea2c3..0a48c4e80cb 100644
--- a/src/tools/clippy/tests/ui/question_mark.stderr
+++ b/src/tools/clippy/tests/ui/question_mark.stderr
@@ -94,29 +94,76 @@ LL | |         };
    | |_________^ help: replace it with: `self.opt?`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:131:5
+  --> tests/ui/question_mark.rs:137:5
    |
 LL | /     if f().is_none() {
 LL | |         return None;
 LL | |     }
    | |_____^ help: replace it with: `f()?;`
 
+error: this `match` expression can be replaced with `?`
+  --> tests/ui/question_mark.rs:141:16
+   |
+LL |       let _val = match f() {
+   |  ________________^
+LL | |         Some(val) => val,
+LL | |         None => return None,
+LL | |     };
+   | |_____^ help: try instead: `f()?`
+
+error: this `match` expression can be replaced with `?`
+  --> tests/ui/question_mark.rs:151:5
+   |
+LL | /     match f() {
+LL | |         Some(val) => val,
+LL | |         None => return None,
+LL | |     };
+   | |_____^ help: try instead: `f()?`
+
+error: this `match` expression can be replaced with `?`
+  --> tests/ui/question_mark.rs:156:5
+   |
+LL | /     match opt_none!() {
+LL | |         Some(x) => x,
+LL | |         None => return None,
+LL | |     };
+   | |_____^ help: try instead: `opt_none!()?`
+
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:143:13
+  --> tests/ui/question_mark.rs:182:13
    |
 LL |     let _ = if let Ok(x) = x { x } else { return x };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x?`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:145:5
+  --> tests/ui/question_mark.rs:184:5
    |
 LL | /     if x.is_err() {
 LL | |         return x;
 LL | |     }
    | |_____^ help: replace it with: `x?;`
 
+error: this `match` expression can be replaced with `?`
+  --> tests/ui/question_mark.rs:188:16
+   |
+LL |       let _val = match func_returning_result() {
+   |  ________________^
+LL | |         Ok(val) => val,
+LL | |         Err(err) => return Err(err),
+LL | |     };
+   | |_____^ help: try instead: `func_returning_result()?`
+
+error: this `match` expression can be replaced with `?`
+  --> tests/ui/question_mark.rs:193:5
+   |
+LL | /     match func_returning_result() {
+LL | |         Ok(val) => val,
+LL | |         Err(err) => return Err(err),
+LL | |     };
+   | |_____^ help: try instead: `func_returning_result()?`
+
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:213:5
+  --> tests/ui/question_mark.rs:284:5
    |
 LL | /     if let Err(err) = func_returning_result() {
 LL | |         return Err(err);
@@ -124,7 +171,7 @@ LL | |     }
    | |_____^ help: replace it with: `func_returning_result()?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:220:5
+  --> tests/ui/question_mark.rs:291:5
    |
 LL | /     if let Err(err) = func_returning_result() {
 LL | |         return Err(err);
@@ -132,7 +179,7 @@ LL | |     }
    | |_____^ help: replace it with: `func_returning_result()?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:297:13
+  --> tests/ui/question_mark.rs:368:13
    |
 LL | /             if a.is_none() {
 LL | |                 return None;
@@ -142,12 +189,12 @@ LL | |             }
    | |_____________^ help: replace it with: `a?;`
 
 error: this `let...else` may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:357:5
+  --> tests/ui/question_mark.rs:428:5
    |
 LL | /     let Some(v) = bar.foo.owned.clone() else {
 LL | |         return None;
 LL | |     };
    | |______^ help: replace it with: `let v = bar.foo.owned.clone()?;`
 
-error: aborting due to 17 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr
index 6403265a39c..6ef333f0cfd 100644
--- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr
@@ -6,7 +6,7 @@ LL | | /// A much longer explanation that goes into a lot more detail about
 LL | | /// how the thing works, possibly with doclinks and so one,
 LL | | /// and probably spanning a many rows. Blablabla, it needs to be over
 LL | | /// 200 characters so I needed to write something longeeeeeeer.
-   | |_
+   | |_^
    |
    = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
index 39926647f54..95f42349b9b 100644
--- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
@@ -23,7 +23,7 @@ error: first doc comment paragraph is too long
 LL | / /// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
 LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
 LL | | /// gravida non lacinia at, rhoncus eu lacus.
-   | |_
+   | |_^
 
 error: first doc comment paragraph is too long
   --> tests/ui/too_long_first_doc_paragraph.rs:36:1
@@ -32,7 +32,7 @@ LL | / /// Lorem
 LL | | /// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
 LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
 LL | | /// gravida non lacinia at, rhoncus eu lacus.
-   | |_
+   | |_^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
new file mode 100644
index 00000000000..2d932a70e9d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
@@ -0,0 +1,64 @@
+//@aux-build:proc_macros.rs
+#![warn(clippy::unnecessary_map_or)]
+#![allow(clippy::no_effect)]
+#![allow(clippy::eq_op)]
+#![allow(clippy::unnecessary_lazy_evaluations)]
+#[clippy::msrv = "1.70.0"]
+#[macro_use]
+extern crate proc_macros;
+
+fn main() {
+    // should trigger
+    let _ = (Some(5) == Some(5));
+    let _ = (Some(5) != Some(5));
+    let _ = (Some(5) == Some(5));
+    let _ = Some(5).is_some_and(|n| {
+        let _ = n;
+        6 >= 5
+    });
+    let _ = Some(vec![5]).is_some_and(|n| n == [5]);
+    let _ = Some(vec![1]).is_some_and(|n| vec![2] == n);
+    let _ = Some(5).is_some_and(|n| n == n);
+    let _ = Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 });
+    let _ = Ok::<Vec<i32>, i32>(vec![5]).is_ok_and(|n| n == [5]);
+    let _ = (Ok::<i32, i32>(5) == Ok(5));
+    let _ = (Some(5) == Some(5)).then(|| 1);
+
+    // shouldnt trigger
+    let _ = Some(5).map_or(true, |n| n == 5);
+    let _ = Some(5).map_or(true, |n| 5 == n);
+    macro_rules! x {
+        () => {
+            Some(1)
+        };
+    }
+    // methods lints dont fire on macros
+    let _ = x!().map_or(false, |n| n == 1);
+    let _ = x!().map_or(false, |n| n == vec![1][0]);
+
+    msrv_1_69();
+
+    external! {
+        let _ = Some(5).map_or(false, |n| n == 5);
+    }
+
+    with_span! {
+        let _ = Some(5).map_or(false, |n| n == 5);
+    }
+
+    // check for presence of PartialEq, and alter suggestion to use `is_ok_and` if absent
+    struct S;
+    let r: Result<i32, S> = Ok(3);
+    let _ = r.is_ok_and(|x| x == 7);
+
+    #[derive(PartialEq)]
+    struct S2;
+    let r: Result<i32, S2> = Ok(4);
+    let _ = (r == Ok(8));
+}
+
+#[clippy::msrv = "1.69.0"]
+fn msrv_1_69() {
+    // is_some_and added in 1.70.0
+    let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.rs b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
new file mode 100644
index 00000000000..4a9d69be1e9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
@@ -0,0 +1,67 @@
+//@aux-build:proc_macros.rs
+#![warn(clippy::unnecessary_map_or)]
+#![allow(clippy::no_effect)]
+#![allow(clippy::eq_op)]
+#![allow(clippy::unnecessary_lazy_evaluations)]
+#[clippy::msrv = "1.70.0"]
+#[macro_use]
+extern crate proc_macros;
+
+fn main() {
+    // should trigger
+    let _ = Some(5).map_or(false, |n| n == 5);
+    let _ = Some(5).map_or(true, |n| n != 5);
+    let _ = Some(5).map_or(false, |n| {
+        let _ = 1;
+        n == 5
+    });
+    let _ = Some(5).map_or(false, |n| {
+        let _ = n;
+        6 >= 5
+    });
+    let _ = Some(vec![5]).map_or(false, |n| n == [5]);
+    let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);
+    let _ = Some(5).map_or(false, |n| n == n);
+    let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
+    let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);
+    let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);
+    let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);
+
+    // shouldnt trigger
+    let _ = Some(5).map_or(true, |n| n == 5);
+    let _ = Some(5).map_or(true, |n| 5 == n);
+    macro_rules! x {
+        () => {
+            Some(1)
+        };
+    }
+    // methods lints dont fire on macros
+    let _ = x!().map_or(false, |n| n == 1);
+    let _ = x!().map_or(false, |n| n == vec![1][0]);
+
+    msrv_1_69();
+
+    external! {
+        let _ = Some(5).map_or(false, |n| n == 5);
+    }
+
+    with_span! {
+        let _ = Some(5).map_or(false, |n| n == 5);
+    }
+
+    // check for presence of PartialEq, and alter suggestion to use `is_ok_and` if absent
+    struct S;
+    let r: Result<i32, S> = Ok(3);
+    let _ = r.map_or(false, |x| x == 7);
+
+    #[derive(PartialEq)]
+    struct S2;
+    let r: Result<i32, S2> = Ok(4);
+    let _ = r.map_or(false, |x| x == 8);
+}
+
+#[clippy::msrv = "1.69.0"]
+fn msrv_1_69() {
+    // is_some_and added in 1.70.0
+    let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
new file mode 100644
index 00000000000..299a4e5da7a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
@@ -0,0 +1,99 @@
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:12:13
+   |
+LL |     let _ = Some(5).map_or(false, |n| n == 5);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) == Some(5))`
+   |
+   = note: `-D clippy::unnecessary-map-or` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_or)]`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:13:13
+   |
+LL |     let _ = Some(5).map_or(true, |n| n != 5);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) != Some(5))`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:14:13
+   |
+LL |       let _ = Some(5).map_or(false, |n| {
+   |  _____________^
+LL | |         let _ = 1;
+LL | |         n == 5
+LL | |     });
+   | |______^ help: use a standard comparison instead: `(Some(5) == Some(5))`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:18:13
+   |
+LL |       let _ = Some(5).map_or(false, |n| {
+   |  _____________^
+LL | |         let _ = n;
+LL | |         6 >= 5
+LL | |     });
+   | |______^
+   |
+help: use is_some_and instead
+   |
+LL ~     let _ = Some(5).is_some_and(|n| {
+LL +         let _ = n;
+LL +         6 >= 5
+LL ~     });
+   |
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:22:13
+   |
+LL |     let _ = Some(vec![5]).map_or(false, |n| n == [5]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(vec![5]).is_some_and(|n| n == [5])`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:23:13
+   |
+LL |     let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(vec![1]).is_some_and(|n| vec![2] == n)`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:24:13
+   |
+LL |     let _ = Some(5).map_or(false, |n| n == n);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(|n| n == n)`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:25:13
+   |
+LL |     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 })`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:26:13
+   |
+LL |     let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `Ok::<Vec<i32>, i32>(vec![5]).is_ok_and(|n| n == [5])`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:27:13
+   |
+LL |     let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Ok::<i32, i32>(5) == Ok(5))`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:28:13
+   |
+LL |     let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) == Some(5))`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:55:13
+   |
+LL |     let _ = r.map_or(false, |x| x == 7);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `r.is_ok_and(|x| x == 7)`
+
+error: this `map_or` is redundant
+  --> tests/ui/unnecessary_map_or.rs:60:13
+   |
+LL |     let _ = r.map_or(false, |x| x == 8);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(r == Ok(8))`
+
+error: aborting due to 13 previous errors
+
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index cef6b525a7b..b784bdb7139 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -14,7 +14,7 @@ unified-diff = "0.2.1"
 getopts = "0.2"
 indexmap = "2.0.0"
 miropt-test-tools = { path = "../miropt-test-tools" }
-build_helper = { path = "../build_helper" }
+build_helper = { path = "../../build_helper" }
 tracing = "0.1"
 tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] }
 regex = "1.0"
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index 8570a8ce115..bdd0b80b395 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -25,6 +25,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "dont-check-failure-status",
     "edition",
     "error-pattern",
+    "exact-llvm-major-version",
     "exec-env",
     "failure-status",
     "filecheck-flags",
@@ -35,6 +36,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "ignore-64bit",
     "ignore-aarch64",
     "ignore-aarch64-unknown-linux-gnu",
+    "ignore-aix",
     "ignore-android",
     "ignore-apple",
     "ignore-arm",
@@ -118,6 +120,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "incremental",
     "known-bug",
     "llvm-cov-flags",
+    "max-llvm-major-version",
     "min-cdb-version",
     "min-gdb-version",
     "min-lldb-version",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 300a03e5f33..3539e85ba63 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -1547,6 +1547,20 @@ fn ignore_llvm(config: &Config, line: &str) -> IgnoreDecision {
                 };
             }
         } else if let Some(version_string) =
+            config.parse_name_value_directive(line, "max-llvm-major-version")
+        {
+            let max_version = extract_llvm_version(&version_string);
+            // Ignore if actual major version is larger than the maximum required major version.
+            if actual_version.major > max_version.major {
+                return IgnoreDecision::Ignore {
+                    reason: format!(
+                        "ignored when the LLVM version ({actual_version}) is newer than major\
+                        version {}",
+                        max_version.major
+                    ),
+                };
+            }
+        } else if let Some(version_string) =
             config.parse_name_value_directive(line, "min-system-llvm-version")
         {
             let min_version = extract_llvm_version(&version_string);
@@ -1585,6 +1599,19 @@ fn ignore_llvm(config: &Config, line: &str) -> IgnoreDecision {
                     };
                 }
             }
+        } else if let Some(version_string) =
+            config.parse_name_value_directive(line, "exact-llvm-major-version")
+        {
+            // Syntax is "exact-llvm-major-version: <version>"
+            let version = extract_llvm_version(&version_string);
+            if actual_version.major != version.major {
+                return IgnoreDecision::Ignore {
+                    reason: format!(
+                        "ignored when the actual LLVM major version is {}, but the test only targets major version {}",
+                        actual_version.major, version.major
+                    ),
+                };
+            }
         }
     }
     IgnoreDecision::Continue
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index c3fb8d4ab80..4d75c38dd32 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -284,6 +284,30 @@ fn llvm_version() {
 
     let config: Config = cfg().llvm_version("10.0.0").build();
     assert!(!check_ignore(&config, "//@ min-llvm-version: 9.0"));
+
+    let config: Config = cfg().llvm_version("10.0.0").build();
+    assert!(check_ignore(&config, "//@ exact-llvm-major-version: 9.0"));
+
+    let config: Config = cfg().llvm_version("9.0.0").build();
+    assert!(check_ignore(&config, "//@ exact-llvm-major-version: 10.0"));
+
+    let config: Config = cfg().llvm_version("10.0.0").build();
+    assert!(!check_ignore(&config, "//@ exact-llvm-major-version: 10.0"));
+
+    let config: Config = cfg().llvm_version("10.0.0").build();
+    assert!(!check_ignore(&config, "//@ exact-llvm-major-version: 10"));
+
+    let config: Config = cfg().llvm_version("10.6.2").build();
+    assert!(!check_ignore(&config, "//@ exact-llvm-major-version: 10"));
+
+    let config: Config = cfg().llvm_version("19.0.0").build();
+    assert!(!check_ignore(&config, "//@ max-llvm-major-version: 19"));
+
+    let config: Config = cfg().llvm_version("19.1.2").build();
+    assert!(!check_ignore(&config, "//@ max-llvm-major-version: 19"));
+
+    let config: Config = cfg().llvm_version("20.0.0").build();
+    assert!(check_ignore(&config, "//@ max-llvm-major-version: 19"));
 }
 
 #[test]
diff --git a/src/tools/opt-dist/Cargo.toml b/src/tools/opt-dist/Cargo.toml
index d34f8ad0520..d0413911014 100644
--- a/src/tools/opt-dist/Cargo.toml
+++ b/src/tools/opt-dist/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
-build_helper = { path = "../build_helper" }
+build_helper = { path = "../../build_helper" }
 env_logger = "0.11"
 log = "0.4"
 anyhow = { version = "1", features = ["backtrace"] }
diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml
index 3affa199fa5..3c172b2d956 100644
--- a/src/tools/run-make-support/Cargo.toml
+++ b/src/tools/run-make-support/Cargo.toml
@@ -10,7 +10,7 @@ similar = "2.5.0"
 wasmparser = { version = "0.216", default-features = false, features = ["std"] }
 regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace
 gimli = "0.31.0"
-build_helper = { path = "../build_helper" }
+build_helper = { path = "../../build_helper" }
 serde_json = "1.0"
 libc = "0.2"
 
diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs
index 35d983dc607..494daeca963 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -5,7 +5,7 @@ use crate::command::Command;
 use crate::env::env_var;
 use crate::path_helpers::cwd;
 use crate::util::set_host_rpath;
-use crate::{is_darwin, is_msvc, is_windows, uname};
+use crate::{is_aix, is_darwin, is_msvc, is_windows, uname};
 
 /// Construct a new `rustc` invocation. This will automatically set the library
 /// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
@@ -346,7 +346,7 @@ impl Rustc {
         //     endif
         // endif
         // ```
-        let flag = if is_windows() {
+        if is_windows() {
             // So this is a bit hacky: we can't use the DLL version of libstdc++ because
             // it pulls in the DLL version of libgcc, which means that we end up with 2
             // instances of the DW2 unwinding implementation. This is a problem on
@@ -362,18 +362,19 @@ impl Rustc {
             // So we end up with the following hack: we link use static:-bundle to only
             // link the parts of libstdc++ that we actually use, which doesn't include
             // the dependency on the pthreads DLL.
-            if is_msvc() { None } else { Some("-lstatic:-bundle=stdc++") }
+            if !is_msvc() {
+                self.cmd.arg("-lstatic:-bundle=stdc++");
+            };
         } else if is_darwin() {
-            Some("-lc++")
+            self.cmd.arg("-lc++");
+        } else if is_aix() {
+            self.cmd.arg("-lc++");
+            self.cmd.arg("-lc++abi");
         } else {
-            match &uname()[..] {
-                "FreeBSD" | "SunOS" | "OpenBSD" => None,
-                _ => Some("-lstdc++"),
-            }
+            if !matches!(&uname()[..], "FreeBSD" | "SunOS" | "OpenBSD") {
+                self.cmd.arg("-lstdc++");
+            };
         };
-        if let Some(flag) = flag {
-            self.cmd.arg(flag);
-        }
         self
     }
 }
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 5765cb97a7e..6cf0aedfe9f 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -78,7 +78,7 @@ pub use env::{env_var, env_var_os, set_current_dir};
 pub use run::{cmd, run, run_fail, run_with_args};
 
 /// Helpers for checking target information.
-pub use targets::{is_darwin, is_msvc, is_windows, llvm_components_contain, target, uname, apple_os};
+pub use targets::{is_aix, is_darwin, is_msvc, is_windows, llvm_components_contain, target, uname, apple_os};
 
 /// Helpers for building names of output artifacts that are potentially target-specific.
 pub use artifact_names::{
diff --git a/src/tools/run-make-support/src/targets.rs b/src/tools/run-make-support/src/targets.rs
index 896abb73fc1..ae004fd0cbd 100644
--- a/src/tools/run-make-support/src/targets.rs
+++ b/src/tools/run-make-support/src/targets.rs
@@ -28,6 +28,12 @@ pub fn is_darwin() -> bool {
     target().contains("darwin")
 }
 
+/// Check if target uses AIX.
+#[must_use]
+pub fn is_aix() -> bool {
+    target().contains("aix")
+}
+
 /// Get the target OS on Apple operating systems.
 #[must_use]
 pub fn apple_os() -> &'static str {
diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
index e0135a0269a..5258d9ddd3a 100644
--- a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
@@ -53,7 +53,6 @@ jobs:
           cargo workspaces rename --from project-model project_model
           cargo workspaces rename --from test-fixture test_fixture
           cargo workspaces rename --from test-utils test_utils
-          cargo workspaces rename --from text-edit text_edit
           # Remove library crates from the workspaces so we don't auto-publish them as well
           sed -i 's/ "lib\/\*",//' ./Cargo.toml
           cargo workspaces rename ra_ap_%n
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index 6d07dc8f9be..2a13f74aac7 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -13,7 +13,6 @@ use syntax::{ast, Parse};
 use triomphe::Arc;
 
 use crate::{
-    attr::Attrs,
     db::DefDatabase,
     expander::{Expander, Mark},
     item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId},
@@ -37,8 +36,6 @@ pub struct FunctionData {
     pub name: Name,
     pub params: Box<[TypeRefId]>,
     pub ret_type: TypeRefId,
-    // FIXME: why are these stored here? They should be accessed via the query
-    pub attrs: Attrs,
     pub visibility: RawVisibility,
     pub abi: Option<Symbol>,
     pub legacy_const_generics_indices: Option<Box<Box<[u32]>>>,
@@ -115,7 +112,6 @@ impl FunctionData {
                 .filter_map(|(_, param)| param.type_ref)
                 .collect(),
             ret_type: func.ret_type,
-            attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
             visibility,
             abi: func.abi.clone(),
             legacy_const_generics_indices,
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
index 5c25a55362e..95dfe56ff54 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
@@ -633,6 +633,19 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
         "the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
     ),
     rustc_attr!(
+        rustc_intrinsic, Normal, template!(Word), ErrorFollowing,
+        "the `#[rustc_intrinsic]` attribute is used to declare intrinsics with function bodies",
+    ),
+    rustc_attr!(
+        rustc_no_mir_inline, Normal, template!(Word), WarnFollowing,
+        "#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen"
+    ),
+    rustc_attr!(
+        rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing,
+        "the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies",
+    ),
+
+    rustc_attr!(
         rustc_deprecated_safe_2024, Normal, template!(Word), WarnFollowing,
         "the `#[rustc_safe_intrinsic]` marks functions as unsafe in Rust 2024",
     ),
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
index 05cd7bd37b4..53795c0b600 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
@@ -381,8 +381,9 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
         TyKind::Error.intern(Interner)
     }
 
+    // object safety was renamed to dyn-compatibility but still remains here in chalk.
+    // This will be removed since we are going to migrate to next-gen trait solver.
     fn is_object_safe(&self, trait_id: chalk_ir::TraitId<Interner>) -> bool {
-        // FIXME: When cargo is updated, change to dyn_compatibility
         let trait_ = from_chalk_trait_id(trait_id);
         crate::dyn_compatibility::dyn_compatibility(self.db, trait_).is_none()
     }
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs
index c5706172b20..c1ac7ae173b 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs
@@ -4,9 +4,8 @@ use super::*;
 fn size_of() {
     check_number(
         r#"
-        extern "rust-intrinsic" {
-            pub fn size_of<T>() -> usize;
-        }
+        #[rustc_intrinsic]
+        pub fn size_of<T>() -> usize;
 
         const GOAL: usize = size_of::<i32>();
         "#,
@@ -19,9 +18,8 @@ fn size_of_val() {
     check_number(
         r#"
         //- minicore: coerce_unsized
-        extern "rust-intrinsic" {
-            pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
-        }
+        #[rustc_intrinsic]
+        pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
 
         struct X(i32, u8);
 
@@ -32,9 +30,8 @@ fn size_of_val() {
     check_number(
         r#"
         //- minicore: coerce_unsized
-        extern "rust-intrinsic" {
-            pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
-        }
+        #[rustc_intrinsic]
+        pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
 
         const GOAL: usize = {
             let it: &[i32] = &[1, 2, 3];
@@ -48,9 +45,8 @@ fn size_of_val() {
         //- minicore: coerce_unsized, transmute
         use core::mem::transmute;
 
-        extern "rust-intrinsic" {
-            pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
-        }
+        #[rustc_intrinsic]
+        pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
 
         struct X {
             x: i64,
@@ -70,9 +66,8 @@ fn size_of_val() {
         //- minicore: coerce_unsized, transmute
         use core::mem::transmute;
 
-        extern "rust-intrinsic" {
-            pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
-        }
+        #[rustc_intrinsic]
+        pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
 
         struct X {
             x: i32,
@@ -90,9 +85,8 @@ fn size_of_val() {
     check_number(
         r#"
         //- minicore: coerce_unsized, fmt, builtin_impls, dispatch_from_dyn
-        extern "rust-intrinsic" {
-            pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
-        }
+        #[rustc_intrinsic]
+        pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
 
         const GOAL: usize = {
             let x: &i16 = &5;
@@ -106,9 +100,8 @@ fn size_of_val() {
     check_number(
         r#"
         //- minicore: coerce_unsized
-        extern "rust-intrinsic" {
-            pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
-        }
+        #[rustc_intrinsic]
+        pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
 
         const GOAL: usize = {
             size_of_val("salam")
@@ -123,9 +116,8 @@ fn min_align_of_val() {
     check_number(
         r#"
         //- minicore: coerce_unsized
-        extern "rust-intrinsic" {
-            pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
-        }
+        #[rustc_intrinsic]
+        pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
 
         struct X(i32, u8);
 
@@ -136,9 +128,8 @@ fn min_align_of_val() {
     check_number(
         r#"
         //- minicore: coerce_unsized
-        extern "rust-intrinsic" {
-            pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
-        }
+        #[rustc_intrinsic]
+        pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
 
         const GOAL: usize = {
             let x: &[i32] = &[1, 2, 3];
@@ -153,9 +144,8 @@ fn min_align_of_val() {
 fn type_name() {
     check_str(
         r#"
-        extern "rust-intrinsic" {
-            pub fn type_name<T: ?Sized>() -> &'static str;
-        }
+        #[rustc_intrinsic]
+        pub fn type_name<T: ?Sized>() -> &'static str;
 
         const GOAL: &str = type_name::<i32>();
         "#,
@@ -163,9 +153,8 @@ fn type_name() {
     );
     check_str(
         r#"
-        extern "rust-intrinsic" {
-            pub fn type_name<T: ?Sized>() -> &'static str;
-        }
+        #[rustc_intrinsic]
+        pub fn type_name<T: ?Sized>() -> &'static str;
 
         mod mod1 {
             pub mod mod2 {
@@ -183,9 +172,8 @@ fn type_name() {
 fn transmute() {
     check_number(
         r#"
-        extern "rust-intrinsic" {
-            pub fn transmute<T, U>(e: T) -> U;
-        }
+        #[rustc_intrinsic]
+        pub fn transmute<T, U>(e: T) -> U;
 
         const GOAL: i32 = transmute((1i16, 1i16));
         "#,
@@ -197,10 +185,10 @@ fn transmute() {
 fn read_via_copy() {
     check_number(
         r#"
-        extern "rust-intrinsic" {
-            pub fn read_via_copy<T>(e: *const T) -> T;
-            pub fn volatile_load<T>(e: *const T) -> T;
-        }
+        #[rustc_intrinsic]
+        pub fn read_via_copy<T>(e: *const T) -> T;
+        #[rustc_intrinsic]
+        pub fn volatile_load<T>(e: *const T) -> T;
 
         const GOAL: i32 = {
             let x = 2;
@@ -399,9 +387,14 @@ fn discriminant_value() {
 fn likely() {
     check_number(
         r#"
-        extern "rust-intrinsic" {
-            pub fn likely(b: bool) -> bool;
-            pub fn unlikely(b: bool) -> bool;
+        #[rustc_intrinsic]
+        pub const fn likely(b: bool) -> bool {
+            b
+        }
+
+        #[rustc_intrinsic]
+        pub const fn unlikely(b: bool) -> bool {
+            b
         }
 
         const GOAL: bool = likely(true) && unlikely(true) && !likely(false) && !unlikely(false);
@@ -704,9 +697,8 @@ fn rotate() {
     );
     check_number(
         r#"
-        extern "rust-intrinsic" {
-            pub fn rotate_right<T: Copy>(x: T, y: T) -> T;
-        }
+        #[rustc_intrinsic]
+        pub fn rotate_right<T: Copy>(x: T, y: T) -> T;
 
         const GOAL: i32 = rotate_right(10006016, 1020315);
         "#,
@@ -721,9 +713,8 @@ fn simd() {
         pub struct i8x16(
             i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,
         );
-        extern "platform-intrinsic" {
-            pub fn simd_bitmask<T, U>(x: T) -> U;
-        }
+        #[rustc_intrinsic]
+        pub fn simd_bitmask<T, U>(x: T) -> U;
         const GOAL: u16 = simd_bitmask(i8x16(
             0, 1, 0, 0, 2, 255, 100, 0, 50, 0, 1, 1, 0, 0, 0, 0
         ));
@@ -735,10 +726,10 @@ fn simd() {
         pub struct i8x16(
             i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,i8,
         );
-        extern "platform-intrinsic" {
-            pub fn simd_lt<T, U>(x: T, y: T) -> U;
-            pub fn simd_bitmask<T, U>(x: T) -> U;
-        }
+        #[rustc_intrinsic]
+        pub fn simd_lt<T, U>(x: T, y: T) -> U;
+        #[rustc_intrinsic]
+        pub fn simd_bitmask<T, U>(x: T) -> U;
         const GOAL: u16 = simd_bitmask(simd_lt::<i8x16, i8x16>(
             i8x16(
                 -105, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
index c9ab0acc084..4991d173b9c 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -201,7 +201,7 @@ impl<'a> DeclValidator<'a> {
 
             // Don't run the lint on extern "[not Rust]" fn items with the
             // #[no_mangle] attribute.
-            let no_mangle = data.attrs.by_key(&sym::no_mangle).exists();
+            let no_mangle = self.db.attrs(func.into()).by_key(&sym::no_mangle).exists();
             if no_mangle && data.abi.as_ref().is_some_and(|abi| *abi != sym::Rust) {
                 cov_mark::hit!(extern_func_no_mangle_ignored);
             } else {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs
index 3d21785a70a..fadf8aca998 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility.rs
@@ -472,7 +472,7 @@ fn receiver_is_dispatchable(
         return false;
     };
 
-    // `self: Self` can't be dispatched on, but this is already considered dyn compatible
+    // `self: Self` can't be dispatched on, but this is already considered dyn-compatible
     // See rustc's comment on https://github.com/rust-lang/rust/blob/3f121b9461cce02a703a0e7e450568849dfaa074/compiler/rustc_trait_selection/src/traits/object_safety.rs#L433-L437
     if sig
         .skip_binders()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs
index 3f3e68eeb1c..8a56bd28b59 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/dyn_compatibility/tests.rs
@@ -66,7 +66,7 @@ fn check_dyn_compatibility<'a>(
             });
             ControlFlow::Continue(())
         });
-        assert_eq!(osvs, expected, "Dyn Compatibility violations for `{name}` do not match;");
+        assert_eq!(osvs, expected, "dyn-compatibility violations for `{name}` do not match;");
     }
 
     let remains: Vec<_> = expected.keys().collect();
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
index 9c1d8bcf36f..22e7b1d920f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -98,7 +98,7 @@ pub use mapping::{
 };
 pub use method_resolution::check_orphan_rules;
 pub use traits::TraitEnvironment;
-pub use utils::{all_super_traits, is_fn_unsafe_to_call};
+pub use utils::{all_super_traits, direct_super_traits, is_fn_unsafe_to_call};
 
 pub use chalk_ir::{
     cast::Cast,
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
index 0cdad74a4f6..0a78f4a5b24 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
@@ -9,7 +9,7 @@ use hir_def::{
     resolver::HasResolver,
 };
 use hir_expand::name::Name;
-use intern::sym;
+use intern::{sym, Symbol};
 
 use crate::{
     error_lifetime,
@@ -54,49 +54,32 @@ impl Evaluator<'_> {
         }
 
         let function_data = self.db.function_data(def);
-        let is_intrinsic = match &function_data.abi {
-            Some(abi) => *abi == sym::rust_dash_intrinsic,
-            None => match def.lookup(self.db.upcast()).container {
-                hir_def::ItemContainerId::ExternBlockId(block) => {
-                    let id = block.lookup(self.db.upcast()).id;
-                    id.item_tree(self.db.upcast())[id.value].abi.as_ref()
-                        == Some(&sym::rust_dash_intrinsic)
-                }
-                _ => false,
-            },
-        };
+        let attrs = self.db.attrs(def.into());
+        let is_intrinsic = attrs.by_key(&sym::rustc_intrinsic).exists()
+            // Keep this around for a bit until extern "rustc-intrinsic" abis are no longer used
+            || (match &function_data.abi {
+                Some(abi) => *abi == sym::rust_dash_intrinsic,
+                None => match def.lookup(self.db.upcast()).container {
+                    hir_def::ItemContainerId::ExternBlockId(block) => {
+                        let id = block.lookup(self.db.upcast()).id;
+                        id.item_tree(self.db.upcast())[id.value].abi.as_ref()
+                            == Some(&sym::rust_dash_intrinsic)
+                    }
+                    _ => false,
+                },
+            });
+
         if is_intrinsic {
-            self.exec_intrinsic(
+            return self.exec_intrinsic(
                 function_data.name.as_str(),
                 args,
                 generic_args,
                 destination,
                 locals,
                 span,
-            )?;
-            return Ok(true);
-        }
-        let is_platform_intrinsic = match &function_data.abi {
-            Some(abi) => *abi == sym::platform_dash_intrinsic,
-            None => match def.lookup(self.db.upcast()).container {
-                hir_def::ItemContainerId::ExternBlockId(block) => {
-                    let id = block.lookup(self.db.upcast()).id;
-                    id.item_tree(self.db.upcast())[id.value].abi.as_ref()
-                        == Some(&sym::platform_dash_intrinsic)
-                }
-                _ => false,
-            },
-        };
-        if is_platform_intrinsic {
-            self.exec_platform_intrinsic(
-                function_data.name.as_str(),
-                args,
-                generic_args,
-                destination,
-                locals,
-                span,
-            )?;
-            return Ok(true);
+                !function_data.has_body()
+                    || attrs.by_key(&sym::rustc_intrinsic_must_be_overridden).exists(),
+            );
         }
         let is_extern_c = match def.lookup(self.db.upcast()).container {
             hir_def::ItemContainerId::ExternBlockId(block) => {
@@ -106,27 +89,25 @@ impl Evaluator<'_> {
             _ => false,
         };
         if is_extern_c {
-            self.exec_extern_c(
-                function_data.name.as_str(),
-                args,
-                generic_args,
-                destination,
-                locals,
-                span,
-            )?;
-            return Ok(true);
+            return self
+                .exec_extern_c(
+                    function_data.name.as_str(),
+                    args,
+                    generic_args,
+                    destination,
+                    locals,
+                    span,
+                )
+                .map(|()| true);
         }
-        let alloc_fn = function_data
-            .attrs
-            .iter()
-            .filter_map(|it| it.path().as_ident())
-            .map(|it| it.as_str())
-            .find(|it| {
+
+        let alloc_fn =
+            attrs.iter().filter_map(|it| it.path().as_ident()).map(|it| it.symbol()).find(|it| {
                 [
-                    "rustc_allocator",
-                    "rustc_deallocator",
-                    "rustc_reallocator",
-                    "rustc_allocator_zeroed",
+                    &sym::rustc_allocator,
+                    &sym::rustc_deallocator,
+                    &sym::rustc_reallocator,
+                    &sym::rustc_allocator_zeroed,
                 ]
                 .contains(it)
             });
@@ -270,12 +251,12 @@ impl Evaluator<'_> {
 
     fn exec_alloc_fn(
         &mut self,
-        alloc_fn: &str,
+        alloc_fn: &Symbol,
         args: &[IntervalAndTy],
         destination: Interval,
     ) -> Result<()> {
         match alloc_fn {
-            "rustc_allocator_zeroed" | "rustc_allocator" => {
+            _ if *alloc_fn == sym::rustc_allocator_zeroed || *alloc_fn == sym::rustc_allocator => {
                 let [size, align] = args else {
                     return Err(MirEvalError::InternalError(
                         "rustc_allocator args are not provided".into(),
@@ -286,8 +267,8 @@ impl Evaluator<'_> {
                 let result = self.heap_allocate(size, align)?;
                 destination.write_from_bytes(self, &result.to_bytes())?;
             }
-            "rustc_deallocator" => { /* no-op for now */ }
-            "rustc_reallocator" => {
+            _ if *alloc_fn == sym::rustc_deallocator => { /* no-op for now */ }
+            _ if *alloc_fn == sym::rustc_reallocator => {
                 let [ptr, old_size, align, new_size] = args else {
                     return Err(MirEvalError::InternalError(
                         "rustc_allocator args are not provided".into(),
@@ -603,21 +584,6 @@ impl Evaluator<'_> {
         }
     }
 
-    fn exec_platform_intrinsic(
-        &mut self,
-        name: &str,
-        args: &[IntervalAndTy],
-        generic_args: &Substitution,
-        destination: Interval,
-        locals: &Locals,
-        span: MirSpan,
-    ) -> Result<()> {
-        if let Some(name) = name.strip_prefix("simd_") {
-            return self.exec_simd_intrinsic(name, args, generic_args, destination, locals, span);
-        }
-        not_supported!("unknown platform intrinsic {name}");
-    }
-
     fn exec_intrinsic(
         &mut self,
         name: &str,
@@ -626,9 +592,17 @@ impl Evaluator<'_> {
         destination: Interval,
         locals: &Locals,
         span: MirSpan,
-    ) -> Result<()> {
+        needs_override: bool,
+    ) -> Result<bool> {
         if let Some(name) = name.strip_prefix("atomic_") {
-            return self.exec_atomic_intrinsic(name, args, generic_args, destination, locals, span);
+            return self
+                .exec_atomic_intrinsic(name, args, generic_args, destination, locals, span)
+                .map(|()| true);
+        }
+        if let Some(name) = name.strip_prefix("simd_") {
+            return self
+                .exec_simd_intrinsic(name, args, generic_args, destination, locals, span)
+                .map(|()| true);
         }
         // FIXME(#17451): Add `f16` and `f128` intrinsics.
         if let Some(name) = name.strip_suffix("f64") {
@@ -701,7 +675,7 @@ impl Evaluator<'_> {
                 }
                 _ => not_supported!("unknown f64 intrinsic {name}"),
             };
-            return destination.write_from_bytes(self, &result.to_le_bytes());
+            return destination.write_from_bytes(self, &result.to_le_bytes()).map(|()| true);
         }
         if let Some(name) = name.strip_suffix("f32") {
             let result = match name {
@@ -773,7 +747,7 @@ impl Evaluator<'_> {
                 }
                 _ => not_supported!("unknown f32 intrinsic {name}"),
             };
-            return destination.write_from_bytes(self, &result.to_le_bytes());
+            return destination.write_from_bytes(self, &result.to_le_bytes()).map(|()| true);
         }
         match name {
             "size_of" => {
@@ -1146,12 +1120,6 @@ impl Evaluator<'_> {
                 };
                 destination.write_from_interval(self, arg.interval)
             }
-            "likely" | "unlikely" => {
-                let [arg] = args else {
-                    return Err(MirEvalError::InternalError("likely arg is not provided".into()));
-                };
-                destination.write_from_interval(self, arg.interval)
-            }
             "ctpop" => {
                 let [arg] = args else {
                     return Err(MirEvalError::InternalError("ctpop arg is not provided".into()));
@@ -1296,7 +1264,7 @@ impl Evaluator<'_> {
                             None,
                             span,
                         )?;
-                        return Ok(());
+                        return Ok(true);
                     }
                 }
                 not_supported!("FnOnce was not available for executing const_eval_select");
@@ -1349,8 +1317,10 @@ impl Evaluator<'_> {
                 self.write_memory_using_ref(dst, size)?.fill(val);
                 Ok(())
             }
-            _ => not_supported!("unknown intrinsic {name}"),
+            _ if needs_override => not_supported!("intrinsic {name} is not implemented"),
+            _ => return Ok(false),
         }
+        .map(|()| true)
     }
 
     fn size_align_of_unsized(
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
index 0a436ff2b41..28bda1e10e5 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -43,6 +43,17 @@ pub(crate) fn fn_traits(
         .flat_map(|it| it.as_trait())
 }
 
+/// Returns an iterator over the direct super traits (including the trait itself).
+pub fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[TraitId; 4]> {
+    let mut result = smallvec![trait_];
+    direct_super_traits_cb(db, trait_, |tt| {
+        if !result.contains(&tt) {
+            result.push(tt);
+        }
+    });
+    result
+}
+
 /// Returns an iterator over the whole super trait hierarchy (including the
 /// trait itself).
 pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[TraitId; 4]> {
@@ -54,7 +65,7 @@ pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[Trai
     while let Some(&t) = result.get(i) {
         // yeah this is quadratic, but trait hierarchies should be flat
         // enough that this doesn't matter
-        direct_super_traits(db, t, |tt| {
+        direct_super_traits_cb(db, t, |tt| {
             if !result.contains(&tt) {
                 result.push(tt);
             }
@@ -153,7 +164,7 @@ impl Iterator for ClauseElaborator<'_> {
     }
 }
 
-fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
+fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
     let resolver = trait_.resolver(db);
     let generic_params = db.generic_params(trait_.into());
     let trait_self = generic_params.trait_self_param();
@@ -259,25 +270,25 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
         return true;
     }
 
+    let is_intrinsic = db.attrs(func.into()).by_key(&sym::rustc_intrinsic).exists()
+        || data.abi.as_ref() == Some(&sym::rust_dash_intrinsic);
+
     let loc = func.lookup(db.upcast());
     match loc.container {
         hir_def::ItemContainerId::ExternBlockId(block) => {
-            // Function in an `extern` block are always unsafe to call, except when
-            // it is marked as `safe` or it has `"rust-intrinsic"` ABI there are a
-            // few exceptions.
-            let id = block.lookup(db.upcast()).id;
-
-            let is_intrinsic =
-                id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic);
-
-            if is_intrinsic {
+            if is_intrinsic || {
+                let id = block.lookup(db.upcast()).id;
+                id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic)
+            } {
                 // Intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
-                !data.attrs.by_key(&sym::rustc_safe_intrinsic).exists()
+                !db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists()
             } else {
-                // Extern items without `safe` modifier are always unsafe
+                // Function in an `extern` block are always unsafe to call, except when
+                // it is marked as `safe`.
                 !data.is_safe()
             }
         }
+        _ if is_intrinsic => !db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists(),
         _ => false,
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index ebd84fd2be2..c9498b3aead 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -68,7 +68,7 @@ use hir_ty::{
     all_super_traits, autoderef, check_orphan_rules,
     consteval::{try_const_usize, unknown_const_as_generic, ConstExt},
     diagnostics::BodyValidationDiagnostic,
-    error_lifetime, known_const_to_ast,
+    direct_super_traits, error_lifetime, known_const_to_ast,
     layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
     method_resolution,
     mir::{interpret_mir, MutBorrowKind},
@@ -2246,35 +2246,33 @@ impl Function {
 
     /// Does this function have `#[test]` attribute?
     pub fn is_test(self, db: &dyn HirDatabase) -> bool {
-        db.function_data(self.id).attrs.is_test()
+        db.attrs(self.id.into()).is_test()
     }
 
     /// is this a `fn main` or a function with an `export_name` of `main`?
     pub fn is_main(self, db: &dyn HirDatabase) -> bool {
-        let data = db.function_data(self.id);
-        data.attrs.export_name() == Some(&sym::main)
-            || self.module(db).is_crate_root() && data.name == sym::main
+        db.attrs(self.id.into()).export_name() == Some(&sym::main)
+            || self.module(db).is_crate_root() && db.function_data(self.id).name == sym::main
     }
 
     /// Is this a function with an `export_name` of `main`?
     pub fn exported_main(self, db: &dyn HirDatabase) -> bool {
-        let data = db.function_data(self.id);
-        data.attrs.export_name() == Some(&sym::main)
+        db.attrs(self.id.into()).export_name() == Some(&sym::main)
     }
 
     /// Does this function have the ignore attribute?
     pub fn is_ignore(self, db: &dyn HirDatabase) -> bool {
-        db.function_data(self.id).attrs.is_ignore()
+        db.attrs(self.id.into()).is_ignore()
     }
 
     /// Does this function have `#[bench]` attribute?
     pub fn is_bench(self, db: &dyn HirDatabase) -> bool {
-        db.function_data(self.id).attrs.is_bench()
+        db.attrs(self.id.into()).is_bench()
     }
 
     /// Is this function marked as unstable with `#[feature]` attribute?
     pub fn is_unstable(self, db: &dyn HirDatabase) -> bool {
-        db.function_data(self.id).attrs.is_unstable()
+        db.attrs(self.id.into()).is_unstable()
     }
 
     pub fn is_unsafe_to_call(self, db: &dyn HirDatabase) -> bool {
@@ -2289,8 +2287,7 @@ impl Function {
     }
 
     pub fn as_proc_macro(self, db: &dyn HirDatabase) -> Option<Macro> {
-        let function_data = db.function_data(self.id);
-        let attrs = &function_data.attrs;
+        let attrs = db.attrs(self.id.into());
         // FIXME: Store this in FunctionData flags?
         if !(attrs.is_proc_macro()
             || attrs.is_proc_macro_attribute()
@@ -2707,13 +2704,22 @@ impl Trait {
         db.trait_data(self.id).name.clone()
     }
 
+    pub fn direct_supertraits(self, db: &dyn HirDatabase) -> Vec<Trait> {
+        let traits = direct_super_traits(db.upcast(), self.into());
+        traits.iter().map(|tr| Trait::from(*tr)).collect()
+    }
+
+    pub fn all_supertraits(self, db: &dyn HirDatabase) -> Vec<Trait> {
+        let traits = all_super_traits(db.upcast(), self.into());
+        traits.iter().map(|tr| Trait::from(*tr)).collect()
+    }
+
     pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
         db.trait_data(self.id).items.iter().map(|(_name, it)| (*it).into()).collect()
     }
 
     pub fn items_with_supertraits(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
-        let traits = all_super_traits(db.upcast(), self.into());
-        traits.iter().flat_map(|tr| Trait::from(*tr).items(db)).collect()
+        self.all_supertraits(db).into_iter().flat_map(|tr| tr.items(db)).collect()
     }
 
     pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
diff --git a/src/tools/rust-analyzer/crates/ide/src/file_structure.rs b/src/tools/rust-analyzer/crates/ide/src/file_structure.rs
index 055080ad17b..5ef65c209ca 100644
--- a/src/tools/rust-analyzer/crates/ide/src/file_structure.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/file_structure.rs
@@ -19,6 +19,7 @@ pub struct StructureNode {
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub enum StructureNodeKind {
     SymbolKind(SymbolKind),
+    ExternBlock,
     Region,
 }
 
@@ -158,6 +159,7 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
             ast::Trait(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Trait)),
             ast::TraitAlias(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::TraitAlias)),
             ast::Module(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Module)),
+            ast::Macro(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Macro)),
             ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty(), StructureNodeKind::SymbolKind(SymbolKind::TypeAlias)),
             ast::RecordField(it) => decl_with_type_ref(&it, it.ty(), StructureNodeKind::SymbolKind(SymbolKind::Field)),
             ast::Const(it) => decl_with_type_ref(&it, it.ty(), StructureNodeKind::SymbolKind(SymbolKind::Const)),
@@ -205,7 +207,23 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
 
                 Some(node)
             },
-            ast::Macro(it) => decl(it, StructureNodeKind::SymbolKind(SymbolKind::Macro)),
+            ast::ExternBlock(it) => {
+                let mut label = "extern".to_owned();
+                let abi = it.abi()?;
+                if let Some(abi) = abi.string_token() {
+                    label.push(' ');
+                    label.push_str(abi.text());
+                }
+                Some(StructureNode {
+                    parent: None,
+                    label,
+                    navigation_range: abi.syntax().text_range(),
+                    node_range: it.syntax().text_range(),
+                    kind: StructureNodeKind::ExternBlock,
+                    detail: None,
+                    deprecated: false,
+                })
+            },
             _ => None,
         }
     }
@@ -327,6 +345,8 @@ fn f() {}
 fn g() {}
 }
 
+extern "C" {}
+
 fn let_statements() {
     let x = 42;
     let mut y = x;
@@ -664,9 +684,18 @@ fn let_statements() {
                     },
                     StructureNode {
                         parent: None,
+                        label: "extern \"C\"",
+                        navigation_range: 638..648,
+                        node_range: 638..651,
+                        kind: ExternBlock,
+                        detail: None,
+                        deprecated: false,
+                    },
+                    StructureNode {
+                        parent: None,
                         label: "let_statements",
-                        navigation_range: 641..655,
-                        node_range: 638..798,
+                        navigation_range: 656..670,
+                        node_range: 653..813,
                         kind: SymbolKind(
                             Function,
                         ),
@@ -677,11 +706,11 @@ fn let_statements() {
                     },
                     StructureNode {
                         parent: Some(
-                            26,
+                            27,
                         ),
                         label: "x",
-                        navigation_range: 668..669,
-                        node_range: 664..675,
+                        navigation_range: 683..684,
+                        node_range: 679..690,
                         kind: SymbolKind(
                             Local,
                         ),
@@ -690,11 +719,11 @@ fn let_statements() {
                     },
                     StructureNode {
                         parent: Some(
-                            26,
+                            27,
                         ),
                         label: "mut y",
-                        navigation_range: 684..689,
-                        node_range: 680..694,
+                        navigation_range: 699..704,
+                        node_range: 695..709,
                         kind: SymbolKind(
                             Local,
                         ),
@@ -703,11 +732,11 @@ fn let_statements() {
                     },
                     StructureNode {
                         parent: Some(
-                            26,
+                            27,
                         ),
                         label: "Foo { .. }",
-                        navigation_range: 703..725,
-                        node_range: 699..738,
+                        navigation_range: 718..740,
+                        node_range: 714..753,
                         kind: SymbolKind(
                             Local,
                         ),
@@ -716,11 +745,11 @@ fn let_statements() {
                     },
                     StructureNode {
                         parent: Some(
-                            26,
+                            27,
                         ),
                         label: "_",
-                        navigation_range: 788..789,
-                        node_range: 784..796,
+                        navigation_range: 803..804,
+                        node_range: 799..811,
                         kind: SymbolKind(
                             Local,
                         ),
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index d9ddc2d015b..5a00d635698 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -1009,10 +1009,10 @@ fn render_dyn_compatibility(
     safety: Option<DynCompatibilityViolation>,
 ) {
     let Some(osv) = safety else {
-        buf.push_str("Is Dyn compatible");
+        buf.push_str("Is dyn-compatible");
         return;
     };
-    buf.push_str("Is not Dyn compatible due to ");
+    buf.push_str("Is not dyn-compatible due to ");
     match osv {
         DynCompatibilityViolation::SizedSelf => {
             buf.push_str("having a `Self: Sized` bound");
@@ -1055,7 +1055,7 @@ fn render_dyn_compatibility(
         }
         DynCompatibilityViolation::HasNonCompatibleSuperTrait(super_trait) => {
             let name = hir::Trait::from(super_trait).name(db);
-            format_to!(buf, "having a dyn incompatible supertrait `{}`", name.as_str());
+            format_to!(buf, "having a dyn-incompatible supertrait `{}`", name.as_str());
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index 0ffbf988c35..0986d5542cd 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -9371,7 +9371,7 @@ trait Compat$0 {}
 
             ---
 
-            Is Dyn compatible
+            Is dyn-compatible
         "#]],
     );
     check(
@@ -9393,7 +9393,7 @@ trait UnCompat$0 {
 
             ---
 
-            Is not Dyn compatible due to having a method `f` that is not dispatchable due to missing a receiver
+            Is not dyn-compatible due to having a method `f` that is not dispatchable due to missing a receiver
         "#]],
     );
     check(
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
index aecafb444c3..865518fe941 100644
--- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
+++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs
@@ -392,18 +392,22 @@ define_symbols! {
     rust_2024,
     rust_analyzer,
     Rust,
+    rustc_allocator_zeroed,
+    rustc_allocator,
     rustc_allow_incoherent_impl,
     rustc_builtin_macro,
     rustc_coherence_is_core,
     rustc_const_panic_str,
+    rustc_deallocator,
     rustc_deprecated_safe_2024,
     rustc_has_incoherent_inherent_impls,
-    rustc_intrinsic,
     rustc_intrinsic_must_be_overridden,
+    rustc_intrinsic,
     rustc_layout_scalar_valid_range_end,
     rustc_layout_scalar_valid_range_start,
     rustc_legacy_const_generics,
     rustc_macro_transparency,
+    rustc_reallocator,
     rustc_reservation_impl,
     rustc_safe_intrinsic,
     rustc_skip_array_during_method_dispatch,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
index fa584ab4d21..a5c9d2823e0 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
@@ -1131,7 +1131,7 @@ pub(crate) fn handle_completion_resolve(
     else {
         return Ok(original_completion);
     };
-    let resolved_completions = to_proto::completion_items(
+    let mut resolved_completions = to_proto::completion_items(
         &snap.config,
         &forced_resolve_completions_config.fields_to_resolve,
         &line_index,
@@ -1140,15 +1140,13 @@ pub(crate) fn handle_completion_resolve(
         resolve_data.trigger_character,
         resolved_completions,
     );
-    let Some(mut resolved_completion) = resolved_completions.into_iter().find(|completion| {
-        completion.label == original_completion.label
-            && completion.kind == original_completion.kind
-            && completion.deprecated == original_completion.deprecated
-            && completion.preselect == original_completion.preselect
-            && completion.sort_text == original_completion.sort_text
-    }) else {
-        return Ok(original_completion);
-    };
+
+    let mut resolved_completion =
+        if resolved_completions.get(resolve_data.completion_item_index).is_some() {
+            resolved_completions.swap_remove(resolve_data.completion_item_index)
+        } else {
+            return Ok(original_completion);
+        };
 
     if !resolve_data.imports.is_empty() {
         let additional_edits = snap
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
index 8039f0644ee..6ddfe118d5e 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs
@@ -826,6 +826,7 @@ pub struct CompletionResolveData {
     pub imports: Vec<CompletionImport>,
     pub version: Option<i32>,
     pub trigger_character: Option<char>,
+    pub completion_item_index: usize,
 }
 
 #[derive(Debug, Serialize, Deserialize)]
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
index d654dc3e7f4..d444f90a131 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -88,6 +88,7 @@ pub(crate) fn structure_node_kind(kind: StructureNodeKind) -> lsp_types::SymbolK
     match kind {
         StructureNodeKind::SymbolKind(symbol) => symbol_kind(symbol),
         StructureNodeKind::Region => lsp_types::SymbolKind::NAMESPACE,
+        StructureNodeKind::ExternBlock => lsp_types::SymbolKind::NAMESPACE,
     }
 }
 
@@ -391,18 +392,36 @@ fn completion_item(
         } else {
             Vec::new()
         };
-    if something_to_resolve || !imports.is_empty() {
-        let data = lsp_ext::CompletionResolveData {
+    let (ref_resolve_data, resolve_data) = if something_to_resolve || !imports.is_empty() {
+        let mut item_index = acc.len();
+        let ref_resolve_data = if ref_match.is_some() {
+            let ref_resolve_data = lsp_ext::CompletionResolveData {
+                position: tdpp.clone(),
+                imports: Vec::new(),
+                version,
+                trigger_character: completion_trigger_character,
+                completion_item_index: item_index,
+            };
+            item_index += 1;
+            Some(to_value(ref_resolve_data).unwrap())
+        } else {
+            None
+        };
+        let resolve_data = lsp_ext::CompletionResolveData {
             position: tdpp.clone(),
             imports,
             version,
             trigger_character: completion_trigger_character,
+            completion_item_index: item_index,
         };
-        lsp_item.data = Some(to_value(data).unwrap());
-    }
+        (ref_resolve_data, Some(to_value(resolve_data).unwrap()))
+    } else {
+        (None, None)
+    };
 
     if let Some((label, indel, relevance)) = ref_match {
-        let mut lsp_item_with_ref = lsp_types::CompletionItem { label, ..lsp_item.clone() };
+        let mut lsp_item_with_ref =
+            lsp_types::CompletionItem { label, data: ref_resolve_data, ..lsp_item.clone() };
         lsp_item_with_ref
             .additional_text_edits
             .get_or_insert_with(Default::default)
@@ -411,6 +430,7 @@ fn completion_item(
         acc.push(lsp_item_with_ref);
     };
 
+    lsp_item.data = resolve_data;
     acc.push(lsp_item);
 
     fn set_score(
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
index 67629fcf7cc..07767d5ae9f 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs
@@ -370,15 +370,13 @@ pub mod mem {
     // endregion:drop
 
     // region:transmute
-    extern "rust-intrinsic" {
-        pub fn transmute<Src, Dst>(src: Src) -> Dst;
-    }
+    #[rustc_intrinsic]
+    pub fn transmute<Src, Dst>(src: Src) -> Dst;
     // endregion:transmute
 
     // region:size_of
-    extern "rust-intrinsic" {
-        pub fn size_of<T>() -> usize;
-    }
+    #[rustc_intrinsic]
+    pub fn size_of<T>() -> usize;
     // endregion:size_of
 
     // region:discriminant
diff --git a/src/tools/rust-analyzer/docs/dev/README.md b/src/tools/rust-analyzer/docs/dev/README.md
index 12e6d829a08..cd0f49174cd 100644
--- a/src/tools/rust-analyzer/docs/dev/README.md
+++ b/src/tools/rust-analyzer/docs/dev/README.md
@@ -47,7 +47,7 @@ https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer
   Each triaged issue should have one of these labels.
 * [fun](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%3Afun)
   is for cool, but probably hard stuff.
-* [Design](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aopen+is%3Aissue+label%Design)
+* [C-Architecture](https://github.com/rust-lang/rust-analyzer/issues?q=is%3Aissue%20state%3Aopen%20label%3AC-Architecture)
   is for moderate/large scale architecture discussion.
   Also a kind of fun.
   These issues should generally include a link to a Zulip discussion thread.
diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
index 7764f7843a0..b7c536e0279 100644
--- a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
+++ b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
 <!---
-lsp/ext.rs hash: 90cf7718d54fe3c2
+lsp/ext.rs hash: 96f88b7a5d0080c6
 
 If you need to change the above hash to make the test pass, please check if you
 need to adjust this doc as well and ping this issue:
diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json
index 10b633511d3..6027f813311 100644
--- a/src/tools/rust-analyzer/editors/code/package-lock.json
+++ b/src/tools/rust-analyzer/editors/code/package-lock.json
@@ -13,12 +13,12 @@
                 "anser": "^2.1.1",
                 "d3": "^7.8.5",
                 "d3-graphviz": "^5.0.2",
-                "vscode-languageclient": "^8.1.0"
+                "vscode-languageclient": "^9.0.1"
             },
             "devDependencies": {
                 "@tsconfig/strictest": "^2.0.1",
                 "@types/node": "~16.11.7",
-                "@types/vscode": "~1.78.1",
+                "@types/vscode": "~1.83",
                 "@typescript-eslint/eslint-plugin": "^6.0.0",
                 "@typescript-eslint/parser": "^6.0.0",
                 "@vscode/test-electron": "^2.3.8",
@@ -32,7 +32,7 @@
                 "typescript": "^5.6.0"
             },
             "engines": {
-                "vscode": "^1.78.0"
+                "vscode": "^1.83.0"
             }
         },
         "node_modules/@aashutoshrathi/word-wrap": {
@@ -880,9 +880,9 @@
             "dev": true
         },
         "node_modules/@types/vscode": {
-            "version": "1.78.1",
-            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.78.1.tgz",
-            "integrity": "sha512-wEA+54axejHu7DhcUfnFBan1IqFD1gBDxAFz8LoX06NbNDMRJv/T6OGthOs52yZccasKfN588EyffHWABkR0fg==",
+            "version": "1.83.3",
+            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.83.3.tgz",
+            "integrity": "sha512-ZPp5+OQNYrCSFoT4jWOZKdcuXijj+JdN2BJNDhWH4pPbVL6PRQycG9NT8C4a94oul1tFMbkVbXXa9HasI7cLUg==",
             "dev": true
         },
         "node_modules/@typescript-eslint/eslint-plugin": {
@@ -5059,24 +5059,24 @@
             }
         },
         "node_modules/vscode-jsonrpc": {
-            "version": "8.1.0",
-            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz",
-            "integrity": "sha512-6TDy/abTQk+zDGYazgbIPc+4JoXdwC8NHU9Pbn4UJP1fehUyZmM4RHp5IthX7A6L5KS30PRui+j+tbbMMMafdw==",
+            "version": "8.2.0",
+            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
+            "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
             "engines": {
                 "node": ">=14.0.0"
             }
         },
         "node_modules/vscode-languageclient": {
-            "version": "8.1.0",
-            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.1.0.tgz",
-            "integrity": "sha512-GL4QdbYUF/XxQlAsvYWZRV3V34kOkpRlvV60/72ghHfsYFnS/v2MANZ9P6sHmxFcZKOse8O+L9G7Czg0NUWing==",
+            "version": "9.0.1",
+            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz",
+            "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==",
             "dependencies": {
                 "minimatch": "^5.1.0",
                 "semver": "^7.3.7",
-                "vscode-languageserver-protocol": "3.17.3"
+                "vscode-languageserver-protocol": "3.17.5"
             },
             "engines": {
-                "vscode": "^1.67.0"
+                "vscode": "^1.82.0"
             }
         },
         "node_modules/vscode-languageclient/node_modules/brace-expansion": {
@@ -5099,18 +5099,18 @@
             }
         },
         "node_modules/vscode-languageserver-protocol": {
-            "version": "3.17.3",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3.tgz",
-            "integrity": "sha512-924/h0AqsMtA5yK22GgMtCYiMdCOtWTSGgUOkgEDX+wk2b0x4sAfLiO4NxBxqbiVtz7K7/1/RgVrVI0NClZwqA==",
+            "version": "3.17.5",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
+            "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
             "dependencies": {
-                "vscode-jsonrpc": "8.1.0",
-                "vscode-languageserver-types": "3.17.3"
+                "vscode-jsonrpc": "8.2.0",
+                "vscode-languageserver-types": "3.17.5"
             }
         },
         "node_modules/vscode-languageserver-types": {
-            "version": "3.17.3",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz",
-            "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA=="
+            "version": "3.17.5",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
+            "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
         },
         "node_modules/which": {
             "version": "2.0.2",
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index ccc8c0e3842..b868622b3a5 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -27,7 +27,7 @@
         }
     },
     "engines": {
-        "vscode": "^1.78.0"
+        "vscode": "^1.83.0"
     },
     "enabledApiProposals": [],
     "scripts": {
@@ -49,12 +49,12 @@
         "anser": "^2.1.1",
         "d3": "^7.8.5",
         "d3-graphviz": "^5.0.2",
-        "vscode-languageclient": "^8.1.0"
+        "vscode-languageclient": "^9.0.1"
     },
     "devDependencies": {
         "@tsconfig/strictest": "^2.0.1",
         "@types/node": "~16.11.7",
-        "@types/vscode": "~1.78.1",
+        "@types/vscode": "~1.83",
         "@typescript-eslint/eslint-plugin": "^6.0.0",
         "@typescript-eslint/parser": "^6.0.0",
         "@vscode/test-electron": "^2.3.8",
@@ -490,15 +490,19 @@
                         "type": "string",
                         "enum": [
                             "auto",
+                            "llvm-vs-code-extensions.lldb-dap",
                             "vadimcn.vscode-lldb",
-                            "ms-vscode.cpptools"
+                            "ms-vscode.cpptools",
+                            "webfreak.debug"
                         ],
                         "default": "auto",
                         "description": "Preferred debug engine.",
                         "markdownEnumDescriptions": [
-                            "First try to use [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb), if it's not installed try to use [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools).",
+                            "Use the first available extension out of [LLDB DAP](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.lldb-dap), [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb), [C/C++ for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools), and [Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug).",
+                            "Use [LLDB DAP](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.lldb-dap)",
                             "Use [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)",
-                            "Use [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)"
+                            "Use [C/C++ for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)",
+                            "Use [Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug)"
                         ]
                     },
                     "rust-analyzer.debug.sourceFileMap": {
diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts
index bf58112916b..eac7b849fdb 100644
--- a/src/tools/rust-analyzer/editors/code/src/client.ts
+++ b/src/tools/rust-analyzer/editors/code/src/client.ts
@@ -350,6 +350,7 @@ class ExperimentalFeatures implements lc.StaticFeature {
         _documentSelector: lc.DocumentSelector | undefined,
     ): void {}
     dispose(): void {}
+    clear(): void {}
 }
 
 class OverrideFeatures implements lc.StaticFeature {
@@ -369,6 +370,7 @@ class OverrideFeatures implements lc.StaticFeature {
         _documentSelector: lc.DocumentSelector | undefined,
     ): void {}
     dispose(): void {}
+    clear(): void {}
 }
 
 function isCodeActionWithoutEditsAndCommands(value: any): boolean {
diff --git a/src/tools/rust-analyzer/triagebot.toml b/src/tools/rust-analyzer/triagebot.toml
index d62adb9144b..1138035d0e8 100644
--- a/src/tools/rust-analyzer/triagebot.toml
+++ b/src/tools/rust-analyzer/triagebot.toml
@@ -19,3 +19,5 @@ exclude_titles = [ # exclude syncs from subtree in rust-lang/rust
     "sync from rust",
 ]
 labels = ["has-merge-commits", "S-waiting-on-author"]
+
+[transfer]
diff --git a/src/tools/rustbook/.gitignore b/src/tools/rustbook/.gitignore
new file mode 100644
index 00000000000..ea8c4bf7f35
--- /dev/null
+++ b/src/tools/rustbook/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock
index 27ccb205b50..9e549348da3 100644
--- a/src/tools/rustbook/Cargo.lock
+++ b/src/tools/rustbook/Cargo.lock
@@ -47,9 +47,9 @@ dependencies = [
 
 [[package]]
 name = "anstream"
-version = "0.6.15"
+version = "0.6.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
+checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338"
 dependencies = [
  "anstyle",
  "anstyle-parse",
@@ -62,43 +62,43 @@ dependencies = [
 
 [[package]]
 name = "anstyle"
-version = "1.0.8"
+version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
 
 [[package]]
 name = "anstyle-parse"
-version = "0.2.5"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
 dependencies = [
  "utf8parse",
 ]
 
 [[package]]
 name = "anstyle-query"
-version = "1.1.1"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
 dependencies = [
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
 name = "anstyle-wincon"
-version = "3.0.4"
+version = "3.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
+checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
 dependencies = [
  "anstyle",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
 name = "anyhow"
-version = "1.0.89"
+version = "1.0.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
+checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13"
 
 [[package]]
 name = "autocfg"
@@ -161,9 +161,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
 [[package]]
 name = "cc"
-version = "1.1.22"
+version = "1.1.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0"
+checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9"
 dependencies = [
  "shlex",
 ]
@@ -185,14 +185,14 @@ dependencies = [
  "js-sys",
  "num-traits",
  "wasm-bindgen",
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
 name = "clap"
-version = "4.5.18"
+version = "4.5.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3"
+checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -200,9 +200,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.18"
+version = "4.5.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b"
+checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
 dependencies = [
  "anstream",
  "anstyle",
@@ -213,9 +213,9 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.29"
+version = "4.5.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8937760c3f4c60871870b8c3ee5f9b30771f792a7045c48bcbba999d7d6b3b8e"
+checksum = "86bc73de94bc81e52f3bebec71bc4463e9748f7a59166663e32044669577b0e2"
 dependencies = [
  "clap",
 ]
@@ -240,9 +240,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
 
 [[package]]
 name = "colorchoice"
-version = "1.0.2"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
 
 [[package]]
 name = "core-foundation-sys"
@@ -441,11 +441,12 @@ dependencies = [
 
 [[package]]
 name = "handlebars"
-version = "5.1.2"
+version = "6.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b"
+checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315"
 dependencies = [
  "log",
+ "num-order",
  "pest",
  "pest_derive",
  "serde",
@@ -455,9 +456,9 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.14.5"
+version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
 
 [[package]]
 name = "heck"
@@ -535,9 +536,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "2.5.0"
+version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
+checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -557,9 +558,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
 
 [[package]]
 name = "js-sys"
-version = "0.3.70"
+version = "0.3.72"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
+checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -572,9 +573,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "libc"
-version = "0.2.159"
+version = "0.2.161"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
 
 [[package]]
 name = "libdbus-sys"
@@ -645,9 +646,9 @@ dependencies = [
 
 [[package]]
 name = "mdbook"
-version = "0.4.40"
+version = "0.4.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b45a38e19bd200220ef07c892b0157ad3d2365e5b5a267ca01ad12182491eea5"
+checksum = "7624879735513024d323e7267a0b3a7176aceb0db537939beb4ee31d9e8945e3"
 dependencies = [
  "ammonia",
  "anyhow",
@@ -763,6 +764,21 @@ dependencies = [
 ]
 
 [[package]]
+name = "num-modular"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f"
+
+[[package]]
+name = "num-order"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6"
+dependencies = [
+ "num-modular",
+]
+
+[[package]]
 name = "num-traits"
 version = "0.2.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -773,9 +789,9 @@ dependencies = [
 
 [[package]]
 name = "once_cell"
-version = "1.19.0"
+version = "1.20.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
 
 [[package]]
 name = "onig"
@@ -831,14 +847,14 @@ dependencies = [
  "libc",
  "redox_syscall",
  "smallvec",
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
 name = "pathdiff"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361"
 
 [[package]]
 name = "percent-encoding"
@@ -848,9 +864,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
 
 [[package]]
 name = "pest"
-version = "2.7.13"
+version = "2.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9"
+checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442"
 dependencies = [
  "memchr",
  "thiserror",
@@ -859,9 +875,9 @@ dependencies = [
 
 [[package]]
 name = "pest_derive"
-version = "2.7.13"
+version = "2.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0"
+checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd"
 dependencies = [
  "pest",
  "pest_generator",
@@ -869,9 +885,9 @@ dependencies = [
 
 [[package]]
 name = "pest_generator"
-version = "2.7.13"
+version = "2.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e"
+checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e"
 dependencies = [
  "pest",
  "pest_meta",
@@ -882,9 +898,9 @@ dependencies = [
 
 [[package]]
 name = "pest_meta"
-version = "2.7.13"
+version = "2.7.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f"
+checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d"
 dependencies = [
  "once_cell",
  "pest",
@@ -980,9 +996,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.86"
+version = "1.0.89"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
+checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
 dependencies = [
  "unicode-ident",
 ]
@@ -1083,18 +1099,18 @@ dependencies = [
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.6"
+version = "0.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b"
+checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
 dependencies = [
  "bitflags 2.6.0",
 ]
 
 [[package]]
 name = "regex"
-version = "1.10.6"
+version = "1.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -1104,9 +1120,9 @@ dependencies = [
 
 [[package]]
 name = "regex-automata"
-version = "0.4.7"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
+checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -1115,9 +1131,9 @@ dependencies = [
 
 [[package]]
 name = "regex-syntax"
-version = "0.8.4"
+version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
 
 [[package]]
 name = "rustbook"
@@ -1134,9 +1150,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.37"
+version = "0.38.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
+checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a"
 dependencies = [
  "bitflags 2.6.0",
  "errno",
@@ -1174,18 +1190,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
 
 [[package]]
 name = "serde"
-version = "1.0.210"
+version = "1.0.214"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
+checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.210"
+version = "1.0.214"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
+checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1194,9 +1210,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.128"
+version = "1.0.132"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
+checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
 dependencies = [
  "itoa",
  "memchr",
@@ -1276,9 +1292,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "syn"
-version = "2.0.79"
+version = "2.0.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
+checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1331,12 +1347,12 @@ dependencies = [
 
 [[package]]
 name = "terminal_size"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
+checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef"
 dependencies = [
  "rustix",
- "windows-sys 0.48.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -1347,18 +1363,18 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
 
 [[package]]
 name = "thiserror"
-version = "1.0.64"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
+checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.64"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
+checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1437,24 +1453,21 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
 
 [[package]]
 name = "ucd-trie"
-version = "0.1.6"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
+checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
 
 [[package]]
 name = "unicase"
-version = "2.7.0"
+version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
-dependencies = [
- "version_check",
-]
+checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df"
 
 [[package]]
 name = "unicode-bidi"
-version = "0.3.15"
+version = "0.3.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
+checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
 
 [[package]]
 name = "unicode-ident"
@@ -1524,9 +1537,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
+checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
 dependencies = [
  "cfg-if",
  "once_cell",
@@ -1535,9 +1548,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
+checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
 dependencies = [
  "bumpalo",
  "log",
@@ -1550,9 +1563,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
+checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -1560,9 +1573,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
+checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1573,9 +1586,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.93"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
+checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
 
 [[package]]
 name = "winapi"
@@ -1614,16 +1627,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
 dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[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",
+ "windows-targets",
 ]
 
 [[package]]
@@ -1632,7 +1636,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 dependencies = [
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
@@ -1641,22 +1645,7 @@ version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
 dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[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",
+ "windows-targets",
 ]
 
 [[package]]
@@ -1665,48 +1654,30 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
  "windows_i686_gnullvm",
- "windows_i686_msvc 0.52.6",
- "windows_x86_64_gnu 0.52.6",
- "windows_x86_64_gnullvm 0.52.6",
- "windows_x86_64_msvc 0.52.6",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
 ]
 
 [[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"
 
 [[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"
 
 [[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"
@@ -1719,48 +1690,24 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 
 [[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"
 
 [[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"
 
 [[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"
 
 [[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/src/tools/rustdoc-gui-test/Cargo.toml b/src/tools/rustdoc-gui-test/Cargo.toml
index 4cb200ebc7c..f7384a98f85 100644
--- a/src/tools/rustdoc-gui-test/Cargo.toml
+++ b/src/tools/rustdoc-gui-test/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies]
-build_helper = { path = "../build_helper" }
+build_helper = { path = "../../build_helper" }
 compiletest = { path = "../compiletest" }
 getopts = "0.2"
 walkdir = "2"
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index e162ba033cc..7aa5e102e6d 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -2,6 +2,14 @@
 const fs = require("fs");
 const path = require("path");
 
+
+function arrayToCode(array) {
+    return array.map((value, index) => {
+        value = value.split("&nbsp;").join(" ");
+        return (index % 2 === 1) ? ("`" + value + "`") : value;
+    }).join("");
+}
+
 function loadContent(content) {
     const Module = module.constructor;
     const m = new Module();
@@ -84,7 +92,6 @@ function checkNeededFields(fullPath, expected, error_text, queryName, position)
     if (fullPath.length === 0) {
         fieldsToCheck = [
             "foundElems",
-            "original",
             "returned",
             "userQuery",
             "error",
@@ -181,15 +188,7 @@ function valueCheck(fullPath, expected, result, error_text, queryName) {
                 if (!result_v.forEach) {
                     throw result_v;
                 }
-                result_v.forEach((value, index) => {
-                    value = value.split("&nbsp;").join(" ");
-                    if (index % 2 === 1) {
-                        result_v[index] = "`" + value + "`";
-                    } else {
-                        result_v[index] = value;
-                    }
-                });
-                result_v = result_v.join("");
+                result_v = arrayToCode(result_v);
             }
             const obj_path = fullPath + (fullPath.length > 0 ? "." : "") + key;
             valueCheck(obj_path, expected[key], result_v, error_text, queryName);
@@ -437,9 +436,41 @@ function loadSearchJS(doc_folder, resource_suffix) {
     searchModule.initSearch(searchIndex.searchIndex);
     const docSearch = searchModule.docSearch;
     return {
-        doSearch: function(queryStr, filterCrate, currentCrate) {
-            return docSearch.execQuery(searchModule.parseQuery(queryStr),
+        doSearch: async function(queryStr, filterCrate, currentCrate) {
+            const result = await docSearch.execQuery(searchModule.parseQuery(queryStr),
                 filterCrate, currentCrate);
+            for (const tab in result) {
+                if (!Object.prototype.hasOwnProperty.call(result, tab)) {
+                    continue;
+                }
+                if (!(result[tab] instanceof Array)) {
+                    continue;
+                }
+                for (const entry of result[tab]) {
+                    for (const key in entry) {
+                        if (!Object.prototype.hasOwnProperty.call(entry, key)) {
+                            continue;
+                        }
+                        if (key === "displayTypeSignature") {
+                            const {type, mappedNames, whereClause} =
+                                await entry.displayTypeSignature;
+                            entry.displayType = arrayToCode(type);
+                            entry.displayMappedNames = [...mappedNames.entries()]
+                                .map(([name, qname]) => {
+                                    return `${name} = ${qname}`;
+                                }).join(", ");
+                            entry.displayWhereClause = [...whereClause.entries()]
+                                .flatMap(([name, value]) => {
+                                    if (value.length === 0) {
+                                        return [];
+                                    }
+                                    return [`${name}: ${arrayToCode(value)}`];
+                                }).join(", ");
+                        }
+                    }
+                }
+            }
+            return result;
         },
         getCorrections: function(queryStr, filterCrate, currentCrate) {
             const parsedQuery = searchModule.parseQuery(queryStr);
diff --git a/src/tools/suggest-tests/Cargo.toml b/src/tools/suggest-tests/Cargo.toml
index 7c048d53a50..d6f86078d7e 100644
--- a/src/tools/suggest-tests/Cargo.toml
+++ b/src/tools/suggest-tests/Cargo.toml
@@ -5,4 +5,4 @@ edition = "2021"
 
 [dependencies]
 glob = "0.3.0"
-build_helper = { version = "0.1.0", path = "../build_helper" }
+build_helper = { version = "0.1.0", path = "../../build_helper" }
diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml
index 42e608ff5ce..bc75787fb1a 100644
--- a/src/tools/tidy/Cargo.toml
+++ b/src/tools/tidy/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
 autobins = false
 
 [dependencies]
-build_helper = { path = "../build_helper" }
+build_helper = { path = "../../build_helper" }
 cargo_metadata = "0.18"
 regex = "1"
 miropt-test-tools = { path = "../miropt-test-tools" }
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 8e12db409ec..e065f01ebba 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -24,6 +24,7 @@ const LICENSES: &[&str] = &[
     "BSD-2-Clause OR Apache-2.0 OR MIT",                   // zerocopy
     "ISC",
     "MIT / Apache-2.0",
+    "MIT AND (MIT OR Apache-2.0)",
     "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)", // compiler-builtins
     "MIT OR Apache-2.0 OR LGPL-2.1-or-later",              // r-efi, r-efi-alloc
     "MIT OR Apache-2.0 OR Zlib",                           // tinyvec_macros
@@ -92,6 +93,7 @@ const EXCEPTIONS: ExceptionList = &[
     ("constant_time_eq", "CC0-1.0 OR MIT-0 OR Apache-2.0"),  // rustc
     ("dissimilar", "Apache-2.0"),                            // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps)
     ("fluent-langneg", "Apache-2.0"),                        // rustc (fluent translations)
+    ("foldhash", "Zlib"),                                    // rustc
     ("instant", "BSD-3-Clause"),                             // rustc_driver/tracing-subscriber/parking_lot
     ("mdbook", "MPL-2.0"),                                   // mdbook
     ("option-ext", "MPL-2.0"),                               // cargo-miri (via `directories`)
@@ -283,6 +285,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "fluent-langneg",
     "fluent-syntax",
     "fnv",
+    "foldhash",
     "generic-array",
     "getopts",
     "getrandom",
diff --git a/src/tools/tidy/src/known_bug.rs b/src/tools/tidy/src/known_bug.rs
index 182a81c6ec9..a8771654144 100644
--- a/src/tools/tidy/src/known_bug.rs
+++ b/src/tools/tidy/src/known_bug.rs
@@ -6,8 +6,22 @@ use crate::walk::*;
 
 pub fn check(filepath: &Path, bad: &mut bool) {
     walk(filepath, |path, _is_dir| filter_not_rust(path), &mut |entry, contents| {
-        let file = entry.path();
-        if !contents.lines().any(|line| line.starts_with("//@ known-bug: ")) {
+        let file: &Path = entry.path();
+
+        // files in "auxiliary" do not need to crash by themselves
+        let test_path_segments =
+            file.iter().map(|s| s.to_string_lossy().into()).collect::<Vec<String>>();
+        let test_path_segments_str =
+            test_path_segments.iter().map(|s| s.as_str()).collect::<Vec<&str>>();
+
+        if !matches!(test_path_segments_str[..], [
+            ..,
+            "tests",
+            "crashes",
+            "auxiliary",
+            _aux_file_rs
+        ]) && !contents.lines().any(|line| line.starts_with("//@ known-bug: "))
+        {
             tidy_error!(
                 bad,
                 "{} crash/ice test does not have a \"//@ known-bug: \" directive",
diff --git a/src/tools/unicode-table-generator/src/range_search.rs b/src/tools/unicode-table-generator/src/range_search.rs
index 9a51979a2f0..14da876eda7 100644
--- a/src/tools/unicode-table-generator/src/range_search.rs
+++ b/src/tools/unicode-table-generator/src/range_search.rs
@@ -1,4 +1,5 @@
 #[inline(always)]
+#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))]
 const fn bitset_search<
     const N: usize,
     const CHUNK_SIZE: usize,
diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs
index 46010692fe5..dd064c59283 100644
--- a/src/tools/unicode-table-generator/src/raw_emitter.rs
+++ b/src/tools/unicode-table-generator/src/raw_emitter.rs
@@ -97,6 +97,10 @@ impl RawEmitter {
 
         self.blank_line();
 
+        writeln!(
+            &mut self.file,
+            r#"#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_unicode_case_lookup", since = "1.84.0"))]"#
+        ).unwrap();
         writeln!(&mut self.file, "pub const fn lookup(c: char) -> bool {{").unwrap();
         if first_code_point > 0x7f {
             writeln!(&mut self.file, "    (c as u32) >= {first_code_point:#04x} &&").unwrap();
diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs
index 1173ba8a4eb..22e60cd8159 100644
--- a/tests/assembly/asm/aarch64-types.rs
+++ b/tests/assembly/asm/aarch64-types.rs
@@ -6,7 +6,7 @@
 //@ [arm64ec] needs-llvm-components: aarch64
 //@ compile-flags: -Zmerge-functions=disabled
 
-#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch, f16, f128)]
+#![feature(no_core, lang_items, rustc_attrs, repr_simd, f16, f128)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
diff --git a/tests/assembly/riscv-soft-abi-with-float-features.rs b/tests/assembly/riscv-soft-abi-with-float-features.rs
index 6d6001af084..8ccfa72a7b6 100644
--- a/tests/assembly/riscv-soft-abi-with-float-features.rs
+++ b/tests/assembly/riscv-soft-abi-with-float-features.rs
@@ -2,7 +2,7 @@
 //@ compile-flags: --target riscv64imac-unknown-none-elf -Ctarget-feature=+f,+d
 //@ needs-llvm-components: riscv
 //@ revisions: LLVM-PRE-20 LLVM-POST-20
-//@ [LLVM-PRE-20] ignore-llvm-version: 20 - 99
+//@ [LLVM-PRE-20] max-llvm-major-version: 19
 //@ [LLVM-POST-20] min-llvm-version: 20
 
 #![feature(no_core, lang_items, f16)]
diff --git a/tests/assembly/x86_64-cmp.rs b/tests/assembly/x86_64-cmp.rs
index 67b7ff99ae2..8cccab7d40d 100644
--- a/tests/assembly/x86_64-cmp.rs
+++ b/tests/assembly/x86_64-cmp.rs
@@ -1,7 +1,7 @@
 //@ revisions: DEBUG LLVM-PRE-20-OPTIM LLVM-20-OPTIM
 //@ [DEBUG] compile-flags: -C opt-level=0
 //@ [LLVM-PRE-20-OPTIM] compile-flags: -C opt-level=3
-//@ [LLVM-PRE-20-OPTIM] ignore-llvm-version: 20 - 99
+//@ [LLVM-PRE-20-OPTIM] max-llvm-major-version: 19
 //@ [LLVM-20-OPTIM] compile-flags: -C opt-level=3
 //@ [LLVM-20-OPTIM] min-llvm-version: 20
 //@ assembly-output: emit-asm
diff --git a/tests/codegen/asm/arm64ec-clobbers.rs b/tests/codegen/asm/arm64ec-clobbers.rs
index 2ec61907947..80059331642 100644
--- a/tests/codegen/asm/arm64ec-clobbers.rs
+++ b/tests/codegen/asm/arm64ec-clobbers.rs
@@ -3,7 +3,7 @@
 //@ needs-llvm-components: aarch64
 
 #![crate_type = "rlib"]
-#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
+#![feature(no_core, rustc_attrs, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
diff --git a/tests/codegen/branch-protection-old-llvm.rs b/tests/codegen/branch-protection-old-llvm.rs
index bb3c7a4b70c..1846f35479d 100644
--- a/tests/codegen/branch-protection-old-llvm.rs
+++ b/tests/codegen/branch-protection-old-llvm.rs
@@ -7,7 +7,7 @@
 //@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf
 //@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key
 //@ compile-flags: --target aarch64-unknown-linux-gnu
-//@ ignore-llvm-version: 19 - 99
+//@ max-llvm-major-version: 18
 
 #![crate_type = "lib"]
 #![feature(no_core, lang_items)]
diff --git a/tests/codegen/call-metadata.rs b/tests/codegen/call-metadata.rs
index 73c4b33e2cf..b986b4467fa 100644
--- a/tests/codegen/call-metadata.rs
+++ b/tests/codegen/call-metadata.rs
@@ -2,7 +2,7 @@
 // scalar value.
 
 //@ compile-flags: -O -C no-prepopulate-passes
-//@ ignore-llvm-version: 19 - 99
+//@ max-llvm-major-version: 18
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/float/f16-f128-inline.rs b/tests/codegen/float/f16-f128-inline.rs
new file mode 100644
index 00000000000..aa2c38c209e
--- /dev/null
+++ b/tests/codegen/float/f16-f128-inline.rs
@@ -0,0 +1,29 @@
+//@ revisions: default nopt
+//@[nopt] compile-flags: -Copt-level=0 -Zcross-crate-inline-threshold=never -Zmir-opt-level=0 -Cno-prepopulate-passes
+
+// Ensure that functions using `f16` and `f128` are always inlined to avoid crashes
+// when the backend does not support these types.
+
+#![crate_type = "lib"]
+#![feature(f128)]
+#![feature(f16)]
+
+pub fn f16_arg(_a: f16) {
+    // CHECK-NOT: f16_arg
+    todo!()
+}
+
+pub fn f16_ret() -> f16 {
+    // CHECK-NOT: f16_ret
+    todo!()
+}
+
+pub fn f128_arg(_a: f128) {
+    // CHECK-NOT: f128_arg
+    todo!()
+}
+
+pub fn f128_ret() -> f128 {
+    // CHECK-NOT: f128_ret
+    todo!()
+}
diff --git a/tests/codegen/integer-cmp.rs b/tests/codegen/integer-cmp.rs
index 8df68d8d490..9bbf243946d 100644
--- a/tests/codegen/integer-cmp.rs
+++ b/tests/codegen/integer-cmp.rs
@@ -3,7 +3,7 @@
 
 //@ revisions: llvm-pre-20 llvm-20
 //@ [llvm-20] min-llvm-version: 20
-//@ [llvm-pre-20] ignore-llvm-version: 20 - 99
+//@ [llvm-pre-20] max-llvm-major-version: 19
 //@ compile-flags: -C opt-level=3
 
 #![crate_type = "lib"]
diff --git a/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs b/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
new file mode 100644
index 00000000000..df65960dfe0
--- /dev/null
+++ b/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
@@ -0,0 +1,19 @@
+// Verifies that the parent block's debug information are assigned to the inserted cfi block.
+//
+//@ needs-sanitizer-cfi
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -Cdebuginfo=1
+
+#![crate_type = "lib"]
+
+pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
+    // CHECK-LABEL: define{{.*}}foo{{.*}}!dbg !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+    // CHECK:       start:
+    // CHECK:       [[TT:%.+]] = call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"{{[[:print:]]+}}"), !dbg !{{[0-9]+}}
+    // CHECK-NEXT:  br i1 [[TT]], label %type_test.pass, label %type_test.fail, !dbg !{{[0-9]+}}
+    // CHECK:       type_test.pass:                                   ; preds = %start
+    // CHECK-NEXT:  {{%.+}} = call i32 %f(i32{{.*}} %arg), !dbg !{{[0-9]+}}
+    // CHECK:       type_test.fail:                                   ; preds = %start
+    // CHECK-NEXT:  call void @llvm.trap(), !dbg !{{[0-9]+}}
+    // CHECK-NEXT:  unreachable, !dbg !{{[0-9]+}}
+    f(arg)
+}
diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index b68ecce869e..36a0d9066c8 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -2,8 +2,7 @@
 //@ only-x86_64
 // FIXME: Remove the `min-llvm-version`.
 //@ revisions: NINETEEN TWENTY
-//@[NINETEEN] min-llvm-version: 19
-//@[NINETEEN] ignore-llvm-version: 20-99
+//@[NINETEEN] exact-llvm-major-version: 19
 //@[TWENTY] min-llvm-version: 20
 //@ min-llvm-version: 19
 
diff --git a/tests/coverage-run-rustdoc/doctest.coverage b/tests/coverage-run-rustdoc/doctest.coverage
index 396811c5487..f007eb0cade 100644
--- a/tests/coverage-run-rustdoc/doctest.coverage
+++ b/tests/coverage-run-rustdoc/doctest.coverage
@@ -45,11 +45,11 @@ $DIR/doctest.rs:
    LL|      1|//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
    LL|      1|//!         println!("{:?}", res);
    LL|      1|//!     }
-                   ^0
+                  ^0
    LL|      1|//!     if *res.as_ref().unwrap_err() == *res.as_ref().unwrap_err() {
    LL|      1|//!         res = Ok(1);
    LL|      1|//!     }
-                   ^0
+                  ^0
    LL|      1|//!     res = Ok(0);
    LL|       |//! }
    LL|       |//! // need to be explicit because rustdoc cant infer the return type
diff --git a/tests/coverage/abort.cov-map b/tests/coverage/abort.cov-map
index 06dce43c3ca..c121fa551dc 100644
--- a/tests/coverage/abort.cov-map
+++ b/tests/coverage/abort.cov-map
@@ -1,5 +1,5 @@
 Function name: abort::main
-Raw bytes (89): 0x[01, 01, 0a, 01, 27, 05, 09, 03, 0d, 22, 11, 03, 0d, 03, 0d, 22, 15, 03, 0d, 03, 0d, 05, 09, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 22, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0e, 02, 0a, 00, 0b, 22, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 1a, 00, 31, 00, 32, 22, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 31, 00, 32, 27, 01, 09, 00, 17, 0d, 02, 05, 01, 02]
+Raw bytes (89): 0x[01, 01, 0a, 01, 27, 05, 09, 03, 0d, 22, 11, 03, 0d, 03, 0d, 22, 15, 03, 0d, 03, 0d, 05, 09, 0d, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 22, 01, 0c, 00, 19, 11, 00, 1a, 02, 0a, 0e, 02, 09, 00, 0a, 22, 02, 0c, 00, 19, 15, 00, 1a, 00, 31, 1a, 00, 30, 00, 31, 22, 04, 0c, 00, 19, 05, 00, 1a, 00, 31, 09, 00, 30, 00, 31, 27, 01, 09, 00, 17, 0d, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 10
@@ -20,17 +20,17 @@ Number of file 0 mappings: 13
 - Code(Expression(8, Sub)) at (prev + 1, 12) to (start + 0, 25)
     = ((c0 + (c1 + c2)) - c3)
 - Code(Counter(4)) at (prev + 0, 26) to (start + 2, 10)
-- Code(Expression(3, Sub)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Expression(3, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (((c0 + (c1 + c2)) - c3) - c4)
 - Code(Expression(8, Sub)) at (prev + 2, 12) to (start + 0, 25)
     = ((c0 + (c1 + c2)) - c3)
 - Code(Counter(5)) at (prev + 0, 26) to (start + 0, 49)
-- Code(Expression(6, Sub)) at (prev + 0, 49) to (start + 0, 50)
+- Code(Expression(6, Sub)) at (prev + 0, 48) to (start + 0, 49)
     = (((c0 + (c1 + c2)) - c3) - c5)
 - Code(Expression(8, Sub)) at (prev + 4, 12) to (start + 0, 25)
     = ((c0 + (c1 + c2)) - c3)
 - Code(Counter(1)) at (prev + 0, 26) to (start + 0, 49)
-- Code(Counter(2)) at (prev + 0, 49) to (start + 0, 50)
+- Code(Counter(2)) at (prev + 0, 48) to (start + 0, 49)
 - Code(Expression(9, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (c1 + c2)
 - Code(Counter(3)) at (prev + 2, 5) to (start + 1, 2)
diff --git a/tests/coverage/abort.coverage b/tests/coverage/abort.coverage
index 29e3ad5eda7..be3dadab487 100644
--- a/tests/coverage/abort.coverage
+++ b/tests/coverage/abort.coverage
@@ -18,12 +18,12 @@
    LL|      6|        }
    LL|       |        // See discussion (below the `Notes` section) on coverage results for the closing brace.
    LL|     10|        if countdown < 5 { might_abort(false); } // Counts for different regions on one line.
-                                       ^4                     ^6
+                                       ^4                    ^6
    LL|       |        // For the following example, the closing brace is the last character on the line.
    LL|       |        // This shows the character after the closing brace is highlighted, even if that next
    LL|       |        // character is a newline.
    LL|     10|        if countdown < 5 { might_abort(false); }
-                                       ^4                     ^6
+                                       ^4                    ^6
    LL|     10|        countdown -= 1;
    LL|       |    }
    LL|      1|    Ok(())
diff --git a/tests/coverage/assert.cov-map b/tests/coverage/assert.cov-map
index 018fcc2c3db..b3cec390119 100644
--- a/tests/coverage/assert.cov-map
+++ b/tests/coverage/assert.cov-map
@@ -1,5 +1,5 @@
 Function name: assert::main
-Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 09, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 0a, 00, 0b, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02]
+Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 09, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 09, 00, 0a, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
@@ -21,7 +21,7 @@ Number of file 0 mappings: 9
 - Code(Expression(4, Sub)) at (prev + 2, 19) to (start + 0, 32)
     = (((c0 + (c1 + (c2 + c3))) - c4) - c1)
 - Code(Counter(2)) at (prev + 0, 33) to (start + 2, 10)
-- Code(Counter(3)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Counter(3)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Expression(6, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (c1 + (c2 + c3))
 - Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2)
diff --git a/tests/coverage/async2.cov-map b/tests/coverage/async2.cov-map
index ed61e91efc2..d6462fded13 100644
--- a/tests/coverage/async2.cov-map
+++ b/tests/coverage/async2.cov-map
@@ -8,14 +8,14 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: async2::async_func::{closure#0}
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 10, 17, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 01, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 10, 17, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 16, 23) to (start + 3, 9)
 - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
@@ -47,14 +47,14 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: async2::non_async_func
-Raw bytes (24): 0x[01, 01, 00, 04, 01, 08, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 06, 00, 07, 01, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 01, 08, 01, 03, 09, 05, 03, 0a, 02, 06, 00, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 8, 1) to (start + 3, 9)
 - Code(Counter(1)) at (prev + 3, 10) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/async2.coverage b/tests/coverage/async2.coverage
index ed9bc4c239d..cdc171180b8 100644
--- a/tests/coverage/async2.coverage
+++ b/tests/coverage/async2.coverage
@@ -11,7 +11,7 @@
    LL|      1|    if b {
    LL|      1|        println!("non_async_func println in block");
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|}
    LL|       |
    LL|      1|async fn async_func() {
@@ -20,7 +20,7 @@
    LL|      1|    if b {
    LL|      1|        println!("async_func println in block");
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|}
    LL|       |
    LL|      1|async fn async_func_just_println() {
diff --git a/tests/coverage/branch/if.cov-map b/tests/coverage/branch/if.cov-map
index 4a8cb664dd8..0ad78a720a7 100644
--- a/tests/coverage/branch/if.cov-map
+++ b/tests/coverage/branch/if.cov-map
@@ -25,7 +25,7 @@ Number of file 0 mappings: 8
 Highest counter ID seen: c4
 
 Function name: if::branch_not
-Raw bytes (116): 0x[01, 01, 07, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 05, 15, 05, 15, 12, 01, 0c, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 01, 09, 00, 11, 02, 01, 06, 00, 07, 05, 01, 08, 00, 0a, 20, 0a, 0d, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 0d, 02, 06, 00, 07, 05, 01, 08, 00, 0b, 20, 11, 12, 00, 08, 00, 0b, 11, 00, 0c, 02, 06, 12, 02, 06, 00, 07, 05, 01, 08, 00, 0c, 20, 1a, 15, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 15, 02, 06, 00, 07, 05, 01, 01, 00, 02]
+Raw bytes (116): 0x[01, 01, 07, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 05, 15, 05, 15, 12, 01, 0c, 01, 01, 10, 05, 03, 08, 00, 09, 20, 09, 02, 00, 08, 00, 09, 09, 01, 09, 00, 11, 02, 01, 05, 00, 06, 05, 01, 08, 00, 0a, 20, 0a, 0d, 00, 08, 00, 0a, 0a, 00, 0b, 02, 06, 0d, 02, 05, 00, 06, 05, 01, 08, 00, 0b, 20, 11, 12, 00, 08, 00, 0b, 11, 00, 0c, 02, 06, 12, 02, 05, 00, 06, 05, 01, 08, 00, 0c, 20, 1a, 15, 00, 08, 00, 0c, 1a, 00, 0d, 02, 06, 15, 02, 05, 00, 06, 05, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 7
@@ -43,7 +43,7 @@ Number of file 0 mappings: 18
     true  = c2
     false = (c1 - c2)
 - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 17)
-- Code(Expression(0, Sub)) at (prev + 1, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 6)
     = (c1 - c2)
 - Code(Counter(1)) at (prev + 1, 8) to (start + 0, 10)
 - Branch { true: Expression(2, Sub), false: Counter(3) } at (prev + 0, 8) to (start + 0, 10)
@@ -51,13 +51,13 @@ Number of file 0 mappings: 18
     false = c3
 - Code(Expression(2, Sub)) at (prev + 0, 11) to (start + 2, 6)
     = (c1 - c3)
-- Code(Counter(3)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(1)) at (prev + 1, 8) to (start + 0, 11)
 - Branch { true: Counter(4), false: Expression(4, Sub) } at (prev + 0, 8) to (start + 0, 11)
     true  = c4
     false = (c1 - c4)
 - Code(Counter(4)) at (prev + 0, 12) to (start + 2, 6)
-- Code(Expression(4, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(4, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c1 - c4)
 - Code(Counter(1)) at (prev + 1, 8) to (start + 0, 12)
 - Branch { true: Expression(6, Sub), false: Counter(5) } at (prev + 0, 8) to (start + 0, 12)
@@ -65,12 +65,12 @@ Number of file 0 mappings: 18
     false = c5
 - Code(Expression(6, Sub)) at (prev + 0, 13) to (start + 2, 6)
     = (c1 - c5)
-- Code(Counter(5)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Counter(5)) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c5
 
 Function name: if::branch_not_as
-Raw bytes (90): 0x[01, 01, 05, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 0e, 01, 1d, 01, 01, 10, 05, 03, 08, 00, 14, 20, 02, 09, 00, 08, 00, 14, 02, 00, 15, 02, 06, 09, 02, 06, 00, 07, 05, 01, 08, 00, 15, 20, 0d, 0a, 00, 08, 00, 15, 0d, 00, 16, 02, 06, 0a, 02, 06, 00, 07, 05, 01, 08, 00, 16, 20, 12, 11, 00, 08, 00, 16, 12, 00, 17, 02, 06, 11, 02, 06, 00, 07, 05, 01, 01, 00, 02]
+Raw bytes (90): 0x[01, 01, 05, 05, 09, 05, 0d, 05, 0d, 05, 11, 05, 11, 0e, 01, 1d, 01, 01, 10, 05, 03, 08, 00, 14, 20, 02, 09, 00, 08, 00, 14, 02, 00, 15, 02, 06, 09, 02, 05, 00, 06, 05, 01, 08, 00, 15, 20, 0d, 0a, 00, 08, 00, 15, 0d, 00, 16, 02, 06, 0a, 02, 05, 00, 06, 05, 01, 08, 00, 16, 20, 12, 11, 00, 08, 00, 16, 12, 00, 17, 02, 06, 11, 02, 05, 00, 06, 05, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 5
@@ -87,13 +87,13 @@ Number of file 0 mappings: 14
     false = c2
 - Code(Expression(0, Sub)) at (prev + 0, 21) to (start + 2, 6)
     = (c1 - c2)
-- Code(Counter(2)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Counter(2)) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(1)) at (prev + 1, 8) to (start + 0, 21)
 - Branch { true: Counter(3), false: Expression(2, Sub) } at (prev + 0, 8) to (start + 0, 21)
     true  = c3
     false = (c1 - c3)
 - Code(Counter(3)) at (prev + 0, 22) to (start + 2, 6)
-- Code(Expression(2, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(2, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c1 - c3)
 - Code(Counter(1)) at (prev + 1, 8) to (start + 0, 22)
 - Branch { true: Expression(4, Sub), false: Counter(4) } at (prev + 0, 8) to (start + 0, 22)
@@ -101,7 +101,7 @@ Number of file 0 mappings: 14
     false = c4
 - Code(Expression(4, Sub)) at (prev + 0, 23) to (start + 2, 6)
     = (c1 - c4)
-- Code(Counter(4)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Counter(4)) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c4
 
diff --git a/tests/coverage/branch/if.coverage b/tests/coverage/branch/if.coverage
index 2a9a408b16a..3d107188ca6 100644
--- a/tests/coverage/branch/if.coverage
+++ b/tests/coverage/branch/if.coverage
@@ -30,7 +30,7 @@
   ------------------
    LL|      2|        say("not not a");
    LL|      2|    }
-                   ^1
+                  ^1
    LL|      3|    if !!!a {
   ------------------
   |  Branch (LL:8): [True: 1, False: 2]
@@ -54,7 +54,7 @@
   ------------------
    LL|      2|        say("not not (a as bool)");
    LL|      2|    }
-                   ^1
+                  ^1
    LL|      3|    if !!!(a as bool) {
   ------------------
   |  Branch (LL:8): [True: 1, False: 2]
diff --git a/tests/coverage/closure.cov-map b/tests/coverage/closure.cov-map
index d50f9f8e7af..adf4aba0c23 100644
--- a/tests/coverage/closure.cov-map
+++ b/tests/coverage/closure.cov-map
@@ -1,5 +1,5 @@
 Function name: closure::main
-Raw bytes (126): 0x[01, 01, 01, 01, 05, 18, 01, 09, 01, 0f, 0d, 01, 16, 0e, 06, 0a, 01, 10, 05, 13, 0d, 01, 1a, 0e, 06, 0a, 01, 10, 05, 0c, 16, 01, 16, 05, 0d, 18, 01, 19, 09, 01, 1e, 01, 04, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 02, 04, 06, 00, 07, 01, 01, 05, 03, 02]
+Raw bytes (126): 0x[01, 01, 01, 01, 05, 18, 01, 09, 01, 0f, 0d, 01, 16, 0e, 06, 0a, 01, 10, 05, 13, 0d, 01, 1a, 0e, 06, 0a, 01, 10, 05, 0c, 16, 01, 16, 05, 0d, 18, 01, 19, 09, 01, 1e, 01, 04, 09, 00, 29, 01, 01, 09, 00, 2d, 01, 01, 09, 00, 24, 01, 05, 09, 00, 24, 01, 02, 09, 00, 21, 01, 04, 09, 00, 21, 01, 04, 09, 00, 28, 01, 09, 09, 00, 32, 01, 04, 09, 00, 33, 01, 07, 09, 00, 4b, 01, 08, 09, 00, 48, 01, 0a, 09, 00, 47, 01, 08, 09, 00, 44, 01, 0a, 08, 00, 10, 05, 00, 11, 04, 06, 02, 04, 05, 00, 06, 01, 01, 05, 03, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -27,13 +27,13 @@ Number of file 0 mappings: 24
 - Code(Counter(0)) at (prev + 8, 9) to (start + 0, 68)
 - Code(Counter(0)) at (prev + 10, 8) to (start + 0, 16)
 - Code(Counter(1)) at (prev + 0, 17) to (start + 4, 6)
-- Code(Expression(0, Sub)) at (prev + 4, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 3, 2)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#0}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 28, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 0a, 00, 0b, 01, 01, 09, 01, 06]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 28, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -41,7 +41,7 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 40, 5) to (start + 2, 20)
 - Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10)
-- Code(Expression(0, Sub)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 1, 6)
 Highest counter ID seen: c1
@@ -83,17 +83,16 @@ Number of file 0 mappings: 1
 Highest counter ID seen: (none)
 
 Function name: closure::main::{closure#14}
-Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, b3, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 01, 0d, 00, 0e]
+Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, b3, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
+Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 179, 13) to (start + 2, 27)
 - Code(Counter(1)) at (prev + 2, 30) to (start + 0, 37)
 - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#15}
@@ -113,17 +112,16 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#16}
-Raw bytes (27): 0x[01, 01, 01, 01, 05, 04, 01, c5, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33, 01, 01, 0d, 00, 0e]
+Raw bytes (22): 0x[01, 01, 01, 01, 05, 03, 01, c5, 01, 0d, 02, 1b, 05, 02, 1e, 00, 25, 02, 00, 2f, 00, 33]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
-Number of file 0 mappings: 4
+Number of file 0 mappings: 3
 - Code(Counter(0)) at (prev + 197, 13) to (start + 2, 27)
 - Code(Counter(1)) at (prev + 2, 30) to (start + 0, 37)
 - Code(Expression(0, Sub)) at (prev + 0, 47) to (start + 0, 51)
     = (c0 - c1)
-- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 14)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#17}
@@ -143,19 +141,19 @@ Number of file 0 mappings: 6
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#18} (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 0d, 02, 1c, 00, 02, 1d, 02, 12, 00, 02, 12, 00, 13, 00, 01, 11, 01, 0e]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 0d, 02, 1c, 00, 02, 1d, 02, 12, 00, 02, 11, 00, 12, 00, 01, 11, 01, 0e]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Zero) at (prev + 25, 13) to (start + 2, 28)
 - Code(Zero) at (prev + 2, 29) to (start + 2, 18)
-- Code(Zero) at (prev + 2, 18) to (start + 0, 19)
+- Code(Zero) at (prev + 2, 17) to (start + 0, 18)
 - Code(Zero) at (prev + 1, 17) to (start + 1, 14)
 Highest counter ID seen: (none)
 
 Function name: closure::main::{closure#19}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 12, 00, 13, 01, 01, 11, 01, 0e]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 43, 0d, 02, 1c, 05, 02, 1d, 02, 12, 02, 02, 11, 00, 12, 01, 01, 11, 01, 0e]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -163,13 +161,13 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 67, 13) to (start + 2, 28)
 - Code(Counter(1)) at (prev + 2, 29) to (start + 2, 18)
-- Code(Expression(0, Sub)) at (prev + 2, 18) to (start + 0, 19)
+- Code(Expression(0, Sub)) at (prev + 2, 17) to (start + 0, 18)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 17) to (start + 1, 14)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#1}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 52, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 0a, 00, 0b, 01, 01, 09, 01, 06]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 52, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -177,13 +175,13 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 82, 5) to (start + 2, 20)
 - Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10)
-- Code(Expression(0, Sub)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 1, 6)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#2}
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 68, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 0a, 00, 0b, 01, 01, 09, 01, 06]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 68, 05, 02, 14, 05, 02, 15, 02, 0a, 02, 02, 09, 00, 0a, 01, 01, 09, 01, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -191,20 +189,20 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 104, 5) to (start + 2, 20)
 - Code(Counter(1)) at (prev + 2, 21) to (start + 2, 10)
-- Code(Expression(0, Sub)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Expression(0, Sub)) at (prev + 2, 9) to (start + 0, 10)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 1, 6)
 Highest counter ID seen: c1
 
 Function name: closure::main::{closure#3} (unused)
-Raw bytes (25): 0x[01, 01, 00, 04, 00, 81, 01, 05, 01, 14, 00, 01, 15, 02, 0a, 00, 02, 0a, 00, 0b, 00, 01, 09, 01, 06]
+Raw bytes (25): 0x[01, 01, 00, 04, 00, 81, 01, 05, 01, 14, 00, 01, 15, 02, 0a, 00, 02, 09, 00, 0a, 00, 01, 09, 01, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Zero) at (prev + 129, 5) to (start + 1, 20)
 - Code(Zero) at (prev + 1, 21) to (start + 2, 10)
-- Code(Zero) at (prev + 2, 10) to (start + 0, 11)
+- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
 - Code(Zero) at (prev + 1, 9) to (start + 1, 6)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/closure.coverage b/tests/coverage/closure.coverage
index 2f040b39f88..3eac52eb723 100644
--- a/tests/coverage/closure.coverage
+++ b/tests/coverage/closure.coverage
@@ -183,7 +183,7 @@
    LL|      0|            println!(
    LL|      0|                "not called: {}",
    LL|      0|                if is_true { "check" } else { "me" }
-   LL|      0|            )
+   LL|       |            )
    LL|       |    ;
    LL|       |
    LL|      1|    let short_used_not_covered_closure_line_break_block_embedded_branch =
@@ -202,7 +202,7 @@
    LL|      1|                "not called: {}",
    LL|      1|                if is_true { "check" } else { "me" }
                                                             ^0
-   LL|      1|            )
+   LL|       |            )
    LL|       |    ;
    LL|       |
    LL|      1|    let short_used_covered_closure_line_break_block_embedded_branch =
diff --git a/tests/coverage/closure_bug.cov-map b/tests/coverage/closure_bug.cov-map
index 96e1e339e56..40a8bdf9c1d 100644
--- a/tests/coverage/closure_bug.cov-map
+++ b/tests/coverage/closure_bug.cov-map
@@ -1,5 +1,5 @@
 Function name: closure_bug::main
-Raw bytes (97): 0x[01, 01, 04, 01, 05, 01, 09, 01, 0d, 01, 11, 11, 01, 07, 01, 03, 0a, 01, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, 02, 00, 17, 00, 18, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, 06, 00, 17, 00, 18, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, 0a, 00, 17, 00, 18, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, 0e, 00, 17, 00, 18, 01, 01, 01, 00, 02]
+Raw bytes (97): 0x[01, 01, 04, 01, 05, 01, 09, 01, 0d, 01, 11, 11, 01, 07, 01, 03, 0a, 01, 09, 05, 01, 0e, 05, 01, 0f, 00, 17, 02, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 09, 01, 0f, 00, 17, 06, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 0d, 01, 0f, 00, 17, 0a, 00, 16, 00, 17, 01, 02, 09, 00, 0a, 01, 06, 05, 01, 0e, 11, 01, 0f, 00, 17, 0e, 00, 16, 00, 17, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -11,22 +11,22 @@ Number of file 0 mappings: 17
 - Code(Counter(0)) at (prev + 7, 1) to (start + 3, 10)
 - Code(Counter(0)) at (prev + 9, 5) to (start + 1, 14)
 - Code(Counter(1)) at (prev + 1, 15) to (start + 0, 23)
-- Code(Expression(0, Sub)) at (prev + 0, 23) to (start + 0, 24)
+- Code(Expression(0, Sub)) at (prev + 0, 22) to (start + 0, 23)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 6, 5) to (start + 1, 14)
 - Code(Counter(2)) at (prev + 1, 15) to (start + 0, 23)
-- Code(Expression(1, Sub)) at (prev + 0, 23) to (start + 0, 24)
+- Code(Expression(1, Sub)) at (prev + 0, 22) to (start + 0, 23)
     = (c0 - c2)
 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 6, 5) to (start + 1, 14)
 - Code(Counter(3)) at (prev + 1, 15) to (start + 0, 23)
-- Code(Expression(2, Sub)) at (prev + 0, 23) to (start + 0, 24)
+- Code(Expression(2, Sub)) at (prev + 0, 22) to (start + 0, 23)
     = (c0 - c3)
 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 6, 5) to (start + 1, 14)
 - Code(Counter(4)) at (prev + 1, 15) to (start + 0, 23)
-- Code(Expression(3, Sub)) at (prev + 0, 23) to (start + 0, 24)
+- Code(Expression(3, Sub)) at (prev + 0, 22) to (start + 0, 23)
     = (c0 - c4)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c4
diff --git a/tests/coverage/closure_bug.coverage b/tests/coverage/closure_bug.coverage
index 3bf19f28072..cc64470baa7 100644
--- a/tests/coverage/closure_bug.coverage
+++ b/tests/coverage/closure_bug.coverage
@@ -16,7 +16,7 @@
    LL|       |
    LL|      1|    a();
    LL|      1|    if truthy { a(); }
-                                    ^0
+                                   ^0
    LL|       |
    LL|      1|    let b
    LL|       |        =
@@ -27,7 +27,7 @@
    LL|       |
    LL|      1|    b();
    LL|      1|    if truthy { b(); }
-                                    ^0
+                                   ^0
    LL|       |
    LL|      1|    let c
    LL|       |        =
@@ -38,7 +38,7 @@
    LL|       |
    LL|      1|    c();
    LL|      1|    if truthy { c(); }
-                                    ^0
+                                   ^0
    LL|       |
    LL|      1|    let d
    LL|       |        =
@@ -49,6 +49,6 @@
    LL|       |
    LL|      1|    d();
    LL|      1|    if truthy { d(); }
-                                    ^0
+                                   ^0
    LL|      1|}
 
diff --git a/tests/coverage/conditions.cov-map b/tests/coverage/conditions.cov-map
index a392d1b7028..938e4404013 100644
--- a/tests/coverage/conditions.cov-map
+++ b/tests/coverage/conditions.cov-map
@@ -1,5 +1,5 @@
 Function name: conditions::main
-Raw bytes (799): 0x[01, 01, 94, 01, 09, 2b, 2f, 41, 33, 3d, 35, 39, 01, 09, 0d, 35, 1e, 39, 0d, 35, 33, 3d, 35, 39, 2f, 41, 33, 3d, 35, 39, ce, 04, 0d, 01, 09, 03, 49, 62, 31, 03, 49, 5e, 4d, 62, 31, 03, 49, 5a, 51, 5e, 4d, 62, 31, 03, 49, 87, 01, 55, 4d, 51, 83, 01, 59, 87, 01, 55, 4d, 51, 49, 7f, 83, 01, 59, 87, 01, 55, 4d, 51, 5d, 65, ae, 01, 2d, 5d, 65, aa, 01, 69, ae, 01, 2d, 5d, 65, a6, 01, 6d, aa, 01, 69, ae, 01, 2d, 5d, 65, f3, 02, 71, 69, 6d, ef, 02, 75, f3, 02, 71, 69, 6d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, de, 02, 29, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, da, 02, 81, 01, de, 02, 29, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, d6, 02, 85, 01, da, 02, 81, 01, de, 02, 29, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, 8f, 04, 89, 01, 81, 01, 85, 01, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, 11, af, 04, b3, 04, 21, b7, 04, 1d, 15, 19, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, fe, 03, 25, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, fa, 03, 15, fe, 03, 25, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, f6, 03, 19, fa, 03, 15, fe, 03, 25, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, b7, 04, 1d, 15, 19, b3, 04, 21, b7, 04, 1d, 15, 19, ab, 04, bb, 04, 11, af, 04, b3, 04, 21, b7, 04, 1d, 15, 19, bf, 04, ca, 04, c3, 04, 31, c7, 04, 2d, 25, 29, ce, 04, 0d, 01, 09, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 06, 00, 07, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, ce, 04, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 1e, 00, 1d, 00, 2a, 1a, 00, 2e, 00, 3c, 2f, 00, 3d, 02, 0a, 41, 02, 0a, 00, 0b, 2b, 01, 09, 01, 12, ca, 04, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 45, 01, 0d, 02, 06, 00, 02, 06, 00, 07, 03, 02, 08, 00, 15, 49, 00, 16, 02, 06, 62, 02, 0f, 00, 1c, 5e, 01, 0c, 00, 19, 5a, 00, 1d, 00, 2a, 56, 00, 2e, 00, 3c, 83, 01, 00, 3d, 02, 0a, 59, 02, 0a, 00, 0b, 7f, 01, 09, 00, 17, 31, 02, 09, 00, 0f, 7b, 03, 08, 00, 0c, 5d, 01, 0d, 01, 10, 61, 01, 11, 02, 0a, 00, 02, 0a, 00, 0b, 5d, 02, 0c, 00, 19, 65, 00, 1a, 02, 0a, ae, 01, 04, 11, 00, 1e, aa, 01, 01, 10, 00, 1d, a6, 01, 00, 21, 00, 2e, a2, 01, 00, 32, 00, 40, ef, 02, 00, 41, 02, 0e, 75, 02, 0e, 00, 0f, eb, 02, 01, 0d, 00, 1b, 2d, 02, 0d, 00, 13, 00, 02, 06, 00, 07, e3, 02, 02, 09, 01, 0c, 79, 01, 0d, 02, 06, 00, 02, 06, 00, 07, 83, 04, 02, 09, 00, 0a, e3, 02, 00, 10, 00, 1d, 7d, 00, 1e, 02, 06, de, 02, 02, 0f, 00, 1c, da, 02, 01, 0c, 00, 19, d6, 02, 00, 1d, 00, 2a, d2, 02, 00, 2e, 00, 3c, 8b, 04, 00, 3d, 02, 0a, 8d, 01, 02, 0a, 00, 0b, 87, 04, 01, 09, 00, 17, 29, 02, 0d, 02, 0f, ab, 04, 05, 09, 00, 0a, 83, 04, 00, 10, 00, 1d, 11, 00, 1e, 02, 06, fe, 03, 02, 0f, 00, 1c, fa, 03, 01, 0c, 00, 19, f6, 03, 00, 1d, 00, 2a, f2, 03, 00, 2e, 00, 3c, b3, 04, 00, 3d, 02, 0a, 21, 02, 0a, 00, 0b, af, 04, 01, 09, 00, 17, 25, 02, 09, 00, 0f, a7, 04, 02, 01, 00, 02]
+Raw bytes (799): 0x[01, 01, 94, 01, 09, 2b, 2f, 41, 33, 3d, 35, 39, 01, 09, 0d, 35, 1e, 39, 0d, 35, 33, 3d, 35, 39, 2f, 41, 33, 3d, 35, 39, ce, 04, 0d, 01, 09, 03, 49, 62, 31, 03, 49, 5e, 4d, 62, 31, 03, 49, 5a, 51, 5e, 4d, 62, 31, 03, 49, 87, 01, 55, 4d, 51, 83, 01, 59, 87, 01, 55, 4d, 51, 49, 7f, 83, 01, 59, 87, 01, 55, 4d, 51, 5d, 65, ae, 01, 2d, 5d, 65, aa, 01, 69, ae, 01, 2d, 5d, 65, a6, 01, 6d, aa, 01, 69, ae, 01, 2d, 5d, 65, f3, 02, 71, 69, 6d, ef, 02, 75, f3, 02, 71, 69, 6d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, de, 02, 29, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, da, 02, 81, 01, de, 02, 29, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, d6, 02, 85, 01, da, 02, 81, 01, de, 02, 29, e3, 02, 7d, e7, 02, 00, 65, eb, 02, ef, 02, 75, f3, 02, 71, 69, 6d, 8f, 04, 89, 01, 81, 01, 85, 01, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, 11, af, 04, b3, 04, 21, b7, 04, 1d, 15, 19, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, fe, 03, 25, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, fa, 03, 15, fe, 03, 25, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, f6, 03, 19, fa, 03, 15, fe, 03, 25, 83, 04, 11, 7d, 87, 04, 8b, 04, 8d, 01, 8f, 04, 89, 01, 81, 01, 85, 01, b7, 04, 1d, 15, 19, b3, 04, 21, b7, 04, 1d, 15, 19, ab, 04, bb, 04, 11, af, 04, b3, 04, 21, b7, 04, 1d, 15, 19, bf, 04, ca, 04, c3, 04, 31, c7, 04, 2d, 25, 29, ce, 04, 0d, 01, 09, 44, 01, 03, 01, 02, 0c, 05, 02, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 09, 01, 09, 01, 0a, ce, 04, 02, 0f, 00, 1c, 0d, 01, 0c, 00, 19, 1e, 00, 1d, 00, 2a, 1a, 00, 2e, 00, 3c, 2f, 00, 3d, 02, 0a, 41, 02, 09, 00, 0a, 2b, 01, 09, 01, 12, ca, 04, 03, 09, 00, 0f, 03, 03, 09, 01, 0c, 45, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 49, 00, 16, 02, 06, 62, 02, 0f, 00, 1c, 5e, 01, 0c, 00, 19, 5a, 00, 1d, 00, 2a, 56, 00, 2e, 00, 3c, 83, 01, 00, 3d, 02, 0a, 59, 02, 09, 00, 0a, 7f, 01, 09, 00, 17, 31, 02, 09, 00, 0f, 7b, 03, 08, 00, 0c, 5d, 01, 0d, 01, 10, 61, 01, 11, 02, 0a, 00, 02, 09, 00, 0a, 5d, 02, 0c, 00, 19, 65, 00, 1a, 02, 0a, ae, 01, 04, 11, 00, 1e, aa, 01, 01, 10, 00, 1d, a6, 01, 00, 21, 00, 2e, a2, 01, 00, 32, 00, 40, ef, 02, 00, 41, 02, 0e, 75, 02, 0d, 00, 0e, eb, 02, 01, 0d, 00, 1b, 2d, 02, 0d, 00, 13, 00, 02, 05, 00, 06, e3, 02, 02, 09, 01, 0c, 79, 01, 0d, 02, 06, 00, 02, 05, 00, 06, 83, 04, 02, 09, 00, 0a, e3, 02, 00, 10, 00, 1d, 7d, 00, 1e, 02, 06, de, 02, 02, 0f, 00, 1c, da, 02, 01, 0c, 00, 19, d6, 02, 00, 1d, 00, 2a, d2, 02, 00, 2e, 00, 3c, 8b, 04, 00, 3d, 02, 0a, 8d, 01, 02, 09, 00, 0a, 87, 04, 01, 09, 00, 17, 29, 02, 0d, 02, 0f, ab, 04, 05, 09, 00, 0a, 83, 04, 00, 10, 00, 1d, 11, 00, 1e, 02, 06, fe, 03, 02, 0f, 00, 1c, fa, 03, 01, 0c, 00, 19, f6, 03, 00, 1d, 00, 2a, f2, 03, 00, 2e, 00, 3c, b3, 04, 00, 3d, 02, 0a, 21, 02, 09, 00, 0a, af, 04, 01, 09, 00, 17, 25, 02, 09, 00, 0f, a7, 04, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 148
@@ -154,7 +154,7 @@ Number of expressions: 148
 Number of file 0 mappings: 68
 - Code(Counter(0)) at (prev + 3, 1) to (start + 2, 12)
 - Code(Counter(1)) at (prev + 2, 13) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 10)
     = (c2 + (((c13 + c14) + c15) + c16))
 - Code(Counter(0)) at (prev + 0, 16) to (start + 0, 29)
@@ -168,7 +168,7 @@ Number of file 0 mappings: 68
     = ((c3 - c13) - c14)
 - Code(Expression(11, Add)) at (prev + 0, 61) to (start + 2, 10)
     = ((c13 + c14) + c15)
-- Code(Counter(16)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Counter(16)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Expression(10, Add)) at (prev + 1, 9) to (start + 1, 18)
     = (((c13 + c14) + c15) + c16)
 - Code(Expression(146, Sub)) at (prev + 3, 9) to (start + 0, 15)
@@ -176,7 +176,7 @@ Number of file 0 mappings: 68
 - Code(Expression(0, Add)) at (prev + 3, 9) to (start + 1, 12)
     = (c2 + (((c13 + c14) + c15) + c16))
 - Code(Counter(17)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Expression(0, Add)) at (prev + 2, 8) to (start + 0, 21)
     = (c2 + (((c13 + c14) + c15) + c16))
 - Code(Counter(18)) at (prev + 0, 22) to (start + 2, 6)
@@ -190,7 +190,7 @@ Number of file 0 mappings: 68
     = (((((c2 + (((c13 + c14) + c15) + c16)) - c18) - c12) - c19) - c20)
 - Code(Expression(32, Add)) at (prev + 0, 61) to (start + 2, 10)
     = ((c19 + c20) + c21)
-- Code(Counter(22)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Counter(22)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Expression(31, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (((c19 + c20) + c21) + c22)
 - Code(Counter(12)) at (prev + 2, 9) to (start + 0, 15)
@@ -198,7 +198,7 @@ Number of file 0 mappings: 68
     = (c18 + (((c19 + c20) + c21) + c22))
 - Code(Counter(23)) at (prev + 1, 13) to (start + 1, 16)
 - Code(Counter(24)) at (prev + 1, 17) to (start + 2, 10)
-- Code(Zero) at (prev + 2, 10) to (start + 0, 11)
+- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
 - Code(Counter(23)) at (prev + 2, 12) to (start + 0, 25)
 - Code(Counter(25)) at (prev + 0, 26) to (start + 2, 10)
 - Code(Expression(43, Sub)) at (prev + 4, 17) to (start + 0, 30)
@@ -211,15 +211,15 @@ Number of file 0 mappings: 68
     = ((((c23 - c25) - c11) - c26) - c27)
 - Code(Expression(91, Add)) at (prev + 0, 65) to (start + 2, 14)
     = ((c26 + c27) + c28)
-- Code(Counter(29)) at (prev + 2, 14) to (start + 0, 15)
+- Code(Counter(29)) at (prev + 2, 13) to (start + 0, 14)
 - Code(Expression(90, Add)) at (prev + 1, 13) to (start + 0, 27)
     = (((c26 + c27) + c28) + c29)
 - Code(Counter(11)) at (prev + 2, 13) to (start + 0, 19)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Expression(88, Add)) at (prev + 2, 9) to (start + 1, 12)
     = ((c25 + (((c26 + c27) + c28) + c29)) + Zero)
 - Code(Counter(30)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Expression(128, Add)) at (prev + 2, 9) to (start + 0, 10)
     = (c31 + (((c32 + c33) + c34) + c35))
 - Code(Expression(88, Add)) at (prev + 0, 16) to (start + 0, 29)
@@ -235,7 +235,7 @@ Number of file 0 mappings: 68
     = ((((((c25 + (((c26 + c27) + c28) + c29)) + Zero) - c31) - c10) - c32) - c33)
 - Code(Expression(130, Add)) at (prev + 0, 61) to (start + 2, 10)
     = ((c32 + c33) + c34)
-- Code(Counter(35)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Counter(35)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Expression(129, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (((c32 + c33) + c34) + c35)
 - Code(Counter(10)) at (prev + 2, 13) to (start + 2, 15)
@@ -254,7 +254,7 @@ Number of file 0 mappings: 68
     = (((((c31 + (((c32 + c33) + c34) + c35)) - c4) - c9) - c5) - c6)
 - Code(Expression(140, Add)) at (prev + 0, 61) to (start + 2, 10)
     = ((c5 + c6) + c7)
-- Code(Counter(8)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Counter(8)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Expression(139, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (((c5 + c6) + c7) + c8)
 - Code(Counter(9)) at (prev + 2, 9) to (start + 0, 15)
diff --git a/tests/coverage/conditions.coverage b/tests/coverage/conditions.coverage
index 48516217592..83944d37c98 100644
--- a/tests/coverage/conditions.coverage
+++ b/tests/coverage/conditions.coverage
@@ -5,7 +5,7 @@
    LL|      1|    if true {
    LL|      1|        countdown = 10;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|       |
    LL|       |    const B: u32 = 100;
    LL|      1|    let x = if countdown > 7 {
@@ -25,7 +25,7 @@
    LL|      1|    if true {
    LL|      1|        countdown = 10;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|       |
    LL|      1|    if countdown > 7 {
    LL|      1|        countdown -= 4;
@@ -44,7 +44,7 @@
    LL|      1|        if true {
    LL|      1|            countdown = 10;
    LL|      1|        }
-                       ^0
+                      ^0
    LL|       |
    LL|      1|        if countdown > 7 {
    LL|      1|            countdown -= 4;
@@ -64,7 +64,7 @@
    LL|      1|    if true {
    LL|      1|        countdown = 1;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|       |
    LL|      1|    let z = if countdown > 7 {
                       ^0
diff --git a/tests/coverage/dead_code.cov-map b/tests/coverage/dead_code.cov-map
index b94c6e656ab..897372fe0b5 100644
--- a/tests/coverage/dead_code.cov-map
+++ b/tests/coverage/dead_code.cov-map
@@ -1,5 +1,5 @@
 Function name: dead_code::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 1b, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 06, 00, 07, 01, 01, 01, 00, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 1b, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -7,32 +7,32 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 27, 1) to (start + 7, 15)
 - Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: dead_code::unused_fn (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 0f, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Zero) at (prev + 15, 1) to (start + 7, 15)
 - Code(Zero) at (prev + 7, 16) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
 Function name: dead_code::unused_pub_fn_not_in_library (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 03, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 03, 01, 07, 0f, 00, 07, 10, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Zero) at (prev + 3, 1) to (start + 7, 15)
 - Code(Zero) at (prev + 7, 16) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/dead_code.coverage b/tests/coverage/dead_code.coverage
index c4ee9f23f08..55d196f8160 100644
--- a/tests/coverage/dead_code.coverage
+++ b/tests/coverage/dead_code.coverage
@@ -34,6 +34,6 @@
    LL|      1|    if is_true {
    LL|      1|        countdown = 10;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|}
 
diff --git a/tests/coverage/if.cov-map b/tests/coverage/if.cov-map
index 8f12afac027..a77ba8194a4 100644
--- a/tests/coverage/if.cov-map
+++ b/tests/coverage/if.cov-map
@@ -1,5 +1,5 @@
 Function name: if::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 04, 01, 12, 10, 05, 13, 05, 05, 06, 02, 05, 06, 00, 07, 01, 01, 01, 00, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 04, 01, 12, 10, 05, 13, 05, 05, 06, 02, 05, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -7,7 +7,7 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 4, 1) to (start + 18, 16)
 - Code(Counter(1)) at (prev + 19, 5) to (start + 5, 6)
-- Code(Expression(0, Sub)) at (prev + 5, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 5, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
diff --git a/tests/coverage/if.coverage b/tests/coverage/if.coverage
index 77db24ef51b..0762418347c 100644
--- a/tests/coverage/if.coverage
+++ b/tests/coverage/if.coverage
@@ -26,6 +26,6 @@
    LL|      1|            10
    LL|      1|        ;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|}
 
diff --git a/tests/coverage/if_not.cov-map b/tests/coverage/if_not.cov-map
index a2c276b7bb7..f47139ce5a4 100644
--- a/tests/coverage/if_not.cov-map
+++ b/tests/coverage/if_not.cov-map
@@ -1,5 +1,5 @@
 Function name: if_not::if_not
-Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0a, 01, 05, 01, 03, 0d, 02, 04, 05, 02, 06, 05, 02, 06, 00, 07, 01, 03, 09, 01, 0d, 06, 02, 05, 02, 06, 09, 02, 06, 00, 07, 01, 03, 09, 01, 0d, 0a, 02, 05, 02, 06, 0d, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (60): 0x[01, 01, 03, 01, 05, 01, 09, 01, 0d, 0a, 01, 05, 01, 03, 0d, 02, 04, 05, 02, 06, 05, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 06, 02, 05, 02, 06, 09, 02, 05, 00, 06, 01, 03, 09, 01, 0d, 0a, 02, 05, 02, 06, 0d, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -10,11 +10,11 @@ Number of file 0 mappings: 10
 - Code(Counter(0)) at (prev + 5, 1) to (start + 3, 13)
 - Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 2, 6)
     = (c0 - c1)
-- Code(Counter(1)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Counter(1)) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 1, 13)
 - Code(Expression(1, Sub)) at (prev + 2, 5) to (start + 2, 6)
     = (c0 - c2)
-- Code(Counter(2)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Counter(2)) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 1, 13)
 - Code(Expression(2, Sub)) at (prev + 2, 5) to (start + 2, 6)
     = (c0 - c3)
diff --git a/tests/coverage/inner_items.cov-map b/tests/coverage/inner_items.cov-map
index 16e86b2cade..a12cce25b64 100644
--- a/tests/coverage/inner_items.cov-map
+++ b/tests/coverage/inner_items.cov-map
@@ -17,7 +17,7 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: inner_items::main
-Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 03, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 06, 00, 07, 01, 24, 08, 00, 0f, 09, 00, 10, 02, 06, 06, 02, 06, 00, 07, 01, 02, 09, 05, 02]
+Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 03, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 01, 24, 08, 00, 0f, 09, 00, 10, 02, 06, 06, 02, 05, 00, 06, 01, 02, 09, 05, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
@@ -26,11 +26,11 @@ Number of expressions: 2
 Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 3, 1) to (start + 7, 15)
 - Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 36, 8) to (start + 0, 15)
 - Code(Counter(2)) at (prev + 0, 16) to (start + 2, 6)
-- Code(Expression(1, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(1, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c2)
 - Code(Counter(0)) at (prev + 2, 9) to (start + 5, 2)
 Highest counter ID seen: c2
diff --git a/tests/coverage/inner_items.coverage b/tests/coverage/inner_items.coverage
index 152f3da1a22..8244d347b59 100644
--- a/tests/coverage/inner_items.coverage
+++ b/tests/coverage/inner_items.coverage
@@ -10,7 +10,7 @@
    LL|      1|    if is_true {
    LL|      1|        countdown = 10;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|       |
    LL|       |    mod in_mod {
    LL|       |        const IN_MOD_CONST: u32 = 1000;
@@ -49,7 +49,7 @@
    LL|      1|    if is_true {
    LL|      1|        in_func(countdown);
    LL|      1|    }
-                   ^0
+                  ^0
    LL|       |
    LL|      1|    let mut val = InStruct {
    LL|      1|        in_struct_field: 101, //
diff --git a/tests/coverage/lazy_boolean.cov-map b/tests/coverage/lazy_boolean.cov-map
index fcb9d8f1ff5..b0c2d736573 100644
--- a/tests/coverage/lazy_boolean.cov-map
+++ b/tests/coverage/lazy_boolean.cov-map
@@ -1,5 +1,5 @@
 Function name: lazy_boolean::main
-Raw bytes (158): 0x[01, 01, 07, 01, 05, 01, 09, 01, 0d, 01, 19, 01, 1d, 01, 21, 01, 25, 1c, 01, 04, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 06, 00, 07, 01, 02, 09, 00, 11, 01, 02, 0d, 00, 12, 06, 02, 0d, 00, 12, 01, 03, 09, 00, 11, 01, 02, 0d, 00, 12, 0a, 02, 0d, 00, 12, 01, 02, 09, 00, 11, 01, 00, 14, 00, 19, 11, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 15, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 19, 03, 06, 00, 07, 01, 03, 09, 00, 10, 1d, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 21, 02, 06, 00, 07, 01, 02, 08, 00, 0f, 25, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
+Raw bytes (158): 0x[01, 01, 07, 01, 05, 01, 09, 01, 0d, 01, 19, 01, 1d, 01, 21, 01, 25, 1c, 01, 04, 01, 07, 0f, 05, 07, 10, 04, 06, 02, 04, 05, 00, 06, 01, 02, 09, 00, 11, 01, 02, 0d, 00, 12, 06, 02, 0d, 00, 12, 01, 03, 09, 00, 11, 01, 02, 0d, 00, 12, 0a, 02, 0d, 00, 12, 01, 02, 09, 00, 11, 01, 00, 14, 00, 19, 11, 00, 1d, 00, 22, 01, 01, 09, 00, 11, 01, 00, 14, 00, 19, 15, 00, 1d, 00, 22, 01, 03, 09, 01, 10, 0e, 02, 05, 03, 06, 19, 03, 05, 00, 06, 01, 03, 09, 00, 10, 1d, 01, 05, 03, 06, 12, 05, 05, 03, 06, 01, 05, 08, 00, 10, 16, 00, 11, 02, 06, 21, 02, 05, 00, 06, 01, 02, 08, 00, 0f, 25, 00, 10, 02, 06, 1a, 02, 0c, 02, 06, 01, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 7
@@ -13,7 +13,7 @@ Number of expressions: 7
 Number of file 0 mappings: 28
 - Code(Counter(0)) at (prev + 4, 1) to (start + 7, 15)
 - Code(Counter(1)) at (prev + 7, 16) to (start + 4, 6)
-- Code(Expression(0, Sub)) at (prev + 4, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 4, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 2, 9) to (start + 0, 17)
 - Code(Counter(0)) at (prev + 2, 13) to (start + 0, 18)
@@ -32,7 +32,7 @@ Number of file 0 mappings: 28
 - Code(Counter(0)) at (prev + 3, 9) to (start + 1, 16)
 - Code(Expression(3, Sub)) at (prev + 2, 5) to (start + 3, 6)
     = (c0 - c6)
-- Code(Counter(6)) at (prev + 3, 6) to (start + 0, 7)
+- Code(Counter(6)) at (prev + 3, 5) to (start + 0, 6)
 - Code(Counter(0)) at (prev + 3, 9) to (start + 0, 16)
 - Code(Counter(7)) at (prev + 1, 5) to (start + 3, 6)
 - Code(Expression(4, Sub)) at (prev + 5, 5) to (start + 3, 6)
@@ -40,7 +40,7 @@ Number of file 0 mappings: 28
 - Code(Counter(0)) at (prev + 5, 8) to (start + 0, 16)
 - Code(Expression(5, Sub)) at (prev + 0, 17) to (start + 2, 6)
     = (c0 - c8)
-- Code(Counter(8)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Counter(8)) at (prev + 2, 5) to (start + 0, 6)
 - Code(Counter(0)) at (prev + 2, 8) to (start + 0, 15)
 - Code(Counter(9)) at (prev + 0, 16) to (start + 2, 6)
 - Code(Expression(6, Sub)) at (prev + 2, 12) to (start + 2, 6)
diff --git a/tests/coverage/lazy_boolean.coverage b/tests/coverage/lazy_boolean.coverage
index f058be83900..828ba2a5811 100644
--- a/tests/coverage/lazy_boolean.coverage
+++ b/tests/coverage/lazy_boolean.coverage
@@ -13,7 +13,7 @@
    LL|      1|        b = 10;
    LL|      1|        c = 100;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|       |    let
    LL|      1|        somebool
    LL|       |        =
diff --git a/tests/coverage/loop-break.cov-map b/tests/coverage/loop-break.cov-map
index 63280a0bf7c..0b4c42a43da 100644
--- a/tests/coverage/loop-break.cov-map
+++ b/tests/coverage/loop-break.cov-map
@@ -1,5 +1,5 @@
 Function name: loop_break::main
-Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 03, 01, 00, 0b, 03, 02, 0c, 00, 27, 01, 01, 0d, 00, 12, 05, 01, 0a, 00, 0b, 01, 02, 01, 00, 02]
+Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 03, 01, 00, 0b, 03, 02, 0c, 00, 27, 01, 01, 0d, 00, 12, 05, 01, 09, 00, 0a, 01, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -9,7 +9,7 @@ Number of file 0 mappings: 5
 - Code(Expression(0, Add)) at (prev + 2, 12) to (start + 0, 39)
     = (c0 + c1)
 - Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18)
-- Code(Counter(1)) at (prev + 1, 10) to (start + 0, 11)
+- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 10)
 - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
diff --git a/tests/coverage/loops_branches.cov-map b/tests/coverage/loops_branches.cov-map
index 1d263611a3a..61a6bda676a 100644
--- a/tests/coverage/loops_branches.cov-map
+++ b/tests/coverage/loops_branches.cov-map
@@ -1,5 +1,5 @@
 Function name: <loops_branches::DebugTest as core::fmt::Debug>::fmt
-Raw bytes (228): 0x[01, 01, 2a, 05, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, a3, 01, a7, 01, 0d, 00, 11, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 96, 01, 00, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 96, 01, 11, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 8f, 01, 19, 25, 92, 01, 96, 01, 11, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0e, 00, 0f, 05, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 9a, 01, 03, 0d, 00, 0e, 9f, 01, 00, 12, 00, 17, 9a, 01, 01, 10, 00, 14, 96, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 46, 01, 12, 00, 13, 96, 01, 01, 11, 00, 22, 92, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, 8b, 01, 01, 05, 00, 06]
+Raw bytes (228): 0x[01, 01, 2a, 05, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, a3, 01, a7, 01, 0d, 00, 11, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 96, 01, 00, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 96, 01, 11, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 8f, 01, 19, 25, 92, 01, 96, 01, 11, 9a, 01, 00, 9f, 01, 19, a3, 01, a7, 01, 0d, 00, 11, 00, 14, 01, 09, 05, 01, 10, 05, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 02, 01, 0d, 00, 0e, 05, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 00, 01, 10, 01, 0a, 9a, 01, 03, 0d, 00, 0e, 9f, 01, 00, 12, 00, 17, 9a, 01, 01, 10, 00, 14, 96, 01, 01, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 46, 01, 11, 00, 12, 96, 01, 01, 11, 00, 22, 92, 01, 00, 22, 00, 23, 00, 01, 14, 01, 0e, 19, 03, 09, 00, 0f, 8b, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 42
@@ -50,7 +50,7 @@ Number of file 0 mappings: 20
 - Code(Counter(1)) at (prev + 2, 16) to (start + 0, 21)
 - Code(Zero) at (prev + 1, 23) to (start + 0, 27)
 - Code(Zero) at (prev + 0, 28) to (start + 0, 30)
-- Code(Expression(0, Sub)) at (prev + 1, 14) to (start + 0, 15)
+- Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 14)
     = (c1 - Zero)
 - Code(Counter(1)) at (prev + 1, 13) to (start + 0, 30)
 - Code(Counter(9)) at (prev + 0, 30) to (start + 0, 31)
@@ -65,7 +65,7 @@ Number of file 0 mappings: 20
     = ((((c3 + Zero) + (c4 + Zero)) - c6) - Zero)
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
-- Code(Expression(17, Sub)) at (prev + 1, 18) to (start + 0, 19)
+- Code(Expression(17, Sub)) at (prev + 1, 17) to (start + 0, 18)
     = (((((c3 + Zero) + (c4 + Zero)) - c6) - Zero) - Zero)
 - Code(Expression(37, Sub)) at (prev + 1, 17) to (start + 0, 34)
     = ((((c3 + Zero) + (c4 + Zero)) - c6) - Zero)
@@ -78,7 +78,7 @@ Number of file 0 mappings: 20
 Highest counter ID seen: c9
 
 Function name: <loops_branches::DisplayTest as core::fmt::Display>::fmt
-Raw bytes (230): 0x[01, 01, 2b, 01, 00, 02, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, a7, 01, ab, 01, 00, 0d, 00, 15, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9a, 01, 00, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9a, 01, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 93, 01, 25, 96, 01, 19, 9a, 01, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 06, 01, 0e, 00, 0f, 02, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 9e, 01, 02, 0d, 00, 0e, a3, 01, 00, 12, 00, 17, 9e, 01, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 9a, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 4a, 01, 12, 00, 13, 9a, 01, 01, 11, 00, 22, 96, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, 8f, 01, 01, 05, 00, 06]
+Raw bytes (230): 0x[01, 01, 2b, 01, 00, 02, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, a7, 01, ab, 01, 00, 0d, 00, 15, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9a, 01, 00, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 9a, 01, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 93, 01, 25, 96, 01, 19, 9a, 01, 15, 9e, 01, 00, a3, 01, 19, a7, 01, ab, 01, 00, 0d, 00, 15, 14, 01, 22, 05, 01, 11, 00, 01, 12, 01, 0a, 02, 02, 10, 00, 15, 00, 01, 17, 00, 1b, 00, 00, 1c, 00, 1e, 06, 01, 0d, 00, 0e, 02, 01, 0d, 00, 1e, 25, 00, 1e, 00, 1f, 9e, 01, 02, 0d, 00, 0e, a3, 01, 00, 12, 00, 17, 9e, 01, 01, 10, 00, 15, 00, 00, 16, 01, 0e, 9a, 01, 02, 14, 00, 19, 00, 01, 1b, 00, 1f, 00, 00, 20, 00, 22, 4a, 01, 11, 00, 12, 9a, 01, 01, 11, 00, 22, 96, 01, 00, 22, 00, 23, 19, 03, 09, 00, 0f, 8f, 01, 01, 05, 00, 06]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 43
@@ -132,7 +132,7 @@ Number of file 0 mappings: 20
     = (c0 - Zero)
 - Code(Zero) at (prev + 1, 23) to (start + 0, 27)
 - Code(Zero) at (prev + 0, 28) to (start + 0, 30)
-- Code(Expression(1, Sub)) at (prev + 1, 14) to (start + 0, 15)
+- Code(Expression(1, Sub)) at (prev + 1, 13) to (start + 0, 14)
     = ((c0 - Zero) - Zero)
 - Code(Expression(0, Sub)) at (prev + 1, 13) to (start + 0, 30)
     = (c0 - Zero)
@@ -148,7 +148,7 @@ Number of file 0 mappings: 20
     = ((((Zero + c3) + (Zero + c5)) - c6) - Zero)
 - Code(Zero) at (prev + 1, 27) to (start + 0, 31)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
-- Code(Expression(18, Sub)) at (prev + 1, 18) to (start + 0, 19)
+- Code(Expression(18, Sub)) at (prev + 1, 17) to (start + 0, 18)
     = (((((Zero + c3) + (Zero + c5)) - c6) - Zero) - Zero)
 - Code(Expression(38, Sub)) at (prev + 1, 17) to (start + 0, 34)
     = ((((Zero + c3) + (Zero + c5)) - c6) - Zero)
diff --git a/tests/coverage/match_or_pattern.cov-map b/tests/coverage/match_or_pattern.cov-map
index f6491ea262d..2beb327bc05 100644
--- a/tests/coverage/match_or_pattern.cov-map
+++ b/tests/coverage/match_or_pattern.cov-map
@@ -1,5 +1,5 @@
 Function name: match_or_pattern::main
-Raw bytes (185): 0x[01, 01, 1c, 01, 05, 09, 0d, 23, 11, 09, 0d, 1f, 15, 23, 11, 09, 0d, 23, 11, 09, 0d, 19, 1d, 43, 21, 19, 1d, 3f, 25, 43, 21, 19, 1d, 43, 21, 19, 1d, 29, 2d, 63, 31, 29, 2d, 5f, 35, 63, 31, 29, 2d, 63, 31, 29, 2d, 39, 3d, 6f, 41, 39, 3d, 19, 01, 01, 01, 08, 0f, 05, 08, 10, 03, 06, 02, 03, 06, 00, 07, 01, 01, 0b, 00, 11, 11, 03, 1b, 00, 1d, 23, 01, 0e, 00, 10, 1f, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 06, 00, 07, 1f, 01, 0b, 00, 11, 21, 01, 1b, 00, 1d, 43, 01, 0e, 00, 10, 3f, 02, 08, 00, 0f, 25, 00, 10, 03, 06, 32, 03, 06, 00, 07, 3f, 01, 0b, 00, 11, 31, 01, 1b, 00, 1d, 63, 01, 0e, 00, 10, 5f, 02, 08, 00, 0f, 35, 00, 10, 03, 06, 52, 03, 06, 00, 07, 5f, 01, 0b, 00, 11, 41, 01, 1b, 00, 1d, 6f, 01, 0e, 00, 10, 6b, 02, 01, 00, 02]
+Raw bytes (185): 0x[01, 01, 1c, 01, 05, 09, 0d, 23, 11, 09, 0d, 1f, 15, 23, 11, 09, 0d, 23, 11, 09, 0d, 19, 1d, 43, 21, 19, 1d, 3f, 25, 43, 21, 19, 1d, 43, 21, 19, 1d, 29, 2d, 63, 31, 29, 2d, 5f, 35, 63, 31, 29, 2d, 63, 31, 29, 2d, 39, 3d, 6f, 41, 39, 3d, 19, 01, 01, 01, 08, 0f, 05, 08, 10, 03, 06, 02, 03, 05, 00, 06, 01, 01, 0b, 00, 11, 11, 03, 1b, 00, 1d, 23, 01, 0e, 00, 10, 1f, 02, 08, 00, 0f, 15, 00, 10, 03, 06, 12, 03, 05, 00, 06, 1f, 01, 0b, 00, 11, 21, 01, 1b, 00, 1d, 43, 01, 0e, 00, 10, 3f, 02, 08, 00, 0f, 25, 00, 10, 03, 06, 32, 03, 05, 00, 06, 3f, 01, 0b, 00, 11, 31, 01, 1b, 00, 1d, 63, 01, 0e, 00, 10, 5f, 02, 08, 00, 0f, 35, 00, 10, 03, 06, 52, 03, 05, 00, 06, 5f, 01, 0b, 00, 11, 41, 01, 1b, 00, 1d, 6f, 01, 0e, 00, 10, 6b, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 28
@@ -34,7 +34,7 @@ Number of expressions: 28
 Number of file 0 mappings: 25
 - Code(Counter(0)) at (prev + 1, 1) to (start + 8, 15)
 - Code(Counter(1)) at (prev + 8, 16) to (start + 3, 6)
-- Code(Expression(0, Sub)) at (prev + 3, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 3, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 11) to (start + 0, 17)
 - Code(Counter(4)) at (prev + 3, 27) to (start + 0, 29)
@@ -43,7 +43,7 @@ Number of file 0 mappings: 25
 - Code(Expression(7, Add)) at (prev + 2, 8) to (start + 0, 15)
     = ((c2 + c3) + c4)
 - Code(Counter(5)) at (prev + 0, 16) to (start + 3, 6)
-- Code(Expression(4, Sub)) at (prev + 3, 6) to (start + 0, 7)
+- Code(Expression(4, Sub)) at (prev + 3, 5) to (start + 0, 6)
     = (((c2 + c3) + c4) - c5)
 - Code(Expression(7, Add)) at (prev + 1, 11) to (start + 0, 17)
     = ((c2 + c3) + c4)
@@ -53,7 +53,7 @@ Number of file 0 mappings: 25
 - Code(Expression(15, Add)) at (prev + 2, 8) to (start + 0, 15)
     = ((c6 + c7) + c8)
 - Code(Counter(9)) at (prev + 0, 16) to (start + 3, 6)
-- Code(Expression(12, Sub)) at (prev + 3, 6) to (start + 0, 7)
+- Code(Expression(12, Sub)) at (prev + 3, 5) to (start + 0, 6)
     = (((c6 + c7) + c8) - c9)
 - Code(Expression(15, Add)) at (prev + 1, 11) to (start + 0, 17)
     = ((c6 + c7) + c8)
@@ -63,7 +63,7 @@ Number of file 0 mappings: 25
 - Code(Expression(23, Add)) at (prev + 2, 8) to (start + 0, 15)
     = ((c10 + c11) + c12)
 - Code(Counter(13)) at (prev + 0, 16) to (start + 3, 6)
-- Code(Expression(20, Sub)) at (prev + 3, 6) to (start + 0, 7)
+- Code(Expression(20, Sub)) at (prev + 3, 5) to (start + 0, 6)
     = (((c10 + c11) + c12) - c13)
 - Code(Expression(23, Add)) at (prev + 1, 11) to (start + 0, 17)
     = ((c10 + c11) + c12)
diff --git a/tests/coverage/match_or_pattern.coverage b/tests/coverage/match_or_pattern.coverage
index 94c7967215c..a65c226e567 100644
--- a/tests/coverage/match_or_pattern.coverage
+++ b/tests/coverage/match_or_pattern.coverage
@@ -10,7 +10,7 @@
    LL|      1|        a = 2;
    LL|      1|        b = 0;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|    match (a, b) {
    LL|       |        // Or patterns generate MIR `SwitchInt` with multiple targets to the same `BasicBlock`.
    LL|       |        // This test confirms a fix for Issue #79569.
@@ -21,7 +21,7 @@
    LL|      1|        a = 0;
    LL|      1|        b = 0;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|    match (a, b) {
    LL|      0|        (0 | 1, 2 | 3) => {}
    LL|      1|        _ => {}
@@ -30,7 +30,7 @@
    LL|      1|        a = 2;
    LL|      1|        b = 2;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|    match (a, b) {
    LL|      0|        (0 | 1, 2 | 3) => {}
    LL|      1|        _ => {}
@@ -39,7 +39,7 @@
    LL|      1|        a = 0;
    LL|      1|        b = 2;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|    match (a, b) {
    LL|      1|        (0 | 1, 2 | 3) => {}
    LL|      0|        _ => {}
diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map
index a3e3b1d09c4..e3f5b49d363 100644
--- a/tests/coverage/mcdc/condition-limit.cov-map
+++ b/tests/coverage/mcdc/condition-limit.cov-map
@@ -1,5 +1,5 @@
 Function name: condition_limit::accept_7_conditions
-Raw bytes (232): 0x[01, 01, 2c, 01, 05, 05, 1d, 05, 1d, 7a, 19, 05, 1d, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 21, 9b, 01, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 12, 01, 07, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 7a, 1d, 07, 06, 00, 00, 0d, 00, 0e, 7a, 00, 12, 00, 13, 30, 76, 19, 06, 05, 00, 00, 12, 00, 13, 76, 00, 17, 00, 18, 30, 72, 15, 05, 04, 00, 00, 17, 00, 18, 72, 00, 1c, 00, 1d, 30, 6e, 11, 04, 03, 00, 00, 1c, 00, 1d, 6e, 00, 21, 00, 22, 30, 6a, 0d, 03, 02, 00, 00, 21, 00, 22, 6a, 00, 26, 00, 27, 30, 21, 09, 02, 00, 00, 00, 26, 00, 27, 21, 00, 28, 02, 06, 9b, 01, 02, 06, 00, 07, 97, 01, 01, 01, 00, 02]
+Raw bytes (232): 0x[01, 01, 2c, 01, 05, 05, 1d, 05, 1d, 7a, 19, 05, 1d, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 21, 9b, 01, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 12, 01, 07, 01, 02, 09, 28, 08, 07, 02, 08, 00, 27, 30, 05, 02, 01, 07, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 7a, 1d, 07, 06, 00, 00, 0d, 00, 0e, 7a, 00, 12, 00, 13, 30, 76, 19, 06, 05, 00, 00, 12, 00, 13, 76, 00, 17, 00, 18, 30, 72, 15, 05, 04, 00, 00, 17, 00, 18, 72, 00, 1c, 00, 1d, 30, 6e, 11, 04, 03, 00, 00, 1c, 00, 1d, 6e, 00, 21, 00, 22, 30, 6a, 0d, 03, 02, 00, 00, 21, 00, 22, 6a, 00, 26, 00, 27, 30, 21, 09, 02, 00, 00, 00, 26, 00, 27, 21, 00, 28, 02, 06, 9b, 01, 02, 05, 00, 06, 97, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 44
@@ -83,7 +83,7 @@ Number of file 0 mappings: 18
     true  = c8
     false = c2
 - Code(Counter(8)) at (prev + 0, 40) to (start + 2, 6)
-- Code(Expression(38, Add)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(38, Add)) at (prev + 2, 5) to (start + 0, 6)
     = ((((((c2 + c3) + c4) + c5) + c6) + c7) + (c0 - c1))
 - Code(Expression(37, Add)) at (prev + 1, 1) to (start + 0, 2)
     = (c8 + ((((((c2 + c3) + c4) + c5) + c6) + c7) + (c0 - c1)))
diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map
index 46960d31c01..c0e7d08bb02 100644
--- a/tests/coverage/mcdc/if.cov-map
+++ b/tests/coverage/mcdc/if.cov-map
@@ -175,7 +175,7 @@ Number of file 0 mappings: 10
 Highest counter ID seen: c4
 
 Function name: if::mcdc_nested_if
-Raw bytes (124): 0x[01, 01, 0d, 01, 05, 02, 09, 05, 09, 1b, 15, 05, 09, 1b, 15, 05, 09, 11, 15, 02, 09, 2b, 32, 0d, 2f, 11, 15, 02, 09, 0e, 01, 3b, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 32, 02, 00, 00, 00, 0d, 00, 0e, 1b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 16, 15, 01, 02, 00, 00, 0c, 00, 0d, 16, 00, 11, 00, 12, 30, 0d, 11, 02, 00, 00, 00, 11, 00, 12, 0d, 00, 13, 02, 0a, 2f, 02, 0a, 00, 0b, 32, 01, 0c, 02, 06, 27, 03, 01, 00, 02]
+Raw bytes (124): 0x[01, 01, 0d, 01, 05, 02, 09, 05, 09, 1b, 15, 05, 09, 1b, 15, 05, 09, 11, 15, 02, 09, 2b, 32, 0d, 2f, 11, 15, 02, 09, 0e, 01, 3b, 01, 01, 09, 28, 03, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 32, 02, 00, 00, 00, 0d, 00, 0e, 1b, 01, 09, 01, 0d, 28, 06, 02, 01, 0c, 00, 12, 30, 16, 15, 01, 02, 00, 00, 0c, 00, 0d, 16, 00, 11, 00, 12, 30, 0d, 11, 02, 00, 00, 00, 11, 00, 12, 0d, 00, 13, 02, 0a, 2f, 02, 09, 00, 0a, 32, 01, 0c, 02, 06, 27, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 13
@@ -215,7 +215,7 @@ Number of file 0 mappings: 14
     true  = c3
     false = c4
 - Code(Counter(3)) at (prev + 0, 19) to (start + 2, 10)
-- Code(Expression(11, Add)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Expression(11, Add)) at (prev + 2, 9) to (start + 0, 10)
     = (c4 + c5)
 - Code(Expression(12, Sub)) at (prev + 1, 12) to (start + 2, 6)
     = ((c0 - c1) - c2)
diff --git a/tests/coverage/nested_loops.cov-map b/tests/coverage/nested_loops.cov-map
index c145d4c5843..21871ef3206 100644
--- a/tests/coverage/nested_loops.cov-map
+++ b/tests/coverage/nested_loops.cov-map
@@ -1,5 +1,5 @@
 Function name: nested_loops::main
-Raw bytes (115): 0x[01, 01, 17, 01, 57, 05, 09, 03, 0d, 4e, 53, 03, 0d, 15, 19, 4b, 09, 4e, 53, 03, 0d, 15, 19, 46, 05, 4b, 09, 4e, 53, 03, 0d, 15, 19, 42, 19, 46, 05, 4b, 09, 4e, 53, 03, 0d, 15, 19, 05, 09, 11, 0d, 0d, 01, 01, 01, 02, 1b, 03, 04, 13, 00, 20, 4e, 01, 0d, 01, 18, 4b, 02, 12, 00, 17, 46, 01, 10, 00, 16, 05, 01, 11, 00, 16, 42, 01, 0e, 03, 16, 3e, 04, 11, 01, 1b, 11, 02, 15, 00, 21, 15, 01, 18, 02, 12, 19, 03, 0e, 00, 0f, 57, 02, 09, 00, 17, 5b, 02, 01, 00, 02]
+Raw bytes (115): 0x[01, 01, 17, 01, 57, 05, 09, 03, 0d, 4e, 53, 03, 0d, 15, 19, 4b, 09, 4e, 53, 03, 0d, 15, 19, 46, 05, 4b, 09, 4e, 53, 03, 0d, 15, 19, 42, 19, 46, 05, 4b, 09, 4e, 53, 03, 0d, 15, 19, 05, 09, 11, 0d, 0d, 01, 01, 01, 02, 1b, 03, 04, 13, 00, 20, 4e, 01, 0d, 01, 18, 4b, 02, 12, 00, 17, 46, 01, 10, 00, 16, 05, 01, 11, 00, 16, 42, 01, 0e, 03, 16, 3e, 04, 11, 01, 1b, 11, 02, 15, 00, 21, 15, 01, 18, 02, 12, 19, 03, 0d, 00, 0e, 57, 02, 09, 00, 17, 5b, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 23
@@ -43,7 +43,7 @@ Number of file 0 mappings: 13
     = ((((((c0 + (c1 + c2)) - c3) + (c5 + c6)) - c2) - c1) - c6)
 - Code(Counter(4)) at (prev + 2, 21) to (start + 0, 33)
 - Code(Counter(5)) at (prev + 1, 24) to (start + 2, 18)
-- Code(Counter(6)) at (prev + 3, 14) to (start + 0, 15)
+- Code(Counter(6)) at (prev + 3, 13) to (start + 0, 14)
 - Code(Expression(21, Add)) at (prev + 2, 9) to (start + 0, 23)
     = (c1 + c2)
 - Code(Expression(22, Add)) at (prev + 2, 1) to (start + 0, 2)
diff --git a/tests/coverage/overflow.cov-map b/tests/coverage/overflow.cov-map
index f842ce3e896..f6bfb465bf9 100644
--- a/tests/coverage/overflow.cov-map
+++ b/tests/coverage/overflow.cov-map
@@ -1,5 +1,5 @@
 Function name: overflow::main
-Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 10, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 03, 0a, 12, 03, 13, 00, 20, 09, 00, 21, 03, 0a, 0d, 03, 0a, 00, 0b, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02]
+Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 10, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 03, 0a, 12, 03, 13, 00, 20, 09, 00, 21, 03, 0a, 0d, 03, 09, 00, 0a, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
@@ -21,14 +21,14 @@ Number of file 0 mappings: 9
 - Code(Expression(4, Sub)) at (prev + 3, 19) to (start + 0, 32)
     = (((c0 + (c1 + (c2 + c3))) - c4) - c1)
 - Code(Counter(2)) at (prev + 0, 33) to (start + 3, 10)
-- Code(Counter(3)) at (prev + 3, 10) to (start + 0, 11)
+- Code(Counter(3)) at (prev + 3, 9) to (start + 0, 10)
 - Code(Expression(6, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (c1 + (c2 + c3))
 - Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2)
 Highest counter ID seen: c4
 
 Function name: overflow::might_overflow
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 12, 05, 01, 13, 02, 06, 02, 02, 06, 00, 07, 01, 01, 09, 05, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 05, 01, 01, 12, 05, 01, 13, 02, 06, 02, 02, 05, 00, 06, 01, 01, 09, 05, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -36,7 +36,7 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 5, 1) to (start + 1, 18)
 - Code(Counter(1)) at (prev + 1, 19) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 9) to (start + 5, 2)
 Highest counter ID seen: c1
diff --git a/tests/coverage/panic_unwind.cov-map b/tests/coverage/panic_unwind.cov-map
index f4a7894cc1c..58a796ff3a2 100644
--- a/tests/coverage/panic_unwind.cov-map
+++ b/tests/coverage/panic_unwind.cov-map
@@ -1,5 +1,5 @@
 Function name: panic_unwind::main
-Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 0a, 00, 0b, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02]
+Raw bytes (65): 0x[01, 01, 08, 01, 1b, 05, 1f, 09, 0d, 03, 11, 16, 05, 03, 11, 05, 1f, 09, 0d, 09, 01, 0d, 01, 01, 1b, 03, 02, 0b, 00, 18, 16, 01, 0c, 00, 1a, 05, 00, 1b, 02, 0a, 12, 02, 13, 00, 20, 09, 00, 21, 02, 0a, 0d, 02, 09, 00, 0a, 1b, 01, 09, 00, 17, 11, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
@@ -21,7 +21,7 @@ Number of file 0 mappings: 9
 - Code(Expression(4, Sub)) at (prev + 2, 19) to (start + 0, 32)
     = (((c0 + (c1 + (c2 + c3))) - c4) - c1)
 - Code(Counter(2)) at (prev + 0, 33) to (start + 2, 10)
-- Code(Counter(3)) at (prev + 2, 10) to (start + 0, 11)
+- Code(Counter(3)) at (prev + 2, 9) to (start + 0, 10)
 - Code(Expression(6, Add)) at (prev + 1, 9) to (start + 0, 23)
     = (c1 + (c2 + c3))
 - Code(Counter(4)) at (prev + 2, 5) to (start + 1, 2)
diff --git a/tests/coverage/simple_loop.cov-map b/tests/coverage/simple_loop.cov-map
index b6f1e8f6afe..d1e684efbbc 100644
--- a/tests/coverage/simple_loop.cov-map
+++ b/tests/coverage/simple_loop.cov-map
@@ -1,5 +1,5 @@
 Function name: simple_loop::main
-Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 04, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 06, 00, 07, 07, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 09, 02, 0a, 03, 0a, 01, 06, 01, 00, 02]
+Raw bytes (43): 0x[01, 01, 02, 01, 05, 01, 09, 07, 01, 04, 01, 09, 10, 05, 0a, 05, 05, 06, 02, 05, 05, 00, 06, 07, 05, 0d, 02, 0e, 01, 04, 0d, 00, 12, 09, 02, 0a, 03, 0a, 01, 06, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
@@ -8,7 +8,7 @@ Number of expressions: 2
 Number of file 0 mappings: 7
 - Code(Counter(0)) at (prev + 4, 1) to (start + 9, 16)
 - Code(Counter(1)) at (prev + 10, 5) to (start + 5, 6)
-- Code(Expression(0, Sub)) at (prev + 5, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 5, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Expression(1, Add)) at (prev + 5, 13) to (start + 2, 14)
     = (c0 + c2)
diff --git a/tests/coverage/simple_loop.coverage b/tests/coverage/simple_loop.coverage
index b6552c62ff9..237e509f42e 100644
--- a/tests/coverage/simple_loop.coverage
+++ b/tests/coverage/simple_loop.coverage
@@ -17,7 +17,7 @@
    LL|      1|            10
    LL|      1|        ;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|       |
    LL|       |    loop
    LL|       |    {
diff --git a/tests/coverage/simple_match.cov-map b/tests/coverage/simple_match.cov-map
index b62edf12650..d8bf9eae4bc 100644
--- a/tests/coverage/simple_match.cov-map
+++ b/tests/coverage/simple_match.cov-map
@@ -1,5 +1,5 @@
 Function name: simple_match::main
-Raw bytes (72): 0x[01, 01, 09, 01, 05, 01, 23, 09, 0d, 1f, 11, 01, 23, 09, 0d, 1f, 11, 01, 23, 09, 0d, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 06, 00, 07, 1f, 05, 09, 00, 0d, 1a, 05, 0d, 00, 16, 09, 02, 0d, 00, 0e, 1a, 02, 11, 02, 12, 09, 04, 0d, 07, 0e, 0d, 0a, 0d, 00, 0f, 11, 03, 01, 00, 02]
+Raw bytes (72): 0x[01, 01, 09, 01, 05, 01, 23, 09, 0d, 1f, 11, 01, 23, 09, 0d, 1f, 11, 01, 23, 09, 0d, 0a, 01, 04, 01, 07, 0f, 05, 07, 10, 02, 06, 02, 02, 05, 00, 06, 1f, 05, 09, 00, 0d, 1a, 05, 0d, 00, 16, 09, 02, 0d, 00, 0e, 1a, 02, 11, 02, 12, 09, 04, 0d, 07, 0e, 0d, 0a, 0d, 00, 0f, 11, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 9
@@ -15,7 +15,7 @@ Number of expressions: 9
 Number of file 0 mappings: 10
 - Code(Counter(0)) at (prev + 4, 1) to (start + 7, 15)
 - Code(Counter(1)) at (prev + 7, 16) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Expression(7, Add)) at (prev + 5, 9) to (start + 0, 13)
     = (c0 + (c2 + c3))
diff --git a/tests/coverage/simple_match.coverage b/tests/coverage/simple_match.coverage
index 3a4fc6743f5..e1d5e48a2bf 100644
--- a/tests/coverage/simple_match.coverage
+++ b/tests/coverage/simple_match.coverage
@@ -11,7 +11,7 @@
    LL|      1|    if is_true {
    LL|      1|        countdown = 0;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|       |
    LL|       |    for
    LL|       |        _
diff --git a/tests/coverage/sort_groups.cov-map b/tests/coverage/sort_groups.cov-map
index 4e7ed059c87..69e13422296 100644
--- a/tests/coverage/sort_groups.cov-map
+++ b/tests/coverage/sort_groups.cov-map
@@ -1,5 +1,5 @@
 Function name: sort_groups::generic_fn::<&str>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 06, 00, 07, 01, 01, 01, 00, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -7,13 +7,13 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12)
 - Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: sort_groups::generic_fn::<()>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 06, 00, 07, 01, 01, 01, 00, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -21,13 +21,13 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12)
 - Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: sort_groups::generic_fn::<char>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 06, 00, 07, 01, 01, 01, 00, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -35,13 +35,13 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12)
 - Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: sort_groups::generic_fn::<i32>
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 06, 00, 07, 01, 01, 01, 00, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 11, 01, 01, 0c, 05, 01, 0d, 02, 06, 02, 02, 05, 00, 06, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -49,13 +49,13 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 17, 1) to (start + 1, 12)
 - Code(Counter(1)) at (prev + 1, 13) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: c1
 
 Function name: sort_groups::main
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 06, 01, 04, 23, 05, 04, 24, 02, 06, 02, 02, 06, 00, 07, 01, 01, 05, 02, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 06, 01, 04, 23, 05, 04, 24, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 02, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -63,7 +63,7 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 6, 1) to (start + 4, 35)
 - Code(Counter(1)) at (prev + 4, 36) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 2, 2)
 Highest counter ID seen: c1
diff --git a/tests/coverage/sort_groups.coverage b/tests/coverage/sort_groups.coverage
index 33a4d9546ce..6e8a4eda09f 100644
--- a/tests/coverage/sort_groups.coverage
+++ b/tests/coverage/sort_groups.coverage
@@ -27,7 +27,7 @@
   |   LL|      1|    if cond {
   |   LL|      1|        println!("{}", std::any::type_name::<T>());
   |   LL|      1|    }
-  |                   ^0
+  |                  ^0
   |   LL|      1|}
   ------------------
   | sort_groups::generic_fn::<()>:
diff --git a/tests/coverage/unicode.cov-map b/tests/coverage/unicode.cov-map
index ac4e691ea7a..769930110d6 100644
--- a/tests/coverage/unicode.cov-map
+++ b/tests/coverage/unicode.cov-map
@@ -1,5 +1,5 @@
 Function name: unicode::main
-Raw bytes (61): 0x[01, 01, 06, 01, 05, 16, 0d, 01, 09, 11, 13, 16, 0d, 01, 09, 09, 01, 0e, 01, 00, 0b, 05, 01, 09, 00, 0c, 03, 00, 10, 00, 1b, 05, 00, 1c, 00, 28, 01, 02, 08, 00, 25, 09, 00, 29, 00, 46, 11, 00, 47, 02, 06, 13, 02, 06, 00, 07, 0f, 02, 05, 01, 02]
+Raw bytes (61): 0x[01, 01, 06, 01, 05, 16, 0d, 01, 09, 11, 13, 16, 0d, 01, 09, 09, 01, 0e, 01, 00, 0b, 05, 01, 09, 00, 0c, 03, 00, 10, 00, 1b, 05, 00, 1c, 00, 28, 01, 02, 08, 00, 25, 09, 00, 29, 00, 46, 11, 00, 47, 02, 06, 13, 02, 05, 00, 06, 0f, 02, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 6
@@ -18,7 +18,7 @@ Number of file 0 mappings: 9
 - Code(Counter(0)) at (prev + 2, 8) to (start + 0, 37)
 - Code(Counter(2)) at (prev + 0, 41) to (start + 0, 70)
 - Code(Counter(4)) at (prev + 0, 71) to (start + 2, 6)
-- Code(Expression(4, Add)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(4, Add)) at (prev + 2, 5) to (start + 0, 6)
     = ((c0 - c2) + c3)
 - Code(Expression(3, Add)) at (prev + 2, 5) to (start + 1, 2)
     = (c4 + ((c0 - c2) + c3))
diff --git a/tests/coverage/unicode.coverage b/tests/coverage/unicode.coverage
index 305591c7062..84c5f05a8c4 100644
--- a/tests/coverage/unicode.coverage
+++ b/tests/coverage/unicode.coverage
@@ -18,7 +18,7 @@
    LL|      1|    if 申し訳ございません() && 申し訳ございません() {
                                                       ^0
    LL|      0|        println!("true");
-   LL|      1|    }
+   LL|      1|    }
    LL|       |
    LL|      1|    サビ();
    LL|      1|}
diff --git a/tests/coverage/unused.cov-map b/tests/coverage/unused.cov-map
index 9f1ad59ce83..e865ac3ee62 100644
--- a/tests/coverage/unused.cov-map
+++ b/tests/coverage/unused.cov-map
@@ -50,38 +50,38 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: unused::unused_func (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 13, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 13, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Zero) at (prev + 19, 1) to (start + 1, 14)
 - Code(Zero) at (prev + 1, 15) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
 Function name: unused::unused_func2 (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 19, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Zero) at (prev + 25, 1) to (start + 1, 14)
 - Code(Zero) at (prev + 1, 15) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
 Function name: unused::unused_func3 (unused)
-Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 06, 00, 07, 00, 01, 01, 00, 02]
+Raw bytes (24): 0x[01, 01, 00, 04, 00, 1f, 01, 01, 0e, 00, 01, 0f, 02, 06, 00, 02, 05, 00, 06, 00, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 4
 - Code(Zero) at (prev + 31, 1) to (start + 1, 14)
 - Code(Zero) at (prev + 1, 15) to (start + 2, 6)
-- Code(Zero) at (prev + 2, 6) to (start + 0, 7)
+- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
 - Code(Zero) at (prev + 1, 1) to (start + 0, 2)
 Highest counter ID seen: (none)
 
diff --git a/tests/coverage/uses_crate.coverage b/tests/coverage/uses_crate.coverage
index d001eeffd86..d1b0dadda76 100644
--- a/tests/coverage/uses_crate.coverage
+++ b/tests/coverage/uses_crate.coverage
@@ -14,7 +14,7 @@ $DIR/auxiliary/used_crate.rs:
    LL|      1|    if is_true {
    LL|      1|        countdown = 10;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|    use_this_lib_crate();
    LL|      1|}
    LL|       |
diff --git a/tests/coverage/uses_inline_crate.cov-map b/tests/coverage/uses_inline_crate.cov-map
index a6909768162..a482d20e3b4 100644
--- a/tests/coverage/uses_inline_crate.cov-map
+++ b/tests/coverage/uses_inline_crate.cov-map
@@ -8,7 +8,7 @@ Number of file 0 mappings: 1
 Highest counter ID seen: c0
 
 Function name: used_inline_crate::used_inline_function
-Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 14, 01, 06, 0f, 05, 06, 10, 02, 06, 02, 02, 06, 00, 07, 01, 01, 05, 01, 02]
+Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 14, 01, 06, 0f, 05, 06, 10, 02, 06, 02, 02, 05, 00, 06, 01, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 1
@@ -16,7 +16,7 @@ Number of expressions: 1
 Number of file 0 mappings: 4
 - Code(Counter(0)) at (prev + 20, 1) to (start + 6, 15)
 - Code(Counter(1)) at (prev + 6, 16) to (start + 2, 6)
-- Code(Expression(0, Sub)) at (prev + 2, 6) to (start + 0, 7)
+- Code(Expression(0, Sub)) at (prev + 2, 5) to (start + 0, 6)
     = (c0 - c1)
 - Code(Counter(0)) at (prev + 1, 5) to (start + 1, 2)
 Highest counter ID seen: c1
diff --git a/tests/coverage/uses_inline_crate.coverage b/tests/coverage/uses_inline_crate.coverage
index 832a5a6a62b..4671c95aefa 100644
--- a/tests/coverage/uses_inline_crate.coverage
+++ b/tests/coverage/uses_inline_crate.coverage
@@ -14,7 +14,7 @@ $DIR/auxiliary/used_inline_crate.rs:
    LL|      1|    if is_true {
    LL|      1|        countdown = 10;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|    use_this_lib_crate();
    LL|      1|}
    LL|       |
@@ -28,7 +28,7 @@ $DIR/auxiliary/used_inline_crate.rs:
    LL|      1|    if is_true {
    LL|      1|        countdown = 10;
    LL|      1|    }
-                   ^0
+                  ^0
    LL|      1|    use_this_lib_crate();
    LL|      1|}
    LL|       |
diff --git a/tests/crashes/118545.rs b/tests/crashes/118545.rs
deleted file mode 100644
index 1d4bb848bf0..00000000000
--- a/tests/crashes/118545.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: #118545
-#![feature(generic_const_exprs)]
-
-struct Checked<const F: fn()>;
-
-fn foo() {}
-const _: Checked<foo> = Checked::<foo>;
-pub fn main() {}
diff --git a/tests/crashes/128232.rs b/tests/crashes/128232.rs
deleted file mode 100644
index 67f61e1b240..00000000000
--- a/tests/crashes/128232.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ known-bug: #128232
-
-#![feature(generic_const_exprs, unsized_const_params)]
-
-fn function() {}
-
-struct Wrapper<const F: fn()>;
-
-impl Wrapper<{ bar() }> {
-    fn call() {}
-}
-
-fn main() {
-    Wrapper::<function>::call;
-}
diff --git a/tests/crashes/131915.rs b/tests/crashes/131915.rs
deleted file mode 100644
index 58d45adcb3b..00000000000
--- a/tests/crashes/131915.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ known-bug: #131915
-
-macro_rules! y {
-    ( $($matcher:tt)*) => {
-        x
-    };
-}
-
-const _: A<
-    {
-        y! { test.tou8 }
-    },
->;
diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
index eeeac70b5b8..cbb11d50f79 100644
--- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff
@@ -26,18 +26,19 @@
           debug a => _9;
       }
   
++     coverage body span: $DIR/branch_match_arms.rs:14:11: 21:2 (#0)
 +     coverage ExpressionId(0) => Expression { lhs: Counter(1), op: Add, rhs: Counter(2) };
 +     coverage ExpressionId(1) => Expression { lhs: Expression(0), op: Add, rhs: Counter(3) };
 +     coverage ExpressionId(2) => Expression { lhs: Counter(0), op: Subtract, rhs: Expression(1) };
 +     coverage ExpressionId(3) => Expression { lhs: Counter(3), op: Add, rhs: Counter(2) };
 +     coverage ExpressionId(4) => Expression { lhs: Expression(3), op: Add, rhs: Counter(1) };
 +     coverage ExpressionId(5) => Expression { lhs: Expression(4), op: Add, rhs: Expression(2) };
-+     coverage Code(Counter(0)) => $DIR/branch_match_arms.rs:14:1 - 15:21;
-+     coverage Code(Counter(3)) => $DIR/branch_match_arms.rs:16:17 - 16:33;
-+     coverage Code(Counter(2)) => $DIR/branch_match_arms.rs:17:17 - 17:33;
-+     coverage Code(Counter(1)) => $DIR/branch_match_arms.rs:18:17 - 18:33;
-+     coverage Code(Expression(2)) => $DIR/branch_match_arms.rs:19:17 - 19:33;
-+     coverage Code(Expression(5)) => $DIR/branch_match_arms.rs:21:1 - 21:2;
++     coverage Code(Counter(0)) => 14:1 - 15:21;
++     coverage Code(Counter(3)) => 16:17 - 16:33;
++     coverage Code(Counter(2)) => 17:17 - 17:33;
++     coverage Code(Counter(1)) => 18:17 - 18:33;
++     coverage Code(Expression(2)) => 19:17 - 19:33;
++     coverage Code(Expression(5)) => 21:1 - 21:2;
 + 
       bb0: {
 +         Coverage::CounterIncrement(0);
diff --git a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
index 01b01ea5c17..2efb1fd0a17 100644
--- a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff
@@ -4,7 +4,8 @@
   fn bar() -> bool {
       let mut _0: bool;
   
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:19:1 - 21:2;
++     coverage body span: $DIR/instrument_coverage.rs:19:18: 21:2 (#0)
++     coverage Code(Counter(0)) => 19:1 - 21:2;
 + 
       bb0: {
 +         Coverage::CounterIncrement(0);
diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
index a594c44c316..a179824d6c7 100644
--- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff
@@ -7,12 +7,13 @@
       let mut _2: bool;
       let mut _3: !;
   
++     coverage body span: $DIR/instrument_coverage.rs:10:11: 16:2 (#0)
 +     coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Add, rhs: Counter(1) };
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:10:1 - 10:11;
-+     coverage Code(Expression(0)) => $DIR/instrument_coverage.rs:12:12 - 12:17;
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:13:13 - 13:18;
-+     coverage Code(Counter(1)) => $DIR/instrument_coverage.rs:14:10 - 14:11;
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:16:1 - 16:2;
++     coverage Code(Counter(0)) => 10:1 - 10:11;
++     coverage Code(Expression(0)) => 12:12 - 12:17;
++     coverage Code(Counter(0)) => 13:13 - 13:18;
++     coverage Code(Counter(1)) => 14:9 - 14:10;
++     coverage Code(Counter(0)) => 16:1 - 16:2;
 + 
       bb0: {
 +         Coverage::CounterIncrement(0);
diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
index efb1559baf5..082539369f7 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff
@@ -7,12 +7,13 @@
   
       coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
   
+      coverage body span: $DIR/instrument_coverage_cleanup.rs:13:11: 15:2 (#0)
       coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
-      coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:13:1 - 14:36;
-      coverage Code(Expression(0)) => $DIR/instrument_coverage_cleanup.rs:14:37 - 14:39;
-      coverage Code(Counter(1)) => $DIR/instrument_coverage_cleanup.rs:14:39 - 14:40;
-      coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:15:1 - 15:2;
-      coverage Branch { true_term: Expression(0), false_term: Counter(1) } => $DIR/instrument_coverage_cleanup.rs:14:8 - 14:36;
+      coverage Code(Counter(0)) => 13:1 - 14:36;
+      coverage Code(Expression(0)) => 14:37 - 14:39;
+      coverage Code(Counter(1)) => 14:38 - 14:39;
+      coverage Code(Counter(0)) => 15:1 - 15:2;
+      coverage Branch { true_term: Expression(0), false_term: Counter(1) } => 14:8 - 14:36;
   
       bb0: {
           Coverage::CounterIncrement(0);
diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
index a0fe9a5c05c..8635818c6a7 100644
--- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
+++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff
@@ -7,12 +7,13 @@
   
       coverage branch { true: BlockMarkerId(0), false: BlockMarkerId(1) } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0)
   
++     coverage body span: $DIR/instrument_coverage_cleanup.rs:13:11: 15:2 (#0)
 +     coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Subtract, rhs: Counter(1) };
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:13:1 - 14:36;
-+     coverage Code(Expression(0)) => $DIR/instrument_coverage_cleanup.rs:14:37 - 14:39;
-+     coverage Code(Counter(1)) => $DIR/instrument_coverage_cleanup.rs:14:39 - 14:40;
-+     coverage Code(Counter(0)) => $DIR/instrument_coverage_cleanup.rs:15:1 - 15:2;
-+     coverage Branch { true_term: Expression(0), false_term: Counter(1) } => $DIR/instrument_coverage_cleanup.rs:14:8 - 14:36;
++     coverage Code(Counter(0)) => 13:1 - 14:36;
++     coverage Code(Expression(0)) => 14:37 - 14:39;
++     coverage Code(Counter(1)) => 14:38 - 14:39;
++     coverage Code(Counter(0)) => 15:1 - 15:2;
++     coverage Branch { true_term: Expression(0), false_term: Counter(1) } => 14:8 - 14:36;
 + 
       bb0: {
 +         Coverage::CounterIncrement(0);
diff --git a/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs b/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs
index cf6e3d86377..0a2186b0953 100644
--- a/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs
+++ b/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs
@@ -10,14 +10,16 @@
 //@ ignore-cross-compile
 // Reason: the compiled binary is executed
 
-use run_make_support::{clang, env_var, llvm_ar, run, rustc, static_lib_name};
+use run_make_support::{clang, env_var, llvm_ar, llvm_objdump, run, rustc, static_lib_name};
+
+static PAUTH_A_KEY_PATTERN: &'static str = "paciasp";
+static PAUTH_B_KEY_PATTERN: &'static str = "pacibsp";
 
 fn main() {
     clang()
         .arg("-v")
         .lto("thin")
-        .arg("-mbranch-protection=bti+pac-ret+leaf")
-        .arg("-O2")
+        .arg("-mbranch-protection=bti+pac-ret+b-key+leaf")
         .arg("-c")
         .out_exe("test.o")
         .input("test.c")
@@ -32,5 +34,15 @@ fn main() {
         .input("test.rs")
         .output("test.bin")
         .run();
+
+    // Check that both a-key and b-key pac-ret survived LTO
+    llvm_objdump()
+        .disassemble()
+        .input("test.bin")
+        .run()
+        .assert_stdout_contains_regex(PAUTH_A_KEY_PATTERN)
+        .assert_stdout_contains_regex(PAUTH_B_KEY_PATTERN);
+
+    // Check that the binary actually runs
     run("test.bin");
 }
diff --git a/tests/run-make/simd-ffi/simd.rs b/tests/run-make/simd-ffi/simd.rs
index b72078faafa..9ea8eb8cf88 100644
--- a/tests/run-make/simd-ffi/simd.rs
+++ b/tests/run-make/simd-ffi/simd.rs
@@ -25,7 +25,7 @@ pub struct i32x4([i32; 4]);
 
 extern "C" {
     // _mm_sll_epi32
-    #[cfg(any(target_arch = "x86", target_arch = "x86-64"))]
+    #[cfg(all(any(target_arch = "x86", target_arch = "x86-64"), target_feature = "sse2"))]
     #[link_name = "llvm.x86.sse2.psll.d"]
     fn integer(a: i32x4, b: i32x4) -> i32x4;
 
@@ -38,15 +38,13 @@ extern "C" {
     #[link_name = "llvm.aarch64.neon.maxs.v4i32"]
     fn integer(a: i32x4, b: i32x4) -> i32x4;
 
-    // just some substitute foreign symbol, not an LLVM intrinsic; so
-    // we still get type checking, but not as detailed as (ab)using
-    // LLVM.
+    // Use a generic LLVM intrinsic to do type checking on other platforms
     #[cfg(not(any(
-        target_arch = "x86",
-        target_arch = "x86-64",
+        all(any(target_arch = "x86", target_arch = "x86-64"), target_feature = "sse2"),
         target_arch = "arm",
         target_arch = "aarch64"
     )))]
+    #[link_name = "llvm.smax.v4i32"]
     fn integer(a: i32x4, b: i32x4) -> i32x4;
 }
 
diff --git a/tests/rustdoc-gui/search-about-this-result.goml b/tests/rustdoc-gui/search-about-this-result.goml
new file mode 100644
index 00000000000..1d45c06dc43
--- /dev/null
+++ b/tests/rustdoc-gui/search-about-this-result.goml
@@ -0,0 +1,42 @@
+// Check the "About this Result" popover.
+// Try a complex result.
+go-to: "file://" + |DOC_PATH| + "/lib2/index.html?search=scroll_traits::Iterator<T>,(T->bool)->(Extend<T>,Extend<T>)"
+
+// These two commands are used to be sure the search will be run.
+focus: ".search-input"
+press-key: "Enter"
+
+wait-for: "#search-tabs"
+assert-count: ("#search-tabs button", 1)
+assert-count: (".search-results > a", 1)
+
+assert: "//div[@class='type-signature']/strong[text()='Iterator']"
+assert: "//div[@class='type-signature']/strong[text()='(B']"
+assert: "//div[@class='type-signature']/strong[text()='B)']"
+
+assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='FnMut']"
+assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='Iterator::Item']"
+assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='bool']"
+assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='Extend']"
+
+assert-text: ("div.type-signature div.where:nth-child(4)", "where")
+assert-text: ("div.type-signature div.where:nth-child(5)", "    T matches Iterator::Item")
+assert-text: ("div.type-signature div.where:nth-child(6)", "    F: FnMut (&Iterator::Item) -> bool")
+assert-text: ("div.type-signature div.where:nth-child(7)", "    B: Default + Extend<Iterator::Item>")
+
+// Try a simple result that *won't* give an info box.
+go-to: "file://" + |DOC_PATH| + "/lib2/index.html?search=F->lib2::WhereWhitespace<T>"
+
+// These two commands are used to be sure the search will be run.
+focus: ".search-input"
+press-key: "Enter"
+
+wait-for: "#search-tabs"
+assert-text: ("//div[@class='type-signature']", "F -> WhereWhitespace<T>")
+assert-count: ("#search-tabs button", 1)
+assert-count: (".search-results > a", 1)
+assert-count: ("//div[@class='type-signature']/div[@class='where']", 0)
+
+assert: "//div[@class='type-signature']/strong[text()='F']"
+assert: "//div[@class='type-signature']/strong[text()='WhereWhitespace']"
+assert: "//div[@class='type-signature']/strong[text()='T']"
diff --git a/tests/rustdoc-gui/search-corrections.goml b/tests/rustdoc-gui/search-corrections.goml
index b81b1f382a9..f80675730c4 100644
--- a/tests/rustdoc-gui/search-corrections.goml
+++ b/tests/rustdoc-gui/search-corrections.goml
@@ -24,7 +24,7 @@ assert-css: (".search-corrections", {
 })
 assert-text: (
     ".search-corrections",
-    "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead."
+    "Type \"NotableStructWithLongNamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead."
 )
 
 // Corrections do get shown on the "In Return Type" tab.
@@ -35,7 +35,7 @@ assert-css: (".search-corrections", {
 })
 assert-text: (
     ".search-corrections",
-    "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead."
+    "Type \"NotableStructWithLongNamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead."
 )
 
 // Now, explicit return values
@@ -52,7 +52,7 @@ assert-css: (".search-corrections", {
 })
 assert-text: (
     ".search-corrections",
-    "Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead."
+    "Type \"NotableStructWithLongNamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead."
 )
 
 // Now, generic correction
@@ -69,7 +69,7 @@ assert-css: (".search-corrections", {
 })
 assert-text: (
     ".search-corrections",
-    "Type \"notablestructwithlongnamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead."
+    "Type \"NotableStructWithLongNamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead."
 )
 
 // Now, generic correction plus error
@@ -86,7 +86,7 @@ assert-css: (".search-corrections", {
 })
 assert-text: (
     ".search-corrections",
-    "Type \"notablestructwithlongnamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead."
+    "Type \"NotableStructWithLongNamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead."
 )
 
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
@@ -102,5 +102,5 @@ assert-css: (".error", {
 })
 assert-text: (
     ".error",
-    "Query parser error: \"Generic type parameter notablestructwithlongnamr does not accept generic parameters\"."
+    "Query parser error: \"Generic type parameter NotableStructWithLongNamr does not accept generic parameters\"."
 )
diff --git a/tests/rustdoc-js-std/bufread-fill-buf.js b/tests/rustdoc-js-std/bufread-fill-buf.js
index 3828cf76026..6b9309f6864 100644
--- a/tests/rustdoc-js-std/bufread-fill-buf.js
+++ b/tests/rustdoc-js-std/bufread-fill-buf.js
@@ -2,12 +2,15 @@
 
 const EXPECTED = [
     {
-        'query': 'bufread -> result<u8>',
+        'query': 'bufread -> result<[u8]>',
         'others': [
-            { 'path': 'std::io::Split', 'name': 'next' },
             { 'path': 'std::boxed::Box', 'name': 'fill_buf' },
-            { 'path': 'std::io::Chain', 'name': 'fill_buf' },
-            { 'path': 'std::io::Take', 'name': 'fill_buf' },
+        ],
+    },
+    {
+        'query': 'split<bufread> -> option<result<vec<u8>>>',
+        'others': [
+            { 'path': 'std::io::Split', 'name': 'next' },
         ],
     },
 ];
diff --git a/tests/rustdoc-js-std/deduplication.js b/tests/rustdoc-js-std/deduplication.js
index 51279dd5ed4..95049d0a174 100644
--- a/tests/rustdoc-js-std/deduplication.js
+++ b/tests/rustdoc-js-std/deduplication.js
@@ -5,6 +5,5 @@ const EXPECTED = {
     'others': [
         { 'path': 'std::f32', 'name': 'is_nan' },
         { 'path': 'std::f64', 'name': 'is_nan' },
-        { 'path': 'std::option::Option', 'name': 'is_none' },
     ],
 };
diff --git a/tests/rustdoc-js-std/option-type-signatures.js b/tests/rustdoc-js-std/option-type-signatures.js
index e154fa707ab..3be18e6adf3 100644
--- a/tests/rustdoc-js-std/option-type-signatures.js
+++ b/tests/rustdoc-js-std/option-type-signatures.js
@@ -6,79 +6,198 @@ const EXPECTED = [
     {
         'query': 'option, fnonce -> option',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'map' },
+            {
+                'path': 'std::option::Option',
+                'name': 'map',
+                'displayType': '`Option`<T>, F -> `Option`<U>',
+                'displayWhereClause': "F: `FnOnce` (T) -> U",
+            },
+        ],
+    },
+    {
+        'query': 'option<t>, fnonce -> option',
+        'others': [
+            {
+                'path': 'std::option::Option',
+                'name': 'map',
+                'displayType': '`Option`<`T`>, F -> `Option`<U>',
+                'displayWhereClause': "F: `FnOnce` (T) -> U",
+            },
         ],
     },
     {
         'query': 'option -> default',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'unwrap_or_default' },
-            { 'path': 'std::option::Option', 'name': 'get_or_insert_default' },
+            {
+                'path': 'std::option::Option',
+                'name': 'unwrap_or_default',
+                'displayType': '`Option`<T> -> `T`',
+                'displayWhereClause': "T: `Default`",
+            },
+            {
+                'path': 'std::option::Option',
+                'name': 'get_or_insert_default',
+                'displayType': '&mut `Option`<T> -> &mut `T`',
+                'displayWhereClause': "T: `Default`",
+            },
         ],
     },
     {
         'query': 'option -> []',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'as_slice' },
-            { 'path': 'std::option::Option', 'name': 'as_mut_slice' },
+            {
+                'path': 'std::option::Option',
+                'name': 'as_slice',
+                'displayType': '&`Option`<T> -> &`[`T`]`',
+            },
+            {
+                'path': 'std::option::Option',
+                'name': 'as_mut_slice',
+                'displayType': '&mut `Option`<T> -> &mut `[`T`]`',
+            },
         ],
     },
     {
         'query': 'option<t>, option<t> -> option<t>',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'or' },
-            { 'path': 'std::option::Option', 'name': 'xor' },
+            {
+                'path': 'std::option::Option',
+                'name': 'or',
+                'displayType': '`Option`<`T`>, `Option`<`T`> -> `Option`<`T`>',
+            },
+            {
+                'path': 'std::option::Option',
+                'name': 'xor',
+                'displayType': '`Option`<`T`>, `Option`<`T`> -> `Option`<`T`>',
+            },
         ],
     },
     {
         'query': 'option<t>, option<u> -> option<u>',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'and' },
-            { 'path': 'std::option::Option', 'name': 'zip' },
+            {
+                'path': 'std::option::Option',
+                'name': 'and',
+                'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<`U`>',
+            },
         ],
     },
     {
         'query': 'option<t>, option<u> -> option<t>',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'and' },
-            { 'path': 'std::option::Option', 'name': 'zip' },
+            {
+                'path': 'std::option::Option',
+                'name': 'and',
+                'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<`U`>',
+            },
+            {
+                'path': 'std::option::Option',
+                'name': 'zip',
+                'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<(`T`, U)>',
+            },
         ],
     },
     {
-        'query': 'option<t>, option<u> -> option<t, u>',
+        'query': 'option<t>, option<u> -> option<(t, u)>',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'zip' },
+            {
+                'path': 'std::option::Option',
+                'name': 'zip',
+                'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<`(T`, `U)`>',
+            },
         ],
     },
     {
         'query': 'option<t>, e -> result<t, e>',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'ok_or' },
-            { 'path': 'std::result::Result', 'name': 'transpose' },
+            {
+                'path': 'std::option::Option',
+                'name': 'ok_or',
+                'displayType': '`Option`<`T`>, `E` -> `Result`<`T`, `E`>',
+            },
+            {
+                'path': 'std::result::Result',
+                'name': 'transpose',
+                'displayType': 'Result<`Option`<`T`>, `E`> -> Option<`Result`<`T`, `E`>>',
+            },
         ],
     },
     {
         'query': 'result<option<t>, e> -> option<result<t, e>>',
         'others': [
-            { 'path': 'std::result::Result', 'name': 'transpose' },
+            {
+                'path': 'std::result::Result',
+                'name': 'transpose',
+                'displayType': '`Result`<`Option`<`T`>, `E`> -> `Option`<`Result`<`T`, `E`>>',
+            },
         ],
     },
     {
         'query': 'option<t>, option<t> -> bool',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'eq' },
+            {
+                'path': 'std::option::Option',
+                'name': 'eq',
+                'displayType': '&`Option`<`T`>, &`Option`<`T`> -> `bool`',
+            },
         ],
     },
     {
         'query': 'option<option<t>> -> option<t>',
         'others': [
-            { 'path': 'std::option::Option', 'name': 'flatten' },
+            {
+                'path': 'std::option::Option',
+                'name': 'flatten',
+                'displayType': '`Option`<`Option`<`T`>> -> `Option`<`T`>',
+            },
         ],
     },
     {
         'query': 'option<t>',
         'returned': [
-            { 'path': 'std::result::Result', 'name': 'ok' },
+            {
+                'path': 'std::result::Result',
+                'name': 'ok',
+                'displayType': 'Result<T, E> -> `Option`<`T`>',
+            },
+        ],
+    },
+    {
+        'query': 'option<t>, (fnonce () -> u) -> option',
+        'others': [
+            {
+                'path': 'std::option::Option',
+                'name': 'map',
+                'displayType': '`Option`<`T`>, F -> `Option`<U>',
+                'displayMappedNames': `t = T, u = U`,
+                'displayWhereClause': "F: `FnOnce` (T) -> `U`",
+            },
+            {
+                'path': 'std::option::Option',
+                'name': 'and_then',
+                'displayType': '`Option`<`T`>, F -> `Option`<U>',
+                'displayMappedNames': `t = T, u = U`,
+                'displayWhereClause': "F: `FnOnce` (T) -> Option<`U`>",
+            },
+            {
+                'path': 'std::option::Option',
+                'name': 'zip_with',
+                'displayType': 'Option<T>, `Option`<`U`>, F -> `Option`<R>',
+                'displayMappedNames': `t = U, u = R`,
+                'displayWhereClause': "F: `FnOnce` (T, U) -> `R`",
+            },
+        ],
+    },
+    {
+        'query': 'option<t>, (fnonce () -> option<u>) -> option',
+        'others': [
+            {
+                'path': 'std::option::Option',
+                'name': 'and_then',
+                'displayType': '`Option`<`T`>, F -> `Option`<U>',
+                'displayMappedNames': `t = T, u = U`,
+                'displayWhereClause': "F: `FnOnce` (T) -> `Option`<`U`>",
+            },
         ],
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-bindings.js b/tests/rustdoc-js-std/parser-bindings.js
index c4909c6242d..bd379f139ff 100644
--- a/tests/rustdoc-js-std/parser-bindings.js
+++ b/tests/rustdoc-js-std/parser-bindings.js
@@ -3,20 +3,22 @@ const PARSED = [
         query: 'A<B=C>',
         elems: [
             {
-                name: "a",
+                name: "A",
                 fullPath: ["a"],
                 pathWithoutLast: [],
                 pathLast: "a",
+                normalizedPathLast: "a",
                 generics: [],
                 bindings: [
                     [
                         'b',
                         [
                             {
-                                name: "c",
+                                name: "C",
                                 fullPath: ["c"],
                                 pathWithoutLast: [],
                                 pathLast: "c",
+                                normalizedPathLast: "c",
                                 generics: [],
                                 typeFilter: -1,
                             },
@@ -27,16 +29,15 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: 'A<B=C>',
+        userQuery: 'A<B=C>',
         returned: [],
-        userQuery: 'a<b=c>',
         error: null,
     },
     {
         query: 'A<B = C>',
         elems: [
             {
-                name: "a",
+                name: "A",
                 fullPath: ["a"],
                 pathWithoutLast: [],
                 pathLast: "a",
@@ -45,7 +46,7 @@ const PARSED = [
                     [
                         'b',
                         [{
-                            name: "c",
+                            name: "C",
                             fullPath: ["c"],
                             pathWithoutLast: [],
                             pathLast: "c",
@@ -58,16 +59,15 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: 'A<B = C>',
+        userQuery: 'A<B = C>',
         returned: [],
-        userQuery: 'a<b = c>',
         error: null,
     },
     {
         query: 'A<B=!>',
         elems: [
             {
-                name: "a",
+                name: "A",
                 fullPath: ["a"],
                 pathWithoutLast: [],
                 pathLast: "a",
@@ -89,16 +89,15 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: 'A<B=!>',
+        userQuery: 'A<B=!>',
         returned: [],
-        userQuery: 'a<b=!>',
         error: null,
     },
     {
         query: 'A<B=[]>',
         elems: [
             {
-                name: "a",
+                name: "A",
                 fullPath: ["a"],
                 pathWithoutLast: [],
                 pathLast: "a",
@@ -120,16 +119,15 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: 'A<B=[]>',
+        userQuery: 'A<B=[]>',
         returned: [],
-        userQuery: 'a<b=[]>',
         error: null,
     },
     {
         query: 'A<B=[!]>',
         elems: [
             {
-                name: "a",
+                name: "A",
                 fullPath: ["a"],
                 pathWithoutLast: [],
                 pathLast: "a",
@@ -160,52 +158,47 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: 'A<B=[!]>',
+        userQuery: 'A<B=[!]>',
         returned: [],
-        userQuery: 'a<b=[!]>',
         error: null,
     },
     {
         query: 'A<B=C=>',
         elems: [],
         foundElems: 0,
-        original: 'A<B=C=>',
+        userQuery: 'A<B=C=>',
         returned: [],
-        userQuery: 'a<b=c=>',
         error: "Cannot write `=` twice in a binding",
     },
     {
         query: 'A<B=>',
         elems: [],
         foundElems: 0,
-        original: 'A<B=>',
+        userQuery: 'A<B=>',
         returned: [],
-        userQuery: 'a<b=>',
         error: "Unexpected `>` after `=`",
     },
     {
         query: 'B=C',
         elems: [],
         foundElems: 0,
-        original: 'B=C',
+        userQuery: 'B=C',
         returned: [],
-        userQuery: 'b=c',
         error: "Type parameter `=` must be within generics list",
     },
     {
         query: '[B=C]',
         elems: [],
         foundElems: 0,
-        original: '[B=C]',
+        userQuery: '[B=C]',
         returned: [],
-        userQuery: '[b=c]',
         error: "Type parameter `=` cannot be within slice `[]`",
     },
     {
         query: 'A<B<X>=C>',
         elems: [
             {
-                name: "a",
+                name: "A",
                 fullPath: ["a"],
                 pathWithoutLast: [],
                 pathLast: "a",
@@ -215,7 +208,7 @@ const PARSED = [
                         'b',
                         [
                             {
-                                name: "c",
+                                name: "C",
                                 fullPath: ["c"],
                                 pathWithoutLast: [],
                                 pathLast: "c",
@@ -223,7 +216,7 @@ const PARSED = [
                                 typeFilter: -1,
                             },
                             {
-                                name: "x",
+                                name: "X",
                                 fullPath: ["x"],
                                 pathWithoutLast: [],
                                 pathLast: "x",
@@ -237,9 +230,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: 'A<B<X>=C>',
+        userQuery: 'A<B<X>=C>',
         returned: [],
-        userQuery: 'a<b<x>=c>',
         error: null,
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js
index 5ce35bf511d..068298e7236 100644
--- a/tests/rustdoc-js-std/parser-errors.js
+++ b/tests/rustdoc-js-std/parser-errors.js
@@ -3,450 +3,400 @@ const PARSED = [
         query: '<P>',
         elems: [],
         foundElems: 0,
-        original: "<P>",
+        userQuery: "<P>",
         returned: [],
-        userQuery: "<p>",
         error: "Found generics without a path",
     },
     {
         query: '-> <P>',
         elems: [],
         foundElems: 0,
-        original: "-> <P>",
+        userQuery: "-> <P>",
         returned: [],
-        userQuery: "-> <p>",
         error: "Found generics without a path",
     },
     {
         query: '-> *',
         elems: [],
         foundElems: 0,
-        original: "-> *",
-        returned: [],
         userQuery: "-> *",
+        returned: [],
         error: "Unexpected `*` after ` ` (not a valid identifier)",
     },
     {
         query: 'a<"P">',
         elems: [],
         foundElems: 0,
-        original: "a<\"P\">",
+        userQuery: "a<\"P\">",
         returned: [],
-        userQuery: "a<\"p\">",
         error: "Unexpected `\"` in generics",
     },
     {
         query: '"P" "P"',
         elems: [],
         foundElems: 0,
-        original: "\"P\" \"P\"",
+        userQuery: "\"P\" \"P\"",
         returned: [],
-        userQuery: "\"p\" \"p\"",
         error: "Cannot have more than one element if you use quotes",
     },
     {
         query: '"P","P"',
         elems: [],
         foundElems: 0,
-        original: "\"P\",\"P\"",
+        userQuery: "\"P\",\"P\"",
         returned: [],
-        userQuery: "\"p\",\"p\"",
         error: "Cannot have more than one literal search element",
     },
     {
         query: "P,\"P\"",
         elems: [],
         foundElems: 0,
-        original: "P,\"P\"",
+        userQuery: "P,\"P\"",
         returned: [],
-        userQuery: "p,\"p\"",
         error: "Cannot use literal search when there is more than one element",
     },
     {
         query: '"p" p',
         elems: [],
         foundElems: 0,
-        original: "\"p\" p",
-        returned: [],
         userQuery: "\"p\" p",
+        returned: [],
         error: "Cannot have more than one element if you use quotes",
     },
     {
         query: '"p",p',
         elems: [],
         foundElems: 0,
-        original: "\"p\",p",
-        returned: [],
         userQuery: "\"p\",p",
+        returned: [],
         error: "Cannot have more than one element if you use quotes",
     },
     {
         query: '"const": p',
         elems: [],
         foundElems: 0,
-        original: "\"const\": p",
-        returned: [],
         userQuery: "\"const\": p",
+        returned: [],
         error: "Cannot use quotes on type filter",
     },
     {
         query: "a<:a>",
         elems: [],
         foundElems: 0,
-        original: "a<:a>",
-        returned: [],
         userQuery: "a<:a>",
+        returned: [],
         error: "Expected type filter before `:`",
     },
     {
         query: "a<::a>",
         elems: [],
         foundElems: 0,
-        original: "a<::a>",
-        returned: [],
         userQuery: "a<::a>",
+        returned: [],
         error: "Unexpected `::`: paths cannot start with `::`",
     },
     {
         query: "(p -> p",
         elems: [],
         foundElems: 0,
-        original: "(p -> p",
-        returned: [],
         userQuery: "(p -> p",
+        returned: [],
         error: "Unclosed `(`",
     },
     {
         query: "::a::b",
         elems: [],
         foundElems: 0,
-        original: "::a::b",
-        returned: [],
         userQuery: "::a::b",
+        returned: [],
         error: "Paths cannot start with `::`",
     },
     {
         query: " ::a::b",
         elems: [],
         foundElems: 0,
-        original: "::a::b",
-        returned: [],
         userQuery: "::a::b",
+        returned: [],
         error: "Paths cannot start with `::`",
     },
     {
         query: "a::::b",
         elems: [],
         foundElems: 0,
-        original: "a::::b",
-        returned: [],
         userQuery: "a::::b",
+        returned: [],
         error: "Unexpected `::::`",
     },
     {
         query: "a:: ::b",
         elems: [],
         foundElems: 0,
-        original: "a:: ::b",
-        returned: [],
         userQuery: "a:: ::b",
+        returned: [],
         error: "Unexpected `:: ::`",
     },
     {
         query: "a::\t::b",
         elems: [],
         foundElems: 0,
-        original: "a:: ::b",
-        returned: [],
         userQuery: "a:: ::b",
+        returned: [],
         error: "Unexpected `:: ::`",
     },
     {
         query: "a::b::",
         elems: [],
         foundElems: 0,
-        original: "a::b::",
-        returned: [],
         userQuery: "a::b::",
+        returned: [],
         error: "Paths cannot end with `::`",
     },
     {
         query: ":a",
         elems: [],
         foundElems: 0,
-        original: ":a",
-        returned: [],
         userQuery: ":a",
+        returned: [],
         error: "Expected type filter before `:`",
     },
     {
         query: "a,b:",
         elems: [],
         foundElems: 0,
-        original: "a,b:",
-        returned: [],
         userQuery: "a,b:",
+        returned: [],
         error: "Unexpected `:` (expected path after type filter `b:`)",
     },
     {
         query: "a (b:",
         elems: [],
         foundElems: 0,
-        original: "a (b:",
-        returned: [],
         userQuery: "a (b:",
+        returned: [],
         error: "Unclosed `(`",
     },
     {
         query: "_:",
         elems: [],
         foundElems: 0,
-        original: "_:",
-        returned: [],
         userQuery: "_:",
+        returned: [],
         error: "Unexpected `_` (not a valid identifier)",
     },
     {
         query: "ab:",
         elems: [],
         foundElems: 0,
-        original: "ab:",
-        returned: [],
         userQuery: "ab:",
+        returned: [],
         error: "Unexpected `:` (expected path after type filter `ab:`)",
     },
     {
         query: "a:b",
         elems: [],
         foundElems: 0,
-        original: "a:b",
-        returned: [],
         userQuery: "a:b",
+        returned: [],
         error: "Unknown type filter `a`",
     },
     {
         query: "a-bb",
         elems: [],
         foundElems: 0,
-        original: "a-bb",
-        returned: [],
         userQuery: "a-bb",
+        returned: [],
         error: "Unexpected `-` (did you mean `->`?)",
     },
     {
         query: "a>bb",
         elems: [],
         foundElems: 0,
-        original: "a>bb",
-        returned: [],
         userQuery: "a>bb",
+        returned: [],
         error: "Unexpected `>` (did you mean `->`?)",
     },
     {
         query: "ab'",
         elems: [],
         foundElems: 0,
-        original: "ab'",
-        returned: [],
         userQuery: "ab'",
+        returned: [],
         error: "Unexpected `'` after `b` (not a valid identifier)",
     },
     {
         query: '"p" <a>',
         elems: [],
         foundElems: 0,
-        original: '"p" <a>',
-        returned: [],
         userQuery: '"p" <a>',
+        returned: [],
         error: "Cannot have more than one element if you use quotes",
     },
     {
         query: '"p",<a>',
         elems: [],
         foundElems: 0,
-        original: '"p",<a>',
-        returned: [],
         userQuery: '"p",<a>',
+        returned: [],
         error: "Found generics without a path",
     },
     {
         query: '"p" a<a>',
         elems: [],
         foundElems: 0,
-        original: '"p" a<a>',
-        returned: [],
         userQuery: '"p" a<a>',
+        returned: [],
         error: "Cannot have more than one element if you use quotes",
     },
     {
         query: '"p",a<a>',
         elems: [],
         foundElems: 0,
-        original: '"p",a<a>',
-        returned: [],
         userQuery: '"p",a<a>',
+        returned: [],
         error: "Cannot have more than one element if you use quotes",
     },
     {
         query: "a,<",
         elems: [],
         foundElems: 0,
-        original: 'a,<',
-        returned: [],
         userQuery: 'a,<',
+        returned: [],
         error: 'Found generics without a path',
     },
     {
         query: "aaaaa<>b",
         elems: [],
         foundElems: 0,
-        original: 'aaaaa<>b',
-        returned: [],
         userQuery: 'aaaaa<>b',
+        returned: [],
         error: 'Expected `,`, `:` or `->` after `>`, found `b`',
     },
     {
         query: "fn:aaaaa<>b",
         elems: [],
         foundElems: 0,
-        original: 'fn:aaaaa<>b',
-        returned: [],
         userQuery: 'fn:aaaaa<>b',
+        returned: [],
         error: 'Expected `,`, `:` or `->` after `>`, found `b`',
     },
     {
         query: "->a<>b",
         elems: [],
         foundElems: 0,
-        original: '->a<>b',
-        returned: [],
         userQuery: '->a<>b',
+        returned: [],
         error: 'Expected `,` or `=` after `>`, found `b`',
     },
     {
         query: "a<->",
         elems: [],
         foundElems: 0,
-        original: 'a<->',
-        returned: [],
         userQuery: 'a<->',
+        returned: [],
         error: 'Unclosed `<`',
     },
     {
         query: "a<a>:",
         elems: [],
         foundElems: 0,
-        original: "a<a>:",
-        returned: [],
         userQuery: "a<a>:",
+        returned: [],
         error: 'Unexpected `<` in type filter (before `:`)',
     },
     {
         query: "a<>:",
         elems: [],
         foundElems: 0,
-        original: "a<>:",
-        returned: [],
         userQuery: "a<>:",
+        returned: [],
         error: 'Unexpected `<` in type filter (before `:`)',
     },
     {
         query: "a,:",
         elems: [],
         foundElems: 0,
-        original: "a,:",
-        returned: [],
         userQuery: "a,:",
+        returned: [],
         error: 'Expected type filter before `:`',
     },
     {
         query: "a!:",
         elems: [],
         foundElems: 0,
-        original: "a!:",
-        returned: [],
         userQuery: "a!:",
+        returned: [],
         error: 'Unexpected `!` in type filter (before `:`)',
     },
     {
         query: "  a<>  :",
         elems: [],
         foundElems: 0,
-        original: "a<>  :",
-        returned: [],
         userQuery: "a<>  :",
+        returned: [],
         error: 'Expected `,`, `:` or `->` after `>`, found `:`',
     },
     {
         query: "mod : :",
         elems: [],
         foundElems: 0,
-        original: "mod : :",
-        returned: [],
         userQuery: "mod : :",
+        returned: [],
         error: 'Unexpected `:` (expected path after type filter `mod:`)',
     },
     {
         query: "mod: :",
         elems: [],
         foundElems: 0,
-        original: "mod: :",
-        returned: [],
         userQuery: "mod: :",
+        returned: [],
         error: 'Unexpected `:` (expected path after type filter `mod:`)',
     },
     {
         query: "a!a",
         elems: [],
         foundElems: 0,
-        original: "a!a",
-        returned: [],
         userQuery: "a!a",
+        returned: [],
         error: 'Unexpected `!`: it can only be at the end of an ident',
     },
     {
         query: "a!!",
         elems: [],
         foundElems: 0,
-        original: "a!!",
-        returned: [],
         userQuery: "a!!",
+        returned: [],
         error: 'Cannot have more than one `!` in an ident',
     },
     {
         query: "mod:a!",
         elems: [],
         foundElems: 0,
-        original: "mod:a!",
-        returned: [],
         userQuery: "mod:a!",
+        returned: [],
         error: 'Invalid search type: macro `!` and `mod` both specified',
     },
     {
         query: "mod:!",
         elems: [],
         foundElems: 0,
-        original: "mod:!",
-        returned: [],
         userQuery: "mod:!",
+        returned: [],
         error: 'Invalid search type: primitive never type `!` and `mod` both specified',
     },
     {
         query: "a!::a",
         elems: [],
         foundElems: 0,
-        original: "a!::a",
-        returned: [],
         userQuery: "a!::a",
+        returned: [],
         error: 'Cannot have associated items in macros',
     },
     {
         query: "a<",
         elems: [],
         foundElems: 0,
-        original: "a<",
-        returned: [],
         userQuery: "a<",
+        returned: [],
         error: "Unclosed `<`",
     },
     {
@@ -479,9 +429,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "p<x> , y",
-        returned: [],
         userQuery: "p<x> , y",
+        returned: [],
         error: null,
     },
     {
@@ -514,9 +463,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "p<x , y>",
-        returned: [],
         userQuery: "p<x , y>",
+        returned: [],
         error: null,
     },
     {
@@ -548,9 +496,8 @@ const PARSED = [
             },
         ],
         foundElems: 3,
-        original: "p ,x , y",
-        returned: [],
         userQuery: "p ,x , y",
+        returned: [],
         error: null,
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-filter.js b/tests/rustdoc-js-std/parser-filter.js
index a1dd0ea3b5a..cda950461f7 100644
--- a/tests/rustdoc-js-std/parser-filter.js
+++ b/tests/rustdoc-js-std/parser-filter.js
@@ -10,9 +10,8 @@ const PARSED = [
             typeFilter: 7,
         }],
         foundElems: 1,
-        original: "fn:foo",
-        returned: [],
         userQuery: "fn:foo",
+        returned: [],
         error: null,
     },
     {
@@ -26,18 +25,16 @@ const PARSED = [
             typeFilter: 6,
         }],
         foundElems: 1,
-        original: "enum : foo",
-        returned: [],
         userQuery: "enum : foo",
+        returned: [],
         error: null,
     },
     {
         query: 'macro<f>:foo',
         elems: [],
         foundElems: 0,
-        original: "macro<f>:foo",
-        returned: [],
         userQuery: "macro<f>:foo",
+        returned: [],
         error: "Unexpected `<` in type filter (before `:`)",
     },
     {
@@ -51,9 +48,8 @@ const PARSED = [
             typeFilter: 16,
         }],
         foundElems: 1,
-        original: "macro!",
-        returned: [],
         userQuery: "macro!",
+        returned: [],
         error: null,
     },
     {
@@ -67,9 +63,8 @@ const PARSED = [
             typeFilter: 16,
         }],
         foundElems: 1,
-        original: "macro:mac!",
-        returned: [],
         userQuery: "macro:mac!",
+        returned: [],
         error: null,
     },
     {
@@ -83,16 +78,15 @@ const PARSED = [
             typeFilter: 16,
         }],
         foundElems: 1,
-        original: "a::mac!",
-        returned: [],
         userQuery: "a::mac!",
+        returned: [],
         error: null,
     },
     {
         query: '-> fn:foo',
         elems: [],
         foundElems: 1,
-        original: "-> fn:foo",
+        userQuery: "-> fn:foo",
         returned: [{
             name: "foo",
             fullPath: ["foo"],
@@ -101,14 +95,13 @@ const PARSED = [
             generics: [],
             typeFilter: 7,
         }],
-        userQuery: "-> fn:foo",
         error: null,
     },
     {
         query: '-> fn:foo<fn:bar>',
         elems: [],
         foundElems: 1,
-        original: "-> fn:foo<fn:bar>",
+        userQuery: "-> fn:foo<fn:bar>",
         returned: [{
             name: "foo",
             fullPath: ["foo"],
@@ -126,14 +119,13 @@ const PARSED = [
             ],
             typeFilter: 7,
         }],
-        userQuery: "-> fn:foo<fn:bar>",
         error: null,
     },
     {
         query: '-> fn:foo<fn:bar, enum : baz::fuzz>',
         elems: [],
         foundElems: 1,
-        original: "-> fn:foo<fn:bar, enum : baz::fuzz>",
+        userQuery: "-> fn:foo<fn:bar, enum : baz::fuzz>",
         returned: [{
             name: "foo",
             fullPath: ["foo"],
@@ -159,7 +151,6 @@ const PARSED = [
             ],
             typeFilter: 7,
         }],
-        userQuery: "-> fn:foo<fn:bar, enum : baz::fuzz>",
         error: null,
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-generics.js b/tests/rustdoc-js-std/parser-generics.js
index 726ee56c2c1..8b8d95bcb88 100644
--- a/tests/rustdoc-js-std/parser-generics.js
+++ b/tests/rustdoc-js-std/parser-generics.js
@@ -3,9 +3,8 @@ const PARSED = [
         query: 'A<B<C<D>,  E>',
         elems: [],
         foundElems: 0,
-        original: 'A<B<C<D>,  E>',
+        userQuery: 'A<B<C<D>,  E>',
         returned: [],
-        userQuery: 'a<b<c<d>,  e>',
         error: 'Unclosed `<`',
     },
     {
@@ -29,9 +28,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "p<>,u8",
-        returned: [],
         userQuery: "p<>,u8",
+        returned: [],
         error: null,
     },
     {
@@ -55,9 +53,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: '"p"<a>',
-        returned: [],
         userQuery: '"p"<a>',
+        returned: [],
         error: null,
     },
     {
@@ -89,9 +86,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: 'p<u<x>>',
-        returned: [],
         userQuery: 'p<u<x>>',
+        returned: [],
         error: null,
     },
     {
@@ -130,9 +126,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: 'p<u<x>, r>',
-        returned: [],
         userQuery: 'p<u<x>, r>',
+        returned: [],
         error: null,
     },
     {
@@ -171,9 +166,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: 'p<u<x, r>>',
-        returned: [],
         userQuery: 'p<u<x, r>>',
+        returned: [],
         error: null,
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-hof.js b/tests/rustdoc-js-std/parser-hof.js
index 0b99c45b7a9..ca761015412 100644
--- a/tests/rustdoc-js-std/parser-hof.js
+++ b/tests/rustdoc-js-std/parser-hof.js
@@ -12,13 +12,13 @@ const PARSED = [
                 [
                     "output",
                     [{
-                        name: "f",
+                        name: "F",
                         fullPath: ["f"],
                         pathWithoutLast: [],
                         pathLast: "f",
                         generics: [
                             {
-                                name: "p",
+                                name: "P",
                                 fullPath: ["p"],
                                 pathWithoutLast: [],
                                 pathLast: "p",
@@ -32,9 +32,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "(-> F<P>)",
+        userQuery: "(-> F<P>)",
         returned: [],
-        userQuery: "(-> f<p>)",
         error: null,
     },
     {
@@ -49,7 +48,7 @@ const PARSED = [
                 [
                     "output",
                     [{
-                        name: "p",
+                        name: "P",
                         fullPath: ["p"],
                         pathWithoutLast: [],
                         pathLast: "p",
@@ -61,9 +60,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "(-> P)",
+        userQuery: "(-> P)",
         returned: [],
-        userQuery: "(-> p)",
         error: null,
     },
     {
@@ -90,9 +88,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "(->,a)",
-        returned: [],
         userQuery: "(->,a)",
+        returned: [],
         error: null,
     },
     {
@@ -103,13 +100,13 @@ const PARSED = [
             pathWithoutLast: [],
             pathLast: "->",
             generics: [{
-                name: "f",
+                name: "F",
                 fullPath: ["f"],
                 pathWithoutLast: [],
                 pathLast: "f",
                 generics: [
                     {
-                        name: "p",
+                        name: "P",
                         fullPath: ["p"],
                         pathWithoutLast: [],
                         pathLast: "p",
@@ -127,9 +124,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "(F<P> ->)",
+        userQuery: "(F<P> ->)",
         returned: [],
-        userQuery: "(f<p> ->)",
         error: null,
     },
     {
@@ -140,7 +136,7 @@ const PARSED = [
             pathWithoutLast: [],
             pathLast: "->",
             generics: [{
-                name: "p",
+                name: "P",
                 fullPath: ["p"],
                 pathWithoutLast: [],
                 pathLast: "p",
@@ -156,9 +152,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "(P ->)",
+        userQuery: "(P ->)",
         returned: [],
-        userQuery: "(p ->)",
         error: null,
     },
     {
@@ -185,9 +180,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "(,a->)",
-        returned: [],
         userQuery: "(,a->)",
+        returned: [],
         error: null,
     },
     {
@@ -221,9 +215,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "(aaaaa->a)",
-        returned: [],
         userQuery: "(aaaaa->a)",
+        returned: [],
         error: null,
     },
     {
@@ -267,9 +260,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "(aaaaa, b -> a)",
-        returned: [],
         userQuery: "(aaaaa, b -> a)",
+        returned: [],
         error: null,
     },
     {
@@ -313,9 +305,8 @@ const PARSED = [
             typeFilter: 1,
         }],
         foundElems: 1,
-        original: "primitive:(aaaaa, b -> a)",
-        returned: [],
         userQuery: "primitive:(aaaaa, b -> a)",
+        returned: [],
         error: null,
     },
     {
@@ -369,16 +360,15 @@ const PARSED = [
             }
         ],
         foundElems: 2,
-        original: "x, trait:(aaaaa, b -> a)",
-        returned: [],
         userQuery: "x, trait:(aaaaa, b -> a)",
+        returned: [],
         error: null,
     },
     // Rust-style HOF
     {
         query: "Fn () -> F<P>",
         elems: [{
-            name: "fn",
+            name: "Fn",
             fullPath: ["fn"],
             pathWithoutLast: [],
             pathLast: "fn",
@@ -387,13 +377,13 @@ const PARSED = [
                 [
                     "output",
                     [{
-                        name: "f",
+                        name: "F",
                         fullPath: ["f"],
                         pathWithoutLast: [],
                         pathLast: "f",
                         generics: [
                             {
-                                name: "p",
+                                name: "P",
                                 fullPath: ["p"],
                                 pathWithoutLast: [],
                                 pathLast: "p",
@@ -407,15 +397,14 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "Fn () -> F<P>",
+        userQuery: "Fn () -> F<P>",
         returned: [],
-        userQuery: "fn () -> f<p>",
         error: null,
     },
     {
         query: "FnMut() -> P",
         elems: [{
-            name: "fnmut",
+            name: "FnMut",
             fullPath: ["fnmut"],
             pathWithoutLast: [],
             pathLast: "fnmut",
@@ -424,7 +413,7 @@ const PARSED = [
                 [
                     "output",
                     [{
-                        name: "p",
+                        name: "P",
                         fullPath: ["p"],
                         pathWithoutLast: [],
                         pathLast: "p",
@@ -436,15 +425,14 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "FnMut() -> P",
+        userQuery: "FnMut() -> P",
         returned: [],
-        userQuery: "fnmut() -> p",
         error: null,
     },
     {
         query: "(FnMut() -> P)",
         elems: [{
-            name: "fnmut",
+            name: "FnMut",
             fullPath: ["fnmut"],
             pathWithoutLast: [],
             pathLast: "fnmut",
@@ -453,7 +441,7 @@ const PARSED = [
                 [
                     "output",
                     [{
-                        name: "p",
+                        name: "P",
                         fullPath: ["p"],
                         pathWithoutLast: [],
                         pathLast: "p",
@@ -465,26 +453,25 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "(FnMut() -> P)",
+        userQuery: "(FnMut() -> P)",
         returned: [],
-        userQuery: "(fnmut() -> p)",
         error: null,
     },
     {
         query: "Fn(F<P>)",
         elems: [{
-            name: "fn",
+            name: "Fn",
             fullPath: ["fn"],
             pathWithoutLast: [],
             pathLast: "fn",
             generics: [{
-                name: "f",
+                name: "F",
                 fullPath: ["f"],
                 pathWithoutLast: [],
                 pathLast: "f",
                 generics: [
                     {
-                        name: "p",
+                        name: "P",
                         fullPath: ["p"],
                         pathWithoutLast: [],
                         pathLast: "p",
@@ -502,9 +489,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "Fn(F<P>)",
+        userQuery: "Fn(F<P>)",
         returned: [],
-        userQuery: "fn(f<p>)",
         error: null,
     },
     {
@@ -548,9 +534,8 @@ const PARSED = [
             typeFilter: 1,
         }],
         foundElems: 1,
-        original: "primitive:fnonce(aaaaa, b) -> a",
-        returned: [],
         userQuery: "primitive:fnonce(aaaaa, b) -> a",
+        returned: [],
         error: null,
     },
     {
@@ -594,9 +579,8 @@ const PARSED = [
             typeFilter: 1,
         }],
         foundElems: 1,
-        original: "primitive:fnonce(aaaaa, keyword:b) -> trait:a",
-        returned: [],
         userQuery: "primitive:fnonce(aaaaa, keyword:b) -> trait:a",
+        returned: [],
         error: null,
     },
     {
@@ -665,9 +649,8 @@ const PARSED = [
             }
         ],
         foundElems: 2,
-        original: "x, trait:fn(aaaaa, b -> a)",
-        returned: [],
         userQuery: "x, trait:fn(aaaaa, b -> a)",
+        returned: [],
         error: null,
     },
     {
@@ -704,9 +687,8 @@ const PARSED = [
             }
         ],
         foundElems: 2,
-        original: "a,b(c)",
-        returned: [],
         userQuery: "a,b(c)",
+        returned: [],
         error: null,
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-ident.js b/tests/rustdoc-js-std/parser-ident.js
index cc79c58f1da..f65391b1571 100644
--- a/tests/rustdoc-js-std/parser-ident.js
+++ b/tests/rustdoc-js-std/parser-ident.js
@@ -2,7 +2,7 @@ const PARSED = [
     {
         query: "R<!>",
         elems: [{
-            name: "r",
+            name: "R",
             fullPath: ["r"],
             pathWithoutLast: [],
             pathLast: "r",
@@ -19,9 +19,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "R<!>",
+        userQuery: "R<!>",
         returned: [],
-        userQuery: "r<!>",
         error: null,
     },
     {
@@ -35,9 +34,8 @@ const PARSED = [
             typeFilter: 1,
         }],
         foundElems: 1,
-        original: "!",
-        returned: [],
         userQuery: "!",
+        returned: [],
         error: null,
     },
     {
@@ -51,27 +49,24 @@ const PARSED = [
             typeFilter: 16,
         }],
         foundElems: 1,
-        original: "a!",
-        returned: [],
         userQuery: "a!",
+        returned: [],
         error: null,
     },
     {
         query: "a!::b",
         elems: [],
         foundElems: 0,
-        original: "a!::b",
-        returned: [],
         userQuery: "a!::b",
+        returned: [],
         error: "Cannot have associated items in macros",
     },
     {
         query: "!<T>",
         elems: [],
         foundElems: 0,
-        original: "!<T>",
+        userQuery: "!<T>",
         returned: [],
-        userQuery: "!<t>",
         error: "Never type `!` does not accept generic parameters",
     },
     {
@@ -85,36 +80,32 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "!::b",
-        returned: [],
         userQuery: "!::b",
+        returned: [],
         error: null,
     },
     {
         query: "b::!",
         elems: [],
         foundElems: 0,
-        original: "b::!",
-        returned: [],
         userQuery: "b::!",
+        returned: [],
         error: "Never type `!` is not associated item",
     },
     {
         query: "!::!",
         elems: [],
         foundElems: 0,
-        original: "!::!",
-        returned: [],
         userQuery: "!::!",
+        returned: [],
         error: "Never type `!` is not associated item",
     },
     {
         query: "b::!::c",
         elems: [],
         foundElems: 0,
-        original: "b::!::c",
-        returned: [],
         userQuery: "b::!::c",
+        returned: [],
         error: "Never type `!` is not associated item",
     },
     {
@@ -126,7 +117,7 @@ const PARSED = [
             pathLast: "b",
             generics: [
                 {
-                    name: "t",
+                    name: "T",
                     fullPath: ["t"],
                     pathWithoutLast: [],
                     pathLast: "t",
@@ -137,18 +128,16 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "!::b<T>",
+        userQuery: "!::b<T>",
         returned: [],
-        userQuery: "!::b<t>",
         error: null,
     },
     {
         query: "a!::b!",
         elems: [],
         foundElems: 0,
-        original: "a!::b!",
-        returned: [],
         userQuery: "a!::b!",
+        returned: [],
         error: "Cannot have associated items in macros",
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-literal.js b/tests/rustdoc-js-std/parser-literal.js
index 87c06224dbf..63e07a246a1 100644
--- a/tests/rustdoc-js-std/parser-literal.js
+++ b/tests/rustdoc-js-std/parser-literal.js
@@ -2,13 +2,13 @@ const PARSED = [
     {
         query: 'R<P>',
         elems: [{
-            name: "r",
+            name: "R",
             fullPath: ["r"],
             pathWithoutLast: [],
             pathLast: "r",
             generics: [
                 {
-                    name: "p",
+                    name: "P",
                     fullPath: ["p"],
                     pathWithoutLast: [],
                     pathLast: "p",
@@ -18,9 +18,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "R<P>",
+        userQuery: "R<P>",
         returned: [],
-        userQuery: "r<p>",
         error: null,
     }
 ];
diff --git a/tests/rustdoc-js-std/parser-paths.js b/tests/rustdoc-js-std/parser-paths.js
index 774e5d028cc..bb34e22e518 100644
--- a/tests/rustdoc-js-std/parser-paths.js
+++ b/tests/rustdoc-js-std/parser-paths.js
@@ -2,7 +2,7 @@ const PARSED = [
     {
         query: 'A::B',
         elems: [{
-            name: "a::b",
+            name: "A::B",
             fullPath: ["a", "b"],
             pathWithoutLast: ["a"],
             pathLast: "b",
@@ -10,9 +10,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "A::B",
+        userQuery: "A::B",
         returned: [],
-        userQuery: "a::b",
         error: null,
     },
     {
@@ -26,9 +25,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: 'a:: a',
-        returned: [],
         userQuery: 'a:: a',
+        returned: [],
         error: null,
     },
     {
@@ -42,9 +40,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: 'a ::a',
-        returned: [],
         userQuery: 'a ::a',
+        returned: [],
         error: null,
     },
     {
@@ -58,16 +55,15 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: 'a  ::  a',
-        returned: [],
         userQuery: 'a  ::  a',
+        returned: [],
         error: null,
     },
     {
         query: 'A::B,C',
         elems: [
             {
-                name: "a::b",
+                name: "A::B",
                 fullPath: ["a", "b"],
                 pathWithoutLast: ["a"],
                 pathLast: "b",
@@ -75,7 +71,7 @@ const PARSED = [
                 typeFilter: -1,
             },
             {
-                name: "c",
+                name: "C",
                 fullPath: ["c"],
                 pathWithoutLast: [],
                 pathLast: "c",
@@ -84,16 +80,15 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: 'A::B,C',
+        userQuery: 'A::B,C',
         returned: [],
-        userQuery: 'a::b,c',
         error: null,
     },
     {
         query: 'A::B<f>,C',
         elems: [
             {
-                name: "a::b",
+                name: "A::B",
                 fullPath: ["a", "b"],
                 pathWithoutLast: ["a"],
                 pathLast: "b",
@@ -109,7 +104,7 @@ const PARSED = [
                 typeFilter: -1,
             },
             {
-                name: "c",
+                name: "C",
                 fullPath: ["c"],
                 pathWithoutLast: [],
                 pathLast: "c",
@@ -118,9 +113,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: 'A::B<f>,C',
+        userQuery: 'A::B<f>,C',
         returned: [],
-        userQuery: 'a::b<f>,c',
         error: null,
     },
     {
@@ -134,9 +128,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "mod::a",
-        returned: [],
         userQuery: "mod::a",
+        returned: [],
         error: null,
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-quote.js b/tests/rustdoc-js-std/parser-quote.js
index 731673cf463..b485047e385 100644
--- a/tests/rustdoc-js-std/parser-quote.js
+++ b/tests/rustdoc-js-std/parser-quote.js
@@ -3,7 +3,7 @@ const PARSED = [
         query: '-> "p"',
         elems: [],
         foundElems: 1,
-        original: '-> "p"',
+        userQuery: '-> "p"',
         returned: [{
             name: "p",
             fullPath: ["p"],
@@ -12,7 +12,6 @@ const PARSED = [
             generics: [],
             typeFilter: -1,
         }],
-        userQuery: '-> "p"',
         error: null,
     },
     {
@@ -26,54 +25,48 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: '"p",',
-        returned: [],
         userQuery: '"p",',
+        returned: [],
         error: null,
     },
     {
         query: '"p" -> a',
         elems: [],
         foundElems: 0,
-        original: '"p" -> a',
-        returned: [],
         userQuery: '"p" -> a',
+        returned: [],
         error: "Cannot have more than one element if you use quotes",
     },
     {
         query: '"a" -> "p"',
         elems: [],
         foundElems: 0,
-        original: '"a" -> "p"',
-        returned: [],
         userQuery: '"a" -> "p"',
+        returned: [],
         error: "Cannot have more than one literal search element",
     },
     {
         query: '->"-"',
         elems: [],
         foundElems: 0,
-        original: '->"-"',
-        returned: [],
         userQuery: '->"-"',
+        returned: [],
         error: 'Unexpected `-` in a string element',
     },
     {
         query: '"a',
         elems: [],
         foundElems: 0,
-        original: '"a',
-        returned: [],
         userQuery: '"a',
+        returned: [],
         error: 'Unclosed `"`',
     },
     {
         query: '""',
         elems: [],
         foundElems: 0,
-        original: '""',
-        returned: [],
         userQuery: '""',
+        returned: [],
         error: 'Cannot have empty string element',
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-reference.js b/tests/rustdoc-js-std/parser-reference.js
index 6b1250146be..0fa07ae9895 100644
--- a/tests/rustdoc-js-std/parser-reference.js
+++ b/tests/rustdoc-js-std/parser-reference.js
@@ -3,18 +3,16 @@ const PARSED = [
         query: '&[',
         elems: [],
         foundElems: 0,
-        original: '&[',
-        returned: [],
         userQuery: '&[',
+        returned: [],
         error: 'Unclosed `[`',
     },
     {
         query: '[&',
         elems: [],
         foundElems: 0,
-        original: '[&',
-        returned: [],
         userQuery: '[&',
+        returned: [],
         error: 'Unclosed `[`',
     },
     {
@@ -39,7 +37,7 @@ const PARSED = [
                                 pathLast: "reference",
                                 generics: [
                                     {
-                                        name: "d",
+                                        name: "D",
                                         fullPath: ["d"],
                                         pathWithoutLast: [],
                                         pathLast: "d",
@@ -65,9 +63,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: '&&&D, []',
+        userQuery: '&&&D, []',
         returned: [],
-        userQuery: '&&&d, []',
         error: null,
     },
     {
@@ -98,7 +95,7 @@ const PARSED = [
                                         pathLast: "[]",
                                         generics: [
                                             {
-                                                name: "d",
+                                                name: "D",
                                                 fullPath: ["d"],
                                                 pathWithoutLast: [],
                                                 pathLast: "d",
@@ -119,9 +116,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: '&&&[D]',
+        userQuery: '&&&[D]',
         returned: [],
-        userQuery: '&&&[d]',
         error: null,
     },
     {
@@ -137,9 +133,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: '&',
-        returned: [],
         userQuery: '&',
+        returned: [],
         error: null,
     },
     {
@@ -164,9 +159,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: '&mut',
-        returned: [],
         userQuery: '&mut',
+        returned: [],
         error: null,
     },
     {
@@ -190,9 +184,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "&,u8",
-        returned: [],
         userQuery: "&,u8",
+        returned: [],
         error: null,
     },
     {
@@ -225,9 +218,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "&mut,u8",
-        returned: [],
         userQuery: "&mut,u8",
+        returned: [],
         error: null,
     },
     {
@@ -252,9 +244,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "&u8",
-        returned: [],
         userQuery: "&u8",
+        returned: [],
         error: null,
     },
     {
@@ -288,9 +279,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "&u8<u8>",
-        returned: [],
         userQuery: "&u8<u8>",
+        returned: [],
         error: null,
     },
     {
@@ -324,9 +314,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "u8<&u8>",
-        returned: [],
         userQuery: "u8<&u8>",
+        returned: [],
         error: null,
     },
     {
@@ -368,9 +357,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "u8<&u8, u8>",
-        returned: [],
         userQuery: "u8<&u8, u8>",
+        returned: [],
         error: null,
     },
     {
@@ -404,9 +392,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "u8<&u8>",
-        returned: [],
         userQuery: "u8<&u8>",
+        returned: [],
         error: null,
     },
     {
@@ -456,9 +443,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "u8<&mut u8, u8>",
-        returned: [],
         userQuery: "u8<&mut u8, u8>",
+        returned: [],
         error: null,
     },
     {
@@ -483,18 +469,16 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "primitive:&u8",
-        returned: [],
         userQuery: "primitive:&u8",
+        returned: [],
         error: null,
     },
     {
         query: 'macro:&u8',
         elems: [],
         foundElems: 0,
-        original: "macro:&u8",
-        returned: [],
         userQuery: "macro:&u8",
+        returned: [],
         error: "Invalid search type: primitive `&` and `macro` both specified",
     },
     {
@@ -519,9 +503,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "&macro:u8",
-        returned: [],
         userQuery: "&macro:u8",
+        returned: [],
         error: null,
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-returned.js b/tests/rustdoc-js-std/parser-returned.js
index 8f68209bb96..30ce26a8920 100644
--- a/tests/rustdoc-js-std/parser-returned.js
+++ b/tests/rustdoc-js-std/parser-returned.js
@@ -3,15 +3,15 @@ const PARSED = [
         query: "-> F<P>",
         elems: [],
         foundElems: 1,
-        original: "-> F<P>",
+        userQuery: "-> F<P>",
         returned: [{
-            name: "f",
+            name: "F",
             fullPath: ["f"],
             pathWithoutLast: [],
             pathLast: "f",
             generics: [
                 {
-                    name: "p",
+                    name: "P",
                     fullPath: ["p"],
                     pathWithoutLast: [],
                     pathLast: "p",
@@ -20,30 +20,28 @@ const PARSED = [
             ],
             typeFilter: -1,
         }],
-        userQuery: "-> f<p>",
         error: null,
     },
     {
         query: "-> P",
         elems: [],
         foundElems: 1,
-        original: "-> P",
+        userQuery: "-> P",
         returned: [{
-            name: "p",
+            name: "P",
             fullPath: ["p"],
             pathWithoutLast: [],
             pathLast: "p",
             generics: [],
             typeFilter: -1,
         }],
-        userQuery: "-> p",
         error: null,
     },
     {
         query: "->,a",
         elems: [],
         foundElems: 1,
-        original: "->,a",
+        userQuery: "->,a",
         returned: [{
             name: "a",
             fullPath: ["a"],
@@ -52,7 +50,6 @@ const PARSED = [
             generics: [],
             typeFilter: -1,
         }],
-        userQuery: "->,a",
         error: null,
     },
     {
@@ -66,7 +63,7 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 2,
-        original: "aaaaa->a",
+        userQuery: "aaaaa->a",
         returned: [{
             name: "a",
             fullPath: ["a"],
@@ -75,14 +72,13 @@ const PARSED = [
             generics: [],
             typeFilter: -1,
         }],
-        userQuery: "aaaaa->a",
         error: null,
     },
     {
         query: "-> !",
         elems: [],
         foundElems: 1,
-        original: "-> !",
+        userQuery: "-> !",
         returned: [{
             name: "never",
             fullPath: ["never"],
@@ -91,7 +87,6 @@ const PARSED = [
             generics: [],
             typeFilter: 1,
         }],
-        userQuery: "-> !",
         error: null,
     },
     {
@@ -105,9 +100,8 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "a->",
-        returned: [],
         userQuery: "a->",
+        returned: [],
         hasReturnArrow: true,
         error: null,
     },
@@ -122,9 +116,8 @@ const PARSED = [
             typeFilter: 1,
         }],
         foundElems: 1,
-        original: "!->",
-        returned: [],
         userQuery: "!->",
+        returned: [],
         hasReturnArrow: true,
         error: null,
     },
@@ -139,9 +132,8 @@ const PARSED = [
             typeFilter: 1,
         }],
         foundElems: 1,
-        original: "! ->",
-        returned: [],
         userQuery: "! ->",
+        returned: [],
         hasReturnArrow: true,
         error: null,
     },
@@ -156,9 +148,8 @@ const PARSED = [
             typeFilter: 1,
         }],
         foundElems: 1,
-        original: "primitive:!->",
-        returned: [],
         userQuery: "primitive:!->",
+        returned: [],
         hasReturnArrow: true,
         error: null,
     },
diff --git a/tests/rustdoc-js-std/parser-separators.js b/tests/rustdoc-js-std/parser-separators.js
index 7f95f61b006..cf271c80cdc 100644
--- a/tests/rustdoc-js-std/parser-separators.js
+++ b/tests/rustdoc-js-std/parser-separators.js
@@ -14,9 +14,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "aaaaaa b",
-        returned: [],
         userQuery: "aaaaaa b",
+        returned: [],
         error: null,
     },
     {
@@ -40,9 +39,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "aaaaaa, b",
-        returned: [],
         userQuery: "aaaaaa, b",
+        returned: [],
         error: null,
     },
     {
@@ -58,9 +56,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "a b",
-        returned: [],
         userQuery: "a b",
+        returned: [],
         error: null,
     },
     {
@@ -84,9 +81,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "a,b",
-        returned: [],
         userQuery: "a,b",
+        returned: [],
         error: null,
     },
     {
@@ -102,9 +98,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "a b",
-        returned: [],
         userQuery: "a b",
+        returned: [],
         error: null,
     },
     {
@@ -128,9 +123,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "a<b c>",
-        returned: [],
         userQuery: "a<b c>",
+        returned: [],
         error: null,
     },
     {
@@ -161,9 +155,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "a<b,c>",
-        returned: [],
         userQuery: "a<b,c>",
+        returned: [],
         error: null,
     },
     {
@@ -187,9 +180,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "a<b c>",
-        returned: [],
         userQuery: "a<b c>",
+        returned: [],
         error: null,
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-slice-array.js b/tests/rustdoc-js-std/parser-slice-array.js
index 1de52af94e6..65797945535 100644
--- a/tests/rustdoc-js-std/parser-slice-array.js
+++ b/tests/rustdoc-js-std/parser-slice-array.js
@@ -3,9 +3,8 @@ const PARSED = [
         query: '[[[D, []]]',
         elems: [],
         foundElems: 0,
-        original: '[[[D, []]]',
+        userQuery: '[[[D, []]]',
         returned: [],
-        userQuery: '[[[d, []]]',
         error: 'Unclosed `[`',
     },
     {
@@ -30,7 +29,7 @@ const PARSED = [
                                 pathLast: "[]",
                                 generics: [
                                     {
-                                        name: "d",
+                                        name: "D",
                                         fullPath: ["d"],
                                         pathWithoutLast: [],
                                         pathLast: "d",
@@ -56,9 +55,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: '[[[D, []]]]',
+        userQuery: '[[[D, []]]]',
         returned: [],
-        userQuery: '[[[d, []]]]',
         error: null,
     },
     {
@@ -82,9 +80,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "[],u8",
-        returned: [],
         userQuery: "[],u8",
+        returned: [],
         error: null,
     },
     {
@@ -109,9 +106,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "[u8]",
-        returned: [],
         userQuery: "[u8]",
+        returned: [],
         error: null,
     },
     {
@@ -144,9 +140,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "[u8,u8]",
-        returned: [],
         userQuery: "[u8,u8]",
+        returned: [],
         error: null,
     },
     {
@@ -180,9 +175,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "[u8<u8>]",
-        returned: [],
         userQuery: "[u8<u8>]",
+        returned: [],
         error: null,
     },
     {
@@ -198,90 +192,80 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "[]",
-        returned: [],
         userQuery: "[]",
+        returned: [],
         error: null,
     },
     {
         query: '[>',
         elems: [],
         foundElems: 0,
-        original: "[>",
-        returned: [],
         userQuery: "[>",
+        returned: [],
         error: "Unexpected `>` after `[`",
     },
     {
         query: '[<',
         elems: [],
         foundElems: 0,
-        original: "[<",
-        returned: [],
         userQuery: "[<",
+        returned: [],
         error: "Found generics without a path",
     },
     {
         query: '[a>',
         elems: [],
         foundElems: 0,
-        original: "[a>",
-        returned: [],
         userQuery: "[a>",
+        returned: [],
         error: "Unexpected `>` after `[`",
     },
     {
         query: '[a<',
         elems: [],
         foundElems: 0,
-        original: "[a<",
-        returned: [],
         userQuery: "[a<",
+        returned: [],
         error: "Unclosed `<`",
     },
     {
         query: '[a',
         elems: [],
         foundElems: 0,
-        original: "[a",
-        returned: [],
         userQuery: "[a",
+        returned: [],
         error: "Unclosed `[`",
     },
     {
         query: '[',
         elems: [],
         foundElems: 0,
-        original: "[",
-        returned: [],
         userQuery: "[",
+        returned: [],
         error: "Unclosed `[`",
     },
     {
         query: ']',
         elems: [],
         foundElems: 0,
-        original: "]",
-        returned: [],
         userQuery: "]",
+        returned: [],
         error: "Unexpected `]`",
     },
     {
         query: '[a<b>',
         elems: [],
         foundElems: 0,
-        original: "[a<b>",
-        returned: [],
         userQuery: "[a<b>",
+        returned: [],
         error: "Unclosed `[`",
     },
     {
         query: 'a<b>]',
         elems: [],
         foundElems: 0,
-        original: "a<b>]",
-        returned: [],
         userQuery: "a<b>]",
+        returned: [],
         error: "Unexpected `]` after `>`",
     },
     {
@@ -306,18 +290,16 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "primitive:[u8]",
-        returned: [],
         userQuery: "primitive:[u8]",
+        returned: [],
         error: null,
     },
     {
         query: 'macro:[u8]',
         elems: [],
         foundElems: 0,
-        original: "macro:[u8]",
-        returned: [],
         userQuery: "macro:[u8]",
+        returned: [],
         error: "Invalid search type: primitive `[]` and `macro` both specified",
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-tuple.js b/tests/rustdoc-js-std/parser-tuple.js
index eb16289d3c0..61925068387 100644
--- a/tests/rustdoc-js-std/parser-tuple.js
+++ b/tests/rustdoc-js-std/parser-tuple.js
@@ -3,9 +3,8 @@ const PARSED = [
         query: '(((D, ()))',
         elems: [],
         foundElems: 0,
-        original: '(((D, ()))',
+        userQuery: '(((D, ()))',
         returned: [],
-        userQuery: '(((d, ()))',
         error: 'Unclosed `(`',
     },
     {
@@ -18,7 +17,7 @@ const PARSED = [
                 pathLast: "()",
                 generics: [
                     {
-                        name: "d",
+                        name: "D",
                         fullPath: ["d"],
                         pathWithoutLast: [],
                         pathLast: "d",
@@ -38,9 +37,8 @@ const PARSED = [
             }
         ],
         foundElems: 1,
-        original: '(((D, ())))',
+        userQuery: '(((D, ())))',
         returned: [],
-        userQuery: '(((d, ())))',
         error: null,
     },
     {
@@ -64,9 +62,8 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "(),u8",
-        returned: [],
         userQuery: "(),u8",
+        returned: [],
         error: null,
     },
     // Parens act as grouping operators when:
@@ -88,9 +85,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "(u8)",
-        returned: [],
         userQuery: "(u8)",
+        returned: [],
         error: null,
     },
     {
@@ -115,9 +111,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "(u8,)",
-        returned: [],
         userQuery: "(u8,)",
+        returned: [],
         error: null,
     },
     {
@@ -142,9 +137,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "(,u8)",
-        returned: [],
         userQuery: "(,u8)",
+        returned: [],
         error: null,
     },
     {
@@ -169,9 +163,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "primitive:(u8)",
-        returned: [],
         userQuery: "primitive:(u8)",
+        returned: [],
         error: null,
     },
     {
@@ -187,9 +180,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "(primitive:u8)",
-        returned: [],
         userQuery: "(primitive:u8)",
+        returned: [],
         error: null,
     },
     {
@@ -222,9 +214,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "(u8,u8)",
-        returned: [],
         userQuery: "(u8,u8)",
+        returned: [],
         error: null,
     },
     {
@@ -249,9 +240,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "(u8<u8>)",
-        returned: [],
         userQuery: "(u8<u8>)",
+        returned: [],
         error: null,
     },
     {
@@ -267,99 +257,88 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "()",
-        returned: [],
         userQuery: "()",
+        returned: [],
         error: null,
     },
     {
         query: '(>',
         elems: [],
         foundElems: 0,
-        original: "(>",
-        returned: [],
         userQuery: "(>",
+        returned: [],
         error: "Unexpected `>` after `(`",
     },
     {
         query: '(<',
         elems: [],
         foundElems: 0,
-        original: "(<",
-        returned: [],
         userQuery: "(<",
+        returned: [],
         error: "Found generics without a path",
     },
     {
         query: '(a>',
         elems: [],
         foundElems: 0,
-        original: "(a>",
-        returned: [],
         userQuery: "(a>",
+        returned: [],
         error: "Unexpected `>` after `(`",
     },
     {
         query: '(a<',
         elems: [],
         foundElems: 0,
-        original: "(a<",
-        returned: [],
         userQuery: "(a<",
+        returned: [],
         error: "Unclosed `<`",
     },
     {
         query: '(a',
         elems: [],
         foundElems: 0,
-        original: "(a",
-        returned: [],
         userQuery: "(a",
+        returned: [],
         error: "Unclosed `(`",
     },
     {
         query: '(',
         elems: [],
         foundElems: 0,
-        original: "(",
-        returned: [],
         userQuery: "(",
+        returned: [],
         error: "Unclosed `(`",
     },
     {
         query: ')',
         elems: [],
         foundElems: 0,
-        original: ")",
-        returned: [],
         userQuery: ")",
+        returned: [],
         error: "Unexpected `)`",
     },
     {
         query: '(a<b>',
         elems: [],
         foundElems: 0,
-        original: "(a<b>",
-        returned: [],
         userQuery: "(a<b>",
+        returned: [],
         error: "Unclosed `(`",
     },
     {
         query: 'a<b>)',
         elems: [],
         foundElems: 0,
-        original: "a<b>)",
-        returned: [],
         userQuery: "a<b>)",
+        returned: [],
         error: "Unexpected `)` after `>`",
     },
     {
         query: 'macro:(u8)',
         elems: [],
         foundElems: 0,
-        original: "macro:(u8)",
-        returned: [],
         userQuery: "macro:(u8)",
+        returned: [],
         error: "Invalid search type: primitive `()` and `macro` both specified",
     },
 ];
diff --git a/tests/rustdoc-js-std/parser-weird-queries.js b/tests/rustdoc-js-std/parser-weird-queries.js
index 499b82a3469..828b0a7d9f6 100644
--- a/tests/rustdoc-js-std/parser-weird-queries.js
+++ b/tests/rustdoc-js-std/parser-weird-queries.js
@@ -15,9 +15,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "a b",
-        returned: [],
         userQuery: "a b",
+        returned: [],
         error: null,
     },
     {
@@ -32,9 +31,8 @@ const PARSED = [
             },
         ],
         foundElems: 1,
-        original: "a   b",
-        returned: [],
         userQuery: "a   b",
+        returned: [],
         error: null,
     },
     {
@@ -56,36 +54,32 @@ const PARSED = [
             },
         ],
         foundElems: 2,
-        original: "aaa,a",
-        returned: [],
         userQuery: "aaa,a",
+        returned: [],
         error: null,
     },
     {
         query: ',,,,',
         elems: [],
         foundElems: 0,
-        original: ",,,,",
-        returned: [],
         userQuery: ",,,,",
+        returned: [],
         error: null,
     },
     {
         query: 'mod    :',
         elems: [],
         foundElems: 0,
-        original: 'mod    :',
-        returned: [],
         userQuery: 'mod    :',
+        returned: [],
         error: "Unexpected `:` (expected path after type filter `mod:`)",
     },
     {
         query: 'mod\t:',
         elems: [],
         foundElems: 0,
-        original: 'mod :',
-        returned: [],
         userQuery: 'mod :',
+        returned: [],
         error: "Unexpected `:` (expected path after type filter `mod:`)",
     },
 ];
diff --git a/tests/rustdoc-js-std/path-maxeditdistance.js b/tests/rustdoc-js-std/path-maxeditdistance.js
index 632df658f75..af71713f055 100644
--- a/tests/rustdoc-js-std/path-maxeditdistance.js
+++ b/tests/rustdoc-js-std/path-maxeditdistance.js
@@ -3,16 +3,8 @@ const FILTER_CRATE = "std";
 const EXPECTED = [
     {
         query: 'vec::intoiterator',
-        others: [
-            // trait std::iter::IntoIterator is not the first result
-            { 'path': 'std::vec', 'name': 'IntoIter' },
-            { 'path': 'std::vec::Vec', 'name': 'into_iter' },
-            { 'path': 'std::vec::Drain', 'name': 'into_iter' },
-            { 'path': 'std::vec::IntoIter', 'name': 'into_iter' },
-            { 'path': 'std::vec::ExtractIf', 'name': 'into_iter' },
-            { 'path': 'std::vec::Splice', 'name': 'into_iter' },
-            { 'path': 'std::collections::vec_deque::VecDeque', 'name': 'into_iter' },
-        ],
+        // trait std::iter::IntoIterator is not the first result
+        others: [],
     },
     {
         query: 'vec::iter',
diff --git a/tests/rustdoc-js-std/simd-type-signatures.js b/tests/rustdoc-js-std/simd-type-signatures.js
index c07f15dcbe8..4fc14e65ac4 100644
--- a/tests/rustdoc-js-std/simd-type-signatures.js
+++ b/tests/rustdoc-js-std/simd-type-signatures.js
@@ -22,11 +22,6 @@ const EXPECTED = [
             },
             {
                 'path': 'std::simd::prelude::Simd',
-                'name': 'simd_clamp',
-                'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_clamp'
-            },
-            {
-                'path': 'std::simd::prelude::Simd',
                 'name': 'saturating_add',
                 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_add'
             },
@@ -35,6 +30,11 @@ const EXPECTED = [
                 'name': 'saturating_sub',
                 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_sub'
             },
+            {
+                'path': 'std::simd::prelude::Simd',
+                'name': 'simd_clamp',
+                'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_clamp'
+            },
         ],
     },
     {
@@ -52,11 +52,6 @@ const EXPECTED = [
             },
             {
                 'path': 'std::simd::prelude::Simd',
-                'name': 'simd_clamp',
-                'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_clamp'
-            },
-            {
-                'path': 'std::simd::prelude::Simd',
                 'name': 'saturating_add',
                 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_add'
             },
@@ -65,6 +60,11 @@ const EXPECTED = [
                 'name': 'saturating_sub',
                 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_sub'
             },
+            {
+                'path': 'std::simd::prelude::Simd',
+                'name': 'simd_clamp',
+                'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_clamp'
+            },
         ],
     },
 ];
diff --git a/tests/rustdoc-js-std/transmute-fail.js b/tests/rustdoc-js-std/transmute-fail.js
new file mode 100644
index 00000000000..c4dddf3cf3c
--- /dev/null
+++ b/tests/rustdoc-js-std/transmute-fail.js
@@ -0,0 +1,13 @@
+// should-fail
+const EXPECTED = [
+    {
+        // Keep this test case identical to `transmute`, except the
+        // should-fail tag and the search query below:
+        'query': 'generic:T -> generic:T',
+        'others': [
+            { 'path': 'std::intrinsics::simd', 'name': 'simd_as' },
+            { 'path': 'std::intrinsics::simd', 'name': 'simd_cast' },
+            { 'path': 'std::intrinsics', 'name': 'transmute' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js-std/transmute.js b/tests/rustdoc-js-std/transmute.js
new file mode 100644
index 00000000000..0e52e21e0de
--- /dev/null
+++ b/tests/rustdoc-js-std/transmute.js
@@ -0,0 +1,12 @@
+const EXPECTED = [
+    {
+        // Keep this test case identical to `transmute-fail`, except the
+        // should-fail tag and the search query below:
+        'query': 'generic:T -> generic:U',
+        'others': [
+            { 'path': 'std::intrinsics::simd', 'name': 'simd_as' },
+            { 'path': 'std::intrinsics::simd', 'name': 'simd_cast' },
+            { 'path': 'std::intrinsics', 'name': 'transmute' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js-std/vec-type-signatures.js b/tests/rustdoc-js-std/vec-type-signatures.js
index 18cf9d6efd0..3c2ff30a833 100644
--- a/tests/rustdoc-js-std/vec-type-signatures.js
+++ b/tests/rustdoc-js-std/vec-type-signatures.js
@@ -19,4 +19,16 @@ const EXPECTED = [
             { 'path': 'std::vec::IntoIter', 'name': 'next_chunk' },
         ],
     },
+    {
+        'query': 'vec<T, Allocator> -> Box<[T]>',
+        'others': [
+            {
+                'path': 'std::boxed::Box',
+                'name': 'from',
+                'displayType': '`Vec`<`T`, `A`> -> `Box`<`[T]`, A>',
+                'displayMappedNames': `T = T`,
+                'displayWhereClause': 'A: `Allocator`',
+            },
+        ],
+    },
 ];
diff --git a/tests/rustdoc-js-std/write.js b/tests/rustdoc-js-std/write.js
new file mode 100644
index 00000000000..4a9475102a5
--- /dev/null
+++ b/tests/rustdoc-js-std/write.js
@@ -0,0 +1,24 @@
+const EXPECTED = [
+    {
+        'query': 'write',
+        'others': [
+            { 'path': 'std::fmt', 'name': 'write' },
+            { 'path': 'std::fs', 'name': 'write' },
+            { 'path': 'std::ptr', 'name': 'write' },
+            { 'path': 'std::fmt', 'name': 'Write' },
+            { 'path': 'std::io', 'name': 'Write' },
+            { 'path': 'std::hash::Hasher', 'name': 'write' },
+        ],
+    },
+    {
+        'query': 'Write',
+        'others': [
+            { 'path': 'std::fmt', 'name': 'Write' },
+            { 'path': 'std::io', 'name': 'Write' },
+            { 'path': 'std::fmt', 'name': 'write' },
+            { 'path': 'std::fs', 'name': 'write' },
+            { 'path': 'std::ptr', 'name': 'write' },
+            { 'path': 'std::hash::Hasher', 'name': 'write' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/assoc-type-backtrack.js b/tests/rustdoc-js/assoc-type-backtrack.js
index 493e1a9910d..ccf5c063c8c 100644
--- a/tests/rustdoc-js/assoc-type-backtrack.js
+++ b/tests/rustdoc-js/assoc-type-backtrack.js
@@ -6,7 +6,6 @@ const EXPECTED = [
         'correction': null,
         'others': [
             { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
-            { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
         ],
     },
     {
@@ -14,6 +13,19 @@ const EXPECTED = [
         'correction': null,
         'others': [
             { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
+        ],
+    },
+    {
+        'query': 'cloned<mytrait>, mytrait2 -> T',
+        'correction': null,
+        'others': [
+            { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
+        ],
+    },
+    {
+        'query': 'cloned<mytrait<U>>, mytrait2 -> T',
+        'correction': null,
+        'others': [
             { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
         ],
     },
@@ -22,7 +34,6 @@ const EXPECTED = [
         'correction': null,
         'others': [
             { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
-            { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
         ],
     },
     {
@@ -50,14 +61,14 @@ const EXPECTED = [
         ],
     },
     {
-        'query': 'mytrait<U> -> Option<T>',
+        'query': 'cloned<mytrait<U>> -> Option<T>',
         'correction': null,
         'others': [
             { 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
         ],
     },
     {
-        'query': 'mytrait<Item=U> -> Option<T>',
+        'query': 'cloned<mytrait<Item=U>> -> Option<T>',
         'correction': null,
         'others': [
             { 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
@@ -89,19 +100,21 @@ const EXPECTED = [
         ],
     },
     {
-        'query': 'myintofuture<myfuture<t>> -> myfuture<t>',
+        'query': 'myintofuture<t, myfuture<t>> -> myfuture<t>',
         'correction': null,
         'others': [
             { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' },
             { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
         ],
     },
-    // Invalid unboxing of the one-argument case.
-    // If you unbox one of the myfutures, you need to unbox both of them.
+    // Unboxings of the one-argument case.
     {
         'query': 'myintofuture<fut=t> -> myfuture<t>',
         'correction': null,
-        'others': [],
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' },
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
     },
     // Unboxings of the two-argument case.
     {
@@ -119,7 +132,7 @@ const EXPECTED = [
         ],
     },
     {
-        'query': 'myintofuture<myfuture>, myintofuture<myfuture> -> myfuture',
+        'query': 'myintofuture<t, myfuture>, myintofuture<t, myfuture> -> myfuture',
         'correction': null,
         'others': [
             { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
@@ -132,24 +145,29 @@ const EXPECTED = [
             { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
         ],
     },
-    // Invalid unboxings of the two-argument case.
-    // If you unbox one of the myfutures, you need to unbox all of them.
+    // If you unbox one of the myfutures, you don't need to unbox all of them.
     {
         'query': 'myintofuture<fut=t>, myintofuture<fut=myfuture<t>> -> myfuture<t>',
         'correction': null,
-        'others': [],
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
     },
     {
         'query': 'myintofuture<fut=myfuture<t>>, myintofuture<fut=t> -> myfuture<t>',
         'correction': null,
-        'others': [],
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
     },
     {
         'query': 'myintofuture<fut=myfuture<t>>, myintofuture<fut=myfuture<t>> -> t',
         'correction': null,
-        'others': [],
+        'others': [
+            { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
+        ],
     },
-    // different generics don't match up either
+    // different generics must match up
     {
         'query': 'myintofuture<fut=myfuture<u>>, myintofuture<fut=myfuture<t>> -> myfuture<t>',
         'correction': null,
diff --git a/tests/rustdoc-js/assoc-type-backtrack.rs b/tests/rustdoc-js/assoc-type-backtrack.rs
index 2dfede9dc38..8a74685b30b 100644
--- a/tests/rustdoc-js/assoc-type-backtrack.rs
+++ b/tests/rustdoc-js/assoc-type-backtrack.rs
@@ -1,3 +1,5 @@
+#![feature(rustdoc_internals)]
+
 pub trait MyTrait2<X> {
     type Output;
 }
@@ -31,10 +33,12 @@ where
     }
 }
 
+#[doc(search_unbox)]
 pub trait MyFuture {
     type Output;
 }
 
+#[doc(search_unbox)]
 pub trait MyIntoFuture {
     type Output;
     type Fut: MyFuture<Output = Self::Output>;
diff --git a/tests/rustdoc-js/assoc-type-unbound.js b/tests/rustdoc-js/assoc-type-unbound.js
new file mode 100644
index 00000000000..9fd14f9d9fb
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type-unbound.js
@@ -0,0 +1,39 @@
+// exact-check
+
+const EXPECTED = [
+    // Trait-associated types (that is, associated types with no constraints)
+    // are treated like type parameters, so that you can "pattern match"
+    // them. We should avoid redundant output (no `Item=MyIter::Item` stuff)
+    // and should give reasonable results
+    {
+        'query': 'MyIter<T> -> Option<T>',
+        'correction': null,
+        'others': [
+            {
+                'path': 'assoc_type_unbound::MyIter',
+                'name': 'next',
+                'displayType': '&mut `MyIter` -> `Option`<`MyIter::Item`>',
+                'displayMappedNames': 'T = MyIter::Item',
+                'displayWhereClause': '',
+            },
+        ],
+    },
+    {
+        'query': 'MyIter<Item=T> -> Option<T>',
+        'correction': null,
+        'others': [
+            {
+                'path': 'assoc_type_unbound::MyIter',
+                'name': 'next',
+                'displayType': '&mut `MyIter` -> `Option`<`MyIter::Item`>',
+                'displayMappedNames': 'T = MyIter::Item',
+                'displayWhereClause': '',
+            },
+        ],
+    },
+    {
+        'query': 'MyIter<T> -> Option<Item=T>',
+        'correction': null,
+        'others': [],
+    },
+];
diff --git a/tests/rustdoc-js/assoc-type-unbound.rs b/tests/rustdoc-js/assoc-type-unbound.rs
new file mode 100644
index 00000000000..713b77b5007
--- /dev/null
+++ b/tests/rustdoc-js/assoc-type-unbound.rs
@@ -0,0 +1,4 @@
+pub trait MyIter {
+    type Item;
+    fn next(&mut self) -> Option<Self::Item>;
+}
diff --git a/tests/rustdoc-js/assoc-type.js b/tests/rustdoc-js/assoc-type.js
index eec4e7a8258..0edf10e794e 100644
--- a/tests/rustdoc-js/assoc-type.js
+++ b/tests/rustdoc-js/assoc-type.js
@@ -7,16 +7,40 @@ const EXPECTED = [
         'query': 'iterator<something> -> u32',
         'correction': null,
         'others': [
-            { 'path': 'assoc_type::my', 'name': 'other_fn' },
-            { 'path': 'assoc_type', 'name': 'my_fn' },
+            {
+                'path': 'assoc_type::my',
+                'name': 'other_fn',
+                'displayType': 'X -> `u32`',
+                'displayMappedNames': '',
+                'displayWhereClause': 'X: `Iterator`<`Something`>',
+            },
+            {
+                'path': 'assoc_type',
+                'name': 'my_fn',
+                'displayType': 'X -> `u32`',
+                'displayMappedNames': '',
+                'displayWhereClause': 'X: `Iterator`<Item=`Something`>',
+            },
         ],
     },
     {
         'query': 'iterator<something>',
         'correction': null,
         'in_args': [
-            { 'path': 'assoc_type::my', 'name': 'other_fn' },
-            { 'path': 'assoc_type', 'name': 'my_fn' },
+            {
+                'path': 'assoc_type::my',
+                'name': 'other_fn',
+                'displayType': 'X -> u32',
+                'displayMappedNames': '',
+                'displayWhereClause': 'X: `Iterator`<`Something`>',
+            },
+            {
+                'path': 'assoc_type',
+                'name': 'my_fn',
+                'displayType': 'X -> u32',
+                'displayMappedNames': '',
+                'displayWhereClause': 'X: `Iterator`<Item=`Something`>',
+            },
         ],
     },
     {
@@ -26,8 +50,20 @@ const EXPECTED = [
             { 'path': 'assoc_type', 'name': 'Something' },
         ],
         'in_args': [
-            { 'path': 'assoc_type::my', 'name': 'other_fn' },
-            { 'path': 'assoc_type', 'name': 'my_fn' },
+            {
+                'path': 'assoc_type::my',
+                'name': 'other_fn',
+                'displayType': '`X` -> u32',
+                'displayMappedNames': '',
+                'displayWhereClause': 'X: Iterator<`Something`>',
+            },
+            {
+                'path': 'assoc_type',
+                'name': 'my_fn',
+                'displayType': '`X` -> u32',
+                'displayMappedNames': '',
+                'displayWhereClause': 'X: Iterator<Item=`Something`>',
+            },
         ],
     },
     // if I write an explicit binding, only it shows up
diff --git a/tests/rustdoc-js/assoc-type.rs b/tests/rustdoc-js/assoc-type.rs
index e12e73cb546..aee8f4b1c3f 100644
--- a/tests/rustdoc-js/assoc-type.rs
+++ b/tests/rustdoc-js/assoc-type.rs
@@ -1,12 +1,22 @@
-pub fn my_fn<X: Iterator<Item = Something>>(_x: X) -> u32 {
+#![feature(rustdoc_internals)]
+
+pub fn my_fn<X: other::Iterator<Item = Something>>(_x: X) -> u32 {
     3
 }
 
 pub struct Something;
 
 pub mod my {
+    #[doc(search_unbox)]
     pub trait Iterator<T> {}
     pub fn other_fn<X: Iterator<crate::Something>>(_: X) -> u32 {
         3
     }
 }
+
+pub mod other {
+    #[doc(search_unbox)]
+    pub trait Iterator {
+        type Item;
+    }
+}
diff --git a/tests/rustdoc-js/case.js b/tests/rustdoc-js/case.js
new file mode 100644
index 00000000000..22b970eb139
--- /dev/null
+++ b/tests/rustdoc-js/case.js
@@ -0,0 +1,17 @@
+const EXPECTED = [
+    {
+        'query': 'Foo',
+        'others': [
+            { 'path': 'case', 'name': 'Foo', 'desc': 'Docs for Foo' },
+            { 'path': 'case', 'name': 'foo', 'desc': 'Docs for foo' },
+        ],
+    },
+    {
+        'query': 'foo',
+        'others': [
+            // https://github.com/rust-lang/rust/issues/133017
+            { 'path': 'case', 'name': 'Foo', 'desc': 'Docs for Foo' },
+            { 'path': 'case', 'name': 'foo', 'desc': 'Docs for foo' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/case.rs b/tests/rustdoc-js/case.rs
new file mode 100644
index 00000000000..532edd55f1d
--- /dev/null
+++ b/tests/rustdoc-js/case.rs
@@ -0,0 +1,7 @@
+#![allow(nonstandard_style)]
+
+/// Docs for Foo
+pub struct Foo;
+
+/// Docs for foo
+pub struct foo;
diff --git a/tests/rustdoc-js/generics-impl.js b/tests/rustdoc-js/generics-impl.js
index 5e33e224876..c104730dcbd 100644
--- a/tests/rustdoc-js/generics-impl.js
+++ b/tests/rustdoc-js/generics-impl.js
@@ -14,7 +14,7 @@ const EXPECTED = [
         ],
     },
     {
-        'query': 'Aaaaaaa -> usize',
+        'query': 'Aaaaaaa -> Result<usize>',
         'others': [
             { 'path': 'generics_impl::Aaaaaaa', 'name': 'read' },
         ],
@@ -23,6 +23,11 @@ const EXPECTED = [
         'query': 'Read -> u64',
         'others': [
             { 'path': 'generics_impl::Ddddddd', 'name': 'eeeeeee' },
+        ],
+    },
+    {
+        'query': 'Ddddddd<Read> -> u64',
+        'others': [
             { 'path': 'generics_impl::Ddddddd', 'name': 'ggggggg' },
         ],
     },
@@ -30,7 +35,6 @@ const EXPECTED = [
         'query': 'trait:Read -> u64',
         'others': [
             { 'path': 'generics_impl::Ddddddd', 'name': 'eeeeeee' },
-            { 'path': 'generics_impl::Ddddddd', 'name': 'ggggggg' },
         ],
     },
     {
diff --git a/tests/rustdoc-js/generics-impl.rs b/tests/rustdoc-js/generics-impl.rs
index 27d44fdd7e9..f9fe7f390f3 100644
--- a/tests/rustdoc-js/generics-impl.rs
+++ b/tests/rustdoc-js/generics-impl.rs
@@ -1,4 +1,4 @@
-use std::io::{Read, Result as IoResult};
+use std::io::{self, Read};
 
 pub struct Aaaaaaa;
 
@@ -12,7 +12,7 @@ impl Aaaaaaa {
 }
 
 impl Read for Aaaaaaa {
-    fn read(&mut self, out: &mut [u8]) -> IoResult<usize> {
+    fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
         Ok(out.len())
     }
 }
diff --git a/tests/rustdoc-js/generics-match-ambiguity-no-unbox.js b/tests/rustdoc-js/generics-match-ambiguity-no-unbox.js
new file mode 100644
index 00000000000..ea4c26d311c
--- /dev/null
+++ b/tests/rustdoc-js/generics-match-ambiguity-no-unbox.js
@@ -0,0 +1,68 @@
+// ignore-order
+// exact-check
+
+// Make sure that results are order-agnostic, even when there's search items that only differ
+// by generics.
+
+const EXPECTED = [
+    {
+        'query': 'Wrap',
+        'in_args': [
+            { 'path': 'generics_match_ambiguity', 'name': 'bar' },
+            { 'path': 'generics_match_ambiguity', 'name': 'foo' },
+        ],
+    },
+    {
+        'query': 'Wrap<i32>',
+        'in_args': [
+            { 'path': 'generics_match_ambiguity', 'name': 'bar' },
+            { 'path': 'generics_match_ambiguity', 'name': 'foo' },
+        ],
+    },
+    {
+        'query': 'Wrap<i32>, Wrap<i32, u32>',
+        'others': [
+            { 'path': 'generics_match_ambiguity', 'name': 'bar' },
+            { 'path': 'generics_match_ambiguity', 'name': 'foo' },
+        ],
+    },
+    {
+        'query': 'Wrap<i32, u32>, Wrap<i32>',
+        'others': [
+            { 'path': 'generics_match_ambiguity', 'name': 'bar' },
+            { 'path': 'generics_match_ambiguity', 'name': 'foo' },
+        ],
+    },
+    {
+        'query': 'W3<i32>, W3<i32, u32>',
+        'others': [
+            { 'path': 'generics_match_ambiguity', 'name': 'baaa' },
+            { 'path': 'generics_match_ambiguity', 'name': 'baab' },
+        ],
+    },
+    {
+        'query': 'W3<i32, u32>, W3<i32>',
+        'others': [
+            { 'path': 'generics_match_ambiguity', 'name': 'baaa' },
+            { 'path': 'generics_match_ambiguity', 'name': 'baab' },
+        ],
+    },
+    {
+        // strict generics matching; W2<i32, u32> doesn't match W2<W3<i32, u32>>,
+        // even though W2<i32> works just fine (ignoring the W3)
+        'query': 'W2<i32>, W2<i32, u32>',
+        'others': [],
+    },
+    {
+        'query': 'W2<i32, u32>, W2<i32>',
+        'others': [],
+    },
+    {
+        'query': 'W2<i32>, W3<i32, u32>',
+        'others': [],
+    },
+    {
+        'query': 'W2<i32>, W2<i32>',
+        'others': [],
+    },
+];
diff --git a/tests/rustdoc-js/generics-match-ambiguity-no-unbox.rs b/tests/rustdoc-js/generics-match-ambiguity-no-unbox.rs
new file mode 100644
index 00000000000..43c2896fa2c
--- /dev/null
+++ b/tests/rustdoc-js/generics-match-ambiguity-no-unbox.rs
@@ -0,0 +1,18 @@
+#![crate_name = "generics_match_ambiguity"]
+
+pub struct Wrap<T, U = ()>(pub T, pub U);
+
+pub fn foo(a: Wrap<i32>, b: Wrap<i32, u32>) {}
+pub fn bar(a: Wrap<i32, u32>, b: Wrap<i32>) {}
+
+pub struct W2<T>(pub T);
+pub struct W3<T, U = ()>(pub T, pub U);
+
+pub fn baaa(a: W3<i32>, b: W3<i32, u32>) {}
+pub fn baab(a: W3<i32, u32>, b: W3<i32>) {}
+pub fn baac(a: W2<W3<i32>>, b: W3<i32, u32>) {}
+pub fn baad(a: W2<W3<i32, u32>>, b: W3<i32>) {}
+pub fn baae(a: W3<i32>, b: W2<W3<i32, u32>>) {}
+pub fn baaf(a: W3<i32, u32>, b: W2<W3<i32>>) {}
+pub fn baag(a: W2<W3<i32>>, b: W2<W3<i32, u32>>) {}
+pub fn baah(a: W2<W3<i32, u32>>, b: W2<W3<i32>>) {}
diff --git a/tests/rustdoc-js/generics-match-ambiguity.js b/tests/rustdoc-js/generics-match-ambiguity.js
index edce4268c5a..aadb179321c 100644
--- a/tests/rustdoc-js/generics-match-ambiguity.js
+++ b/tests/rustdoc-js/generics-match-ambiguity.js
@@ -60,18 +60,14 @@ const EXPECTED = [
         ],
     },
     {
+        // strict generics matching; W2<i32, u32> doesn't match W2<W3<i32, u32>>,
+        // even though W2<i32> works just fine (ignoring the W3)
         'query': 'W2<i32>, W2<i32, u32>',
-        'others': [
-            { 'path': 'generics_match_ambiguity', 'name': 'baag' },
-            { 'path': 'generics_match_ambiguity', 'name': 'baah' },
-        ],
+        'others': [],
     },
     {
         'query': 'W2<i32, u32>, W2<i32>',
-        'others': [
-            { 'path': 'generics_match_ambiguity', 'name': 'baag' },
-            { 'path': 'generics_match_ambiguity', 'name': 'baah' },
-        ],
+        'others': [],
     },
     {
         'query': 'W2<i32>, W3<i32, u32>',
diff --git a/tests/rustdoc-js/generics-match-ambiguity.rs b/tests/rustdoc-js/generics-match-ambiguity.rs
index 79c493856eb..7aadbbd609c 100644
--- a/tests/rustdoc-js/generics-match-ambiguity.rs
+++ b/tests/rustdoc-js/generics-match-ambiguity.rs
@@ -1,9 +1,14 @@
+#![feature(rustdoc_internals)]
+
+#[doc(search_unbox)]
 pub struct Wrap<T, U = ()>(pub T, pub U);
 
 pub fn foo(a: Wrap<i32>, b: Wrap<i32, u32>) {}
 pub fn bar(a: Wrap<i32, u32>, b: Wrap<i32>) {}
 
+#[doc(search_unbox)]
 pub struct W2<T>(pub T);
+#[doc(search_unbox)]
 pub struct W3<T, U = ()>(pub T, pub U);
 
 pub fn baaa(a: W3<i32>, b: W3<i32, u32>) {}
@@ -14,4 +19,3 @@ pub fn baae(a: W3<i32>, b: W2<W3<i32, u32>>) {}
 pub fn baaf(a: W3<i32, u32>, b: W2<W3<i32>>) {}
 pub fn baag(a: W2<W3<i32>>, b: W2<W3<i32, u32>>) {}
 pub fn baah(a: W2<W3<i32, u32>>, b: W2<W3<i32>>) {}
-//
diff --git a/tests/rustdoc-js/generics-nested.js b/tests/rustdoc-js/generics-nested.js
index 294c1949074..b3184dde0d0 100644
--- a/tests/rustdoc-js/generics-nested.js
+++ b/tests/rustdoc-js/generics-nested.js
@@ -18,9 +18,8 @@ const EXPECTED = [
         ],
     },
     {
+        // can't put generics out of order
         'query': '-> Out<Second, First>',
-        'others': [
-            { 'path': 'generics_nested', 'name': 'bet' },
-        ],
+        'others': [],
     },
 ];
diff --git a/tests/rustdoc-js/generics-trait.js b/tests/rustdoc-js/generics-trait.js
index a71393b5e05..8da9c67050e 100644
--- a/tests/rustdoc-js/generics-trait.js
+++ b/tests/rustdoc-js/generics-trait.js
@@ -5,10 +5,22 @@ const EXPECTED = [
         'query': 'Result<SomeTrait>',
         'correction': null,
         'in_args': [
-            { 'path': 'generics_trait', 'name': 'beta' },
+            {
+                'path': 'generics_trait',
+                'name': 'beta',
+                'displayType': '`Result`<`T`, ()> -> ()',
+                'displayMappedNames': '',
+                'displayWhereClause': 'T: `SomeTrait`',
+            },
         ],
         'returned': [
-            { 'path': 'generics_trait', 'name': 'bet' },
+            {
+                'path': 'generics_trait',
+                'name': 'bet',
+                'displayType': ' -> `Result`<`T`, ()>',
+                'displayMappedNames': '',
+                'displayWhereClause': 'T: `SomeTrait`',
+            },
         ],
     },
     {
@@ -25,20 +37,44 @@ const EXPECTED = [
         'query': 'OtherThingxxxxxxxx',
         'correction': null,
         'in_args': [
-            { 'path': 'generics_trait', 'name': 'alpha' },
+            {
+                'path': 'generics_trait',
+                'name': 'alpha',
+                'displayType': 'Result<`T`, ()> -> ()',
+                'displayMappedNames': '',
+                'displayWhereClause': 'T: `OtherThingxxxxxxxx`',
+            },
         ],
         'returned': [
-            { 'path': 'generics_trait', 'name': 'alef' },
+            {
+                'path': 'generics_trait',
+                'name': 'alef',
+                'displayType': ' -> Result<`T`, ()>',
+                'displayMappedNames': '',
+                'displayWhereClause': 'T: `OtherThingxxxxxxxx`',
+            },
         ],
     },
     {
         'query': 'OtherThingxxxxxxxy',
         'correction': 'OtherThingxxxxxxxx',
         'in_args': [
-            { 'path': 'generics_trait', 'name': 'alpha' },
+            {
+                'path': 'generics_trait',
+                'name': 'alpha',
+                'displayType': 'Result<`T`, ()> -> ()',
+                'displayMappedNames': '',
+                'displayWhereClause': 'T: `OtherThingxxxxxxxx`',
+            },
         ],
         'returned': [
-            { 'path': 'generics_trait', 'name': 'alef' },
+            {
+                'path': 'generics_trait',
+                'name': 'alef',
+                'displayType': ' -> Result<`T`, ()>',
+                'displayMappedNames': '',
+                'displayWhereClause': 'T: `OtherThingxxxxxxxx`',
+            },
         ],
     },
 ];
diff --git a/tests/rustdoc-js/generics-unbox.js b/tests/rustdoc-js/generics-unbox.js
index 9cdfc7ac8b6..6baf00c814b 100644
--- a/tests/rustdoc-js/generics-unbox.js
+++ b/tests/rustdoc-js/generics-unbox.js
@@ -11,20 +11,17 @@ const EXPECTED = [
         'query': 'Inside<T> -> Out3<T>',
         'others': [
             { 'path': 'generics_unbox', 'name': 'beta' },
-            { 'path': 'generics_unbox', 'name': 'gamma' },
         ],
     },
     {
         'query': 'Inside<T> -> Out4<T>',
         'others': [
-            { 'path': 'generics_unbox', 'name': 'beta' },
             { 'path': 'generics_unbox', 'name': 'gamma' },
         ],
     },
     {
         'query': 'Inside<T> -> Out3<U, T>',
         'others': [
-            { 'path': 'generics_unbox', 'name': 'beta' },
             { 'path': 'generics_unbox', 'name': 'gamma' },
         ],
     },
@@ -32,7 +29,6 @@ const EXPECTED = [
         'query': 'Inside<T> -> Out4<U, T>',
         'others': [
             { 'path': 'generics_unbox', 'name': 'beta' },
-            { 'path': 'generics_unbox', 'name': 'gamma' },
         ],
     },
 ];
diff --git a/tests/rustdoc-js/generics-unbox.rs b/tests/rustdoc-js/generics-unbox.rs
index bef34f891e9..c2578575997 100644
--- a/tests/rustdoc-js/generics-unbox.rs
+++ b/tests/rustdoc-js/generics-unbox.rs
@@ -1,26 +1,34 @@
+#![feature(rustdoc_internals)]
+
+#[doc(search_unbox)]
 pub struct Out<A, B = ()> {
     a: A,
     b: B,
 }
 
+#[doc(search_unbox)]
 pub struct Out1<A, const N: usize> {
     a: [A; N],
 }
 
+#[doc(search_unbox)]
 pub struct Out2<A, const N: usize> {
     a: [A; N],
 }
 
+#[doc(search_unbox)]
 pub struct Out3<A, B> {
     a: A,
     b: B,
 }
 
+#[doc(search_unbox)]
 pub struct Out4<A, B> {
     a: A,
     b: B,
 }
 
+#[doc(search_unbox)]
 pub struct Inside<T>(T);
 
 pub fn alpha<const N: usize, T>(_: Inside<T>) -> Out<Out1<T, N>, Out2<T, N>> {
diff --git a/tests/rustdoc-js/generics.js b/tests/rustdoc-js/generics.js
index b3ca0af3056..a6d20538efe 100644
--- a/tests/rustdoc-js/generics.js
+++ b/tests/rustdoc-js/generics.js
@@ -30,21 +30,13 @@ const EXPECTED = [
         'others': [
             { 'path': 'generics', 'name': 'P' },
         ],
-        'returned': [
-            { 'path': 'generics', 'name': 'alef' },
-        ],
-        'in_args': [
-            { 'path': 'generics', 'name': 'alpha' },
-        ],
+        'returned': [],
+        'in_args': [],
     },
     {
         'query': 'P',
-        'returned': [
-            { 'path': 'generics', 'name': 'alef' },
-        ],
-        'in_args': [
-            { 'path': 'generics', 'name': 'alpha' },
-        ],
+        'returned': [],
+        'in_args': [],
     },
     {
         'query': '"ExtraCreditStructMulti"<ExtraCreditInnerMulti, ExtraCreditInnerMulti>',
diff --git a/tests/rustdoc-js/hof.js b/tests/rustdoc-js/hof.js
index 5e6c9d83c7c..c1142f10668 100644
--- a/tests/rustdoc-js/hof.js
+++ b/tests/rustdoc-js/hof.js
@@ -9,19 +9,19 @@ const EXPECTED = [
 
     // ML-style higher-order function notation
     {
-        'query': 'bool, (u32 -> !) -> ()',
+        'query': 'bool, (first<u32> -> !) -> ()',
         'others': [
             {"path": "hof", "name": "fn_ptr"},
         ],
     },
     {
-        'query': 'u8, (u32 -> !) -> ()',
+        'query': 'u8, (second<u32> -> !) -> ()',
         'others': [
             {"path": "hof", "name": "fn_once"},
         ],
     },
     {
-        'query': 'i8, (u32 -> !) -> ()',
+        'query': 'i8, (third<u32> -> !) -> ()',
         'others': [
             {"path": "hof", "name": "fn_mut"},
         ],
@@ -54,9 +54,6 @@ const EXPECTED = [
         'query': '(u32 -> !) -> ()',
         'others': [
             {"path": "hof", "name": "fn_"},
-            {"path": "hof", "name": "fn_ptr"},
-            {"path": "hof", "name": "fn_mut"},
-            {"path": "hof", "name": "fn_once"},
         ],
     },
     {
@@ -95,30 +92,30 @@ const EXPECTED = [
 
     // Rust-style higher-order function notation
     {
-        'query': 'bool, fn(u32) -> ! -> ()',
+        'query': 'bool, fn(first<u32>) -> ! -> ()',
         'others': [
             {"path": "hof", "name": "fn_ptr"},
         ],
     },
     {
-        'query': 'u8, fnonce(u32) -> ! -> ()',
+        'query': 'u8, fnonce(second<u32>) -> ! -> ()',
         'others': [
             {"path": "hof", "name": "fn_once"},
         ],
     },
     {
-        'query': 'u8, fn(u32) -> ! -> ()',
+        'query': 'u8, fn(second<u32>) -> ! -> ()',
         // fnonce != fn
         'others': [],
     },
     {
-        'query': 'i8, fnmut(u32) -> ! -> ()',
+        'query': 'i8, fnmut(third<u32>) -> ! -> ()',
         'others': [
             {"path": "hof", "name": "fn_mut"},
         ],
     },
     {
-        'query': 'i8, fn(u32) -> ! -> ()',
+        'query': 'i8, fn(third<u32>) -> ! -> ()',
         // fnmut != fn
         'others': [],
     },
@@ -152,7 +149,7 @@ const EXPECTED = [
         ],
     },
     {
-        'query': 'fn(u32) -> ! -> ()',
+        'query': 'fn() -> ! -> ()',
         'others': [
             // fn matches primitive:fn and trait:Fn
             {"path": "hof", "name": "fn_"},
@@ -160,14 +157,14 @@ const EXPECTED = [
         ],
     },
     {
-        'query': 'trait:fn(u32) -> ! -> ()',
+        'query': 'trait:fn() -> ! -> ()',
         'others': [
             // fn matches primitive:fn and trait:Fn
             {"path": "hof", "name": "fn_"},
         ],
     },
     {
-        'query': 'primitive:fn(u32) -> ! -> ()',
+        'query': 'primitive:fn() -> ! -> ()',
         'others': [
             // fn matches primitive:fn and trait:Fn
             {"path": "hof", "name": "fn_ptr"},
diff --git a/tests/rustdoc-js/impl-trait.js b/tests/rustdoc-js/impl-trait.js
index 8bb3f2d3e99..3d7d0ca5bcd 100644
--- a/tests/rustdoc-js/impl-trait.js
+++ b/tests/rustdoc-js/impl-trait.js
@@ -23,8 +23,8 @@ const EXPECTED = [
         'others': [
             { 'path': 'impl_trait', 'name': 'bbbbbbb' },
             { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
-            { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
             { 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' },
+            { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
         ],
     },
     {
@@ -39,14 +39,14 @@ const EXPECTED = [
             { 'path': 'impl_trait', 'name': 'Aaaaaaa' },
         ],
         'in_args': [
-            { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
             { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
+            { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
         ],
         'returned': [
             { 'path': 'impl_trait', 'name': 'bbbbbbb' },
             { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
-            { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
             { 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' },
+            { 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
         ],
     },
 ];
diff --git a/tests/rustdoc-js/looks-like-rustc-interner.js b/tests/rustdoc-js/looks-like-rustc-interner.js
index a4806d23499..d6d2764c3ae 100644
--- a/tests/rustdoc-js/looks-like-rustc-interner.js
+++ b/tests/rustdoc-js/looks-like-rustc-interner.js
@@ -1,9 +1,15 @@
 // https://github.com/rust-lang/rust/pull/122247
 // exact-check
 
-const EXPECTED = {
-    'query': 'canonicalvarinfo, intoiterator -> intoiterator',
-    'others': [
-        { 'path': 'looks_like_rustc_interner::Interner', 'name': 'mk_canonical_var_infos' },
-    ],
-};
+const EXPECTED = [
+    {
+        'query': 'canonicalvarinfo, intoiterator -> intoiterator',
+        'others': [],
+    },
+    {
+        'query': '[canonicalvarinfo], interner<tys=intoiterator> -> intoiterator',
+        'others': [
+            { 'path': 'looks_like_rustc_interner::Interner', 'name': 'mk_canonical_var_infos' },
+        ],
+    },
+];
diff --git a/tests/rustdoc-js/nested-unboxed.js b/tests/rustdoc-js/nested-unboxed.js
index 44f784eb1f6..5f9eabc12f6 100644
--- a/tests/rustdoc-js/nested-unboxed.js
+++ b/tests/rustdoc-js/nested-unboxed.js
@@ -33,9 +33,8 @@ const EXPECTED = [
     },
     {
         'query': '-> Result<i32, u32, bool>',
-        'others': [
-            { 'path': 'nested_unboxed', 'name': 'something' },
-        ],
+        // can't put nested generics out of order
+        'others': [],
     },
     {
         'query': '-> Result<Object<i32>, bool>',
@@ -45,9 +44,7 @@ const EXPECTED = [
     },
     {
         'query': '-> Result<Object<u32>, bool>',
-        'others': [
-            { 'path': 'nested_unboxed', 'name': 'something' },
-        ],
+        'others': [],
     },
     {
         'query': '-> Result<Object<i32>, u32, bool>',
diff --git a/tests/rustdoc-js/nested-unboxed.rs b/tests/rustdoc-js/nested-unboxed.rs
index 57f9592b791..6c8b1bd6aa1 100644
--- a/tests/rustdoc-js/nested-unboxed.rs
+++ b/tests/rustdoc-js/nested-unboxed.rs
@@ -1,3 +1,6 @@
+#![feature(rustdoc_internals)]
+
+#[doc(search_unbox)]
 pub struct Object<T, U>(T, U);
 
 pub fn something() -> Result<Object<i32, u32>, bool> {
diff --git a/tests/rustdoc-js/non-english-identifier.js b/tests/rustdoc-js/non-english-identifier.js
index 1765a69152a..f2180b4c755 100644
--- a/tests/rustdoc-js/non-english-identifier.js
+++ b/tests/rustdoc-js/non-english-identifier.js
@@ -11,30 +11,29 @@ const PARSED = [
         }],
         returned: [],
         foundElems: 1,
-        original: "中文",
         userQuery: "中文",
         error: null,
     },
     {
         query: '_0Mixed中英文',
         elems: [{
-            name: "_0mixed中英文",
+            name: "_0Mixed中英文",
             fullPath: ["_0mixed中英文"],
             pathWithoutLast: [],
             pathLast: "_0mixed中英文",
+            normalizedPathLast: "0mixed中英文",
             generics: [],
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "_0Mixed中英文",
+        userQuery: "_0Mixed中英文",
         returned: [],
-        userQuery: "_0mixed中英文",
         error: null,
     },
     {
         query: 'my_crate::中文API',
         elems: [{
-            name: "my_crate::中文api",
+            name: "my_crate::中文API",
             fullPath: ["my_crate", "中文api"],
             pathWithoutLast: ["my_crate"],
             pathLast: "中文api",
@@ -42,26 +41,25 @@ const PARSED = [
             typeFilter: -1,
         }],
         foundElems: 1,
-        original: "my_crate::中文API",
+        userQuery: "my_crate::中文API",
         returned: [],
-        userQuery: "my_crate::中文api",
         error: null,
     },
     {
         query: '类型A,类型B<约束C>->返回类型<关联类型=路径::约束D>',
         elems: [{
-            name: "类型a",
+            name: "类型A",
             fullPath: ["类型a"],
             pathWithoutLast: [],
             pathLast: "类型a",
             generics: [],
         }, {
-            name: "类型b",
+            name: "类型B",
             fullPath: ["类型b"],
             pathWithoutLast: [],
             pathLast: "类型b",
             generics: [{
-                name: "约束c",
+                name: "约束C",
                 fullPath: ["约束c"],
                 pathWithoutLast: [],
                 pathLast: "约束c",
@@ -71,15 +69,21 @@ const PARSED = [
         foundElems: 3,
         totalElems: 5,
         literalSearch: true,
-        original: "类型A,类型B<约束C>->返回类型<关联类型=路径::约束D>",
+        userQuery: "类型A,类型B<约束C>->返回类型<关联类型=路径::约束D>",
         returned: [{
             name: "返回类型",
             fullPath: ["返回类型"],
             pathWithoutLast: [],
             pathLast: "返回类型",
             generics: [],
+            bindings: [["关联类型", [{
+                name: "路径::约束D",
+                fullPath: ["路径", "约束d"],
+                pathWithoutLast: ["路径"],
+                pathLast: "约束d",
+                generics: [],
+            }]]],
         }],
-        userQuery: "类型a,类型b<约束c>->返回类型<关联类型=路径::约束d>",
         error: null,
     },
     {
@@ -93,18 +97,16 @@ const PARSED = [
             typeFilter: 16,
         }],
         foundElems: 1,
-        original: "my_crate 中文宏!",
-        returned: [],
         userQuery: "my_crate 中文宏!",
+        returned: [],
         error: null,
     },
     {
         query: '非法符号——',
         elems: [],
         foundElems: 0,
-        original: "非法符号——",
-        returned: [],
         userQuery: "非法符号——",
+        returned: [],
         error: "Unexpected `—` after `号` (not a valid identifier)",
     }
 ]
@@ -131,22 +133,34 @@ const EXPECTED = [
                 path: "non_english_identifier",
                 href: "../non_english_identifier/trait.加法.html",
                 desc: "Add"
-            },
+            }],
+        in_args: [{
+            name: "加上",
+            path: "non_english_identifier::加法",
+            href: "../non_english_identifier/trait.加法.html#tymethod.加上",
+        }],
+        returned: [],
+    },
+    { // levensthein and substring checking only kick in at three characters
+        query: '加法宏',
+        others: [
             {
                 name: "中文名称的加法宏",
                 path: "non_english_identifier",
                 href: "../non_english_identifier/macro.中文名称的加法宏.html",
-            },
+            }],
+        in_args: [],
+        returned: [],
+    },
+    { // levensthein and substring checking only kick in at three characters
+        query: '加法A',
+        others: [
             {
                 name: "中文名称的加法API",
                 path: "non_english_identifier",
                 href: "../non_english_identifier/fn.中文名称的加法API.html",
             }],
-        in_args: [{
-            name: "加上",
-            path: "non_english_identifier::加法",
-            href: "../non_english_identifier/trait.加法.html#tymethod.加上",
-        }],
+        in_args: [],
         returned: [],
     },
     { // Extensive type-based search is still buggy, experimental & work-in-progress.
diff --git a/tests/rustdoc-js/path-maxeditdistance.js b/tests/rustdoc-js/path-maxeditdistance.js
index 73b24a6dddf..cf700193ac4 100644
--- a/tests/rustdoc-js/path-maxeditdistance.js
+++ b/tests/rustdoc-js/path-maxeditdistance.js
@@ -14,21 +14,38 @@ const EXPECTED = [
         ],
     },
     {
-        // swap br/rb; that's edit distance 2, where maxPathEditDistance = 3 (11 / 3)
+        // swap br/rb; that's edit distance 1, where maxPathEditDistance = 2
         'query': 'arbacadarba::hocuspocusprestidigitation',
         'others': [
             { 'path': 'abracadabra', 'name': 'HocusPocusPrestidigitation' },
         ],
     },
     {
-        // truncate 5 chars, where maxEditDistance = 7 (21 / 3)
-        'query': 'abracadarba::hocusprestidigitation',
+        // swap p/o o/p, that's also edit distance 1
+        'query': 'abracadabra::hocusopcusprestidigitation',
         'others': [
             { 'path': 'abracadabra', 'name': 'HocusPocusPrestidigitation' },
         ],
     },
     {
-        // truncate 9 chars, where maxEditDistance = 5 (17 / 3)
+        // swap p/o o/p and gi/ig, that's edit distance 2
+        'query': 'abracadabra::hocusopcusprestidiigtation',
+        'others': [
+            { 'path': 'abracadabra', 'name': 'HocusPocusPrestidigitation' },
+        ],
+    },
+    {
+        // swap p/o o/p, gi/ig, and ti/it, that's edit distance 3 and not shown (we stop at 2)
+        'query': 'abracadabra::hocusopcusprestidiigtaiton',
+        'others': [],
+    },
+    {
+        // truncate 5 chars, where maxEditDistance = 2
+        'query': 'abracadarba::hocusprestidigitation',
+        'others': [],
+    },
+    {
+        // truncate 9 chars, where maxEditDistance = 2
         'query': 'abracadarba::hprestidigitation',
         'others': [],
     },
diff --git a/tests/rustdoc-js/prototype.js b/tests/rustdoc-js/prototype.js
index da72fdce3db..0862acd8ffa 100644
--- a/tests/rustdoc-js/prototype.js
+++ b/tests/rustdoc-js/prototype.js
@@ -9,7 +9,9 @@ const EXPECTED = [
     },
     {
         'query': '__proto__',
-        'others': [],
+        'others': [
+            {"path": "", "name": "prototype"},
+        ],
         'returned': [],
         'in_args': [],
     },
diff --git a/tests/rustdoc-js/reference.js b/tests/rustdoc-js/reference.js
index b4a1fb15d36..378fc03475b 100644
--- a/tests/rustdoc-js/reference.js
+++ b/tests/rustdoc-js/reference.js
@@ -79,9 +79,8 @@ const EXPECTED = [
     },
     {
         'query': 'reference<ring>, reference<ring> -> ()',
-        'others': [
-            { 'path': 'reference::Ring', 'name': 'wear' },
-        ],
+        // can't leave out the `mut`, because can't reorder like that
+        'others': [],
     },
     {
         'query': 'reference<mut, ring>, reference<ring> -> ()',
@@ -102,9 +101,8 @@ const EXPECTED = [
     },
     {
         'query': 'reference<middle>, reference<middle> -> ()',
-        'others': [
-            { 'path': 'reference', 'name': 'show' },
-        ],
+        // can't leave out the mut
+        'others': [],
     },
     {
         'query': 'reference<mut, middle>, reference<mut, middle> -> ()',
@@ -203,9 +201,8 @@ const EXPECTED = [
     // middle with shorthand
     {
         'query': '&middle, &middle -> ()',
-        'others': [
-            { 'path': 'reference', 'name': 'show' },
-        ],
+        // can't leave out the mut
+        'others': [],
     },
     {
         'query': '&mut middle, &mut middle -> ()',
diff --git a/tests/rustdoc-js/tuple-unit.js b/tests/rustdoc-js/tuple-unit.js
index d24a3da328c..6a9b861cf94 100644
--- a/tests/rustdoc-js/tuple-unit.js
+++ b/tests/rustdoc-js/tuple-unit.js
@@ -57,7 +57,7 @@ const EXPECTED = [
         'in_args': [],
     },
     {
-        'query': '(Q, ())',
+        'query': '(Q, R<()>)',
         'returned': [
             { 'path': 'tuple_unit', 'name': 'nest' },
         ],
@@ -71,7 +71,7 @@ const EXPECTED = [
         'in_args': [],
     },
     {
-        'query': '(u32)',
+        'query': 'R<(u32)>',
         'returned': [
             { 'path': 'tuple_unit', 'name': 'nest' },
         ],
diff --git a/tests/rustdoc-js/type-parameters.js b/tests/rustdoc-js/type-parameters.js
index e045409e507..fa2b8d2ebfd 100644
--- a/tests/rustdoc-js/type-parameters.js
+++ b/tests/rustdoc-js/type-parameters.js
@@ -11,9 +11,9 @@ const EXPECTED = [
     {
         query: '-> generic:T',
         others: [
-            { path: 'foo', name: 'beta' },
             { path: 'foo', name: 'bet' },
             { path: 'foo', name: 'alef' },
+            { path: 'foo', name: 'beta' },
         ],
     },
     {
@@ -50,8 +50,8 @@ const EXPECTED = [
     {
         query: 'generic:T',
         in_args: [
-            { path: 'foo', name: 'beta' },
             { path: 'foo', name: 'bet' },
+            { path: 'foo', name: 'beta' },
             { path: 'foo', name: 'alternate' },
             { path: 'foo', name: 'other' },
         ],
@@ -59,8 +59,8 @@ const EXPECTED = [
     {
         query: 'generic:Other',
         in_args: [
-            { path: 'foo', name: 'beta' },
             { path: 'foo', name: 'bet' },
+            { path: 'foo', name: 'beta' },
             { path: 'foo', name: 'alternate' },
             { path: 'foo', name: 'other' },
         ],
diff --git a/tests/rustdoc-ui/invalid-syntax.stderr b/tests/rustdoc-ui/invalid-syntax.stderr
index 46d7cdb4f7e..c6e1f6fd413 100644
--- a/tests/rustdoc-ui/invalid-syntax.stderr
+++ b/tests/rustdoc-ui/invalid-syntax.stderr
@@ -130,7 +130,7 @@ warning: could not parse code block as Rust code
 LL |   ///     \____/
    |  _________^
 LL | | ///
-   | |_
+   | |_^
    |
    = note: error from rustc: unknown start of token: \
 
diff --git a/tests/rustdoc/decl_macro.rs b/tests/rustdoc/decl_macro.rs
index da471e7c224..040859baffb 100644
--- a/tests/rustdoc/decl_macro.rs
+++ b/tests/rustdoc/decl_macro.rs
@@ -48,6 +48,8 @@ mod a {
         }
         mod c {
             //@ has decl_macro/a/b/c/macro.by_example_vis_named.html //pre 'pub(in a) macro by_example_vis_named($foo:expr) {'
+            // Regression test for <https://github.com/rust-lang/rust/issues/83000>:
+            //@ has - '//pre[@class="rust item-decl"]//a[@class="mod"]/@href' '../../index.html'
             pub(in a) macro by_example_vis_named {
                 ($foo:expr) => {}
             }
diff --git a/tests/rustdoc/footnote-ids.rs b/tests/rustdoc/footnote-ids.rs
new file mode 100644
index 00000000000..d3a8435bb47
--- /dev/null
+++ b/tests/rustdoc/footnote-ids.rs
@@ -0,0 +1,41 @@
+// This test ensures that footnotes ID are not duplicated across an item page.
+// This is a regression test for <https://github.com/rust-lang/rust/issues/131901>.
+
+#![crate_name = "foo"]
+
+//@ has 'foo/struct.Foo.html'
+
+pub struct Foo;
+
+impl Foo {
+    //@ has - '//a[@href="#fn1"]' '1'
+    //@ has - '//li[@id="fn1"]' 'Hiya'
+    //@ has - '//a[@href="#fn2"]' '2'
+    //@ has - '//li[@id="fn2"]' 'Tiya'
+    /// Link 1 [^1]
+    /// Link 1.1 [^2]
+    ///
+    /// [^1]: Hiya
+    /// [^2]: Tiya
+    pub fn l1(){}
+
+    //@ has - '//a[@href="#fn3"]' '1'
+    //@ has - '//li[@id="fn3"]' 'Yiya'
+    //@ has - '//a[@href="#fn4"]' '2'
+    //@ has - '//li[@id="fn4"]' 'Biya'
+    /// Link 2 [^1]
+    /// Link 3 [^2]
+    ///
+    /// [^1]: Yiya
+    /// [^2]: Biya
+    pub fn l2() {}
+}
+
+impl Foo {
+    //@ has - '//a[@href="#fn5"]' '1'
+    //@ has - '//li[@id="fn5"]' 'Ciya'
+    /// Link 3 [^1]
+    ///
+    /// [^1]: Ciya
+    pub fn l3(){}
+}
diff --git a/tests/rustdoc/footnote-reference-in-footnote-def.rs b/tests/rustdoc/footnote-reference-in-footnote-def.rs
new file mode 100644
index 00000000000..db3f9a59ef8
--- /dev/null
+++ b/tests/rustdoc/footnote-reference-in-footnote-def.rs
@@ -0,0 +1,20 @@
+// Checks that footnote references in footnote definitions are correctly generated.
+// Regression test for <https://github.com/rust-lang/rust/issues/131946>.
+
+#![crate_name = "foo"]
+
+//@ has 'foo/index.html'
+//@ has - '//*[@class="docblock"]/p/sup[@id="fnref1"]/a[@href="#fn1"]' '1'
+//@ has - '//li[@id="fn1"]/p' 'meow'
+//@ has - '//li[@id="fn1"]/p/sup[@id="fnref2"]/a[@href="#fn2"]' '2'
+//@ has - '//li[@id="fn1"]//a[@href="#fn2"]' '2'
+//@ has - '//li[@id="fn2"]/p' 'uwu'
+//@ has - '//li[@id="fn2"]/p/sup[@id="fnref1"]/a[@href="#fn1"]' '1'
+//@ has - '//li[@id="fn2"]//a[@href="#fn1"]' '1'
+
+//! # footnote-hell
+//!
+//! Hello [^a].
+//!
+//! [^a]: meow [^b]
+//! [^b]: uwu [^a]
diff --git a/tests/rustdoc/heterogeneous-concat.rs b/tests/rustdoc/heterogeneous-concat.rs
new file mode 100644
index 00000000000..8443ccc559e
--- /dev/null
+++ b/tests/rustdoc/heterogeneous-concat.rs
@@ -0,0 +1,11 @@
+// regression test for https://github.com/rust-lang/rust/issues/85763
+
+#![crate_name = "foo"]
+
+//@ has foo/index.html '//main' 'Some text that should be concatenated.'
+#[doc = " Some text"]
+#[doc = r" that should"]
+/// be concatenated.
+pub fn main() {
+    println!("Hello, world!");
+}
diff --git a/tests/rustdoc/macro_rules-matchers.rs b/tests/rustdoc/macro_rules-matchers.rs
index c3ee8febdf5..2c9fb50539a 100644
--- a/tests/rustdoc/macro_rules-matchers.rs
+++ b/tests/rustdoc/macro_rules-matchers.rs
@@ -3,29 +3,17 @@
 
 #![crate_name = "foo"]
 
-//@ has 'foo/macro.todo.html'
-//@ has - '//span[@class="macro"]' 'macro_rules!'
-//@ hasraw - ' todo {'
-
-//@ hasraw - '{ () =&gt; { ... }; ($('
-//@ has - '//span[@class="macro-nonterminal"]' '$'
-//@ has - '//span[@class="macro-nonterminal"]' 'arg'
-//@ hasraw - ':tt)+'
-//@ hasraw - ') =&gt; { ... }; }'
+//@ has 'foo/macro.todo.html' '//pre' 'macro_rules! todo { \
+//      () => { ... }; \
+//      ($($arg:tt)+) => { ... }; \
+// }'
 pub use std::todo;
 
 mod mod1 {
-    //@ has 'foo/macro.macro1.html'
-    //@ hasraw - 'macro_rules!'
-    //@ hasraw - 'macro1'
-    //@ hasraw - '{ () =&gt; { ... }; ($('
-    //@ has - '//span[@class="macro-nonterminal"]' '$'
-    //@ has - '//span[@class="macro-nonterminal"]' 'arg'
-    //@ hasraw - ':'
-    //@ hasraw - 'expr'
-    //@ hasraw - '),'
-    //@ hasraw - '+'
-    //@ hasraw - ') =&gt; { ... }; }'
+    //@ has 'foo/macro.macro1.html' '//pre' 'macro_rules! macro1 { \
+    //      () => { ... }; \
+    //      ($($arg:expr),+) => { ... }; \
+    // }'
     #[macro_export]
     macro_rules! macro1 {
         () => {};
diff --git a/tests/ui-fulldeps/internal-lints/bad_opt_access.rs b/tests/ui-fulldeps/internal-lints/bad_opt_access.rs
index 708c3651b87..a2a94db919d 100644
--- a/tests/ui-fulldeps/internal-lints/bad_opt_access.rs
+++ b/tests/ui-fulldeps/internal-lints/bad_opt_access.rs
@@ -15,7 +15,7 @@ pub fn access_bad_option(sess: Session) {
     //~^ ERROR use `Session::split_debuginfo` instead of this field
 
     let _ = sess.opts.crate_types;
-    //~^ ERROR use `Session::crate_types` instead of this field
+    //~^ ERROR use `TyCtxt::crate_types` instead of this field
 
     let _ = sess.opts.crate_name;
     // okay!
diff --git a/tests/ui-fulldeps/internal-lints/bad_opt_access.stderr b/tests/ui-fulldeps/internal-lints/bad_opt_access.stderr
index e4145bff8be..35b179f2a3a 100644
--- a/tests/ui-fulldeps/internal-lints/bad_opt_access.stderr
+++ b/tests/ui-fulldeps/internal-lints/bad_opt_access.stderr
@@ -10,7 +10,7 @@ note: the lint level is defined here
 LL | #![deny(rustc::bad_opt_access)]
    |         ^^^^^^^^^^^^^^^^^^^^^
 
-error: use `Session::crate_types` instead of this field
+error: use `TyCtxt::crate_types` instead of this field
   --> $DIR/bad_opt_access.rs:17:13
    |
 LL |     let _ = sess.opts.crate_types;
diff --git a/tests/ui/asan-odr-win/asan_odr_windows.rs b/tests/ui/asan-odr-win/asan_odr_windows.rs
new file mode 100644
index 00000000000..c618ac02a66
--- /dev/null
+++ b/tests/ui/asan-odr-win/asan_odr_windows.rs
@@ -0,0 +1,18 @@
+//! Check that crates can be linked together with `-Z sanitizer=address` on msvc.
+//! See <https://github.com/rust-lang/rust/issues/124390>.
+
+//@ run-pass
+//@ compile-flags:-Zsanitizer=address
+//@ aux-build: asan_odr_win-2.rs
+//@ only-windows-msvc
+
+extern crate othercrate;
+
+fn main() {
+    let result = std::panic::catch_unwind(|| {
+        println!("hello!");
+    });
+    assert!(result.is_ok());
+
+    othercrate::exposed_func();
+}
diff --git a/tests/ui/asan-odr-win/auxiliary/asan_odr_win-2.rs b/tests/ui/asan-odr-win/auxiliary/asan_odr_win-2.rs
new file mode 100644
index 00000000000..75488a29e5e
--- /dev/null
+++ b/tests/ui/asan-odr-win/auxiliary/asan_odr_win-2.rs
@@ -0,0 +1,11 @@
+//@ no-prefer-dynamic
+//@ compile-flags: -Z sanitizer=address
+#![crate_name = "othercrate"]
+#![crate_type = "rlib"]
+
+pub fn exposed_func() {
+    let result = std::panic::catch_unwind(|| {
+        println!("hello!");
+    });
+    assert!(result.is_ok());
+}
diff --git a/tests/ui/asm/aarch64/arm64ec-sve.rs b/tests/ui/asm/aarch64/arm64ec-sve.rs
index 389b365a754..d2313f8417d 100644
--- a/tests/ui/asm/aarch64/arm64ec-sve.rs
+++ b/tests/ui/asm/aarch64/arm64ec-sve.rs
@@ -3,7 +3,7 @@
 //@ needs-llvm-components: aarch64
 
 #![crate_type = "rlib"]
-#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
+#![feature(no_core, rustc_attrs, lang_items)]
 #![no_core]
 
 // SVE cannot be used for Arm64EC
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr
index 58b82fc9306..06dca48b616 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr
@@ -15,10 +15,10 @@ LL |     for<'b> <T as X<'b, T>>::U: Clone,
    |                                 ^^^^^ required by this bound in `X`
 
 error[E0277]: the trait bound `str: Clone` is not satisfied
-  --> $DIR/hr-associated-type-bound-param-3.rs:18:5
+  --> $DIR/hr-associated-type-bound-param-3.rs:18:18
    |
 LL |     <(i32,) as X<(i32,)>>::f("abc");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+   |                  ^^^^^^ the trait `Clone` is not implemented for `str`
    |
    = help: the trait `Clone` is implemented for `String`
 note: required by a bound in `X::f`
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr
index 6d6373a1918..da0cf6f55ba 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr
@@ -15,10 +15,10 @@ LL |     for<'b> <(T,) as X<'b, T>>::U: Clone,
    |                                    ^^^^^ required by this bound in `X`
 
 error[E0277]: the trait bound `str: Clone` is not satisfied
-  --> $DIR/hr-associated-type-bound-param-4.rs:18:5
+  --> $DIR/hr-associated-type-bound-param-4.rs:18:18
    |
 LL |     <(i32,) as X<i32>>::f("abc");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+   |                  ^^^ the trait `Clone` is not implemented for `str`
    |
    = help: the trait `Clone` is implemented for `String`
 note: required by a bound in `X::f`
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr
index 44c446c599f..dd576577dce 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr
@@ -31,10 +31,10 @@ LL |     for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
    |                                             ^^^^^ required by this bound in `X`
 
 error[E0277]: the trait bound `str: Clone` is not satisfied
-  --> $DIR/hr-associated-type-bound-param-5.rs:36:5
+  --> $DIR/hr-associated-type-bound-param-5.rs:36:15
    |
 LL |     <i32 as X<Box<i32>>>::f("abc");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+   |               ^^^^^^^^ the trait `Clone` is not implemented for `str`
    |
    = help: the trait `Clone` is implemented for `String`
 note: required by a bound in `X::f`
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-6.rs b/tests/ui/associated-types/hr-associated-type-bound-param-6.rs
index f6639904ab3..c09d3675584 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-6.rs
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-6.rs
@@ -17,5 +17,6 @@ impl<S, T> X<'_, T> for (S,) {
 pub fn main() {
     <(i32,) as X<i32>>::f("abc");
     //~^ ERROR the trait bound `for<'b> i32: X<'b, i32>` is not satisfied
+    //~| ERROR the trait bound `for<'b> i32: X<'b, i32>` is not satisfied
     //~| ERROR the trait bound `i32: X<'_, i32>` is not satisfied
 }
diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr
index cba83120fdc..5278bdb7a5c 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-param-6.stderr
@@ -17,6 +17,22 @@ LL |     <(i32,) as X<i32>>::f("abc");
    |
    = help: the trait `X<'_, T>` is implemented for `(S,)`
 
+error[E0277]: the trait bound `for<'b> i32: X<'b, i32>` is not satisfied
+  --> $DIR/hr-associated-type-bound-param-6.rs:18:18
+   |
+LL |     <(i32,) as X<i32>>::f("abc");
+   |                  ^^^ the trait `for<'b> X<'b, i32>` is not implemented for `i32`
+   |
+   = help: the trait `X<'_, T>` is implemented for `(S,)`
+note: required by a bound in `X::f`
+  --> $DIR/hr-associated-type-bound-param-6.rs:3:16
+   |
+LL |     for<'b> T: X<'b, T>,
+   |                ^^^^^^^^ required by this bound in `X::f`
+...
+LL |     fn f(x: &<T as X<'_, T>>::U) {
+   |        - required by a bound in this associated function
+
 error[E0277]: the trait bound `i32: X<'_, i32>` is not satisfied
   --> $DIR/hr-associated-type-bound-param-6.rs:18:27
    |
@@ -25,6 +41,6 @@ LL |     <(i32,) as X<i32>>::f("abc");
    |
    = help: the trait `X<'_, T>` is implemented for `(S,)`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr
index ab212dda015..0a993214f5a 100644
--- a/tests/ui/check-cfg/mix.stderr
+++ b/tests/ui/check-cfg/mix.stderr
@@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra`
 LL |     cfg!(target_feature = "zebra");
    |          ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 250 more
+   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 251 more
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: 27 warnings emitted
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index f51271dc3de..ca6a173d638 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -174,7 +174,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_feature = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `cssc`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `ecv`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `faminmax`, `fcma`, `fdivdu`, `fhm`, `flagm`, `flagm2`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fp8`, `fp8dot2`, `fp8dot4`, `fp8fma`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `hbc`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `leoncasa`, `lor`, `lse`, `lse128`, `lse2`, `lsx`, `lut`, `lvz`, `lzcnt`, `m`, `mclass`, `mops`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `partword-atomics`, `pauth-lr`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `quadword-atomics`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rcpc3`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `sme`, `sme-b16b16`, `sme-f16f16`, `sme-f64f64`, `sme-f8f16`, `sme-f8f32`, `sme-fa64`, `sme-i16i64`, `sme-lutv2`, `sme2`, `sme2p1`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `ssve-fp8dot2`, `ssve-fp8dot4`, `ssve-fp8fma`, `sve`, `sve-b16b16`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `sve2p1`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `v8.8a`, `v8.9a`, `v8plus`, `v9`, `v9.1a`, `v9.2a`, `v9.3a`, `v9.4a`, `v9.5a`, `v9a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `wfxt`, `wide-arithmetic`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zaamo`, `zabha`, `zalrsc`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt`
+   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `cssc`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `ecv`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `faminmax`, `fcma`, `fdivdu`, `fhm`, `flagm`, `flagm2`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fp8`, `fp8dot2`, `fp8dot4`, `fp8fma`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `hbc`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `leoncasa`, `lor`, `lse`, `lse128`, `lse2`, `lsx`, `lut`, `lvz`, `lzcnt`, `m`, `mclass`, `mops`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `partword-atomics`, `pauth-lr`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `quadword-atomics`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rcpc3`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `sme`, `sme-b16b16`, `sme-f16f16`, `sme-f64f64`, `sme-f8f16`, `sme-f8f32`, `sme-fa64`, `sme-i16i64`, `sme-lutv2`, `sme2`, `sme2p1`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `ssve-fp8dot2`, `ssve-fp8dot4`, `ssve-fp8fma`, `sve`, `sve-b16b16`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `sve2p1`, `tail-call`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `v8.8a`, `v8.9a`, `v8plus`, `v9`, `v9.1a`, `v9.2a`, `v9.3a`, `v9.4a`, `v9.5a`, `v9a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `wfxt`, `wide-arithmetic`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zaamo`, `zabha`, `zalrsc`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
diff --git a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
index ca8c2a16d32..5f980c46a1f 100644
--- a/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
+++ b/tests/ui/closures/2229_closure_analysis/bad-pattern.stderr
@@ -97,16 +97,19 @@ LL |         if let Refutable::A = v3 { todo!() };
 error[E0005]: refutable pattern in local binding
   --> $DIR/bad-pattern.rs:19:13
    |
+LL |     const PAT: u32 = 0;
+   |     -------------- missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable
+...
 LL |         let PAT = v1;
-   |             ^^^
-   |             |
-   |             pattern `1_u32..=u32::MAX` not covered
-   |             missing patterns are not covered because `PAT` is interpreted as a constant pattern, not a new variable
-   |             help: introduce a variable instead: `PAT_var`
+   |             ^^^ pattern `1_u32..=u32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `u32`
+help: introduce a variable instead
+   |
+LL |         let PAT_var = v1;
+   |             ~~~~~~~
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr
index 347fa3fa892..4cfe51eccac 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-multi-variant-diagnostics.stderr
@@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
    |
 LL |         if let MultiVariant::Point(ref mut x, _) = point {
    |                                                    ^^^^^
-help: consider mutably borrowing `c`
-   |
-LL |     let a = &mut c;
-   |             ++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr
index c9b27e76879..2ed611d6b52 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-single-variant-diagnostics.stderr
@@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
    |
 LL |         let SingleVariant::Point(ref mut x, _) = point;
    |                                                  ^^^^^
-help: consider mutably borrowing `c`
-   |
-LL |     let b = &mut c;
-   |             ++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr
index 079a9abedf9..47db2c76a2f 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-struct-diagnostics.stderr
@@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
    |
 LL |         x.y.a += 1;
    |         ^^^^^
-help: consider mutably borrowing `hello`
-   |
-LL |     let b = &mut hello;
-   |             ++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr
index 0bf717404ce..9db64ec04b9 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/closure-origin-tuple-diagnostics-1.stderr
@@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
    |
 LL |         x.0 += 1;
    |         ^^^
-help: consider mutably borrowing `hello`
-   |
-LL |     let b = &mut hello;
-   |             ++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.svg b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg
index 12058176dc0..6f46df0101e 100644
--- a/tests/ui/codemap_tests/huge_multispan_highlight.svg
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg
@@ -1,4 +1,4 @@
-<svg width="818px" height="848px" xmlns="http://www.w3.org/2000/svg">
+<svg width="743px" height="848px" xmlns="http://www.w3.org/2000/svg">
   <style>
     .fg { fill: #AAAAAA }
     .bg { background: #000000 }
@@ -21,7 +21,7 @@
   <text xml:space="preserve" class="container fg">
     <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: `match` arms have incompatible types</tspan>
 </tspan>
-    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/huge_multispan_highlight.rs:96:18</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/huge_multispan_highlight.rs:99:18</tspan>
 </tspan>
     <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -31,7 +31,7 @@
 </tspan>
     <tspan x="10px" y="118px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           true =&gt; (</tspan>
 </tspan>
-    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">_________________-</tspan>
+    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold"> _________________-</tspan>
 </tspan>
     <tspan x="10px" y="154px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>             // last line shown in multispan header</tspan>
 </tspan>
@@ -45,7 +45,7 @@
 </tspan>
     <tspan x="10px" y="244px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           false =&gt; "</tspan>
 </tspan>
-    <tspan x="10px" y="262px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">__________________^</tspan>
+    <tspan x="10px" y="262px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold"> __________________^</tspan>
 </tspan>
     <tspan x="10px" y="280px"><tspan class="fg-ansi256-012 bold">...</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
 </tspan>
@@ -59,7 +59,7 @@
 </tspan>
     <tspan x="10px" y="370px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: `match` arms have incompatible types</tspan>
 </tspan>
-    <tspan x="10px" y="388px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/huge_multispan_highlight.rs:213:18</tspan>
+    <tspan x="10px" y="388px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/huge_multispan_highlight.rs:216:18</tspan>
 </tspan>
     <tspan x="10px" y="406px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -69,7 +69,7 @@
 </tspan>
     <tspan x="10px" y="460px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           true =&gt; (</tspan>
 </tspan>
-    <tspan x="10px" y="478px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">_________________-</tspan>
+    <tspan x="10px" y="478px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold"> _________________-</tspan>
 </tspan>
     <tspan x="10px" y="496px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
 </tspan>
@@ -85,7 +85,7 @@
 </tspan>
     <tspan x="10px" y="604px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>           false =&gt; "</tspan>
 </tspan>
-    <tspan x="10px" y="622px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-009 bold">__________________^</tspan>
+    <tspan x="10px" y="622px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold"> __________________^</tspan>
 </tspan>
     <tspan x="10px" y="640px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">|</tspan>
 </tspan>
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.rs b/tests/ui/codemap_tests/huge_multispan_highlight.rs
index 28c595cca64..7d7b7570823 100644
--- a/tests/ui/codemap_tests/huge_multispan_highlight.rs
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.rs
@@ -1,4 +1,7 @@
-//@ compile-flags: --error-format=human --color=always
+//@ revisions: ascii unicode
+//@ compile-flags: --color=always
+//@[ascii] compile-flags: --error-format=human
+//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode
 //@ ignore-windows
 fn main() {
     let _ = match true {
diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg b/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg
new file mode 100644
index 00000000000..4e1a8d14a28
--- /dev/null
+++ b/tests/ui/codemap_tests/huge_multispan_highlight.unicode.svg
@@ -0,0 +1,116 @@
+<svg width="743px" height="848px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .fg-ansi256-009 { fill: #FF5555 }
+    .fg-ansi256-012 { fill: #5555FF }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    .bold { font-weight: bold; }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: `match` arms have incompatible types</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold"> ╭▸ </tspan><tspan>$DIR/huge_multispan_highlight.rs:99:18</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>       let _ = match true {</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>               </tspan><tspan class="fg-ansi256-012 bold">──────────</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           true =&gt; (</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">┌─────────────────┘</tspan>
+</tspan>
+    <tspan x="10px" y="154px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>             // last line shown in multispan header</tspan>
+</tspan>
+    <tspan x="10px" y="172px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="190px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="208px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>         ),</tspan>
+</tspan>
+    <tspan x="10px" y="226px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">└─────────┘</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `()`</tspan>
+</tspan>
+    <tspan x="10px" y="244px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           false =&gt; "</tspan>
+</tspan>
+    <tspan x="10px" y="262px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┏━━━━━━━━━━━━━━━━━━┛</tspan>
+</tspan>
+    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+</tspan>
+    <tspan x="10px" y="298px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+</tspan>
+    <tspan x="10px" y="316px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan><tspan>         ",</tspan>
+</tspan>
+    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰╴</tspan><tspan class="fg-ansi256-009 bold">┗━━━━━━━━━┛</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected `()`, found `&amp;str`</tspan>
+</tspan>
+    <tspan x="10px" y="352px">
+</tspan>
+    <tspan x="10px" y="370px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: `match` arms have incompatible types</tspan>
+</tspan>
+    <tspan x="10px" y="388px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold"> ╭▸ </tspan><tspan>$DIR/huge_multispan_highlight.rs:216:18</tspan>
+</tspan>
+    <tspan x="10px" y="406px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="424px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>       let _ = match true {</tspan>
+</tspan>
+    <tspan x="10px" y="442px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>               </tspan><tspan class="fg-ansi256-012 bold">──────────</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">`match` arms have incompatible types</tspan>
+</tspan>
+    <tspan x="10px" y="460px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           true =&gt; (</tspan>
+</tspan>
+    <tspan x="10px" y="478px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">┌─────────────────┘</tspan>
+</tspan>
+    <tspan x="10px" y="496px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="514px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>         1 // last line shown in multispan header</tspan>
+</tspan>
+    <tspan x="10px" y="532px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="550px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="568px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>         ),</tspan>
+</tspan>
+    <tspan x="10px" y="586px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">└─────────┘</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">this is found to be of type `{integer}`</tspan>
+</tspan>
+    <tspan x="10px" y="604px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>           false =&gt; "</tspan>
+</tspan>
+    <tspan x="10px" y="622px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┏━━━━━━━━━━━━━━━━━━┛</tspan>
+</tspan>
+    <tspan x="10px" y="640px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+</tspan>
+    <tspan x="10px" y="658px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+</tspan>
+    <tspan x="10px" y="676px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan><tspan>         1 last line shown in multispan</tspan>
+</tspan>
+    <tspan x="10px" y="694px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">‡</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+</tspan>
+    <tspan x="10px" y="712px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan>
+</tspan>
+    <tspan x="10px" y="730px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">┃</tspan><tspan>         ",</tspan>
+</tspan>
+    <tspan x="10px" y="748px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰╴</tspan><tspan class="fg-ansi256-009 bold">┗━━━━━━━━━┛</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">expected integer, found `&amp;str`</tspan>
+</tspan>
+    <tspan x="10px" y="766px">
+</tspan>
+    <tspan x="10px" y="784px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="bold">: aborting due to 2 previous errors</tspan>
+</tspan>
+    <tspan x="10px" y="802px">
+</tspan>
+    <tspan x="10px" y="820px"><tspan class="bold">For more information about this error, try `rustc --explain E0308`.</tspan>
+</tspan>
+    <tspan x="10px" y="838px">
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-1.rs b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-1.rs
new file mode 100644
index 00000000000..cea82722a0e
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-1.rs
@@ -0,0 +1,12 @@
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+// Regression test for #118545
+
+struct Checked<const F: fn()>;
+//~^ ERROR: using function pointers as const generic parameters is forbidden
+
+fn foo() {}
+const _: Checked<foo> = Checked::<foo>;
+
+pub fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-1.stderr b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-1.stderr
new file mode 100644
index 00000000000..71339411c84
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-1.stderr
@@ -0,0 +1,10 @@
+error: using function pointers as const generic parameters is forbidden
+  --> $DIR/non_valtreeable_const_arg-1.rs:6:25
+   |
+LL | struct Checked<const F: fn()>;
+   |                         ^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs
new file mode 100644
index 00000000000..6b87ad86d4b
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs
@@ -0,0 +1,19 @@
+#![feature(generic_const_exprs, unsized_const_params)]
+#![allow(incomplete_features)]
+
+// Regression test for 128232
+
+fn function() {}
+
+struct Wrapper<const F: fn()>;
+//~^ ERROR: using function pointers as const generic parameters is forbidden
+
+impl Wrapper<{ bar() }> {
+    //~^ ERROR: cannot find function `bar` in this scope
+    fn call() {}
+}
+
+fn main() {
+    Wrapper::<function>::call;
+    //~^ ERROR: the function or associated item `call` exists for struct `Wrapper<function>`,
+}
diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr
new file mode 100644
index 00000000000..b13f76eabad
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr
@@ -0,0 +1,39 @@
+error[E0425]: cannot find function `bar` in this scope
+  --> $DIR/non_valtreeable_const_arg-2.rs:11:16
+   |
+LL | impl Wrapper<{ bar() }> {
+   |                ^^^ not found in this scope
+   |
+help: you might be missing a const parameter
+   |
+LL | impl<const bar: /* Type */> Wrapper<{ bar() }> {
+   |     +++++++++++++++++++++++
+
+error[E0741]: using function pointers as const generic parameters is forbidden
+  --> $DIR/non_valtreeable_const_arg-2.rs:8:25
+   |
+LL | struct Wrapper<const F: fn()>;
+   |                         ^^^^
+
+error[E0599]: the function or associated item `call` exists for struct `Wrapper<function>`, but its trait bounds were not satisfied
+  --> $DIR/non_valtreeable_const_arg-2.rs:17:26
+   |
+LL | struct Wrapper<const F: fn()>;
+   | ----------------------------- function or associated item `call` not found for this struct because it doesn't satisfy `Wrapper<function>: Fn<_>`
+...
+LL |     Wrapper::<function>::call;
+   |                          ^^^^ function or associated item cannot be called on `Wrapper<function>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `Wrapper<function>: Fn<_>`
+           which is required by `&Wrapper<function>: Fn<_>`
+note: the trait `Fn` must be implemented
+  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following trait defines an item `call`, perhaps you need to implement it:
+           candidate #1: `Fn`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0425, E0599, E0741.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.rs
new file mode 100644
index 00000000000..bce7ac5708a
--- /dev/null
+++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.rs
@@ -0,0 +1,20 @@
+// Regression test for #131915 where we did not handle macro calls as
+// statements correctly when determining if a const argument should
+// have a `DefId` created or not.
+
+macro_rules! y {
+    ( $($matcher:tt)*) => {
+        x
+        //~^ ERROR: cannot find value `x` in this scope
+    };
+}
+
+const _: A<
+    //~^ ERROR: free constant item without body
+    //~| ERROR: cannot find type `A` in this scope
+    {
+        y! { test.tou8 }
+    },
+>;
+
+fn main() {}
diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr
new file mode 100644
index 00000000000..a3211b77623
--- /dev/null
+++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-2.stderr
@@ -0,0 +1,39 @@
+error: free constant item without body
+  --> $DIR/const_arg_trivial_macro_expansion-2.rs:12:1
+   |
+LL | / const _: A<
+LL | |
+LL | |
+LL | |     {
+LL | |         y! { test.tou8 }
+LL | |     },
+LL | | >;
+   | |  ^ help: provide a definition for the constant: `= <expr>;`
+   | |__|
+   |
+
+error[E0412]: cannot find type `A` in this scope
+  --> $DIR/const_arg_trivial_macro_expansion-2.rs:12:10
+   |
+LL | const _: A<
+   |          ^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/const_arg_trivial_macro_expansion-2.rs:7:9
+   |
+LL |         x
+   |         ^ not found in this scope
+...
+LL |         y! { test.tou8 }
+   |         ---------------- in this macro invocation
+   |
+   = note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might be missing a const parameter
+   |
+LL | const _<const x: /* Type */>: A<
+   |        +++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0412, E0425.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs
new file mode 100644
index 00000000000..2fdd703ab6f
--- /dev/null
+++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs
@@ -0,0 +1,366 @@
+//@ known-bug: #132647
+//@ dont-check-compiler-stderr
+#![allow(unused_braces)]
+
+// FIXME(bootstrap): This isn't a known bug, we just don't want to write any error annotations.
+// this is hard because macro expansion errors have their span be inside the *definition* of the
+// macro rather than the line *invoking* it. This means we would wind up with hundreds of error
+// annotations on the macro definitions below rather than on any of the actual lines
+// that act as a "test".
+//
+// It's also made more complicated by the fact that compiletest generates "extra" expected
+// notes to give an assertable macro backtrace as otherwise there would *nothing* to annotate
+// on the actual test lines. All of these extra notes result in needing to write hundreds of
+// unnecessary notes on almost every line in this file.
+//
+// Even though this is marked `known-bug` it should still fail if this test starts ICEing which
+// is "enough" in this case.
+
+// Test that we correctly create definitions for anon consts even when
+// the trivial-ness of the expression is obscured by macro expansions.
+//
+// Acts as a regression test for: #131915 130321 128016
+
+// macros expanding to idents
+
+macro_rules! unbraced_ident {
+    () => {
+        ident
+    };
+}
+
+macro_rules! braced_ident {
+    () => {{ ident }};
+}
+
+macro_rules! unbraced_unbraced_ident {
+    () => {
+        unbraced_ident!()
+    };
+}
+
+macro_rules! braced_unbraced_ident {
+    () => {{ unbraced_ident!() }};
+}
+
+macro_rules! unbraced_braced_ident {
+    () => {
+        braced_ident!()
+    };
+}
+
+macro_rules! braced_braced_ident {
+    () => {{ braced_ident!() }};
+}
+
+// macros expanding to complex expr
+
+macro_rules! unbraced_expr {
+    () => {
+        ident.other
+    };
+}
+
+macro_rules! braced_expr {
+    () => {{ ident.otherent }};
+}
+
+macro_rules! unbraced_unbraced_expr {
+    () => {
+        unbraced_expr!()
+    };
+}
+
+macro_rules! braced_unbraced_expr {
+    () => {{ unbraced_expr!() }};
+}
+
+macro_rules! unbraced_braced_expr {
+    () => {
+        braced_expr!()
+    };
+}
+
+macro_rules! braced_braced_expr {
+    () => {{ braced_expr!() }};
+}
+
+#[rustfmt::skip]
+mod array_paren_call {
+    // Arrays where the expanded result is a `Res::Err`
+    fn array_0() -> [(); unbraced_unbraced_ident!()] { loop {} }
+    fn array_1() -> [(); braced_unbraced_ident!()] { loop {} }
+    fn array_2() -> [(); unbraced_braced_ident!()] { loop {} }
+    fn array_3() -> [(); braced_braced_ident!()] { loop {} }
+    fn array_4() -> [(); { unbraced_unbraced_ident!() }] { loop {} }
+    fn array_5() -> [(); { braced_unbraced_ident!() }] { loop {} }
+    fn array_6() -> [(); { unbraced_braced_ident!() }] { loop {} }
+    fn array_7() -> [(); { braced_braced_ident!() }] { loop {} }
+    fn array_8() -> [(); unbraced_ident!()] { loop {} }
+    fn array_9() -> [(); braced_ident!()] { loop {} }
+    fn array_10() -> [(); { unbraced_ident!() }] { loop {} }
+    fn array_11() -> [(); { braced_ident!() }] { loop {} }
+
+    // Arrays where the expanded result is a `Res::ConstParam`
+    fn array_12<const ident: usize>() -> [(); unbraced_unbraced_ident!()] { loop {} }
+    fn array_13<const ident: usize>() -> [(); braced_unbraced_ident!()] { loop {} }
+    fn array_14<const ident: usize>() -> [(); unbraced_braced_ident!()] { loop {} }
+    fn array_15<const ident: usize>() -> [(); braced_braced_ident!()] { loop {} }
+    fn array_16<const ident: usize>() -> [(); { unbraced_unbraced_ident!() }] { loop {} }
+    fn array_17<const ident: usize>() -> [(); { braced_unbraced_ident!() }] { loop {} }
+    fn array_18<const ident: usize>() -> [(); { unbraced_braced_ident!() }] { loop {} }
+    fn array_19<const ident: usize>() -> [(); { braced_braced_ident!() }] { loop {} }
+    fn array_20<const ident: usize>() -> [(); unbraced_ident!()] { loop {} }
+    fn array_21<const ident: usize>() -> [(); braced_ident!()] { loop {} }
+    fn array_22<const ident: usize>() -> [(); { unbraced_ident!() }] { loop {} }
+    fn array_23<const ident: usize>() -> [(); { braced_ident!() }] { loop {} }
+
+    // Arrays where the expanded result is a complex expr
+    fn array_24() -> [(); unbraced_unbraced_expr!()] { loop {} }
+    fn array_25() -> [(); braced_unbraced_expr!()] { loop {} }
+    fn array_26() -> [(); unbraced_braced_expr!()] { loop {} }
+    fn array_27() -> [(); braced_braced_expr!()] { loop {} }
+    fn array_28() -> [(); { unbraced_unbraced_expr!() }] { loop {} }
+    fn array_29() -> [(); { braced_unbraced_expr!() }] { loop {} }
+    fn array_30() -> [(); { unbraced_braced_expr!() }] { loop {} }
+    fn array_31() -> [(); { braced_braced_expr!() }] { loop {} }
+    fn array_32() -> [(); unbraced_expr!()] { loop {} }
+    fn array_33() -> [(); braced_expr!()] { loop {} }
+    fn array_34() -> [(); { unbraced_expr!() }] { loop {} }
+    fn array_35() -> [(); { braced_expr!() }] { loop {} }
+}
+
+#[rustfmt::skip]
+mod array_brace_call {
+    // Arrays where the expanded result is a `Res::Err`
+    fn array_0() -> [(); unbraced_unbraced_ident!{}] { loop {} }
+    fn array_1() -> [(); braced_unbraced_ident!{}] { loop {} }
+    fn array_2() -> [(); unbraced_braced_ident!{}] { loop {} }
+    fn array_3() -> [(); braced_braced_ident!{}] { loop {} }
+    fn array_4() -> [(); { unbraced_unbraced_ident!{} }] { loop {} }
+    fn array_5() -> [(); { braced_unbraced_ident!{} }] { loop {} }
+    fn array_6() -> [(); { unbraced_braced_ident!{} }] { loop {} }
+    fn array_7() -> [(); { braced_braced_ident!{} }] { loop {} }
+    fn array_8() -> [(); unbraced_ident!{}] { loop {} }
+    fn array_9() -> [(); braced_ident!{}] { loop {} }
+    fn array_10() -> [(); { unbraced_ident!{} }] { loop {} }
+    fn array_11() -> [(); { braced_ident!{} }] { loop {} }
+
+    // Arrays where the expanded result is a `Res::ConstParam`
+    fn array_12<const ident: usize>() -> [(); unbraced_unbraced_ident!{}] { loop {} }
+    fn array_13<const ident: usize>() -> [(); braced_unbraced_ident!{}] { loop {} }
+    fn array_14<const ident: usize>() -> [(); unbraced_braced_ident!{}] { loop {} }
+    fn array_15<const ident: usize>() -> [(); braced_braced_ident!{}] { loop {} }
+    fn array_16<const ident: usize>() -> [(); { unbraced_unbraced_ident!{} }] { loop {} }
+    fn array_17<const ident: usize>() -> [(); { braced_unbraced_ident!{} }] { loop {} }
+    fn array_18<const ident: usize>() -> [(); { unbraced_braced_ident!{} }] { loop {} }
+    fn array_19<const ident: usize>() -> [(); { braced_braced_ident!{} }] { loop {} }
+    fn array_20<const ident: usize>() -> [(); unbraced_ident!{}] { loop {} }
+    fn array_21<const ident: usize>() -> [(); braced_ident!{}] { loop {} }
+    fn array_22<const ident: usize>() -> [(); { unbraced_ident!{} }] { loop {} }
+    fn array_23<const ident: usize>() -> [(); { braced_ident!{} }] { loop {} }
+
+    // Arrays where the expanded result is a complex expr
+    fn array_24() -> [(); unbraced_unbraced_expr!{}] { loop {} }
+    fn array_25() -> [(); braced_unbraced_expr!{}] { loop {} }
+    fn array_26() -> [(); unbraced_braced_expr!{}] { loop {} }
+    fn array_27() -> [(); braced_braced_expr!{}] { loop {} }
+    fn array_28() -> [(); { unbraced_unbraced_expr!{} }] { loop {} }
+    fn array_29() -> [(); { braced_unbraced_expr!{} }] { loop {} }
+    fn array_30() -> [(); { unbraced_braced_expr!{} }] { loop {} }
+    fn array_31() -> [(); { braced_braced_expr!{} }] { loop {} }
+    fn array_32() -> [(); unbraced_expr!{}] { loop {} }
+    fn array_33() -> [(); braced_expr!{}] { loop {} }
+    fn array_34() -> [(); { unbraced_expr!{} }] { loop {} }
+    fn array_35() -> [(); { braced_expr!{} }] { loop {} }
+}
+
+#[rustfmt::skip]
+mod array_square_call {
+    // Arrays where the expanded result is a `Res::Err`
+    fn array_0() -> [(); unbraced_unbraced_ident![]] { loop {} }
+    fn array_1() -> [(); braced_unbraced_ident![]] { loop {} }
+    fn array_2() -> [(); unbraced_braced_ident![]] { loop {} }
+    fn array_3() -> [(); braced_braced_ident![]] { loop {} }
+    fn array_4() -> [(); { unbraced_unbraced_ident![] }] { loop {} }
+    fn array_5() -> [(); { braced_unbraced_ident![] }] { loop {} }
+    fn array_6() -> [(); { unbraced_braced_ident![] }] { loop {} }
+    fn array_7() -> [(); { braced_braced_ident![] }] { loop {} }
+    fn array_8() -> [(); unbraced_ident![]] { loop {} }
+    fn array_9() -> [(); braced_ident![]] { loop {} }
+    fn array_10() -> [(); { unbraced_ident![] }] { loop {} }
+    fn array_11() -> [(); { braced_ident![] }] { loop {} }
+
+    // Arrays where the expanded result is a `Res::ConstParam`
+    fn array_12<const ident: usize>() -> [(); unbraced_unbraced_ident![]] { loop {} }
+    fn array_13<const ident: usize>() -> [(); braced_unbraced_ident![]] { loop {} }
+    fn array_14<const ident: usize>() -> [(); unbraced_braced_ident![]] { loop {} }
+    fn array_15<const ident: usize>() -> [(); braced_braced_ident![]] { loop {} }
+    fn array_16<const ident: usize>() -> [(); { unbraced_unbraced_ident![] }] { loop {} }
+    fn array_17<const ident: usize>() -> [(); { braced_unbraced_ident![] }] { loop {} }
+    fn array_18<const ident: usize>() -> [(); { unbraced_braced_ident![] }] { loop {} }
+    fn array_19<const ident: usize>() -> [(); { braced_braced_ident![] }] { loop {} }
+    fn array_20<const ident: usize>() -> [(); unbraced_ident![]] { loop {} }
+    fn array_21<const ident: usize>() -> [(); braced_ident![]] { loop {} }
+    fn array_22<const ident: usize>() -> [(); { unbraced_ident![] }] { loop {} }
+    fn array_23<const ident: usize>() -> [(); { braced_ident![] }] { loop {} }
+
+    // Arrays where the expanded result is a complex expr
+    fn array_24() -> [(); unbraced_unbraced_expr![]] { loop {} }
+    fn array_25() -> [(); braced_unbraced_expr![]] { loop {} }
+    fn array_26() -> [(); unbraced_braced_expr![]] { loop {} }
+    fn array_27() -> [(); braced_braced_expr![]] { loop {} }
+    fn array_28() -> [(); { unbraced_unbraced_expr![] }] { loop {} }
+    fn array_29() -> [(); { braced_unbraced_expr![] }] { loop {} }
+    fn array_30() -> [(); { unbraced_braced_expr![] }] { loop {} }
+    fn array_31() -> [(); { braced_braced_expr![] }] { loop {} }
+    fn array_32() -> [(); unbraced_expr![]] { loop {} }
+    fn array_33() -> [(); braced_expr![]] { loop {} }
+    fn array_34() -> [(); { unbraced_expr![] }] { loop {} }
+    fn array_35() -> [(); { braced_expr![] }] { loop {} }
+}
+
+struct Foo<const N: usize>;
+
+#[rustfmt::skip]
+mod adt_paren_call {
+    use super::Foo;
+
+    // An ADT where the expanded result is a `Res::Err`
+    fn adt_0() -> Foo<unbraced_unbraced_ident!()> { loop {} }
+    fn adt_1() -> Foo<braced_unbraced_ident!()> { loop {} }
+    fn adt_2() -> Foo<unbraced_braced_ident!()> { loop {} }
+    fn adt_3() -> Foo<braced_braced_ident!()> { loop {} }
+    fn adt_4() -> Foo<{ unbraced_unbraced_ident!() }> { loop {} }
+    fn adt_5() -> Foo<{ braced_unbraced_ident!() }> { loop {} }
+    fn adt_6() -> Foo<{ unbraced_braced_ident!() }> { loop {} }
+    fn adt_7() -> Foo<{ braced_braced_ident!() }> { loop {} }
+    fn adt_8() -> Foo<unbraced_ident!()> { loop {} }
+    fn adt_9() -> Foo<braced_ident!()> { loop {} }
+    fn adt_10() -> Foo<{ unbraced_ident!() }> { loop {} }
+    fn adt_11() -> Foo<{ braced_ident!() }> { loop {} }
+
+    // An ADT where the expanded result is a `Res::ConstParam`
+    fn adt_12<const ident: usize>() -> Foo<unbraced_unbraced_ident!()> { loop {} }
+    fn adt_13<const ident: usize>() -> Foo<braced_unbraced_ident!()> { loop {} }
+    fn adt_14<const ident: usize>() -> Foo<unbraced_braced_ident!()> { loop {} }
+    fn adt_15<const ident: usize>() -> Foo<braced_braced_ident!()> { loop {} }
+    fn adt_16<const ident: usize>() -> Foo<{ unbraced_unbraced_ident!() }> { loop {} }
+    fn adt_17<const ident: usize>() -> Foo<{ braced_unbraced_ident!() }> { loop {} }
+    fn adt_18<const ident: usize>() -> Foo<{ unbraced_braced_ident!() }> { loop {} }
+    fn adt_19<const ident: usize>() -> Foo<{ braced_braced_ident!() }> { loop {} }
+    fn adt_20<const ident: usize>() -> Foo<unbraced_ident!()> { loop {} }
+    fn adt_21<const ident: usize>() -> Foo<braced_ident!()> { loop {} }
+    fn adt_22<const ident: usize>() -> Foo<{ unbraced_ident!() }> { loop {} }
+    fn adt_23<const ident: usize>() -> Foo<{ braced_ident!() }> { loop {} }
+
+    // An ADT where the expanded result is a complex expr
+    fn array_24() -> Foo<unbraced_unbraced_expr!()> { loop {} }
+    fn array_25() -> Foo<braced_unbraced_expr!()> { loop {} }
+    fn array_26() -> Foo<unbraced_braced_expr!()> { loop {} }
+    fn array_27() -> Foo<braced_braced_expr!()> { loop {} }
+    fn array_28() -> Foo<{ unbraced_unbraced_expr!() }> { loop {} }
+    fn array_29() -> Foo<{ braced_unbraced_expr!() }> { loop {} }
+    fn array_30() -> Foo<{ unbraced_braced_expr!() }> { loop {} }
+    fn array_31() -> Foo<{ braced_braced_expr!() }> { loop {} }
+    fn array_32() -> Foo<unbraced_expr!()> { loop {} }
+    fn array_33() -> Foo<braced_expr!()> { loop {} }
+    fn array_34() -> Foo<{ unbraced_expr!() }> { loop {} }
+    fn array_35() -> Foo<{ braced_expr!() }> { loop {} }
+}
+
+#[rustfmt::skip]
+mod adt_brace_call {
+    use super::Foo;
+
+    // An ADT where the expanded result is a `Res::Err`
+    fn adt_0() -> Foo<unbraced_unbraced_ident!{}> { loop {} }
+    fn adt_1() -> Foo<braced_unbraced_ident!{}> { loop {} }
+    fn adt_2() -> Foo<unbraced_braced_ident!{}> { loop {} }
+    fn adt_3() -> Foo<braced_braced_ident!{}> { loop {} }
+    fn adt_4() -> Foo<{ unbraced_unbraced_ident!{} }> { loop {} }
+    fn adt_5() -> Foo<{ braced_unbraced_ident!{} }> { loop {} }
+    fn adt_6() -> Foo<{ unbraced_braced_ident!{} }> { loop {} }
+    fn adt_7() -> Foo<{ braced_braced_ident!{} }> { loop {} }
+    fn adt_8() -> Foo<unbraced_ident!{}> { loop {} }
+    fn adt_9() -> Foo<braced_ident!{}> { loop {} }
+    fn adt_10() -> Foo<{ unbraced_ident!{} }> { loop {} }
+    fn adt_11() -> Foo<{ braced_ident!{} }> { loop {} }
+
+    // An ADT where the expanded result is a `Res::ConstParam`
+    fn adt_12<const ident: usize>() -> Foo<unbraced_unbraced_ident!{}> { loop {} }
+    fn adt_13<const ident: usize>() -> Foo<braced_unbraced_ident!{}> { loop {} }
+    fn adt_14<const ident: usize>() -> Foo<unbraced_braced_ident!{}> { loop {} }
+    fn adt_15<const ident: usize>() -> Foo<braced_braced_ident!{}> { loop {} }
+    fn adt_16<const ident: usize>() -> Foo<{ unbraced_unbraced_ident!{} }> { loop {} }
+    fn adt_17<const ident: usize>() -> Foo<{ braced_unbraced_ident!{} }> { loop {} }
+    fn adt_18<const ident: usize>() -> Foo<{ unbraced_braced_ident!{} }> { loop {} }
+    fn adt_19<const ident: usize>() -> Foo<{ braced_braced_ident!{} }> { loop {} }
+    fn adt_20<const ident: usize>() -> Foo<unbraced_ident!{}> { loop {} }
+    fn adt_21<const ident: usize>() -> Foo<braced_ident!{}> { loop {} }
+    fn adt_22<const ident: usize>() -> Foo<{ unbraced_ident!{} }> { loop {} }
+    fn adt_23<const ident: usize>() -> Foo<{ braced_ident!{} }> { loop {} }
+
+    // An ADT where the expanded result is a complex expr
+    fn array_24() -> Foo<unbraced_unbraced_expr!{}> { loop {} }
+    fn array_25() -> Foo<braced_unbraced_expr!{}> { loop {} }
+    fn array_26() -> Foo<unbraced_braced_expr!{}> { loop {} }
+    fn array_27() -> Foo<braced_braced_expr!{}> { loop {} }
+    fn array_28() -> Foo<{ unbraced_unbraced_expr!{} }> { loop {} }
+    fn array_29() -> Foo<{ braced_unbraced_expr!{} }> { loop {} }
+    fn array_30() -> Foo<{ unbraced_braced_expr!{} }> { loop {} }
+    fn array_31() -> Foo<{ braced_braced_expr!{} }> { loop {} }
+    fn array_32() -> Foo<unbraced_expr!{}> { loop {} }
+    fn array_33() -> Foo<braced_expr!{}> { loop {} }
+    fn array_34() -> Foo<{ unbraced_expr!{} }> { loop {} }
+    fn array_35() -> Foo<{ braced_expr!{} }> { loop {} }
+}
+
+#[rustfmt::skip]
+mod adt_square_call {
+    use super::Foo;
+
+    // An ADT where the expanded result is a `Res::Err`
+    fn adt_0() -> Foo<unbraced_unbraced_ident![]> { loop {} }
+    fn adt_1() -> Foo<braced_unbraced_ident![]> { loop {} }
+    fn adt_2() -> Foo<unbraced_braced_ident![]> { loop {} }
+    fn adt_3() -> Foo<braced_braced_ident![]> { loop {} }
+    fn adt_4() -> Foo<{ unbraced_unbraced_ident![] }> { loop {} }
+    fn adt_5() -> Foo<{ braced_unbraced_ident![] }> { loop {} }
+    fn adt_6() -> Foo<{ unbraced_braced_ident![] }> { loop {} }
+    fn adt_7() -> Foo<{ braced_braced_ident![] }> { loop {} }
+    fn adt_8() -> Foo<unbraced_ident![]> { loop {} }
+    fn adt_9() -> Foo<braced_ident![]> { loop {} }
+    fn adt_10() -> Foo<{ unbraced_ident![] }> { loop {} }
+    fn adt_11() -> Foo<{ braced_ident![] }> { loop {} }
+
+    // An ADT where the expanded result is a `Res::ConstParam`
+    fn adt_12<const ident: usize>() -> Foo<unbraced_unbraced_ident![]> { loop {} }
+    fn adt_13<const ident: usize>() -> Foo<braced_unbraced_ident![]> { loop {} }
+    fn adt_14<const ident: usize>() -> Foo<unbraced_braced_ident![]> { loop {} }
+    fn adt_15<const ident: usize>() -> Foo<braced_braced_ident![]> { loop {} }
+    fn adt_16<const ident: usize>() -> Foo<{ unbraced_unbraced_ident![] }> { loop {} }
+    fn adt_17<const ident: usize>() -> Foo<{ braced_unbraced_ident![] }> { loop {} }
+    fn adt_18<const ident: usize>() -> Foo<{ unbraced_braced_ident![] }> { loop {} }
+    fn adt_19<const ident: usize>() -> Foo<{ braced_braced_ident![] }> { loop {} }
+    fn adt_20<const ident: usize>() -> Foo<unbraced_ident![]> { loop {} }
+    fn adt_21<const ident: usize>() -> Foo<braced_ident![]> { loop {} }
+    fn adt_22<const ident: usize>() -> Foo<{ unbraced_ident![] }> { loop {} }
+    fn adt_23<const ident: usize>() -> Foo<{ braced_ident![] }> { loop {} }
+
+    // An ADT where the expanded result is a complex expr
+    fn array_24() -> Foo<unbraced_unbraced_expr![]> { loop {} }
+    fn array_25() -> Foo<braced_unbraced_expr![]> { loop {} }
+    fn array_26() -> Foo<unbraced_braced_expr![]> { loop {} }
+    fn array_27() -> Foo<braced_braced_expr![]> { loop {} }
+    fn array_28() -> Foo<{ unbraced_unbraced_expr![] }> { loop {} }
+    fn array_29() -> Foo<{ braced_unbraced_expr![] }> { loop {} }
+    fn array_30() -> Foo<{ unbraced_braced_expr![] }> { loop {} }
+    fn array_31() -> Foo<{ braced_braced_expr![] }> { loop {} }
+    fn array_32() -> Foo<unbraced_expr![]> { loop {} }
+    fn array_33() -> Foo<braced_expr![]> { loop {} }
+    fn array_34() -> Foo<{ unbraced_expr![] }> { loop {} }
+    fn array_35() -> Foo<{ braced_expr![] }> { loop {} }
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.rs b/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.rs
new file mode 100644
index 00000000000..346ef64a8a6
--- /dev/null
+++ b/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.rs
@@ -0,0 +1,21 @@
+// Regression test for #132955 checking that we handle anon consts with
+// inference variables in their generic arguments correctly.
+//
+// This arose via diagnostics where we would have some failing goal such
+// as `[u8; AnonConst<Self>]: PartialEq<Self::A>`, then as part of diagnostics
+// we would replace all generic parameters with inference vars which would yield
+// a self type of `[u8; AnonConst<?x>]` and then attempt to normalize `AnonConst<?x>`.
+
+pub trait T {
+    type A;
+    const P: Self::A;
+
+    fn a() {
+        [0u8; std::mem::size_of::<Self::A>()] == Self::P;
+        //~^ ERROR: can't compare
+        //~| ERROR: constant expression depends on a generic parameter
+        //~| ERROR: constant expression depends on a generic parameter
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.stderr b/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.stderr
new file mode 100644
index 00000000000..12de4f1dc30
--- /dev/null
+++ b/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.stderr
@@ -0,0 +1,31 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:15
+   |
+LL |         [0u8; std::mem::size_of::<Self::A>()] == Self::P;
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error: constant expression depends on a generic parameter
+  --> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47
+   |
+LL |         [0u8; std::mem::size_of::<Self::A>()] == Self::P;
+   |                                               ^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
+error[E0277]: can't compare `[u8; std::mem::size_of::<Self::A>()]` with `<Self as T>::A`
+  --> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47
+   |
+LL |         [0u8; std::mem::size_of::<Self::A>()] == Self::P;
+   |                                               ^^ no implementation for `[u8; std::mem::size_of::<Self::A>()] == <Self as T>::A`
+   |
+   = help: the trait `PartialEq<<Self as T>::A>` is not implemented for `[u8; std::mem::size_of::<Self::A>()]`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | pub trait T where [u8; std::mem::size_of::<Self::A>()]: PartialEq<<Self as T>::A> {
+   |             +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs
deleted file mode 100644
index 6c0ac639612..00000000000
--- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-//@ known-bug: #110395
-//@ compile-flags: -Znext-solver
-#![feature(generic_const_exprs, adt_const_params, const_trait_impl)]
-#![allow(incomplete_features)]
-
-// test `N + N` unifies with explicit function calls for non-builtin-types
-#[derive(PartialEq, Eq)]
-struct Foo(u8);
-
-impl const std::ops::Add for Foo {
-    type Output = Self;
-
-    fn add(self, rhs: Self) -> Self::Output {
-        self
-    }
-}
-
-struct Evaluatable<const N: Foo>;
-
-fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
-    bar::<{ std::ops::Add::add(N, N) }>();
-}
-
-fn bar<const N: Foo>() {}
-
-// test that `N + N` unifies with explicit function calls for builin-types
-struct Evaluatable2<const N: usize>;
-
-fn foo2<const N: usize>(a: Evaluatable2<{ N + N }>) {
-    bar2::<{ std::ops::Add::add(N, N) }>();
-    // FIXME(generic_const_exprs) make this not an error
-}
-
-fn bar2<const N: usize>() {}
-
-fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
deleted file mode 100644
index 882fdf0b228..00000000000
--- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr
+++ /dev/null
@@ -1,93 +0,0 @@
-error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
-  --> $DIR/unify-op-with-fn-call.rs:3:12
-   |
-LL | #![feature(generic_const_exprs, adt_const_params, const_trait_impl)]
-   |            ^^^^^^^^^^^^^^^^^^^
-   |
-   = help: remove one of these features
-
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/unify-op-with-fn-call.rs:10:12
-   |
-LL | impl const std::ops::Add for Foo {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
-  --> $DIR/unify-op-with-fn-call.rs:18:29
-   |
-LL | struct Evaluatable<const N: Foo>;
-   |                             ^^^
-   |
-help: add `#[derive(ConstParamTy)]` to the struct
-   |
-LL + #[derive(ConstParamTy)]
-LL | struct Foo(u8);
-   |
-
-error[E0015]: cannot call non-const operator in constants
-  --> $DIR/unify-op-with-fn-call.rs:20:39
-   |
-LL | fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
-   |                                       ^^^^^
-   |
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
-
-error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
-  --> $DIR/unify-op-with-fn-call.rs:20:17
-   |
-LL | fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
-   |                 ^^^
-   |
-help: add `#[derive(ConstParamTy)]` to the struct
-   |
-LL + #[derive(ConstParamTy)]
-LL | struct Foo(u8);
-   |
-
-error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
-  --> $DIR/unify-op-with-fn-call.rs:24:17
-   |
-LL | fn bar<const N: Foo>() {}
-   |                 ^^^
-   |
-help: add `#[derive(ConstParamTy)]` to the struct
-   |
-LL + #[derive(ConstParamTy)]
-LL | struct Foo(u8);
-   |
-
-error[E0284]: type annotations needed: cannot normalize `foo2<N>::{constant#0}`
-  --> $DIR/unify-op-with-fn-call.rs:29:28
-   |
-LL | fn foo2<const N: usize>(a: Evaluatable2<{ N + N }>) {
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2<N>::{constant#0}`
-
-error[E0015]: cannot call non-const fn `<Foo as Add>::add` in constants
-  --> $DIR/unify-op-with-fn-call.rs:21:13
-   |
-LL |     bar::<{ std::ops::Add::add(N, N) }>();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
-
-error[E0015]: cannot call non-const fn `<usize as Add>::add` in constants
-  --> $DIR/unify-op-with-fn-call.rs:30:14
-   |
-LL |     bar2::<{ std::ops::Add::add(N, N) }>();
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
-
-error[E0284]: type annotations needed: cannot normalize `foo2<N>::{constant#0}`
-  --> $DIR/unify-op-with-fn-call.rs:30:12
-   |
-LL |     bar2::<{ std::ops::Add::add(N, N) }>();
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2<N>::{constant#0}`
-
-error: aborting due to 10 previous errors
-
-Some errors have detailed explanations: E0015, E0284, E0741.
-For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/const-pattern-irrefutable.rs b/tests/ui/consts/const-pattern-irrefutable.rs
index 61bdf57ffdb..759d2e8b2ed 100644
--- a/tests/ui/consts/const-pattern-irrefutable.rs
+++ b/tests/ui/consts/const-pattern-irrefutable.rs
@@ -1,28 +1,43 @@
 mod foo {
     pub const b: u8 = 2;
-    pub const d: u8 = 2;
+    //~^ missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable
+    pub const d: (u8, u8) = (2, 1);
+    //~^ missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
 }
 
 use foo::b as c;
 use foo::d;
 
 const a: u8 = 2;
+//~^ missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
+
+#[derive(PartialEq)]
+struct S {
+    foo: u8,
+}
+
+const e: S = S {
+    foo: 0,
+};
 
 fn main() {
     let a = 4;
     //~^ ERROR refutable pattern in local binding
     //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
-    //~| missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
     //~| HELP introduce a variable instead
     let c = 4;
     //~^ ERROR refutable pattern in local binding
     //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
-    //~| missing patterns are not covered because `c` is interpreted as a constant pattern, not a new variable
     //~| HELP introduce a variable instead
-    let d = 4;
+    let d = (4, 4);
     //~^ ERROR refutable pattern in local binding
-    //~| patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
-    //~| missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
+    //~| patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered
+    //~| HELP introduce a variable instead
+    let e = S {
+    //~^ ERROR refutable pattern in local binding
+    //~| pattern `S { foo: 1_u8..=u8::MAX }` not covered
     //~| HELP introduce a variable instead
+        foo: 1,
+    };
     fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115).
 }
diff --git a/tests/ui/consts/const-pattern-irrefutable.stderr b/tests/ui/consts/const-pattern-irrefutable.stderr
index 2aed68bdd64..afb67a3a118 100644
--- a/tests/ui/consts/const-pattern-irrefutable.stderr
+++ b/tests/ui/consts/const-pattern-irrefutable.stderr
@@ -1,45 +1,76 @@
 error[E0005]: refutable pattern in local binding
-  --> $DIR/const-pattern-irrefutable.rs:12:9
+  --> $DIR/const-pattern-irrefutable.rs:24:9
    |
+LL | const a: u8 = 2;
+   | ----------- missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
+...
 LL |     let a = 4;
-   |         ^
-   |         |
-   |         patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
-   |         missing patterns are not covered because `a` is interpreted as a constant pattern, not a new variable
-   |         help: introduce a variable instead: `a_var`
+   |         ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `u8`
+help: introduce a variable instead
+   |
+LL |     let a_var = 4;
+   |         ~~~~~
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/const-pattern-irrefutable.rs:17:9
+  --> $DIR/const-pattern-irrefutable.rs:28:9
    |
+LL |     pub const b: u8 = 2;
+   |     --------------- missing patterns are not covered because `b` is interpreted as a constant pattern, not a new variable
+...
 LL |     let c = 4;
-   |         ^
-   |         |
-   |         patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
-   |         missing patterns are not covered because `c` is interpreted as a constant pattern, not a new variable
-   |         help: introduce a variable instead: `c_var`
+   |         ^ patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `u8`
+help: introduce a variable instead
+   |
+LL |     let b_var = 4;
+   |         ~~~~~
 
 error[E0005]: refutable pattern in local binding
-  --> $DIR/const-pattern-irrefutable.rs:22:9
+  --> $DIR/const-pattern-irrefutable.rs:32:9
    |
-LL |     let d = 4;
-   |         ^
-   |         |
-   |         patterns `0_u8..=1_u8` and `3_u8..=u8::MAX` not covered
-   |         missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
-   |         help: introduce a variable instead: `d_var`
+LL |     pub const d: (u8, u8) = (2, 1);
+   |     --------------------- missing patterns are not covered because `d` is interpreted as a constant pattern, not a new variable
+...
+LL |     let d = (4, 4);
+   |         ^ patterns `(0_u8..=1_u8, _)` and `(3_u8..=u8::MAX, _)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
-   = note: the matched value is of type `u8`
+   = note: the matched value is of type `(u8, u8)`
+help: introduce a variable instead
+   |
+LL |     let d_var = (4, 4);
+   |         ~~~~~
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/const-pattern-irrefutable.rs:36:9
+   |
+LL | const e: S = S {
+   | ---------- missing patterns are not covered because `e` is interpreted as a constant pattern, not a new variable
+...
+LL |     let e = S {
+   |         ^ pattern `S { foo: 1_u8..=u8::MAX }` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+note: `S` defined here
+  --> $DIR/const-pattern-irrefutable.rs:15:8
+   |
+LL | struct S {
+   |        ^
+   = note: the matched value is of type `S`
+help: introduce a variable instead
+   |
+LL |     let e_var = S {
+   |         ~~~~~
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0005`.
diff --git a/tests/ui/consts/const-unstable-intrinsic.rs b/tests/ui/consts/const-unstable-intrinsic.rs
index 56b552b6a3f..8b38067e46e 100644
--- a/tests/ui/consts/const-unstable-intrinsic.rs
+++ b/tests/ui/consts/const-unstable-intrinsic.rs
@@ -16,13 +16,13 @@ const fn const_main() {
     unsafe {
         unstable_intrinsic::size_of_val(&x);
         //~^ERROR: unstable library feature `unstable`
-        //~|ERROR: cannot be (indirectly) exposed to stable
+        //~|ERROR: not yet stable as a const intrinsic
         unstable_intrinsic::min_align_of_val(&x);
         //~^ERROR: unstable library feature `unstable`
         //~|ERROR: not yet stable as a const intrinsic
 
         size_of_val(&x);
-        //~^ERROR: cannot be (indirectly) exposed to stable
+        //~^ERROR: cannot use `#[feature(local)]`
         min_align_of_val(&x);
         //~^ERROR: cannot use `#[feature(local)]`
     }
@@ -59,6 +59,6 @@ mod fallback {
     #[rustc_intrinsic]
     const unsafe fn copy<T>(src: *const T, _dst: *mut T, _count: usize) {
         super::size_of_val(src);
-        //~^ ERROR cannot be (indirectly) exposed to stable
+        //~^ ERROR cannot use `#[feature(local)]`
     }
 }
diff --git a/tests/ui/consts/const-unstable-intrinsic.stderr b/tests/ui/consts/const-unstable-intrinsic.stderr
index 3e605f3d003..8b61b0904a9 100644
--- a/tests/ui/consts/const-unstable-intrinsic.stderr
+++ b/tests/ui/consts/const-unstable-intrinsic.stderr
@@ -18,13 +18,13 @@ LL |         unstable_intrinsic::min_align_of_val(&x);
    = help: add `#![feature(unstable)]` 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: intrinsic `unstable_intrinsic::size_of_val` cannot be (indirectly) exposed to stable
+error: `size_of_val` is not yet stable as a const intrinsic
   --> $DIR/const-unstable-intrinsic.rs:17:9
    |
 LL |         unstable_intrinsic::size_of_val(&x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
 
 error: `min_align_of_val` is not yet stable as a const intrinsic
   --> $DIR/const-unstable-intrinsic.rs:20:9
@@ -34,13 +34,22 @@ LL |         unstable_intrinsic::min_align_of_val(&x);
    |
    = help: add `#![feature(unstable)]` to the crate attributes to enable
 
-error: intrinsic `size_of_val` cannot be (indirectly) exposed to stable
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local)]`
   --> $DIR/const-unstable-intrinsic.rs:24:9
    |
 LL |         size_of_val(&x);
    |         ^^^^^^^^^^^^^^^
    |
-   = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn const_main() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(local)]
+LL | const fn const_main() {
+   |
 
 error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local)]`
   --> $DIR/const-unstable-intrinsic.rs:26:9
@@ -67,13 +76,22 @@ LL |     unsafe { copy(src, dst, count) }
    |
    = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
 
-error: intrinsic `size_of_val` cannot be (indirectly) exposed to stable
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(local)]`
   --> $DIR/const-unstable-intrinsic.rs:61:9
    |
 LL |         super::size_of_val(src);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_const_stable_intrinsic]` (but this requires team approval)
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL +     #[rustc_const_unstable(feature = "...", issue = "...")]
+LL |     const unsafe fn copy<T>(src: *const T, _dst: *mut T, _count: usize) {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL +     #[rustc_allow_const_fn_unstable(local)]
+LL |     const unsafe fn copy<T>(src: *const T, _dst: *mut T, _count: usize) {
+   |
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/consts/const_in_pattern/incomplete-slice.stderr b/tests/ui/consts/const_in_pattern/incomplete-slice.stderr
index bd61f43727b..c73d1f05900 100644
--- a/tests/ui/consts/const_in_pattern/incomplete-slice.stderr
+++ b/tests/ui/consts/const_in_pattern/incomplete-slice.stderr
@@ -3,8 +3,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
    |
 LL |     match &[][..] {
    |           ^^^^^^^ patterns `&[]` and `&[_, _, ..]` not covered
+LL |
+LL |         E_SL => {}
+   |         ---- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `E_SL`
    |
    = note: the matched value is of type `&[E]`
+note: constant `E_SL` defined here
+  --> $DIR/incomplete-slice.rs:6:1
+   |
+LL | const E_SL: &[E] = &[E::A];
+   | ^^^^^^^^^^^^^^^^
+help: if you meant to introduce a binding, use a different name
+   |
+LL |         E_SL_var => {}
+   |             ++++
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~         E_SL => {},
diff --git a/tests/ui/consts/min_const_fn/auxiliary/unmarked_const_fn_crate.rs b/tests/ui/consts/min_const_fn/auxiliary/unmarked_const_fn_crate.rs
new file mode 100644
index 00000000000..aec92c5ae16
--- /dev/null
+++ b/tests/ui/consts/min_const_fn/auxiliary/unmarked_const_fn_crate.rs
@@ -0,0 +1 @@
+pub const fn just_a_fn() {}
diff --git a/tests/ui/consts/min_const_fn/auxiliary/unstable_if_unmarked_const_fn_crate.rs b/tests/ui/consts/min_const_fn/auxiliary/unstable_if_unmarked_const_fn_crate.rs
new file mode 100644
index 00000000000..f102902fce3
--- /dev/null
+++ b/tests/ui/consts/min_const_fn/auxiliary/unstable_if_unmarked_const_fn_crate.rs
@@ -0,0 +1,8 @@
+//@ compile-flags: -Zforce-unstable-if-unmarked
+
+#![feature(rustc_attrs)]
+
+pub const fn not_stably_const() {}
+
+#[rustc_const_stable_indirect]
+pub const fn expose_on_stable() {}
diff --git a/tests/ui/consts/min_const_fn/recursive_const_stab_unmarked_crate_imports.rs b/tests/ui/consts/min_const_fn/recursive_const_stab_unmarked_crate_imports.rs
new file mode 100644
index 00000000000..06ce406fd89
--- /dev/null
+++ b/tests/ui/consts/min_const_fn/recursive_const_stab_unmarked_crate_imports.rs
@@ -0,0 +1,21 @@
+//@ aux-build:unstable_if_unmarked_const_fn_crate.rs
+//@ aux-build:unmarked_const_fn_crate.rs
+#![feature(staged_api, rustc_private)]
+#![stable(since = "1.0.0", feature = "stable")]
+
+extern crate unmarked_const_fn_crate;
+extern crate unstable_if_unmarked_const_fn_crate;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+const fn stable_fn() {
+    // This one is fine.
+    unstable_if_unmarked_const_fn_crate::expose_on_stable();
+    // This one is not.
+    unstable_if_unmarked_const_fn_crate::not_stably_const();
+    //~^ERROR: cannot use `#[feature(rustc_private)]`
+    unmarked_const_fn_crate::just_a_fn();
+    //~^ERROR: cannot be (indirectly) exposed to stable
+}
+
+fn main() {}
diff --git a/tests/ui/consts/min_const_fn/recursive_const_stab_unmarked_crate_imports.stderr b/tests/ui/consts/min_const_fn/recursive_const_stab_unmarked_crate_imports.stderr
new file mode 100644
index 00000000000..a655c0faab6
--- /dev/null
+++ b/tests/ui/consts/min_const_fn/recursive_const_stab_unmarked_crate_imports.stderr
@@ -0,0 +1,28 @@
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(rustc_private)]`
+  --> $DIR/recursive_const_stab_unmarked_crate_imports.rs:15:5
+   |
+LL |     unstable_if_unmarked_const_fn_crate::not_stably_const();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
+help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | const fn stable_fn() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(rustc_private)]
+LL | const fn stable_fn() {
+   |
+
+error: `just_a_fn` cannot be (indirectly) exposed to stable
+  --> $DIR/recursive_const_stab_unmarked_crate_imports.rs:17:5
+   |
+LL |     unmarked_const_fn_crate::just_a_fn();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/consts/min_const_fn/recursive_const_stab_unstable_if_unmarked.rs b/tests/ui/consts/min_const_fn/recursive_const_stab_unstable_if_unmarked.rs
new file mode 100644
index 00000000000..429fa060521
--- /dev/null
+++ b/tests/ui/consts/min_const_fn/recursive_const_stab_unstable_if_unmarked.rs
@@ -0,0 +1,24 @@
+//@ compile-flags: -Zforce-unstable-if-unmarked
+//@ edition: 2021
+#![feature(const_async_blocks, rustc_attrs)]
+
+pub const fn not_stably_const() {
+    // We need to do something const-unstable here.
+    // For now we use `async`, eventually we might have to add a auxiliary crate
+    // as a dependency just to be sure we have something const-unstable.
+    let _x = async { 15 };
+}
+
+#[rustc_const_stable_indirect]
+pub const fn expose_on_stable() {
+    // Calling `not_stably_const` here is *not* okay.
+    not_stably_const();
+    //~^ERROR: cannot use `#[feature(rustc_private)]`
+    // Also directly using const-unstable things is not okay.
+    let _x = async { 15 };
+    //~^ERROR: cannot use `#[feature(const_async_blocks)]`
+}
+
+fn main() {
+    const { expose_on_stable() };
+}
diff --git a/tests/ui/consts/min_const_fn/recursive_const_stab_unstable_if_unmarked.stderr b/tests/ui/consts/min_const_fn/recursive_const_stab_unstable_if_unmarked.stderr
new file mode 100644
index 00000000000..d4ba0f9df2d
--- /dev/null
+++ b/tests/ui/consts/min_const_fn/recursive_const_stab_unstable_if_unmarked.stderr
@@ -0,0 +1,37 @@
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(rustc_private)]`
+  --> $DIR/recursive_const_stab_unstable_if_unmarked.rs:15:5
+   |
+LL |     not_stably_const();
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+   = help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
+help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | pub const fn expose_on_stable() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(rustc_private)]
+LL | pub const fn expose_on_stable() {
+   |
+
+error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_async_blocks)]`
+  --> $DIR/recursive_const_stab_unstable_if_unmarked.rs:18:14
+   |
+LL |     let _x = async { 15 };
+   |              ^^^^^^^^^^^^
+   |
+help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
+   |
+LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+LL | pub const fn expose_on_stable() {
+   |
+help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
+   |
+LL + #[rustc_allow_const_fn_unstable(const_async_blocks)]
+LL | pub const fn expose_on_stable() {
+   |
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/consts/rustc-const-stability-require-const.rs b/tests/ui/consts/rustc-const-stability-require-const.rs
index 6cc3f0f0da1..ad27fcf6cb9 100644
--- a/tests/ui/consts/rustc-const-stability-require-const.rs
+++ b/tests/ui/consts/rustc-const-stability-require-const.rs
@@ -56,9 +56,3 @@ const fn barfoo_unmarked() {}
 #[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")]
 pub const fn barfoo_unstable() {}
 //~^ ERROR can only be applied to functions that are declared `#[stable]`
-
-// `#[rustc_const_stable_indirect]` also requires a const fn
-#[rustc_const_stable_indirect]
-#[unstable(feature = "unstable", issue = "none")]
-pub fn not_a_const_fn() {}
-//~^ ERROR require the function or method to be `const`
diff --git a/tests/ui/consts/rustc-const-stability-require-const.stderr b/tests/ui/consts/rustc-const-stability-require-const.stderr
index d9a7d37cbcd..4b13826584d 100644
--- a/tests/ui/consts/rustc-const-stability-require-const.stderr
+++ b/tests/ui/consts/rustc-const-stability-require-const.stderr
@@ -86,17 +86,5 @@ LL | #[rustc_const_stable(feature = "barfoo_const", since = "1.0.0")]
 LL | pub const fn barfoo_unstable() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const`
-  --> $DIR/rustc-const-stability-require-const.rs:63:1
-   |
-LL | pub fn not_a_const_fn() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: make the function or method const
-  --> $DIR/rustc-const-stability-require-const.rs:63:1
-   |
-LL | pub fn not_a_const_fn() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 9 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/tests/ui/diagnostic-width/E0271.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr
index 31ec3fe366f..e276299e9e8 100644
--- a/tests/ui/diagnostic-width/E0271.stderr
+++ b/tests/ui/diagnostic-width/E0271.ascii.stderr
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ...>>, ...>>, ...> as Future>::Error == Foo`
-  --> $DIR/E0271.rs:18:5
+  --> $DIR/E0271.rs:20:5
    |
 LL | /     Box::new(
 LL | |         Ok::<_, ()>(
@@ -11,7 +11,7 @@ LL | |     )
    | |_____^ type mismatch resolving `<Result<Result<(), Result<Result<(), ...>, ...>>, ...> as Future>::Error == Foo`
    |
 note: expected this to be `Foo`
-  --> $DIR/E0271.rs:8:18
+  --> $DIR/E0271.rs:10:18
    |
 LL |     type Error = E;
    |                  ^
diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs
index d8cb24898ac..ce41ad2952b 100644
--- a/tests/ui/diagnostic-width/E0271.rs
+++ b/tests/ui/diagnostic-width/E0271.rs
@@ -1,4 +1,6 @@
-//@ compile-flags: --diagnostic-width=40
+//@ revisions: ascii unicode
+//@[ascii] compile-flags: --diagnostic-width=40
+//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=40
 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 trait Future {
     type Error;
@@ -15,7 +17,7 @@ impl<T> Future for Option<T> {
 struct Foo;
 
 fn foo() -> Box<dyn Future<Error=Foo>> {
-    Box::new( //~ ERROR E0271
+    Box::new( //[ascii]~ ERROR E0271
         Ok::<_, ()>(
             Err::<(), _>(
                 Ok::<_, ()>(
diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr
new file mode 100644
index 00000000000..4a96ca36cd7
--- /dev/null
+++ b/tests/ui/diagnostic-width/E0271.unicode.stderr
@@ -0,0 +1,22 @@
+error[E0271]: type mismatch resolving `<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ...>>, ...>>, ...> as Future>::Error == Foo`
+   ╭▸ $DIR/E0271.rs:20:5
+   │
+LL │ ┏     Box::new(
+LL │ ┃         Ok::<_, ()>(
+LL │ ┃             Err::<(), _>(
+LL │ ┃                 Ok::<_, ()>(
+   ‡ ┃
+LL │ ┃         )
+LL │ ┃     )
+   │ ┗━━━━━┛ type mismatch resolving `<Result<Result<(), Result<Result<(), ...>, ...>>, ...> as Future>::Error == Foo`
+   ╰╴
+note: expected this to be `Foo`
+   ╭▸ $DIR/E0271.rs:10:18
+   │
+LL │     type Error = E;
+   │                  ━
+   ╰ note: required for the cast from `Box<Result<Result<(), Result<Result<(), Result<Result<(), Option<{integer}>>, ()>>, ()>>, ()>>` to `Box<(dyn Future<Error = Foo> + 'static)>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/diagnostic-width/flag-human.stderr b/tests/ui/diagnostic-width/flag-human.ascii.stderr
index eaa96841080..4593304e087 100644
--- a/tests/ui/diagnostic-width/flag-human.stderr
+++ b/tests/ui/diagnostic-width/flag-human.ascii.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/flag-human.rs:7:17
+  --> $DIR/flag-human.rs:9:17
    |
 LL | ..._: () = 42;
    |       --   ^^ expected `()`, found integer
diff --git a/tests/ui/diagnostic-width/flag-human.rs b/tests/ui/diagnostic-width/flag-human.rs
index a46122ed783..1af41659141 100644
--- a/tests/ui/diagnostic-width/flag-human.rs
+++ b/tests/ui/diagnostic-width/flag-human.rs
@@ -1,9 +1,11 @@
-//@ compile-flags: --diagnostic-width=20
+//@ revisions: ascii unicode
+//@[ascii] compile-flags: --diagnostic-width=20
+//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=20
 
 // This test checks that `-Z output-width` effects the human error output by restricting it to an
 // arbitrarily low value so that the effect is visible.
 
 fn main() {
     let _: () = 42;
-    //~^ ERROR mismatched types
+    //[ascii]~^ ERROR mismatched types
 }
diff --git a/tests/ui/diagnostic-width/flag-human.unicode.stderr b/tests/ui/diagnostic-width/flag-human.unicode.stderr
new file mode 100644
index 00000000000..50176564786
--- /dev/null
+++ b/tests/ui/diagnostic-width/flag-human.unicode.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+   ╭▸ $DIR/flag-human.rs:9:17
+   │
+LL │ …t _: () = 42;
+   │       ┬─   ━━ expected `()`, found integer
+   │       │
+   ╰╴      expected due to this
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/diagnostic-width/long-E0308.stderr b/tests/ui/diagnostic-width/long-E0308.ascii.stderr
index eb37da037e9..d45d6bf329b 100644
--- a/tests/ui/diagnostic-width/long-E0308.stderr
+++ b/tests/ui/diagnostic-width/long-E0308.ascii.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/long-E0308.rs:44:9
+  --> $DIR/long-E0308.rs:46:9
    |
 LL |        let x: Atype<
    |  _____________-
@@ -20,11 +20,11 @@ LL |  |     ))))))))))))))))))))))))))))));
    |
    = note: expected struct `Atype<Btype<..., ...>, ...>`
                 found enum `Result<Result<..., ...>, ...>`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.ascii/long-E0308.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
-  --> $DIR/long-E0308.rs:57:26
+  --> $DIR/long-E0308.rs:59:26
    |
 LL |       ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
    |  __________________________^
@@ -36,11 +36,11 @@ LL | |     ))))))))))))))))))))))));
    |
    = note: expected enum `Option<Result<..., ...>>`
               found enum `Result<Result<..., ...>, ...>`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.ascii/long-E0308.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
-  --> $DIR/long-E0308.rs:88:9
+  --> $DIR/long-E0308.rs:90:9
    |
 LL |       let x: Atype<
    |  ____________-
@@ -56,11 +56,11 @@ LL | |     > = ();
    |
    = note: expected struct `Atype<Btype<..., ...>, ...>`
            found unit type `()`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.ascii/long-E0308.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
-  --> $DIR/long-E0308.rs:91:17
+  --> $DIR/long-E0308.rs:93:17
    |
 LL |       let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
    |  ____________--___^
@@ -74,7 +74,7 @@ LL | |     ))))))))))))))))))))))));
    |
    = note: expected unit type `()`
                    found enum `Result<Result<..., ...>, ...>`
-   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308/long-E0308.long-type-hash.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.ascii/long-E0308.long-type-hash.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs
index 150164ba21b..73f81f5872a 100644
--- a/tests/ui/diagnostic-width/long-E0308.rs
+++ b/tests/ui/diagnostic-width/long-E0308.rs
@@ -1,4 +1,6 @@
-//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
+//@ revisions: ascii unicode
+//@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
+//@[unicode] compile-flags: -Zunstable-options=yes --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 
 mod a {
diff --git a/tests/ui/diagnostic-width/long-E0308.unicode.stderr b/tests/ui/diagnostic-width/long-E0308.unicode.stderr
new file mode 100644
index 00000000000..3e8d881d7a6
--- /dev/null
+++ b/tests/ui/diagnostic-width/long-E0308.unicode.stderr
@@ -0,0 +1,82 @@
+error[E0308]: mismatched types
+   ╭▸ $DIR/long-E0308.rs:46:9
+   │
+LL │        let x: Atype<
+   │ ┌─────────────┘
+LL │ │        Btype<
+LL │ │          Ctype<
+LL │ │            Atype<
+   ‡ │
+LL │ │        i32
+LL │ │      > = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O…
+   │ │┏━━━━━│━━━┛
+   │ └┃─────┤
+   │  ┃     expected due to this
+LL │  ┃         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O…
+LL │  ┃             Ok("")
+LL │  ┃         ))))))))))))))))))))))))))))))
+LL │  ┃     ))))))))))))))))))))))))))))));
+   │  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Atype<Btype<..., ...>, ...>`, found `Result<Result<..., ...>, ...>`
+   │
+   ├ note: expected struct `Atype<Btype<..., ...>, ...>`
+   │            found enum `Result<Result<..., ...>, ...>`
+   ├ note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.unicode/long-E0308.long-type-hash.txt'
+   ╰ note: consider using `--verbose` to print the full type name to the console
+
+error[E0308]: mismatched types
+   ╭▸ $DIR/long-E0308.rs:59:26
+   │
+LL │       ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(…
+   │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┛
+LL │ ┃         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok…
+LL │ ┃             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
+LL │ ┃         ))))))))))))))))))))))))))))))
+LL │ ┃     ))))))))))))))))))))))));
+   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `Option<Result<..., ...>>`, found `Result<Result<..., ...>, ...>`
+   │
+   ├ note: expected enum `Option<Result<..., ...>>`
+   │          found enum `Result<Result<..., ...>, ...>`
+   ├ note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.unicode/long-E0308.long-type-hash.txt'
+   ╰ note: consider using `--verbose` to print the full type name to the console
+
+error[E0308]: mismatched types
+   ╭▸ $DIR/long-E0308.rs:90:9
+   │
+LL │       let x: Atype<
+   │ ┌────────────┘
+LL │ │       Btype<
+LL │ │         Ctype<
+LL │ │           Atype<
+   ‡ │
+LL │ │       i32
+LL │ │     > = ();
+   │ │     │   ━━ expected `Atype<Btype<..., ...>, ...>`, found `()`
+   │ └─────┤
+   │       expected due to this
+   │
+   ├ note: expected struct `Atype<Btype<..., ...>, ...>`
+   │       found unit type `()`
+   ├ note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.unicode/long-E0308.long-type-hash.txt'
+   ╰ note: consider using `--verbose` to print the full type name to the console
+
+error[E0308]: mismatched types
+   ╭▸ $DIR/long-E0308.rs:93:17
+   │
+LL │       let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(…
+   │ ┏━━━━━━━━━━━━┬─━━━┛
+   │ ┃            │
+   │ ┃            expected due to this
+LL │ ┃         Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok…
+LL │ ┃             Ok(Ok(Ok(Ok(Ok(Ok(Ok("")))))))
+LL │ ┃         ))))))))))))))))))))))))))))))
+LL │ ┃     ))))))))))))))))))))))));
+   │ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ expected `()`, found `Result<Result<..., ...>, ...>`
+   │
+   ├ note: expected unit type `()`
+   │               found enum `Result<Result<..., ...>, ...>`
+   ├ note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/long-E0308.unicode/long-E0308.long-type-hash.txt'
+   ╰ note: consider using `--verbose` to print the full type name to the console
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr
index 8f200e15c64..4d8afb6f3ad 100644
--- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.stderr
+++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr
@@ -1,5 +1,5 @@
 error[E0369]: cannot add `&str` to `&str`
-  --> $DIR/non-1-width-unicode-multiline-label.rs:5:260
+  --> $DIR/non-1-width-unicode-multiline-label.rs:7:260
    |
 LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇...࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
    |                                                  -------------- ^ -------------- &str
diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs
index 1989ea88635..61c4b31e03a 100644
--- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs
+++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs
@@ -1,7 +1,9 @@
+//@ revisions: ascii unicode
+//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode
 // ignore-tidy-linelength
 
 fn main() {
     let unicode_is_fun = "؁‱ஹ௸௵꧄.ဪ꧅⸻𒈙𒐫﷽𒌄𒈟𒍼𒁎𒀱𒌧𒅃 𒈓𒍙𒊎𒄡𒅌𒁏𒀰𒐪𒐩𒈙𒐫𪚥";
     let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
-    //~^ ERROR cannot add `&str` to `&str`
+    //[ascii]~^ ERROR cannot add `&str` to `&str`
 }
diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr
new file mode 100644
index 00000000000..ed8ce770bb7
--- /dev/null
+++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr
@@ -0,0 +1,18 @@
+error[E0369]: cannot add `&str` to `&str`
+   ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:7:260
+   │
+LL │ …ཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉…࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
+   │                                                  ┬───────────── ┯ ────────────── &str
+   │                                                  │              │
+   │                                                  │              `+` cannot be used to concatenate two `&str` strings
+   │                                                  &str
+   │
+   ╰ note: string concatenation requires an owned `String` on the left
+help: create an owned `String` from a string reference
+   ╭╴
+LL │     let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!";
+   ╰╴                                                                                                                                                                                        +++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-2.stderr b/tests/ui/diagnostic-width/non-whitespace-trimming-2.ascii.stderr
index a7d5c0bfb94..70bd149545c 100644
--- a/tests/ui/diagnostic-width/non-whitespace-trimming-2.stderr
+++ b/tests/ui/diagnostic-width/non-whitespace-trimming-2.ascii.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/non-whitespace-trimming-2.rs:4:311
+  --> $DIR/non-whitespace-trimming-2.rs:6:311
    |
 LL | ...13; let _: usize = 14; let _: usize = 15; let _: () = 42; let _: usize = 0; let _: usize = 1; let _: usize = 2; let _: usize = 3; let ...
    |                                                     --   ^^ expected `()`, found integer
diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs
index abd9e189a75..283506bd6c9 100644
--- a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs
+++ b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs
@@ -1,6 +1,8 @@
+//@ revisions: ascii unicode
+//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode
 // ignore-tidy-linelength
 
 fn main() {
     let _: usize = 0; let _: usize = 1; let _: usize = 2; let _: usize = 3; let _: usize = 4; let _: usize = 5; let _: usize = 6; let _: usize = 7; let _: usize = 8; let _: usize = 9; let _: usize = 10; let _: usize = 11; let _: usize = 12; let _: usize = 13; let _: usize = 14; let _: usize = 15; let _: () = 42; let _: usize = 0; let _: usize = 1; let _: usize = 2; let _: usize = 3; let _: usize = 4; let _: usize = 5; let _: usize = 6; let _: usize = 7; let _: usize = 8; let _: usize = 9; let _: usize = 10; let _: usize = 11; let _: usize = 12; let _: usize = 13; let _: usize = 14; let _: usize = 15;
-//~^ ERROR mismatched types
+//[ascii]~^ ERROR mismatched types
 }
diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-2.unicode.stderr b/tests/ui/diagnostic-width/non-whitespace-trimming-2.unicode.stderr
new file mode 100644
index 00000000000..600d196de16
--- /dev/null
+++ b/tests/ui/diagnostic-width/non-whitespace-trimming-2.unicode.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+   ╭▸ $DIR/non-whitespace-trimming-2.rs:6:311
+   │
+LL │ …= 13; let _: usize = 14; let _: usize = 15; let _: () = 42; let _: usize = 0; let _: usize = 1; let _: usize = 2; let _: usize = 3; let _:…
+   │                                                     ┬─   ━━ expected `()`, found integer
+   │                                                     │
+   ╰╴                                                    expected due to this
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.fixed b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
new file mode 100644
index 00000000000..3fed16f0ee7
--- /dev/null
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.fixed
@@ -0,0 +1,52 @@
+//@ revisions: e2021 e2024
+//
+//@[e2021] edition: 2021
+//@[e2024] edition: 2024
+//@[e2024] compile-flags: -Zunstable-options
+//
+//@[e2021] run-pass
+//@[e2021] run-rustfix
+//@[e2024] check-fail
+
+fn main() {
+    m();
+    q();
+    let _ = meow();
+}
+
+fn m() {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    let x: () = match true {
+        true => Default::default(),
+        //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+        false => panic!("..."),
+    };
+
+    dbg!(x);
+}
+
+fn q() -> Option<()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    fn deserialize<T: Default>() -> Option<T> {
+        Some(T::default())
+    }
+
+    deserialize::<()>()?;
+    //[e2024]~^ error: the trait bound `!: Default` is not satisfied
+
+    None
+}
+
+// Make sure we turbofish the right argument
+fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
+    Err(())
+}
+fn meow() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    help::<(), _>(1)?;
+    //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
+    Ok(())
+}
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
index 79eee2a3def..fdc97e54d4e 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
@@ -1,5 +1,5 @@
 warning: this function depends on never type fallback being `()`
-  --> $DIR/never-type-fallback-breaking.rs:15:1
+  --> $DIR/never-type-fallback-breaking.rs:17:1
    |
 LL | fn m() {
    | ^^^^^^
@@ -8,7 +8,7 @@ LL | fn m() {
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
-  --> $DIR/never-type-fallback-breaking.rs:19:17
+  --> $DIR/never-type-fallback-breaking.rs:21:17
    |
 LL |         true => Default::default(),
    |                 ^^^^^^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL |     let x: () = match true {
    |          ++++
 
 warning: this function depends on never type fallback being `()`
-  --> $DIR/never-type-fallback-breaking.rs:27:1
+  --> $DIR/never-type-fallback-breaking.rs:29:1
    |
 LL | fn q() -> Option<()> {
    | ^^^^^^^^^^^^^^^^^^^^
@@ -28,7 +28,7 @@ LL | fn q() -> Option<()> {
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the types explicitly
 note: in edition 2024, the requirement `!: Default` will fail
-  --> $DIR/never-type-fallback-breaking.rs:34:5
+  --> $DIR/never-type-fallback-breaking.rs:36:5
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^
@@ -37,5 +37,24 @@ help: use `()` annotations to avoid fallback changes
 LL |     deserialize::<()>()?;
    |                ++++++
 
-warning: 2 warnings emitted
+warning: this function depends on never type fallback being `()`
+  --> $DIR/never-type-fallback-breaking.rs:46:1
+   |
+LL | fn meow() -> Result<(), ()> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: 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 #123748 <https://github.com/rust-lang/rust/issues/123748>
+   = help: specify the types explicitly
+note: in edition 2024, the requirement `(): From<!>` will fail
+  --> $DIR/never-type-fallback-breaking.rs:49:5
+   |
+LL |     help(1)?;
+   |     ^^^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     help::<(), _>(1)?;
+   |         +++++++++
+
+warning: 3 warnings emitted
 
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
index 461e4ae0bdf..6258247f8b2 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `!: Default` is not satisfied
-  --> $DIR/never-type-fallback-breaking.rs:19:17
+  --> $DIR/never-type-fallback-breaking.rs:21:17
    |
 LL |         true => Default::default(),
    |                 ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@@ -8,7 +8,7 @@ LL |         true => Default::default(),
    = help: did you intend to use the type `()` here instead?
 
 error[E0277]: the trait bound `!: Default` is not satisfied
-  --> $DIR/never-type-fallback-breaking.rs:34:5
+  --> $DIR/never-type-fallback-breaking.rs:36:5
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
@@ -16,11 +16,34 @@ LL |     deserialize()?;
    = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
    = help: did you intend to use the type `()` here instead?
 note: required by a bound in `deserialize`
-  --> $DIR/never-type-fallback-breaking.rs:30:23
+  --> $DIR/never-type-fallback-breaking.rs:32:23
    |
 LL |     fn deserialize<T: Default>() -> Option<T> {
    |                       ^^^^^^^ required by this bound in `deserialize`
 
-error: aborting due to 2 previous errors
+error[E0277]: the trait bound `(): From<!>` is not satisfied
+  --> $DIR/never-type-fallback-breaking.rs:49:5
+   |
+LL |     help(1)?;
+   |     ^^^^^^^ the trait `From<!>` is not implemented for `()`
+   |
+   = help: the following other types implement trait `From<T>`:
+             `(T, T)` implements `From<[T; 2]>`
+             `(T, T, T)` implements `From<[T; 3]>`
+             `(T, T, T, T)` implements `From<[T; 4]>`
+             `(T, T, T, T, T)` implements `From<[T; 5]>`
+             `(T, T, T, T, T, T)` implements `From<[T; 6]>`
+             `(T, T, T, T, T, T, T)` implements `From<[T; 7]>`
+             `(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>`
+             `(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
+           and 4 others
+   = note: required for `!` to implement `Into<()>`
+note: required by a bound in `help`
+  --> $DIR/never-type-fallback-breaking.rs:43:20
+   |
+LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
+   |                    ^^^^^^^^ required by this bound in `help`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs
index 7b4a1b1de04..71d36f3a2d9 100644
--- a/tests/ui/editions/never-type-fallback-breaking.rs
+++ b/tests/ui/editions/never-type-fallback-breaking.rs
@@ -5,11 +5,13 @@
 //@[e2024] compile-flags: -Zunstable-options
 //
 //@[e2021] run-pass
+//@[e2021] run-rustfix
 //@[e2024] check-fail
 
 fn main() {
     m();
     q();
+    let _ = meow();
 }
 
 fn m() {
@@ -36,3 +38,15 @@ fn q() -> Option<()> {
 
     None
 }
+
+// Make sure we turbofish the right argument
+fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
+    Err(())
+}
+fn meow() -> Result<(), ()> {
+    //[e2021]~^ this function depends on never type fallback being `()`
+    //[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    help(1)?;
+    //[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
+    Ok(())
+}
diff --git a/tests/ui/error-emitter/highlighting.svg b/tests/ui/error-emitter/highlighting.svg
index be92c00c19b..a4019c78f48 100644
--- a/tests/ui/error-emitter/highlighting.svg
+++ b/tests/ui/error-emitter/highlighting.svg
@@ -49,7 +49,7 @@
 </tspan>
     <tspan x="10px" y="262px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>   fn query(_: fn(Box&lt;(dyn Any + Send + '_)&gt;) -&gt; Pin&lt;Box&lt;(</tspan>
 </tspan>
-    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-012 bold">____</tspan><tspan class="fg-ansi256-010 bold">^^^^^</tspan><tspan class="fg-ansi256-012 bold">_-</tspan>
+    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold"> ____</tspan><tspan class="fg-ansi256-010 bold">^^^^^</tspan><tspan class="fg-ansi256-012 bold">_-</tspan>
 </tspan>
     <tspan x="10px" y="298px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan>     dyn Future&lt;Output = Result&lt;Box&lt;(dyn Any + 'static)&gt;, String&gt;&gt; + Send + 'static</tspan>
 </tspan>
diff --git a/tests/ui/error-emitter/highlighting.windows.svg b/tests/ui/error-emitter/highlighting.windows.svg
index 152245da9dd..c2378113b86 100644
--- a/tests/ui/error-emitter/highlighting.windows.svg
+++ b/tests/ui/error-emitter/highlighting.windows.svg
@@ -50,7 +50,7 @@
 </tspan>
     <tspan x="10px" y="262px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>   fn query(_: fn(Box&lt;(dyn Any + Send + '_)&gt;) -&gt; Pin&lt;Box&lt;(</tspan>
 </tspan>
-    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>  </tspan><tspan class="fg-ansi256-014 bold">____</tspan><tspan class="fg-ansi256-010 bold">^^^^^</tspan><tspan class="fg-ansi256-014 bold">_-</tspan>
+    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold"> ____</tspan><tspan class="fg-ansi256-010 bold">^^^^^</tspan><tspan class="fg-ansi256-014 bold">_-</tspan>
 </tspan>
     <tspan x="10px" y="298px"><tspan class="fg-ansi256-014 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-014 bold">|</tspan><tspan>     dyn Future&lt;Output = Result&lt;Box&lt;(dyn Any + 'static)&gt;, String&gt;&gt; + Send + 'static</tspan>
 </tspan>
diff --git a/tests/ui/error-emitter/unicode-output.rs b/tests/ui/error-emitter/unicode-output.rs
new file mode 100644
index 00000000000..ba6db37b66c
--- /dev/null
+++ b/tests/ui/error-emitter/unicode-output.rs
@@ -0,0 +1,21 @@
+//@ compile-flags: -Zunstable-options=yes --error-format=human-unicode --color=always
+//@ edition:2018
+//@ only-linux
+
+use core::pin::Pin;
+use core::future::Future;
+use core::any::Any;
+
+fn query(_: fn(Box<(dyn Any + Send + '_)>) -> Pin<Box<(
+    dyn Future<Output = Result<Box<(dyn Any + 'static)>, String>> + Send + 'static
+)>>) {}
+
+fn wrapped_fn<'a>(_: Box<(dyn Any + Send)>) -> Pin<Box<(
+    dyn Future<Output = Result<Box<(dyn Any + 'static)>, String>> + Send + 'static
+)>> {
+    Box::pin(async { Err("nope".into()) })
+}
+
+fn main() {
+    query(wrapped_fn);
+}
diff --git a/tests/ui/error-emitter/unicode-output.svg b/tests/ui/error-emitter/unicode-output.svg
new file mode 100644
index 00000000000..f98fd8b7403
--- /dev/null
+++ b/tests/ui/error-emitter/unicode-output.svg
@@ -0,0 +1,72 @@
+<svg width="785px" height="434px" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    .fg { fill: #AAAAAA }
+    .bg { background: #000000 }
+    .fg-ansi256-009 { fill: #FF5555 }
+    .fg-ansi256-010 { fill: #55FF55 }
+    .fg-ansi256-012 { fill: #5555FF }
+    .fg-magenta { fill: #AA00AA }
+    .container {
+      padding: 0 10px;
+      line-height: 18px;
+    }
+    .bold { font-weight: bold; }
+    tspan {
+      font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
+      white-space: pre;
+      line-height: 18px;
+    }
+  </style>
+
+  <rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
+
+  <text xml:space="preserve" class="container fg">
+    <tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[E0308]</tspan><tspan class="bold">: mismatched types</tspan>
+</tspan>
+    <tspan x="10px" y="46px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold"> ╭▸ </tspan><tspan>$DIR/unicode-output.rs:20:11</tspan>
+</tspan>
+    <tspan x="10px" y="64px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="82px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>     query(wrapped_fn);</tspan>
+</tspan>
+    <tspan x="10px" y="100px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>     </tspan><tspan class="fg-ansi256-012 bold">┬────</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">━━━━━━━━━━</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">one type is more general than the other</tspan>
+</tspan>
+    <tspan x="10px" y="118px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>     </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="136px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>     </tspan><tspan class="fg-ansi256-012 bold">arguments to this function are incorrect</tspan>
+</tspan>
+    <tspan x="10px" y="154px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="172px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰ </tspan><tspan class="bold">note</tspan><tspan>: expected fn pointer `</tspan><tspan class="fg-magenta bold">for&lt;'a&gt; </tspan><tspan>fn(Box&lt;</tspan><tspan class="fg-magenta bold">(dyn Any + Send + 'a)</tspan><tspan>&gt;) -&gt; Pin&lt;_&gt;`</tspan>
+</tspan>
+    <tspan x="10px" y="190px"><tspan>                 found fn item `fn(Box&lt;</tspan><tspan class="fg-magenta bold">(dyn Any + Send + 'static)</tspan><tspan>&gt;) -&gt; Pin&lt;_&gt; {wrapped_fn}`</tspan>
+</tspan>
+    <tspan x="10px" y="208px"><tspan class="fg-ansi256-010 bold">note</tspan><tspan>: function defined here</tspan>
+</tspan>
+    <tspan x="10px" y="226px"><tspan>  </tspan><tspan class="fg-ansi256-012 bold"> ╭▸ </tspan><tspan>$DIR/unicode-output.rs:9:4</tspan>
+</tspan>
+    <tspan x="10px" y="244px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan>
+</tspan>
+    <tspan x="10px" y="262px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>   fn query(_: fn(Box&lt;(dyn Any + Send + '_)&gt;) -&gt; Pin&lt;Box&lt;(</tspan>
+</tspan>
+    <tspan x="10px" y="280px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">┌────</tspan><tspan class="fg-ansi256-010 bold">━━━━━</tspan><tspan class="fg-ansi256-012 bold">─┘</tspan>
+</tspan>
+    <tspan x="10px" y="298px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan>     dyn Future&lt;Output = Result&lt;Box&lt;(dyn Any + 'static)&gt;, String&gt;&gt; + Send + 'static</tspan>
+</tspan>
+    <tspan x="10px" y="316px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">│</tspan><tspan> )&gt;&gt;) {}</tspan>
+</tspan>
+    <tspan x="10px" y="334px"><tspan>   </tspan><tspan class="fg-ansi256-012 bold">╰╴</tspan><tspan class="fg-ansi256-012 bold">└───┘</tspan>
+</tspan>
+    <tspan x="10px" y="352px">
+</tspan>
+    <tspan x="10px" y="370px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="bold">: aborting due to 1 previous error</tspan>
+</tspan>
+    <tspan x="10px" y="388px">
+</tspan>
+    <tspan x="10px" y="406px"><tspan class="bold">For more information about this error, try `rustc --explain E0308`.</tspan>
+</tspan>
+    <tspan x="10px" y="424px">
+</tspan>
+  </text>
+
+</svg>
diff --git a/tests/ui/extern-flag/auxiliary/panic_handler.rs b/tests/ui/extern-flag/auxiliary/panic_handler.rs
index 5ca32fa992b..9140ceed229 100644
--- a/tests/ui/extern-flag/auxiliary/panic_handler.rs
+++ b/tests/ui/extern-flag/auxiliary/panic_handler.rs
@@ -1,14 +1,10 @@
-#![feature(lang_items)]
+#![feature(lang_items, panic_unwind)]
 #![no_std]
 
-// Since `rustc` generally passes `-nodefaultlibs` to the linker,
-// Rust programs link necessary system libraries via `#[link()]`
-// attributes in the `libc` crate. `libc` is a dependency of `std`,
-// but as we are `#![no_std]`, we need to include it manually.
-// Except on windows-msvc.
-#![feature(rustc_private)]
-#[cfg(not(all(windows, target_env = "msvc")))]
-extern crate libc;
+// Since the `unwind` crate is a dependency of the `std` crate, and we have
+// `#![no_std]`, the unwinder is not included in the link command by default.
+// We need to include crate `unwind` manually.
+extern crate unwind;
 
 #[panic_handler]
 pub fn begin_panic_handler(_info: &core::panic::PanicInfo<'_>) -> ! {
diff --git a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr
index 3bb48e4a37a..032d7adf77a 100644
--- a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr
+++ b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr
@@ -8,6 +8,46 @@ LL |     yield true;
    = help: add `#![feature(coroutines)]` 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]: yield syntax is experimental
+  --> $DIR/feature-gate-coroutines.rs:10:16
+   |
+LL |     let _ = || yield true;
+   |                ^^^^^^^^^^
+   |
+   = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
+   = help: add `#![feature(coroutines)]` 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]: yield syntax is experimental
+  --> $DIR/feature-gate-coroutines.rs:18:5
+   |
+LL |     yield;
+   |     ^^^^^
+   |
+   = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
+   = help: add `#![feature(coroutines)]` 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]: yield syntax is experimental
+  --> $DIR/feature-gate-coroutines.rs:19:5
+   |
+LL |     yield 0;
+   |     ^^^^^^^
+   |
+   = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
+   = help: add `#![feature(coroutines)]` 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]: yield syntax is experimental
+  --> $DIR/feature-gate-coroutines.rs:5:5
+   |
+LL |     yield true;
+   |     ^^^^^^^^^^
+   |
+   = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
+   = help: add `#![feature(coroutines)]` 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
   --> $DIR/feature-gate-coroutines.rs:5:5
    |
@@ -46,7 +86,7 @@ error[E0627]: yield expression outside of coroutine literal
 LL |     yield true;
    |     ^^^^^^^^^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0627, E0658.
 For more information about an error, try `rustc --explain E0627`.
diff --git a/tests/ui/feature-gates/feature-gate-coroutines.rs b/tests/ui/feature-gates/feature-gate-coroutines.rs
index 28dce8596d3..a686357d910 100644
--- a/tests/ui/feature-gates/feature-gate-coroutines.rs
+++ b/tests/ui/feature-gates/feature-gate-coroutines.rs
@@ -4,17 +4,17 @@
 fn main() {
     yield true; //~ ERROR yield syntax is experimental
                 //~^ ERROR yield expression outside of coroutine literal
-                //[none]~^^ ERROR yield syntax is experimental
+                //~^^ ERROR yield syntax is experimental
                 //~^^^ ERROR `yield` can only be used
 
     let _ = || yield true; //~ ERROR yield syntax is experimental
-    //[none]~^ ERROR yield syntax is experimental
+    //~^ ERROR yield syntax is experimental
     //~^^ ERROR `yield` can only be used
 }
 
 #[cfg(FALSE)]
 fn foo() {
     // Ok in 2024 edition
-    yield; //[none]~ ERROR yield syntax is experimental
-    yield 0; //[none]~ ERROR yield syntax is experimental
+    yield; //~ ERROR yield syntax is experimental
+    yield 0; //~ ERROR yield syntax is experimental
 }
diff --git a/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs b/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs
index 58306a4cfc9..57d6b591287 100644
--- a/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs
+++ b/tests/ui/feature-gates/feature-gate-rustdoc_internals.rs
@@ -7,4 +7,7 @@ trait Mine {}
 #[doc(fake_variadic)]  //~ ERROR: `#[doc(fake_variadic)]` is meant for internal use only
 impl<T> Mine for (T,) {}
 
+#[doc(search_unbox)]  //~ ERROR: `#[doc(search_unbox)]` is meant for internal use only
+struct Wrap<T> (T);
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr b/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr
index bbb9edd58f0..f3c00a2156b 100644
--- a/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr
+++ b/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr
@@ -18,6 +18,16 @@ LL | #[doc(fake_variadic)]
    = help: add `#![feature(rustdoc_internals)]` 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
+error[E0658]: `#[doc(search_unbox)]` is meant for internal use only
+  --> $DIR/feature-gate-rustdoc_internals.rs:10:1
+   |
+LL | #[doc(search_unbox)]
+   | ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #90418 <https://github.com/rust-lang/rust/issues/90418> for more information
+   = help: add `#![feature(rustdoc_internals)]` 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
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr b/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr
index d599523c727..319056a9c88 100644
--- a/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr
+++ b/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr
@@ -1,31 +1,31 @@
 error: can't mark as unstable using an already stable feature
-  --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1
+  --> $DIR/unstable-attribute-rejects-already-stable-features.rs:6:1
    |
+LL | #[unstable(feature = "arbitrary_enum_discriminant", issue = "42")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable
 LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable
 LL | const fn my_fun() {}
    | -------------------- the stability attribute annotates this item
    |
 help: consider removing the attribute
-  --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1
+  --> $DIR/unstable-attribute-rejects-already-stable-features.rs:6:1
    |
-LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[unstable(feature = "arbitrary_enum_discriminant", issue = "42")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: can't mark as unstable using an already stable feature
-  --> $DIR/unstable-attribute-rejects-already-stable-features.rs:6:1
+  --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1
    |
-LL | #[unstable(feature = "arbitrary_enum_discriminant", issue = "42")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable
 LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable
 LL | const fn my_fun() {}
    | -------------------- the stability attribute annotates this item
    |
 help: consider removing the attribute
-  --> $DIR/unstable-attribute-rejects-already-stable-features.rs:6:1
+  --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1
    |
-LL | #[unstable(feature = "arbitrary_enum_discriminant", issue = "42")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr
index 3697bd9cf02..0f5a9de7ab8 100644
--- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied
-  --> $DIR/candidate-from-env-universe-err-2.rs:15:5
+  --> $DIR/candidate-from-env-universe-err-2.rs:15:15
    |
 LL |     impl_hr::<T>();
-   |     ^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T`
+   |               ^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T`
    |
 note: required by a bound in `impl_hr`
   --> $DIR/candidate-from-env-universe-err-2.rs:12:19
diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.rs b/tests/ui/impl-trait/precise-capturing/migration-note.rs
index a5bade4ddc5..1d98750f6dd 100644
--- a/tests/ui/impl-trait/precise-capturing/migration-note.rs
+++ b/tests/ui/impl-trait/precise-capturing/migration-note.rs
@@ -187,4 +187,19 @@ fn returned() -> impl Sized {
 }
 //~^ NOTE `x` dropped here while still borrowed
 
+fn capture_apit(x: &impl Sized) -> impl Sized {}
+//~^ NOTE you could use a `use<...>` bound to explicitly specify captures, but
+
+fn test_apit() {
+    let x = String::new();
+    //~^ NOTE binding `x` declared here
+    let y = capture_apit(&x);
+    //~^ NOTE borrow of `x` occurs here
+    //~| NOTE this call may capture more lifetimes than intended
+    drop(x);
+    //~^ ERROR cannot move out of `x` because it is borrowed
+    //~| NOTE move out of `x` occurs here
+}
+//~^ NOTE borrow might be used here, when `y` is dropped
+
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr
index 3ac47ed1bcd..a859a114dbc 100644
--- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr
+++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr
@@ -30,7 +30,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |     let a = display_len(&x);
    |             ^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
@@ -55,7 +55,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |     let a = display_len(&x);
    |             ^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
@@ -80,7 +80,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |     let a = display_len(&x);
    |             ^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
@@ -106,7 +106,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |     let a = display_len_mut(&mut x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_len_mut<T>(x: &mut Vec<T>) -> impl Display + use<T> {
    |                                                       ++++++++
@@ -131,7 +131,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |     let a = display_len_mut(&mut x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_len_mut<T>(x: &mut Vec<T>) -> impl Display + use<T> {
    |                                                       ++++++++
@@ -156,7 +156,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |     let a = display_len_mut(&mut x);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_len_mut<T>(x: &mut Vec<T>) -> impl Display + use<T> {
    |                                                       ++++++++
@@ -182,7 +182,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |     let a = display_field(&s.f);
    |             ^^^^^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_field<T: Copy + Display>(t: &T) -> impl Display + use<T> {
    |                                                            ++++++++
@@ -204,7 +204,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |     let a = display_field(&mut s.f);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_field<T: Copy + Display>(t: &T) -> impl Display + use<T> {
    |                                                            ++++++++
@@ -226,7 +226,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |     let a = display_field(&mut s.f);
    |             ^^^^^^^^^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_field<T: Copy + Display>(t: &T) -> impl Display + use<T> {
    |                                                            ++++++++
@@ -252,7 +252,7 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
    |
 LL |         x = display_len(&z.f);
    |             ^^^^^^^^^^^^^^^^^
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
@@ -273,12 +273,46 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has
 LL |     let x = { let x = display_len(&mut vec![0]); x };
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: add a precise capturing bound to avoid overcapturing
+help: use the precise capturing `use<...>` syntax to make the captures explicit
    |
 LL | fn display_len<T>(x: &Vec<T>) -> impl Display + use<T> {
    |                                               ++++++++
 
-error: aborting due to 12 previous errors
+error[E0505]: cannot move out of `x` because it is borrowed
+  --> $DIR/migration-note.rs:199:10
+   |
+LL |     let x = String::new();
+   |         - binding `x` declared here
+LL |
+LL |     let y = capture_apit(&x);
+   |                          -- borrow of `x` occurs here
+...
+LL |     drop(x);
+   |          ^ move out of `x` occurs here
+...
+LL | }
+   | - borrow might be used here, when `y` is dropped and runs the destructor for type `impl Sized`
+   |
+note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
+  --> $DIR/migration-note.rs:196:13
+   |
+LL |     let y = capture_apit(&x);
+   |             ^^^^^^^^^^^^^^^^
+note: you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable
+  --> $DIR/migration-note.rs:190:21
+   |
+LL | fn capture_apit(x: &impl Sized) -> impl Sized {}
+   |                     ^^^^^^^^^^
+help: use the precise capturing `use<...>` syntax to make the captures explicit
+   |
+LL | fn capture_apit<T: Sized>(x: &T) -> impl Sized + use<T> {}
+   |                ++++++++++     ~                ++++++++
+help: consider cloning the value if the performance cost is acceptable
+   |
+LL |     let y = capture_apit(&x.clone());
+   |                            ++++++++
+
+error: aborting due to 13 previous errors
 
 Some errors have detailed explanations: E0499, E0502, E0503, E0505, E0506, E0597, E0716.
 For more information about an error, try `rustc --explain E0499`.
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.fixed b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.fixed
new file mode 100644
index 00000000000..960f2f1bb13
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.fixed
@@ -0,0 +1,13 @@
+//@ run-rustfix
+//@ rustfix-only-machine-applicable
+
+// Make sure that simple overcapture suggestions remain machine applicable.
+
+#![allow(unused)]
+#![deny(impl_trait_overcaptures)]
+
+fn named<'a>(x: &'a i32) -> impl Sized + use<> { *x }
+//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
+
+fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.rs b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.rs
new file mode 100644
index 00000000000..dc9efbf3b95
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.rs
@@ -0,0 +1,13 @@
+//@ run-rustfix
+//@ rustfix-only-machine-applicable
+
+// Make sure that simple overcapture suggestions remain machine applicable.
+
+#![allow(unused)]
+#![deny(impl_trait_overcaptures)]
+
+fn named<'a>(x: &'a i32) -> impl Sized { *x }
+//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
+
+fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.stderr b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.stderr
new file mode 100644
index 00000000000..35fff9ef170
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.stderr
@@ -0,0 +1,26 @@
+error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+  --> $DIR/overcaptures-2024-machine-applicable.rs:9:29
+   |
+LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
+   |                             ^^^^^^^^^^
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+note: specifically, this lifetime is in scope but not mentioned in the type's bounds
+  --> $DIR/overcaptures-2024-machine-applicable.rs:9:10
+   |
+LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
+   |          ^^
+   = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
+note: the lint level is defined here
+  --> $DIR/overcaptures-2024-machine-applicable.rs:7:9
+   |
+LL | #![deny(impl_trait_overcaptures)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+help: use the precise capturing `use<...>` syntax to make the captures explicit
+   |
+LL | fn named<'a>(x: &'a i32) -> impl Sized + use<> { *x }
+   |                                        +++++++
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed
index 89a3f3136c8..1eb88c71d54 100644
--- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed
@@ -1,4 +1,5 @@
 //@ run-rustfix
+//@ edition: 2018
 
 #![allow(unused)]
 #![deny(impl_trait_overcaptures)]
@@ -29,4 +30,16 @@ fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized + use<>> {}
 //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
 //~| WARN this changes meaning in Rust 2024
 
+fn apit<T: Sized>(_: &T) -> impl Sized + use<T> {}
+//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
+
+fn apit2<U, T: Sized>(_: &T, _: U) -> impl Sized + use<U, T> {}
+//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
+
+async fn async_fn<'a>(x: &'a ()) -> impl Sized + use<> {}
+//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
+
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs
index 18c04f9f799..6f1ef6a472f 100644
--- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs
@@ -1,4 +1,5 @@
 //@ run-rustfix
+//@ edition: 2018
 
 #![allow(unused)]
 #![deny(impl_trait_overcaptures)]
@@ -29,4 +30,16 @@ fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
 //~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
 //~| WARN this changes meaning in Rust 2024
 
+fn apit(_: &impl Sized) -> impl Sized {}
+//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
+
+fn apit2<U>(_: &impl Sized, _: U) -> impl Sized {}
+//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
+
+async fn async_fn<'a>(x: &'a ()) -> impl Sized {}
+//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+//~| WARN this changes meaning in Rust 2024
+
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr
index 94dafb04d64..63c87cd46c8 100644
--- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr
@@ -1,5 +1,5 @@
 error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
-  --> $DIR/overcaptures-2024.rs:6:29
+  --> $DIR/overcaptures-2024.rs:7:29
    |
 LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
    |                             ^^^^^^^^^^
@@ -7,13 +7,13 @@ LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
 note: specifically, this lifetime is in scope but not mentioned in the type's bounds
-  --> $DIR/overcaptures-2024.rs:6:10
+  --> $DIR/overcaptures-2024.rs:7:10
    |
 LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
    |          ^^
    = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
 note: the lint level is defined here
-  --> $DIR/overcaptures-2024.rs:4:9
+  --> $DIR/overcaptures-2024.rs:5:9
    |
 LL | #![deny(impl_trait_overcaptures)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL | fn named<'a>(x: &'a i32) -> impl Sized + use<> { *x }
    |                                        +++++++
 
 error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
-  --> $DIR/overcaptures-2024.rs:10:25
+  --> $DIR/overcaptures-2024.rs:11:25
    |
 LL | fn implicit(x: &i32) -> impl Sized { *x }
    |                         ^^^^^^^^^^
@@ -31,7 +31,7 @@ LL | fn implicit(x: &i32) -> impl Sized { *x }
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
 note: specifically, this lifetime is in scope but not mentioned in the type's bounds
-  --> $DIR/overcaptures-2024.rs:10:16
+  --> $DIR/overcaptures-2024.rs:11:16
    |
 LL | fn implicit(x: &i32) -> impl Sized { *x }
    |                ^
@@ -42,7 +42,7 @@ LL | fn implicit(x: &i32) -> impl Sized + use<> { *x }
    |                                    +++++++
 
 error: `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024
-  --> $DIR/overcaptures-2024.rs:16:33
+  --> $DIR/overcaptures-2024.rs:17:33
    |
 LL |     fn hello(&self, x: &i32) -> impl Sized + '_ { self }
    |                                 ^^^^^^^^^^^^^^^
@@ -50,7 +50,7 @@ LL |     fn hello(&self, x: &i32) -> impl Sized + '_ { self }
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
 note: specifically, this lifetime is in scope but not mentioned in the type's bounds
-  --> $DIR/overcaptures-2024.rs:16:24
+  --> $DIR/overcaptures-2024.rs:17:24
    |
 LL |     fn hello(&self, x: &i32) -> impl Sized + '_ { self }
    |                        ^
@@ -61,7 +61,7 @@ LL |     fn hello(&self, x: &i32) -> impl Sized + '_ + use<'_> { self }
    |                                                 +++++++++
 
 error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
-  --> $DIR/overcaptures-2024.rs:28:47
+  --> $DIR/overcaptures-2024.rs:29:47
    |
 LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
    |                                               ^^^^^^^^^^
@@ -69,7 +69,7 @@ LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
    = warning: this changes meaning in Rust 2024
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
 note: specifically, this lifetime is in scope but not mentioned in the type's bounds
-  --> $DIR/overcaptures-2024.rs:28:23
+  --> $DIR/overcaptures-2024.rs:29:23
    |
 LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
    |                       ^^
@@ -79,5 +79,72 @@ help: use the precise capturing `use<...>` syntax to make the captures explicit
 LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized + use<>> {}
    |                                                          +++++++
 
-error: aborting due to 4 previous errors
+error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+  --> $DIR/overcaptures-2024.rs:33:28
+   |
+LL | fn apit(_: &impl Sized) -> impl Sized {}
+   |                            ^^^^^^^^^^
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+note: specifically, this lifetime is in scope but not mentioned in the type's bounds
+  --> $DIR/overcaptures-2024.rs:33:12
+   |
+LL | fn apit(_: &impl Sized) -> impl Sized {}
+   |            ^
+   = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
+note: you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable
+  --> $DIR/overcaptures-2024.rs:33:13
+   |
+LL | fn apit(_: &impl Sized) -> impl Sized {}
+   |             ^^^^^^^^^^
+help: use the precise capturing `use<...>` syntax to make the captures explicit
+   |
+LL | fn apit<T: Sized>(_: &T) -> impl Sized + use<T> {}
+   |        ++++++++++     ~                ++++++++
+
+error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+  --> $DIR/overcaptures-2024.rs:37:38
+   |
+LL | fn apit2<U>(_: &impl Sized, _: U) -> impl Sized {}
+   |                                      ^^^^^^^^^^
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+note: specifically, this lifetime is in scope but not mentioned in the type's bounds
+  --> $DIR/overcaptures-2024.rs:37:16
+   |
+LL | fn apit2<U>(_: &impl Sized, _: U) -> impl Sized {}
+   |                ^
+   = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
+note: you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable
+  --> $DIR/overcaptures-2024.rs:37:17
+   |
+LL | fn apit2<U>(_: &impl Sized, _: U) -> impl Sized {}
+   |                 ^^^^^^^^^^
+help: use the precise capturing `use<...>` syntax to make the captures explicit
+   |
+LL | fn apit2<U, T: Sized>(_: &T, _: U) -> impl Sized + use<U, T> {}
+   |           ++++++++++      ~                      +++++++++++
+
+error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024
+  --> $DIR/overcaptures-2024.rs:41:37
+   |
+LL | async fn async_fn<'a>(x: &'a ()) -> impl Sized {}
+   |                                     ^^^^^^^^^^
+   |
+   = warning: this changes meaning in Rust 2024
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+note: specifically, this lifetime is in scope but not mentioned in the type's bounds
+  --> $DIR/overcaptures-2024.rs:41:19
+   |
+LL | async fn async_fn<'a>(x: &'a ()) -> impl Sized {}
+   |                   ^^
+   = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
+help: use the precise capturing `use<...>` syntax to make the captures explicit
+   |
+LL | async fn async_fn<'a>(x: &'a ()) -> impl Sized + use<> {}
+   |                                                +++++++
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/inline-const/cross_const_control_flow.rs b/tests/ui/inline-const/cross_const_control_flow.rs
new file mode 100644
index 00000000000..109764a1812
--- /dev/null
+++ b/tests/ui/inline-const/cross_const_control_flow.rs
@@ -0,0 +1,46 @@
+//@edition:2021
+
+fn foo() {
+    const { return }
+    //~^ ERROR: return statement outside of function body
+}
+
+fn labelled_block_break() {
+    'a: { const { break 'a } }
+    //~^ ERROR: `break` outside of a loop or labeled block
+    //~| ERROR: use of unreachable label
+}
+
+fn loop_break() {
+    loop {
+        const { break }
+        //~^ ERROR: `break` outside of a loop or labeled block
+    }
+}
+
+fn continue_to_labelled_block() {
+    'a: { const { continue 'a } }
+    //~^ ERROR: `continue` outside of a loop
+    //~| ERROR: use of unreachable label
+}
+
+fn loop_continue() {
+    loop {
+        const { continue }
+        //~^ ERROR: `continue` outside of a loop
+    }
+}
+
+async fn await_across_const_block() {
+    const { async {}.await }
+    //~^ ERROR: `await` is only allowed inside `async` functions and blocks
+}
+
+fn reference_to_non_constant_in_const_block() {
+    let x = 1;
+    const { &x };
+    //~^ ERROR: attempt to use a non-constant value in a constant
+}
+
+
+fn main() {}
diff --git a/tests/ui/inline-const/cross_const_control_flow.stderr b/tests/ui/inline-const/cross_const_control_flow.stderr
new file mode 100644
index 00000000000..ecfa921edd2
--- /dev/null
+++ b/tests/ui/inline-const/cross_const_control_flow.stderr
@@ -0,0 +1,78 @@
+error[E0767]: use of unreachable label `'a`
+  --> $DIR/cross_const_control_flow.rs:9:25
+   |
+LL |     'a: { const { break 'a } }
+   |     --                  ^^ unreachable label `'a`
+   |     |
+   |     unreachable label defined here
+   |
+   = note: labels are unreachable through functions, closures, async blocks and modules
+
+error[E0767]: use of unreachable label `'a`
+  --> $DIR/cross_const_control_flow.rs:22:28
+   |
+LL |     'a: { const { continue 'a } }
+   |     --                     ^^ unreachable label `'a`
+   |     |
+   |     unreachable label defined here
+   |
+   = note: labels are unreachable through functions, closures, async blocks and modules
+
+error[E0435]: attempt to use a non-constant value in a constant
+  --> $DIR/cross_const_control_flow.rs:41:14
+   |
+LL |     const { &x };
+   |              ^ non-constant value
+   |
+help: consider using `const` instead of `let`
+   |
+LL |     const x: /* Type */ = 1;
+   |     ~~~~~  ++++++++++++
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+  --> $DIR/cross_const_control_flow.rs:35:22
+   |
+LL |     const { async {}.await }
+   |           -----------^^^^^--
+   |           |          |
+   |           |          only allowed inside `async` functions and blocks
+   |           this is not `async`
+
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/cross_const_control_flow.rs:9:19
+   |
+LL |     'a: { const { break 'a } }
+   |                   ^^^^^^^^ cannot `break` outside of a loop or labeled block
+
+error[E0268]: `break` outside of a loop or labeled block
+  --> $DIR/cross_const_control_flow.rs:16:17
+   |
+LL |         const { break }
+   |                 ^^^^^ cannot `break` outside of a loop or labeled block
+
+error[E0268]: `continue` outside of a loop
+  --> $DIR/cross_const_control_flow.rs:22:19
+   |
+LL |     'a: { const { continue 'a } }
+   |                   ^^^^^^^^^^^ cannot `continue` outside of a loop
+
+error[E0268]: `continue` outside of a loop
+  --> $DIR/cross_const_control_flow.rs:29:17
+   |
+LL |         const { continue }
+   |                 ^^^^^^^^ cannot `continue` outside of a loop
+
+error[E0572]: return statement outside of function body
+  --> $DIR/cross_const_control_flow.rs:4:13
+   |
+LL | / fn foo() {
+LL | |     const { return }
+   | |           --^^^^^^-- the return is part of this body...
+LL | |
+LL | | }
+   | |_- ...not the enclosing function body
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0268, E0435, E0572, E0728, E0767.
+For more information about an error, try `rustc --explain E0268`.
diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.edition2021.run.stdout b/tests/ui/lifetimes/temporary-lifetime-extension.edition2021.run.stdout
new file mode 100644
index 00000000000..86437221589
--- /dev/null
+++ b/tests/ui/lifetimes/temporary-lifetime-extension.edition2021.run.stdout
@@ -0,0 +1 @@
+("Hello", 1) [(("Hello", 1),)] "Hello" "Hello" "Hello" ("Hello", 1) ("Hello", 1) ("Hello", 1)
diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout b/tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout
new file mode 100644
index 00000000000..86437221589
--- /dev/null
+++ b/tests/ui/lifetimes/temporary-lifetime-extension.edition2024.run.stdout
@@ -0,0 +1 @@
+("Hello", 1) [(("Hello", 1),)] "Hello" "Hello" "Hello" ("Hello", 1) ("Hello", 1) ("Hello", 1)
diff --git a/tests/ui/lifetimes/temporary-lifetime-extension.rs b/tests/ui/lifetimes/temporary-lifetime-extension.rs
index 1ecef2f3d04..d03027cf4a3 100644
--- a/tests/ui/lifetimes/temporary-lifetime-extension.rs
+++ b/tests/ui/lifetimes/temporary-lifetime-extension.rs
@@ -1,4 +1,21 @@
-//@ check-pass
+// This is a test for the new temporary lifetime behaviour as implemented for RFC 3606.
+// In essence, with #3606 we can write the following variable initialisation without
+// a borrow checking error because the temporary lifetime is automatically extended.
+// ```rust
+// let x = if condition() {
+//    &something()
+// } else {
+//    &something_else()
+// };
+// ```
+// More details can be found in https://github.com/rust-lang/rfcs/pull/3606
+
+//@ run-pass
+//@ check-run-results
+//@ revisions: edition2021 edition2024
+//@ [edition2021] edition: 2021
+//@ [edition2024] edition: 2024
+//@ [edition2024] compile-flags: -Z unstable-options
 
 fn temp() -> (String, i32) {
     (String::from("Hello"), 1)
@@ -13,11 +30,7 @@ fn main() {
         let _ = 123;
         &(*temp().0)[..]
     };
-    let f = if true {
-        &temp()
-    } else {
-        &temp()
-    };
+    let f = if true { &temp() } else { &temp() };
     let g = match true {
         true => &temp(),
         false => {
diff --git a/tests/ui/lint/unreachable_pub.fixed b/tests/ui/lint/unreachable_pub.fixed
new file mode 100644
index 00000000000..163e8d24b32
--- /dev/null
+++ b/tests/ui/lint/unreachable_pub.fixed
@@ -0,0 +1,116 @@
+//@ check-pass
+//@ edition: 2018
+//@ run-rustfix
+
+#![allow(unused)]
+#![warn(unreachable_pub)]
+
+mod private_mod {
+    // non-leaked `pub` items in private module should be linted
+    pub(crate) use std::fmt; //~ WARNING unreachable_pub
+    pub(crate) use std::env::{Args}; // braced-use has different item spans than unbraced
+    //~^ WARNING unreachable_pub
+
+    // we lint on struct definition
+    pub(crate) struct Hydrogen { //~ WARNING unreachable_pub
+        // but not on fields, even if they are `pub` as putting `pub(crate)`
+        // it would clutter the source code for little value
+        pub neutrons: usize,
+        pub(crate) electrons: usize
+    }
+    pub(crate) struct Calcium {
+        pub neutrons: usize,
+    }
+    impl Hydrogen {
+        // impls, too
+        pub(crate) fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub
+        pub(crate) fn count_electrons(&self) -> usize { self.electrons }
+    }
+    impl Clone for Hydrogen {
+        fn clone(&self) -> Hydrogen {
+            Hydrogen { neutrons: self.neutrons, electrons: self.electrons }
+        }
+    }
+
+    pub(crate) enum Helium {} //~ WARNING unreachable_pub
+    pub(crate) union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub
+    pub(crate) fn beryllium() {} //~ WARNING unreachable_pub
+    pub(crate) trait Boron {} //~ WARNING unreachable_pub
+    pub(crate) const CARBON: usize = 1; //~ WARNING unreachable_pub
+    pub(crate) static NITROGEN: usize = 2; //~ WARNING unreachable_pub
+    pub(crate) type Oxygen = bool; //~ WARNING unreachable_pub
+
+    macro_rules! define_empty_struct_with_visibility {
+        ($visibility: vis, $name: ident) => { $visibility struct $name {} }
+        //~^ WARNING unreachable_pub
+    }
+    define_empty_struct_with_visibility!(pub(crate), Fluorine);
+
+    extern "C" {
+        pub(crate) fn catalyze() -> bool; //~ WARNING unreachable_pub
+    }
+
+    mod private_in_private {
+        pub(super) enum Helium {} //~ WARNING unreachable_pub
+        pub(super) fn beryllium() {} //~ WARNING unreachable_pub
+    }
+
+    pub(crate) mod crate_in_private {
+        pub(crate) const CARBON: usize = 1; //~ WARNING unreachable_pub
+    }
+
+    pub(crate) mod pub_in_private { //~ WARNING unreachable_pub
+        pub(crate) static NITROGEN: usize = 2; //~ WARNING unreachable_pub
+    }
+
+    fn foo() {
+        const {
+            pub(crate) struct Foo; //~ WARNING unreachable_pub
+        };
+    }
+
+    enum Weird {
+        Variant = {
+            pub(crate) struct Foo; //~ WARNING unreachable_pub
+
+            mod tmp {
+                pub(crate) struct Bar; //~ WARNING unreachable_pub
+            }
+
+            let _ = tmp::Bar;
+
+            0
+        },
+    }
+
+    pub(crate) use fpu_precision::set_precision; //~ WARNING unreachable_pub
+
+    mod fpu_precision {
+        pub(crate) fn set_precision<T>() {} //~ WARNING unreachable_pub
+        pub(super) fn set_micro_precision<T>() {} //~ WARNING unreachable_pub
+    }
+
+    // items leaked through signatures (see `get_neon` below) are OK
+    pub struct Neon {}
+
+    // crate-visible items are OK
+    pub(crate) struct Sodium {}
+}
+
+pub mod public_mod {
+    // module is public: these are OK, too
+    pub struct Magnesium {}
+    pub(crate) struct Aluminum {}
+}
+
+pub fn get_neon() -> private_mod::Neon {
+    private_mod::Neon {}
+}
+
+fn main() {
+    let _ = get_neon();
+    let _ = private_mod::beryllium();
+    let _ = private_mod::crate_in_private::CARBON;
+    let _ = private_mod::pub_in_private::NITROGEN;
+    let _ = unsafe { private_mod::catalyze() };
+}
diff --git a/tests/ui/lint/unreachable_pub.rs b/tests/ui/lint/unreachable_pub.rs
index f21f6640342..8524820bcfb 100644
--- a/tests/ui/lint/unreachable_pub.rs
+++ b/tests/ui/lint/unreachable_pub.rs
@@ -1,4 +1,6 @@
 //@ check-pass
+//@ edition: 2018
+//@ run-rustfix
 
 #![allow(unused)]
 #![warn(unreachable_pub)]
@@ -48,6 +50,46 @@ mod private_mod {
         pub fn catalyze() -> bool; //~ WARNING unreachable_pub
     }
 
+    mod private_in_private {
+        pub enum Helium {} //~ WARNING unreachable_pub
+        pub fn beryllium() {} //~ WARNING unreachable_pub
+    }
+
+    pub(crate) mod crate_in_private {
+        pub const CARBON: usize = 1; //~ WARNING unreachable_pub
+    }
+
+    pub mod pub_in_private { //~ WARNING unreachable_pub
+        pub static NITROGEN: usize = 2; //~ WARNING unreachable_pub
+    }
+
+    fn foo() {
+        const {
+            pub struct Foo; //~ WARNING unreachable_pub
+        };
+    }
+
+    enum Weird {
+        Variant = {
+            pub struct Foo; //~ WARNING unreachable_pub
+
+            mod tmp {
+                pub struct Bar; //~ WARNING unreachable_pub
+            }
+
+            let _ = tmp::Bar;
+
+            0
+        },
+    }
+
+    pub use fpu_precision::set_precision; //~ WARNING unreachable_pub
+
+    mod fpu_precision {
+        pub fn set_precision<T>() {} //~ WARNING unreachable_pub
+        pub fn set_micro_precision<T>() {} //~ WARNING unreachable_pub
+    }
+
     // items leaked through signatures (see `get_neon` below) are OK
     pub struct Neon {}
 
@@ -67,4 +109,8 @@ pub fn get_neon() -> private_mod::Neon {
 
 fn main() {
     let _ = get_neon();
+    let _ = private_mod::beryllium();
+    let _ = private_mod::crate_in_private::CARBON;
+    let _ = private_mod::pub_in_private::NITROGEN;
+    let _ = unsafe { private_mod::catalyze() };
 }
diff --git a/tests/ui/lint/unreachable_pub.stderr b/tests/ui/lint/unreachable_pub.stderr
index 65f45fbd816..5173ff1f026 100644
--- a/tests/ui/lint/unreachable_pub.stderr
+++ b/tests/ui/lint/unreachable_pub.stderr
@@ -1,5 +1,5 @@
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:8:13
+  --> $DIR/unreachable_pub.rs:10:13
    |
 LL |     pub use std::fmt;
    |     ---     ^^^^^^^^
@@ -8,13 +8,13 @@ LL |     pub use std::fmt;
    |
    = help: or consider exporting it for use by other crates
 note: the lint level is defined here
-  --> $DIR/unreachable_pub.rs:4:9
+  --> $DIR/unreachable_pub.rs:6:9
    |
 LL | #![warn(unreachable_pub)]
    |         ^^^^^^^^^^^^^^^
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:9:24
+  --> $DIR/unreachable_pub.rs:11:24
    |
 LL |     pub use std::env::{Args}; // braced-use has different item spans than unbraced
    |     ---                ^^^^
@@ -24,7 +24,7 @@ LL |     pub use std::env::{Args}; // braced-use has different item spans than u
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:13:5
+  --> $DIR/unreachable_pub.rs:15:5
    |
 LL |     pub struct Hydrogen {
    |     ---^^^^^^^^^^^^^^^^
@@ -34,7 +34,7 @@ LL |     pub struct Hydrogen {
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:24:9
+  --> $DIR/unreachable_pub.rs:26:9
    |
 LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
    |         ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
    |         help: consider restricting its visibility: `pub(crate)`
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:33:5
+  --> $DIR/unreachable_pub.rs:35:5
    |
 LL |     pub enum Helium {}
    |     ---^^^^^^^^^^^^
@@ -52,7 +52,7 @@ LL |     pub enum Helium {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:34:5
+  --> $DIR/unreachable_pub.rs:36:5
    |
 LL |     pub union Lithium { c1: usize, c2: u8 }
    |     ---^^^^^^^^^^^^^^
@@ -62,7 +62,7 @@ LL |     pub union Lithium { c1: usize, c2: u8 }
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:35:5
+  --> $DIR/unreachable_pub.rs:37:5
    |
 LL |     pub fn beryllium() {}
    |     ---^^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     pub fn beryllium() {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:36:5
+  --> $DIR/unreachable_pub.rs:38:5
    |
 LL |     pub trait Boron {}
    |     ---^^^^^^^^^^^^
@@ -82,7 +82,7 @@ LL |     pub trait Boron {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:37:5
+  --> $DIR/unreachable_pub.rs:39:5
    |
 LL |     pub const CARBON: usize = 1;
    |     ---^^^^^^^^^^^^^^^^^^^^
@@ -92,7 +92,7 @@ LL |     pub const CARBON: usize = 1;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:38:5
+  --> $DIR/unreachable_pub.rs:40:5
    |
 LL |     pub static NITROGEN: usize = 2;
    |     ---^^^^^^^^^^^^^^^^^^^^^^^
@@ -102,7 +102,7 @@ LL |     pub static NITROGEN: usize = 2;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:39:5
+  --> $DIR/unreachable_pub.rs:41:5
    |
 LL |     pub type Oxygen = bool;
    |     ---^^^^^^^^^^^^
@@ -112,7 +112,7 @@ LL |     pub type Oxygen = bool;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:42:47
+  --> $DIR/unreachable_pub.rs:44:47
    |
 LL |         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -127,7 +127,7 @@ LL |     define_empty_struct_with_visibility!(pub, Fluorine);
    = note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:48:9
+  --> $DIR/unreachable_pub.rs:50:9
    |
 LL |         pub fn catalyze() -> bool;
    |         ---^^^^^^^^^^^^^^^^^^^^^^^
@@ -136,5 +136,115 @@ LL |         pub fn catalyze() -> bool;
    |
    = help: or consider exporting it for use by other crates
 
-warning: 13 warnings emitted
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:62:5
+   |
+LL |     pub mod pub_in_private {
+   |     ---^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:68:13
+   |
+LL |             pub struct Foo;
+   |             ---^^^^^^^^^^^
+   |             |
+   |             help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:74:13
+   |
+LL |             pub struct Foo;
+   |             ---^^^^^^^^^^^
+   |             |
+   |             help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:86:13
+   |
+LL |     pub use fpu_precision::set_precision;
+   |     ---     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:54:9
+   |
+LL |         pub enum Helium {}
+   |         ---^^^^^^^^^^^^
+   |         |
+   |         help: consider restricting its visibility: `pub(super)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:55:9
+   |
+LL |         pub fn beryllium() {}
+   |         ---^^^^^^^^^^^^^^^
+   |         |
+   |         help: consider restricting its visibility: `pub(super)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:59:9
+   |
+LL |         pub const CARBON: usize = 1;
+   |         ---^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:63:9
+   |
+LL |         pub static NITROGEN: usize = 2;
+   |         ---^^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:77:17
+   |
+LL |                 pub struct Bar;
+   |                 ---^^^^^^^^^^^
+   |                 |
+   |                 help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:89:9
+   |
+LL |         pub fn set_precision<T>() {}
+   |         ---^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         help: consider restricting its visibility: `pub(crate)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: unreachable `pub` item
+  --> $DIR/unreachable_pub.rs:90:9
+   |
+LL |         pub fn set_micro_precision<T>() {}
+   |         ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         help: consider restricting its visibility: `pub(super)`
+   |
+   = help: or consider exporting it for use by other crates
+
+warning: 24 warnings emitted
 
diff --git a/tests/ui/match/intended-binding-pattern-is-const.rs b/tests/ui/match/intended-binding-pattern-is-const.rs
new file mode 100644
index 00000000000..95c8119cdb9
--- /dev/null
+++ b/tests/ui/match/intended-binding-pattern-is-const.rs
@@ -0,0 +1,10 @@
+fn main() {
+    match 1 { //~ ERROR non-exhaustive patterns
+        //~^ patterns `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
+        //~| the matched value is of type `i32`
+        x => {} //~ this pattern doesn't introduce a new catch-all binding
+        //~^ HELP ensure that all possible cases are being handled
+        //~| HELP if you meant to introduce a binding, use a different name
+    }
+    const x: i32 = 4; //~ NOTE constant `x` defined here
+}
diff --git a/tests/ui/match/intended-binding-pattern-is-const.stderr b/tests/ui/match/intended-binding-pattern-is-const.stderr
new file mode 100644
index 00000000000..99af1c7a16e
--- /dev/null
+++ b/tests/ui/match/intended-binding-pattern-is-const.stderr
@@ -0,0 +1,27 @@
+error[E0004]: non-exhaustive patterns: `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
+  --> $DIR/intended-binding-pattern-is-const.rs:2:11
+   |
+LL |     match 1 {
+   |           ^ patterns `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
+...
+LL |         x => {}
+   |         - this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `x`
+   |
+   = note: the matched value is of type `i32`
+note: constant `x` defined here
+  --> $DIR/intended-binding-pattern-is-const.rs:9:5
+   |
+LL |     const x: i32 = 4;
+   |     ^^^^^^^^^^^^
+help: if you meant to introduce a binding, use a different name
+   |
+LL |         x_var => {}
+   |          ++++
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL |         x => {}, i32::MIN..=3_i32 | 5_i32..=i32::MAX => todo!()
+   |                ++++++++++++++++++++++++++++++++++++++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/mir/enable_passes_validation.all_unknown.stderr b/tests/ui/mir/enable_passes_validation.all_unknown.stderr
new file mode 100644
index 00000000000..85a942c00ed
--- /dev/null
+++ b/tests/ui/mir/enable_passes_validation.all_unknown.stderr
@@ -0,0 +1,14 @@
+warning: MIR pass `ThisPass` is unknown and will be ignored
+
+warning: MIR pass `DoesNotExist` is unknown and will be ignored
+
+warning: MIR pass `ThisPass` is unknown and will be ignored
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+warning: MIR pass `DoesNotExist` is unknown and will be ignored
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+warning: 4 warnings emitted
+
diff --git a/tests/ui/mir/enable_passes_validation.empty.stderr b/tests/ui/mir/enable_passes_validation.empty.stderr
new file mode 100644
index 00000000000..0e922663acc
--- /dev/null
+++ b/tests/ui/mir/enable_passes_validation.empty.stderr
@@ -0,0 +1,2 @@
+error: incorrect value `` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
+
diff --git a/tests/ui/mir/enable_passes_validation.mixed.stderr b/tests/ui/mir/enable_passes_validation.mixed.stderr
new file mode 100644
index 00000000000..5aace86abc0
--- /dev/null
+++ b/tests/ui/mir/enable_passes_validation.mixed.stderr
@@ -0,0 +1,8 @@
+warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
+
+warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/mir/enable_passes_validation.rs b/tests/ui/mir/enable_passes_validation.rs
new file mode 100644
index 00000000000..957e7d4d96d
--- /dev/null
+++ b/tests/ui/mir/enable_passes_validation.rs
@@ -0,0 +1,21 @@
+//@ revisions: empty unprefixed all_unknown all_known mixed
+
+//@[empty] compile-flags: -Zmir-enable-passes=
+//@[empty] error-pattern error: incorrect value `` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
+
+//@[unprefixed] compile-flags: -Zmir-enable-passes=CheckAlignment
+//@[unprefixed] error-pattern error: incorrect value `CheckAlignment` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
+
+//@[all_unknown] check-pass
+//@[all_unknown] compile-flags: -Zmir-enable-passes=+ThisPass,-DoesNotExist
+//@[all_unknown] error-pattern: warning: MIR pass `ThisPass` is unknown and will be ignored
+//@[all_unknown] error-pattern: warning: MIR pass `DoesNotExist` is unknown and will be ignored
+
+//@[all_known] check-pass
+//@[all_known] compile-flags: -Zmir-enable-passes=+CheckAlignment,+LowerIntrinsics
+
+//@[mixed] check-pass
+//@[mixed] compile-flags: -Zmir-enable-passes=+ThisPassDoesNotExist,+CheckAlignment
+//@[mixed] error-pattern: warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
+
+fn main() {}
diff --git a/tests/ui/mir/enable_passes_validation.unprefixed.stderr b/tests/ui/mir/enable_passes_validation.unprefixed.stderr
new file mode 100644
index 00000000000..697589448f4
--- /dev/null
+++ b/tests/ui/mir/enable_passes_validation.unprefixed.stderr
@@ -0,0 +1,2 @@
+error: incorrect value `CheckAlignment` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
+
diff --git a/tests/ui/mir/issue-112269.stderr b/tests/ui/mir/issue-112269.stderr
index f5b79602797..adb662c98a7 100644
--- a/tests/ui/mir/issue-112269.stderr
+++ b/tests/ui/mir/issue-112269.stderr
@@ -1,30 +1,34 @@
 error[E0005]: refutable pattern in local binding
   --> $DIR/issue-112269.rs:3:9
    |
+LL |     const x: i32 = 4;
+   |     ------------ missing patterns are not covered because `x` is interpreted as a constant pattern, not a new variable
 LL |     let x: i32 = 3;
-   |         ^
-   |         |
-   |         patterns `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
-   |         missing patterns are not covered because `x` is interpreted as a constant pattern, not a new variable
-   |         help: introduce a variable instead: `x_var`
+   |         ^ patterns `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
+help: introduce a variable instead
+   |
+LL |     let x_var: i32 = 3;
+   |         ~~~~~
 
 error[E0005]: refutable pattern in local binding
   --> $DIR/issue-112269.rs:7:9
    |
+LL |     const y: i32 = 3;
+   |     ------------ missing patterns are not covered because `y` is interpreted as a constant pattern, not a new variable
 LL |     let y = 4;
-   |         ^
-   |         |
-   |         patterns `i32::MIN..=2_i32` and `4_i32..=i32::MAX` not covered
-   |         missing patterns are not covered because `y` is interpreted as a constant pattern, not a new variable
-   |         help: introduce a variable instead: `y_var`
+   |         ^ patterns `i32::MIN..=2_i32` and `4_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
+help: introduce a variable instead
+   |
+LL |     let y_var = 4;
+   |         ~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/moves/auxiliary/suggest-borrow-for-generic-arg-aux.rs b/tests/ui/moves/auxiliary/suggest-borrow-for-generic-arg-aux.rs
new file mode 100644
index 00000000000..c71238ba072
--- /dev/null
+++ b/tests/ui/moves/auxiliary/suggest-borrow-for-generic-arg-aux.rs
@@ -0,0 +1,20 @@
+//! auxiliary definitons for suggest-borrow-for-generic-arg.rs, to ensure the suggestion works on
+//! functions defined in other crates.
+
+use std::io::{self, Read, Write};
+use std::iter::Sum;
+
+pub fn write_stuff<W: Write>(mut writer: W) -> io::Result<()> {
+    writeln!(writer, "stuff")
+}
+
+pub fn read_and_discard<R: Read>(mut reader: R) -> io::Result<()> {
+    let mut buf = Vec::new();
+    reader.read_to_end(&mut buf).map(|_| ())
+}
+
+pub fn sum_three<I: IntoIterator>(iter: I) -> <I as IntoIterator>::Item
+    where <I as IntoIterator>::Item: Sum
+{
+    iter.into_iter().take(3).sum()
+}
diff --git a/tests/ui/moves/borrow-closures-instead-of-move.rs b/tests/ui/moves/borrow-closures-instead-of-move.rs
index e4bca54e995..869aa654ef7 100644
--- a/tests/ui/moves/borrow-closures-instead-of-move.rs
+++ b/tests/ui/moves/borrow-closures-instead-of-move.rs
@@ -1,4 +1,4 @@
-fn takes_fn(f: impl Fn()) { //~ HELP if `impl Fn()` implemented `Clone`
+fn takes_fn(f: impl Fn()) {
     loop {
         takes_fnonce(f);
         //~^ ERROR use of moved value
diff --git a/tests/ui/moves/borrow-closures-instead-of-move.stderr b/tests/ui/moves/borrow-closures-instead-of-move.stderr
index ab6ff417efb..ea145f365c2 100644
--- a/tests/ui/moves/borrow-closures-instead-of-move.stderr
+++ b/tests/ui/moves/borrow-closures-instead-of-move.stderr
@@ -8,21 +8,6 @@ LL |     loop {
 LL |         takes_fnonce(f);
    |                      ^ value moved here, in previous iteration of loop
    |
-note: consider changing this parameter type in function `takes_fnonce` to borrow instead if owning the value isn't necessary
-  --> $DIR/borrow-closures-instead-of-move.rs:34:20
-   |
-LL | fn takes_fnonce(_: impl FnOnce()) {}
-   |    ------------    ^^^^^^^^^^^^^ this parameter takes ownership of the value
-   |    |
-   |    in this function
-help: if `impl Fn()` implemented `Clone`, you could clone the value
-  --> $DIR/borrow-closures-instead-of-move.rs:1:16
-   |
-LL | fn takes_fn(f: impl Fn()) {
-   |                ^^^^^^^^^ consider constraining this type parameter with `Clone`
-LL |     loop {
-LL |         takes_fnonce(f);
-   |                      - you could clone this value
 help: consider borrowing `f`
    |
 LL |         takes_fnonce(&f);
@@ -40,13 +25,6 @@ LL |         takes_fnonce(m);
 LL |     takes_fnonce(m);
    |                  ^ value used here after move
    |
-note: consider changing this parameter type in function `takes_fnonce` to borrow instead if owning the value isn't necessary
-  --> $DIR/borrow-closures-instead-of-move.rs:34:20
-   |
-LL | fn takes_fnonce(_: impl FnOnce()) {}
-   |    ------------    ^^^^^^^^^^^^^ this parameter takes ownership of the value
-   |    |
-   |    in this function
 help: if `impl FnMut()` implemented `Clone`, you could clone the value
   --> $DIR/borrow-closures-instead-of-move.rs:9:20
    |
diff --git a/tests/ui/moves/moved-value-on-as-ref-arg.stderr b/tests/ui/moves/moved-value-on-as-ref-arg.stderr
index 4004b7a43bc..a99bdb4fe9d 100644
--- a/tests/ui/moves/moved-value-on-as-ref-arg.stderr
+++ b/tests/ui/moves/moved-value-on-as-ref-arg.stderr
@@ -8,7 +8,7 @@ LL |     foo(bar);
 LL |     let _baa = bar;
    |                ^^^ value used here after move
    |
-help: borrow the value to avoid moving it
+help: consider borrowing `bar`
    |
 LL |     foo(&bar);
    |         +
@@ -31,7 +31,7 @@ LL | struct Bar;
 ...
 LL |     qux(bar);
    |         --- you could clone this value
-help: borrow the value to avoid moving it
+help: consider mutably borrowing `bar`
    |
 LL |     qux(&mut bar);
    |         ++++
@@ -46,7 +46,7 @@ LL |     bat(bar);
 LL |     let _baa = bar;
    |                ^^^ value used here after move
    |
-help: borrow the value to avoid moving it
+help: consider borrowing `bar`
    |
 LL |     bat(&bar);
    |         +
@@ -69,7 +69,7 @@ LL | struct Bar;
 ...
 LL |     baz(bar);
    |         --- you could clone this value
-help: borrow the value to avoid moving it
+help: consider mutably borrowing `bar`
    |
 LL |     baz(&mut bar);
    |         ++++
diff --git a/tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr b/tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
index a8473bb8198..a4c8401ce57 100644
--- a/tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
+++ b/tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
@@ -24,10 +24,6 @@ LL | fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
    |                ^ consider constraining this type parameter with `Clone`
 LL |     let mut r = R {c: Box::new(f)};
    |                                - you could clone this value
-help: consider mutably borrowing `f`
-   |
-LL |     let mut r = R {c: Box::new(&mut f)};
-   |                                ++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/moves/suggest-borrow-for-generic-arg.fixed b/tests/ui/moves/suggest-borrow-for-generic-arg.fixed
new file mode 100644
index 00000000000..b5e0b468aa6
--- /dev/null
+++ b/tests/ui/moves/suggest-borrow-for-generic-arg.fixed
@@ -0,0 +1,46 @@
+//! Test suggetions to borrow generic arguments instead of moving. Tests for other instances of this
+//! can be found in `moved-value-on-as-ref-arg.rs` and `borrow-closures-instead-of-move.rs`
+//@ run-rustfix
+//@ aux-crate:aux=suggest-borrow-for-generic-arg-aux.rs
+//@ edition: 2021
+
+#![allow(unused_mut)]
+use std::io::{self, Write};
+
+// test for `std::io::Write` (#131413)
+fn test_write() -> io::Result<()> {
+    let mut stdout = io::stdout();
+    aux::write_stuff(&stdout)?; //~ HELP consider borrowing `stdout`
+    writeln!(stdout, "second line")?; //~ ERROR borrow of moved value: `stdout`
+
+    let mut buf = Vec::new();
+    aux::write_stuff(&mut buf.clone())?; //~ HELP consider mutably borrowing `buf`
+    //~^ HELP consider cloning the value
+    writeln!(buf, "second_line") //~ ERROR borrow of moved value: `buf`
+}
+
+/// test for `std::io::Read` (#131413)
+fn test_read() -> io::Result<()> {
+    let stdin = io::stdin();
+    aux::read_and_discard(&stdin)?; //~ HELP consider borrowing `stdin`
+    aux::read_and_discard(stdin)?; //~ ERROR use of moved value: `stdin`
+
+    let mut bytes = std::collections::VecDeque::from([1, 2, 3, 4, 5, 6]);
+    aux::read_and_discard(&mut bytes.clone())?; //~ HELP consider mutably borrowing `bytes`
+    //~^ HELP consider cloning the value
+    aux::read_and_discard(bytes) //~ ERROR use of moved value: `bytes`
+}
+
+/// test that suggestions work with projection types in the callee's signature
+fn test_projections() {
+    let mut iter = [1, 2, 3, 4, 5, 6].into_iter();
+    let _six: usize = aux::sum_three(&mut iter.clone()); //~ HELP consider mutably borrowing `iter`
+    //~^ HELP consider cloning the value
+    let _fifteen: usize = aux::sum_three(iter); //~ ERROR use of moved value: `iter`
+}
+
+fn main() {
+    test_write().unwrap();
+    test_read().unwrap();
+    test_projections();
+}
diff --git a/tests/ui/moves/suggest-borrow-for-generic-arg.rs b/tests/ui/moves/suggest-borrow-for-generic-arg.rs
new file mode 100644
index 00000000000..e08978db63a
--- /dev/null
+++ b/tests/ui/moves/suggest-borrow-for-generic-arg.rs
@@ -0,0 +1,46 @@
+//! Test suggetions to borrow generic arguments instead of moving. Tests for other instances of this
+//! can be found in `moved-value-on-as-ref-arg.rs` and `borrow-closures-instead-of-move.rs`
+//@ run-rustfix
+//@ aux-crate:aux=suggest-borrow-for-generic-arg-aux.rs
+//@ edition: 2021
+
+#![allow(unused_mut)]
+use std::io::{self, Write};
+
+// test for `std::io::Write` (#131413)
+fn test_write() -> io::Result<()> {
+    let mut stdout = io::stdout();
+    aux::write_stuff(stdout)?; //~ HELP consider borrowing `stdout`
+    writeln!(stdout, "second line")?; //~ ERROR borrow of moved value: `stdout`
+
+    let mut buf = Vec::new();
+    aux::write_stuff(buf)?; //~ HELP consider mutably borrowing `buf`
+    //~^ HELP consider cloning the value
+    writeln!(buf, "second_line") //~ ERROR borrow of moved value: `buf`
+}
+
+/// test for `std::io::Read` (#131413)
+fn test_read() -> io::Result<()> {
+    let stdin = io::stdin();
+    aux::read_and_discard(stdin)?; //~ HELP consider borrowing `stdin`
+    aux::read_and_discard(stdin)?; //~ ERROR use of moved value: `stdin`
+
+    let mut bytes = std::collections::VecDeque::from([1, 2, 3, 4, 5, 6]);
+    aux::read_and_discard(bytes)?; //~ HELP consider mutably borrowing `bytes`
+    //~^ HELP consider cloning the value
+    aux::read_and_discard(bytes) //~ ERROR use of moved value: `bytes`
+}
+
+/// test that suggestions work with projection types in the callee's signature
+fn test_projections() {
+    let mut iter = [1, 2, 3, 4, 5, 6].into_iter();
+    let _six: usize = aux::sum_three(iter); //~ HELP consider mutably borrowing `iter`
+    //~^ HELP consider cloning the value
+    let _fifteen: usize = aux::sum_three(iter); //~ ERROR use of moved value: `iter`
+}
+
+fn main() {
+    test_write().unwrap();
+    test_read().unwrap();
+    test_projections();
+}
diff --git a/tests/ui/moves/suggest-borrow-for-generic-arg.stderr b/tests/ui/moves/suggest-borrow-for-generic-arg.stderr
new file mode 100644
index 00000000000..07e24f566cb
--- /dev/null
+++ b/tests/ui/moves/suggest-borrow-for-generic-arg.stderr
@@ -0,0 +1,93 @@
+error[E0382]: borrow of moved value: `stdout`
+  --> $DIR/suggest-borrow-for-generic-arg.rs:14:14
+   |
+LL |     let mut stdout = io::stdout();
+   |         ---------- move occurs because `stdout` has type `Stdout`, which does not implement the `Copy` trait
+LL |     aux::write_stuff(stdout)?;
+   |                      ------ value moved here
+LL |     writeln!(stdout, "second line")?;
+   |              ^^^^^^ value borrowed here after move
+   |
+help: consider borrowing `stdout`
+   |
+LL |     aux::write_stuff(&stdout)?;
+   |                      +
+
+error[E0382]: borrow of moved value: `buf`
+  --> $DIR/suggest-borrow-for-generic-arg.rs:19:14
+   |
+LL |     let mut buf = Vec::new();
+   |         ------- move occurs because `buf` has type `Vec<u8>`, which does not implement the `Copy` trait
+LL |     aux::write_stuff(buf)?;
+   |                      --- value moved here
+LL |
+LL |     writeln!(buf, "second_line")
+   |              ^^^ value borrowed here after move
+   |
+help: consider mutably borrowing `buf`
+   |
+LL |     aux::write_stuff(&mut buf)?;
+   |                      ++++
+help: consider cloning the value if the performance cost is acceptable
+   |
+LL |     aux::write_stuff(buf.clone())?;
+   |                         ++++++++
+
+error[E0382]: use of moved value: `stdin`
+  --> $DIR/suggest-borrow-for-generic-arg.rs:26:27
+   |
+LL |     let stdin = io::stdin();
+   |         ----- move occurs because `stdin` has type `Stdin`, which does not implement the `Copy` trait
+LL |     aux::read_and_discard(stdin)?;
+   |                           ----- value moved here
+LL |     aux::read_and_discard(stdin)?;
+   |                           ^^^^^ value used here after move
+   |
+help: consider borrowing `stdin`
+   |
+LL |     aux::read_and_discard(&stdin)?;
+   |                           +
+
+error[E0382]: use of moved value: `bytes`
+  --> $DIR/suggest-borrow-for-generic-arg.rs:31:27
+   |
+LL |     let mut bytes = std::collections::VecDeque::from([1, 2, 3, 4, 5, 6]);
+   |         --------- move occurs because `bytes` has type `VecDeque<u8>`, which does not implement the `Copy` trait
+LL |     aux::read_and_discard(bytes)?;
+   |                           ----- value moved here
+LL |
+LL |     aux::read_and_discard(bytes)
+   |                           ^^^^^ value used here after move
+   |
+help: consider mutably borrowing `bytes`
+   |
+LL |     aux::read_and_discard(&mut bytes)?;
+   |                           ++++
+help: consider cloning the value if the performance cost is acceptable
+   |
+LL |     aux::read_and_discard(bytes.clone())?;
+   |                                ++++++++
+
+error[E0382]: use of moved value: `iter`
+  --> $DIR/suggest-borrow-for-generic-arg.rs:39:42
+   |
+LL |     let mut iter = [1, 2, 3, 4, 5, 6].into_iter();
+   |         -------- move occurs because `iter` has type `std::array::IntoIter<usize, 6>`, which does not implement the `Copy` trait
+LL |     let _six: usize = aux::sum_three(iter);
+   |                                      ---- value moved here
+LL |
+LL |     let _fifteen: usize = aux::sum_three(iter);
+   |                                          ^^^^ value used here after move
+   |
+help: consider mutably borrowing `iter`
+   |
+LL |     let _six: usize = aux::sum_three(&mut iter);
+   |                                      ++++
+help: consider cloning the value if the performance cost is acceptable
+   |
+LL |     let _six: usize = aux::sum_three(iter.clone());
+   |                                          ++++++++
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/not-copy-closure.stderr b/tests/ui/not-copy-closure.stderr
index 50e25a24d81..60cb1352313 100644
--- a/tests/ui/not-copy-closure.stderr
+++ b/tests/ui/not-copy-closure.stderr
@@ -11,10 +11,6 @@ note: closure cannot be moved more than once as it is not `Copy` due to moving t
    |
 LL |         a += 1;
    |         ^
-help: consider mutably borrowing `hello`
-   |
-LL |     let b = &mut hello;
-   |             ++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/bad-char-literals.stderr b/tests/ui/parser/bad-char-literals.stderr
index 1fb324a1b7e..5a81ede0336 100644
--- a/tests/ui/parser/bad-char-literals.stderr
+++ b/tests/ui/parser/bad-char-literals.stderr
@@ -15,7 +15,7 @@ error: character constant must be escaped: `\n`
 LL |       '
    |  ______^
 LL | | ';
-   | |_
+   | |_^
    |
 help: escape the character
    |
diff --git a/tests/ui/parser/unnecessary-let.stderr b/tests/ui/parser/unnecessary-let.stderr
index c6ac0d562f8..05ac1faafd4 100644
--- a/tests/ui/parser/unnecessary-let.stderr
+++ b/tests/ui/parser/unnecessary-let.stderr
@@ -2,12 +2,12 @@ error: expected pattern, found `let`
   --> $DIR/unnecessary-let.rs:2:9
    |
 LL |     for let x of [1, 2, 3] {}
-   |         ^^^
+   |         ^^^^
    |
 help: remove the unnecessary `let` keyword
    |
 LL -     for let x of [1, 2, 3] {}
-LL +     for  x of [1, 2, 3] {}
+LL +     for x of [1, 2, 3] {}
    |
 
 error: missing `in` in `for` loop
@@ -25,12 +25,12 @@ error: expected pattern, found `let`
   --> $DIR/unnecessary-let.rs:7:9
    |
 LL |         let 1 => {}
-   |         ^^^
+   |         ^^^^
    |
 help: remove the unnecessary `let` keyword
    |
 LL -         let 1 => {}
-LL +          1 => {}
+LL +         1 => {}
    |
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/pattern/usefulness/match-arm-statics-2.stderr b/tests/ui/pattern/usefulness/match-arm-statics-2.stderr
index e4dd35a5995..60b4fcca286 100644
--- a/tests/ui/pattern/usefulness/match-arm-statics-2.stderr
+++ b/tests/ui/pattern/usefulness/match-arm-statics-2.stderr
@@ -3,8 +3,20 @@ error[E0004]: non-exhaustive patterns: `(true, false)` not covered
    |
 LL |     match (true, false) {
    |           ^^^^^^^^^^^^^ pattern `(true, false)` not covered
+LL |
+LL |         TRUE_TRUE => (),
+   |         --------- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `TRUE_TRUE`
    |
    = note: the matched value is of type `(bool, bool)`
+note: constant `TRUE_TRUE` defined here
+  --> $DIR/match-arm-statics-2.rs:14:1
+   |
+LL | const TRUE_TRUE: (bool, bool) = (true, true);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: if you meant to introduce a binding, use a different name
+   |
+LL |         TRUE_TRUE_var => (),
+   |                  ++++
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         (false, true) => (),
diff --git a/tests/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr b/tests/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
index a8786d02414..0a3991fe3d1 100644
--- a/tests/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
+++ b/tests/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
@@ -199,8 +199,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
    |
 LL |     match s {
    |           ^ patterns `&[]` and `&[_, _, ..]` not covered
+LL |
+LL |         CONST => {}
+   |         ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
    |
    = note: the matched value is of type `&[bool]`
+note: constant `CONST` defined here
+  --> $DIR/slice-patterns-exhaustiveness.rs:88:5
+   |
+LL |     const CONST: &[bool] = &[true];
+   |     ^^^^^^^^^^^^^^^^^^^^
+help: if you meant to introduce a binding, use a different name
+   |
+LL |         CONST_var => {}
+   |              ++++
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~         CONST => {},
@@ -212,8 +224,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
    |
 LL |     match s {
    |           ^ patterns `&[]` and `&[_, _, ..]` not covered
+LL |
+LL |         CONST => {}
+   |         ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
    |
    = note: the matched value is of type `&[bool]`
+note: constant `CONST` defined here
+  --> $DIR/slice-patterns-exhaustiveness.rs:88:5
+   |
+LL |     const CONST: &[bool] = &[true];
+   |     ^^^^^^^^^^^^^^^^^^^^
+help: if you meant to introduce a binding, use a different name
+   |
+LL |         CONST_var => {}
+   |              ++++
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~         &[false] => {},
@@ -225,8 +249,20 @@ error[E0004]: non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
    |
 LL |     match s {
    |           ^ patterns `&[]` and `&[_, _, ..]` not covered
+...
+LL |         CONST => {}
+   |         ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
    |
    = note: the matched value is of type `&[bool]`
+note: constant `CONST` defined here
+  --> $DIR/slice-patterns-exhaustiveness.rs:88:5
+   |
+LL |     const CONST: &[bool] = &[true];
+   |     ^^^^^^^^^^^^^^^^^^^^
+help: if you meant to introduce a binding, use a different name
+   |
+LL |         CONST_var => {}
+   |              ++++
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~         CONST => {},
@@ -238,8 +274,20 @@ error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
    |
 LL |     match s {
    |           ^ pattern `&[_, _, ..]` not covered
+...
+LL |         CONST => {}
+   |         ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
    |
    = note: the matched value is of type `&[bool]`
+note: constant `CONST` defined here
+  --> $DIR/slice-patterns-exhaustiveness.rs:88:5
+   |
+LL |     const CONST: &[bool] = &[true];
+   |     ^^^^^^^^^^^^^^^^^^^^
+help: if you meant to introduce a binding, use a different name
+   |
+LL |         CONST_var => {}
+   |              ++++
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         CONST => {},
@@ -251,8 +299,20 @@ error[E0004]: non-exhaustive patterns: `&[false]` not covered
    |
 LL |     match s {
    |           ^ pattern `&[false]` not covered
+...
+LL |         CONST => {}
+   |         ----- this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST`
    |
    = note: the matched value is of type `&[bool]`
+note: constant `CONST` defined here
+  --> $DIR/slice-patterns-exhaustiveness.rs:88:5
+   |
+LL |     const CONST: &[bool] = &[true];
+   |     ^^^^^^^^^^^^^^^^^^^^
+help: if you meant to introduce a binding, use a different name
+   |
+LL |         CONST_var => {}
+   |              ++++
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         &[_, _, ..] => {},
@@ -264,8 +324,20 @@ error[E0004]: non-exhaustive patterns: `&[false]` not covered
    |
 LL |     match s1 {
    |           ^^ pattern `&[false]` not covered
+LL |
+LL |         CONST1 => {}
+   |         ------ this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `CONST1`
    |
    = note: the matched value is of type `&[bool; 1]`
+note: constant `CONST1` defined here
+  --> $DIR/slice-patterns-exhaustiveness.rs:124:5
+   |
+LL |     const CONST1: &[bool; 1] = &[true];
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+help: if you meant to introduce a binding, use a different name
+   |
+LL |         CONST1_var => {}
+   |               ++++
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~         CONST1 => {},
diff --git a/tests/ui/proc-macro/auxiliary/helper-attr.rs b/tests/ui/proc-macro/auxiliary/helper-attr.rs
new file mode 100644
index 00000000000..79ccefd9844
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/helper-attr.rs
@@ -0,0 +1,12 @@
+//@ force-host
+//@ no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+// Doesn't do anything, but has a helper attribute.
+#[proc_macro_derive(WithHelperAttr, attributes(x))]
+pub fn derive(_input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+    proc_macro::TokenStream::new()
+}
diff --git a/tests/ui/proc-macro/helper-attr-builtin-derive.rs b/tests/ui/proc-macro/helper-attr-builtin-derive.rs
new file mode 100644
index 00000000000..eb7292e093c
--- /dev/null
+++ b/tests/ui/proc-macro/helper-attr-builtin-derive.rs
@@ -0,0 +1,19 @@
+// This test checks that helper attributes of a derive proc macro can be used together with
+// other built-in derive macros.
+// issue: rust-lang/rust#132561
+//@ check-pass
+//@ aux-build:helper-attr.rs
+//@ edition:2021
+
+#[macro_use]
+extern crate helper_attr;
+
+use helper_attr::WithHelperAttr;
+
+#[derive(WithHelperAttr, Debug, Clone, PartialEq)]
+struct MyStruct<#[x] 'a, #[x] const A: usize, #[x] B> {
+    #[x]
+    field: &'a [B; A],
+}
+
+fn main() {}
diff --git a/tests/ui/simd-abi-checks-empty-list.rs b/tests/ui/simd-abi-checks-empty-list.rs
new file mode 100644
index 00000000000..c1785051e5a
--- /dev/null
+++ b/tests/ui/simd-abi-checks-empty-list.rs
@@ -0,0 +1,19 @@
+//@ needs-llvm-components: sparc
+//@ compile-flags: --target=sparc-unknown-none-elf --crate-type=rlib
+//@ build-pass
+//@ ignore-pass (test emits codegen-time warnings)
+#![no_core]
+#![feature(no_core, lang_items, repr_simd)]
+#![allow(improper_ctypes_definitions)]
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[repr(simd)]
+pub struct SimdVec([i32; 4]);
+
+pub extern "C" fn pass_by_vec(_: SimdVec) {}
+//~^ this function definition uses a SIMD vector type that is not currently supported with the chosen ABI
+//~| WARNING this was previously accepted by the compiler
diff --git a/tests/ui/simd-abi-checks-empty-list.stderr b/tests/ui/simd-abi-checks-empty-list.stderr
new file mode 100644
index 00000000000..d7ce52eab80
--- /dev/null
+++ b/tests/ui/simd-abi-checks-empty-list.stderr
@@ -0,0 +1,12 @@
+warning: this function definition uses a SIMD vector type that is not currently supported with the chosen ABI
+  --> $DIR/simd-abi-checks-empty-list.rs:17:1
+   |
+LL | pub extern "C" fn pass_by_vec(_: SimdVec) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here
+   |
+   = warning: 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 #116558 <https://github.com/rust-lang/rust/issues/116558>
+   = note: `#[warn(abi_unsupported_vector_types)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/simd-abi-checks.rs b/tests/ui/simd-abi-checks.rs
index 094c89930b7..9e3af26e9c4 100644
--- a/tests/ui/simd-abi-checks.rs
+++ b/tests/ui/simd-abi-checks.rs
@@ -12,19 +12,19 @@ use std::arch::x86_64::*;
 struct Wrapper(__m256);
 
 unsafe extern "C" fn w(_: Wrapper) {
-    //~^ ABI error: this function definition uses a vector type that requires the `avx` target feature, which is not enabled
+    //~^ this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
     //~| WARNING this was previously accepted by the compiler
     todo!()
 }
 
 unsafe extern "C" fn f(_: __m256) {
-    //~^ ABI error: this function definition uses a vector type that requires the `avx` target feature, which is not enabled
+    //~^ this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
     //~| WARNING this was previously accepted by the compiler
     todo!()
 }
 
 unsafe extern "C" fn g() -> __m256 {
-    //~^ ABI error: this function definition uses a vector type that requires the `avx` target feature, which is not enabled
+    //~^ this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
     //~| WARNING this was previously accepted by the compiler
     todo!()
 }
@@ -53,16 +53,16 @@ unsafe fn test() {
 fn main() {
     unsafe {
         f(g());
-        //~^ WARNING ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
-        //~| WARNING ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
+        //~^ WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+        //~| WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
         //~| WARNING this was previously accepted by the compiler
         //~| WARNING this was previously accepted by the compiler
     }
 
     unsafe {
         gavx(favx());
-        //~^ WARNING ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
-        //~| WARNING ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
+        //~^ WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+        //~| WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
         //~| WARNING this was previously accepted by the compiler
         //~| WARNING this was previously accepted by the compiler
     }
@@ -73,8 +73,8 @@ fn main() {
 
     unsafe {
         w(Wrapper(g()));
-        //~^ WARNING ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
-        //~| WARNING ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
+        //~^ WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
+        //~| WARNING this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
         //~| WARNING this was previously accepted by the compiler
         //~| WARNING this was previously accepted by the compiler
     }
diff --git a/tests/ui/simd-abi-checks.stderr b/tests/ui/simd-abi-checks.stderr
index aa7e9400169..7d2915f7dea 100644
--- a/tests/ui/simd-abi-checks.stderr
+++ b/tests/ui/simd-abi-checks.stderr
@@ -1,4 +1,4 @@
-warning: ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
   --> $DIR/simd-abi-checks.rs:55:11
    |
 LL |         f(g());
@@ -9,7 +9,7 @@ LL |         f(g());
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
    = note: `#[warn(abi_unsupported_vector_types)]` on by default
 
-warning: ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
   --> $DIR/simd-abi-checks.rs:55:9
    |
 LL |         f(g());
@@ -19,7 +19,7 @@ LL |         f(g());
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
-warning: ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
   --> $DIR/simd-abi-checks.rs:63:14
    |
 LL |         gavx(favx());
@@ -29,7 +29,7 @@ LL |         gavx(favx());
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
-warning: ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
   --> $DIR/simd-abi-checks.rs:63:9
    |
 LL |         gavx(favx());
@@ -39,7 +39,7 @@ LL |         gavx(favx());
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
-warning: ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
   --> $DIR/simd-abi-checks.rs:75:19
    |
 LL |         w(Wrapper(g()));
@@ -49,7 +49,7 @@ LL |         w(Wrapper(g()));
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
-warning: ABI error: this function call uses a vector type that requires the `avx` target feature, which is not enabled in the caller
+warning: this function call uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller
   --> $DIR/simd-abi-checks.rs:75:9
    |
 LL |         w(Wrapper(g()));
@@ -59,7 +59,7 @@ LL |         w(Wrapper(g()));
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
-warning: ABI error: this function definition uses a vector type that requires the `avx` target feature, which is not enabled
+warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
   --> $DIR/simd-abi-checks.rs:26:1
    |
 LL | unsafe extern "C" fn g() -> __m256 {
@@ -69,7 +69,7 @@ LL | unsafe extern "C" fn g() -> __m256 {
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
-warning: ABI error: this function definition uses a vector type that requires the `avx` target feature, which is not enabled
+warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
   --> $DIR/simd-abi-checks.rs:20:1
    |
 LL | unsafe extern "C" fn f(_: __m256) {
@@ -79,7 +79,7 @@ LL | unsafe extern "C" fn f(_: __m256) {
    = note: for more information, see issue #116558 <https://github.com/rust-lang/rust/issues/116558>
    = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`)
 
-warning: ABI error: this function definition uses a vector type that requires the `avx` target feature, which is not enabled
+warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `avx` target feature, which is not enabled
   --> $DIR/simd-abi-checks.rs:14:1
    |
 LL | unsafe extern "C" fn w(_: Wrapper) {
diff --git a/tests/ui/sse-abi-checks.rs b/tests/ui/sse-abi-checks.rs
index d2afd38fcc8..c453e91d11b 100644
--- a/tests/ui/sse-abi-checks.rs
+++ b/tests/ui/sse-abi-checks.rs
@@ -19,6 +19,6 @@ pub struct SseVector([i64; 2]);
 
 #[no_mangle]
 pub unsafe extern "C" fn f(_: SseVector) {
-    //~^ ABI error: this function definition uses a vector type that requires the `sse` target feature, which is not enabled
+    //~^ this function definition uses a SIMD vector type that (with the chosen ABI) requires the `sse` target feature, which is not enabled
     //~| WARNING this was previously accepted by the compiler
 }
diff --git a/tests/ui/sse-abi-checks.stderr b/tests/ui/sse-abi-checks.stderr
index 77c4e1fc07a..7dd13af5091 100644
--- a/tests/ui/sse-abi-checks.stderr
+++ b/tests/ui/sse-abi-checks.stderr
@@ -1,4 +1,4 @@
-warning: ABI error: this function definition uses a vector type that requires the `sse` target feature, which is not enabled
+warning: this function definition uses a SIMD vector type that (with the chosen ABI) requires the `sse` target feature, which is not enabled
   --> $DIR/sse-abi-checks.rs:21:1
    |
 LL | pub unsafe extern "C" fn f(_: SseVector) {
diff --git a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs
index af47ba8baa3..1a440a90cd7 100644
--- a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs
+++ b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.rs
@@ -2,9 +2,9 @@ fn main() {
     let A = 3;
     //~^ ERROR refutable pattern in local binding
     //~| patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
-    //~| missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable
     //~| HELP introduce a variable instead
     //~| SUGGESTION A_var
 
     const A: i32 = 2;
+    //~^ missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable
 }
diff --git a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
index b6c28612802..a275d8e4e83 100644
--- a/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
+++ b/tests/ui/suggestions/const-pat-non-exaustive-let-new-var.stderr
@@ -2,15 +2,18 @@ error[E0005]: refutable pattern in local binding
   --> $DIR/const-pat-non-exaustive-let-new-var.rs:2:9
    |
 LL |     let A = 3;
-   |         ^
-   |         |
-   |         patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
-   |         missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable
-   |         help: introduce a variable instead: `A_var`
+   |         ^ patterns `i32::MIN..=1_i32` and `3_i32..=i32::MAX` not covered
+...
+LL |     const A: i32 = 2;
+   |     ------------ missing patterns are not covered because `A` is interpreted as a constant pattern, not a new variable
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
+help: introduce a variable instead
+   |
+LL |     let A_var = 3;
+   |         ~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/no-method-found-suggest-trait-args.rs b/tests/ui/suggestions/no-method-found-suggest-trait-args.rs
new file mode 100644
index 00000000000..d51f86b29e8
--- /dev/null
+++ b/tests/ui/suggestions/no-method-found-suggest-trait-args.rs
@@ -0,0 +1,30 @@
+/// Tests that suggestions to add trait bounds that would enable using a method include appropriate
+/// placeholder arguments for that trait.
+
+trait Trait<I> {
+    fn method(&self) {}
+}
+
+trait Trait2<'a, A, const B: u8, C = (), const D: u8 = 0> {
+    fn method2(&self) {}
+}
+
+fn foo<T>(value: T) {
+    //~^ SUGGESTION : Trait</* I */>
+    //~| SUGGESTION : Trait2</* 'a, A, B */>
+    value.method();
+    //~^ ERROR no method named `method` found for type parameter `T` in the current scope [E0599]
+    value.method2();
+    //~^ ERROR no method named `method2` found for type parameter `T` in the current scope [E0599]
+}
+
+fn bar(value: impl Copy) {
+    //~^ SUGGESTION + Trait</* I */>
+    //~| SUGGESTION + Trait2</* 'a, A, B */>
+    value.method();
+    //~^ ERROR no method named `method` found for type parameter `impl Copy` in the current scope [E0599]
+    value.method2();
+    //~^ ERROR no method named `method2` found for type parameter `impl Copy` in the current scope [E0599]
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/no-method-found-suggest-trait-args.stderr b/tests/ui/suggestions/no-method-found-suggest-trait-args.stderr
new file mode 100644
index 00000000000..3dcd4667fa0
--- /dev/null
+++ b/tests/ui/suggestions/no-method-found-suggest-trait-args.stderr
@@ -0,0 +1,63 @@
+error[E0599]: no method named `method` found for type parameter `T` in the current scope
+  --> $DIR/no-method-found-suggest-trait-args.rs:15:11
+   |
+LL | fn foo<T>(value: T) {
+   |        - method `method` not found for this type parameter
+...
+LL |     value.method();
+   |           ^^^^^^ method not found in `T`
+   |
+   = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it:
+   |
+LL | fn foo<T: Trait</* I */>>(value: T) {
+   |         ++++++++++++++++
+
+error[E0599]: no method named `method2` found for type parameter `T` in the current scope
+  --> $DIR/no-method-found-suggest-trait-args.rs:17:11
+   |
+LL | fn foo<T>(value: T) {
+   |        - method `method2` not found for this type parameter
+...
+LL |     value.method2();
+   |           ^^^^^^^ method not found in `T`
+   |
+   = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following trait defines an item `method2`, perhaps you need to restrict type parameter `T` with it:
+   |
+LL | fn foo<T: Trait2</* 'a, A, B */>>(value: T) {
+   |         ++++++++++++++++++++++++
+
+error[E0599]: no method named `method` found for type parameter `impl Copy` in the current scope
+  --> $DIR/no-method-found-suggest-trait-args.rs:24:11
+   |
+LL | fn bar(value: impl Copy) {
+   |               --------- method `method` not found for this type parameter
+...
+LL |     value.method();
+   |           ^^^^^^ method not found in `impl Copy`
+   |
+   = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following trait defines an item `method`, perhaps you need to restrict type parameter `impl Copy` with it:
+   |
+LL | fn bar(value: impl Copy + Trait</* I */>) {
+   |                         ++++++++++++++++
+
+error[E0599]: no method named `method2` found for type parameter `impl Copy` in the current scope
+  --> $DIR/no-method-found-suggest-trait-args.rs:26:11
+   |
+LL | fn bar(value: impl Copy) {
+   |               --------- method `method2` not found for this type parameter
+...
+LL |     value.method2();
+   |           ^^^^^^^ method not found in `impl Copy`
+   |
+   = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following trait defines an item `method2`, perhaps you need to restrict type parameter `impl Copy` with it:
+   |
+LL | fn bar(value: impl Copy + Trait2</* 'a, A, B */>) {
+   |                         ++++++++++++++++++++++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/traits/const-traits/const-trait-bounds.rs b/tests/ui/traits/const-traits/const-trait-bounds.rs
deleted file mode 100644
index 8722d9909ed..00000000000
--- a/tests/ui/traits/const-traits/const-trait-bounds.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-//@ known-bug: #110395
-//@ compile-flags: -Znext-solver
-// FIXME(const_trait_impl): check-pass
-#![feature(const_trait_impl, generic_const_exprs)]
-#![allow(incomplete_features)]
-
-fn main() {
-    let _ = process::<()>([()]);
-    let _ = Struct::<(), 4> { field: [1, 0] };
-}
-
-fn process<T: const Trait>(input: [(); T::make(2)]) -> [(); T::make(2)] {
-    input
-}
-
-struct Struct<T: const Trait, const P: usize>
-where
-    [u32; T::make(P)]:,
-{
-    field: [u32; T::make(P)],
-}
-
-#[const_trait]
-trait Trait {
-    fn make(input: usize) -> usize;
-}
-
-impl const Trait for () {
-    fn make(input: usize) -> usize {
-        input / 2
-    }
-}
diff --git a/tests/ui/traits/const-traits/const-trait-bounds.stderr b/tests/ui/traits/const-traits/const-trait-bounds.stderr
deleted file mode 100644
index 29a01b9d7dc..00000000000
--- a/tests/ui/traits/const-traits/const-trait-bounds.stderr
+++ /dev/null
@@ -1,29 +0,0 @@
-error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
-  --> $DIR/const-trait-bounds.rs:4:30
-   |
-LL | #![feature(const_trait_impl, generic_const_exprs)]
-   |                              ^^^^^^^^^^^^^^^^^^^
-   |
-   = help: remove one of these features
-
-error[E0284]: type annotations needed: cannot normalize `process<T>::{constant#0}`
-  --> $DIR/const-trait-bounds.rs:12:35
-   |
-LL | fn process<T: const Trait>(input: [(); T::make(2)]) -> [(); T::make(2)] {
-   |                                   ^^^^^^^^^^^^^^^^ cannot normalize `process<T>::{constant#0}`
-
-error[E0284]: type annotations needed: cannot normalize `Struct<T, P>::field::{constant#0}`
-  --> $DIR/const-trait-bounds.rs:20:12
-   |
-LL |     field: [u32; T::make(P)],
-   |            ^^^^^^^^^^^^^^^^^ cannot normalize `Struct<T, P>::field::{constant#0}`
-
-error[E0284]: type annotations needed: cannot normalize `process<T>::{constant#1}`
-  --> $DIR/const-trait-bounds.rs:13:5
-   |
-LL |     input
-   |     ^^^^^ cannot normalize `process<T>::{constant#1}`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.stderr b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.current.stderr
index 5554f0ccc0a..ef636811fd5 100644
--- a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.stderr
+++ b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.current.stderr
@@ -1,5 +1,5 @@
 warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/normalize-self-type-constrains-trait-args.rs:5:12
+  --> $DIR/normalize-self-type-constrains-trait-args.rs:8:12
    |
 LL | #![feature(lazy_type_alias)]
    |            ^^^^^^^^^^^^^^^
diff --git a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.next.stderr
new file mode 100644
index 00000000000..ef636811fd5
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.next.stderr
@@ -0,0 +1,11 @@
+warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/normalize-self-type-constrains-trait-args.rs:8:12
+   |
+LL | #![feature(lazy_type_alias)]
+   |            ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.rs b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.rs
index 0ece8f8321c..c2a01671346 100644
--- a/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.rs
+++ b/tests/ui/traits/next-solver/normalize/normalize-self-type-constrains-trait-args.rs
@@ -1,3 +1,6 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@ ignore-compare-mode-next-solver (explicit revisions)
 //@ check-pass
 
 // This goal is also possible w/ a GAT, but lazy_type_alias
diff --git a/tests/ui/wasm/wasm-stable-target-features.rs b/tests/ui/wasm/wasm-stable-target-features.rs
new file mode 100644
index 00000000000..b6d4b67d070
--- /dev/null
+++ b/tests/ui/wasm/wasm-stable-target-features.rs
@@ -0,0 +1,49 @@
+//@ only-wasm32
+//@ build-pass
+
+// Test that a variety of WebAssembly features are all stable and can be used in
+// `#[target_feature]`. That should mean they're also available via
+// `#[cfg(target_feature)]` as well.
+
+#[target_feature(enable = "multivalue")]
+fn foo1() {}
+
+#[target_feature(enable = "reference-types")]
+fn foo2() {}
+
+#[target_feature(enable = "bulk-memory")]
+fn foo3() {}
+
+#[target_feature(enable = "extended-const")]
+fn foo4() {}
+
+#[target_feature(enable = "mutable-globals")]
+fn foo5() {}
+
+#[target_feature(enable = "nontrapping-fptoint")]
+fn foo6() {}
+
+#[target_feature(enable = "simd128")]
+fn foo7() {}
+
+#[target_feature(enable = "relaxed-simd")]
+fn foo8() {}
+
+#[target_feature(enable = "sign-ext")]
+fn foo9() {}
+
+#[target_feature(enable = "tail-call")]
+fn foo10() {}
+
+fn main() {
+    foo1();
+    foo2();
+    foo3();
+    foo4();
+    foo5();
+    foo6();
+    foo7();
+    foo8();
+    foo9();
+    foo10();
+}
diff --git a/triagebot.toml b/triagebot.toml
index 95538dd7ee3..d5bc549ca9f 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -212,6 +212,10 @@ trigger_files = [
     "src/tools/rustdoc-gui",
     "src/tools/rustdoc-js",
     "src/tools/rustdoc-themes",
+
+    # Docs
+    "src/doc/rustdoc.md",
+    "src/doc/rustdoc/",
 ]
 exclude_labels = [
     "T-*",
@@ -971,36 +975,30 @@ cc = ["@kobzol"]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
 users_on_vacation = [
-    "fmease",
     "jyn514",
     "oli-obk",
+    "onur-ozkan",
 ]
 
 [assign.adhoc_groups]
-compiler-team = [
+compiler = [
+    "@BoxyUwU",
+    "@chenyukang",
     "@cjgillot",
     "@compiler-errors",
-    "@petrochenkov",
     "@davidtwco",
     "@estebank",
+    "@fee1-dead",
+    "@fmease",
+    "@jieyouxu",
     "@lcnr",
+    "@Nadrieril",
+    "@nnethercote",
     "@oli-obk",
+    "@petrochenkov",
     "@pnkfelix",
-    "@wesleywiser",
-]
-compiler-team-contributors = [
     "@TaKO8Ki",
-    "@Nadrieril",
-    "@nnethercote",
-    "@fmease",
-    "@fee1-dead",
-    "@jieyouxu",
-    "@BoxyUwU",
-    "@chenyukang",
-]
-compiler = [
-    "compiler-team",
-    "compiler-team-contributors",
+    "@wesleywiser",
 ]
 libs = [
     "@cuviper",
@@ -1034,6 +1032,11 @@ docs = [
     "@ehuss",
     "@GuillaumeGomez",
 ]
+
+codegen = [
+    "@saethlin",
+    "@workingjubilee",
+]
 query-system = [
     "@cjgillot",
 ]
@@ -1129,6 +1132,7 @@ project-exploit-mitigations = [
 "/Cargo.lock" =                                          ["@Mark-Simulacrum"]
 "/Cargo.toml" =                                          ["@Mark-Simulacrum"]
 "/compiler" =                                            ["compiler"]
+"/compiler/rustc_abi" =                                  ["compiler", "codegen"]
 "/compiler/rustc_arena" =                                ["compiler", "arena"]
 "/compiler/rustc_ast" =                                  ["compiler", "parser"]
 "/compiler/rustc_ast_lowering" =                         ["compiler", "ast_lowering"]
@@ -1139,7 +1143,7 @@ project-exploit-mitigations = [
 "/compiler/rustc_lexer" =                                ["compiler", "lexer"]
 "/compiler/rustc_llvm" =                                 ["@cuviper"]
 "/compiler/rustc_codegen_llvm/src/debuginfo" =           ["compiler", "debuginfo"]
-"/compiler/rustc_codegen_ssa" =                          ["compiler", "@saethlin"]
+"/compiler/rustc_codegen_ssa" =                          ["compiler", "codegen"]
 "/compiler/rustc_middle/src/mir" =                       ["compiler", "mir"]
 "/compiler/rustc_middle/src/traits" =                    ["compiler", "types"]
 "/compiler/rustc_middle/src/ty" =                        ["compiler", "types"]
@@ -1185,6 +1189,12 @@ project-exploit-mitigations = [
 "/src/rustdoc-json-types" =                              ["rustdoc"]
 "/src/stage0" =                                          ["bootstrap"]
 "/tests/run-make" =                                      ["@jieyouxu"]
+"/tests/rustdoc" =                                       ["rustdoc"]
+"/tests/rustdoc-gui" =                                   ["rustdoc"]
+"/tests/rustdoc-js-std" =                                ["rustdoc"]
+"/tests/rustdoc-js" =                                    ["rustdoc"]
+"/tests/rustdoc-json" =                                  ["@aDotInTheVoid"]
+"/tests/rustdoc-ui" =                                    ["rustdoc"]
 "/tests/ui" =                                            ["compiler"]
 "/src/tools/cargo" =                                     ["@ehuss"]
 "/src/tools/compiletest" =                               ["bootstrap", "@wesleywiser", "@oli-obk", "@compiler-errors", "@jieyouxu"]